Merge pull request #821 from mgomezch/yesodauthpersist
Decouple YesodAuthPersist from Persistent
This commit is contained in:
commit
bec985467f
@ -9,6 +9,7 @@
|
|||||||
{-# LANGUAGE RankNTypes #-}
|
{-# LANGUAGE RankNTypes #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE DeriveDataTypeable #-}
|
{-# LANGUAGE DeriveDataTypeable #-}
|
||||||
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||||
module Yesod.Auth
|
module Yesod.Auth
|
||||||
( -- * Subsite
|
( -- * Subsite
|
||||||
@ -18,8 +19,7 @@ module Yesod.Auth
|
|||||||
, AuthPlugin (..)
|
, AuthPlugin (..)
|
||||||
, getAuth
|
, getAuth
|
||||||
, YesodAuth (..)
|
, YesodAuth (..)
|
||||||
, YesodAuthPersist
|
, YesodAuthPersist (..)
|
||||||
, AuthEntity
|
|
||||||
-- * Plugin interface
|
-- * Plugin interface
|
||||||
, Creds (..)
|
, Creds (..)
|
||||||
, setCreds
|
, setCreds
|
||||||
@ -29,8 +29,10 @@ module Yesod.Auth
|
|||||||
, loginErrorMessageI
|
, loginErrorMessageI
|
||||||
-- * User functions
|
-- * User functions
|
||||||
, defaultMaybeAuthId
|
, defaultMaybeAuthId
|
||||||
|
, maybeAuthPair
|
||||||
, maybeAuth
|
, maybeAuth
|
||||||
, requireAuthId
|
, requireAuthId
|
||||||
|
, requireAuthPair
|
||||||
, requireAuth
|
, requireAuth
|
||||||
-- * Exception
|
-- * Exception
|
||||||
, AuthException (..)
|
, AuthException (..)
|
||||||
@ -162,14 +164,7 @@ class (Yesod master, PathPiece (AuthId master), RenderMessage master FormMessage
|
|||||||
maybeAuthId :: HandlerT master IO (Maybe (AuthId master))
|
maybeAuthId :: HandlerT master IO (Maybe (AuthId master))
|
||||||
|
|
||||||
default maybeAuthId
|
default maybeAuthId
|
||||||
:: ( YesodAuth master
|
:: (YesodAuthPersist master, Typeable (AuthEntity master))
|
||||||
, PersistEntityBackend val ~ YesodPersistBackend master
|
|
||||||
, Key val ~ AuthId master
|
|
||||||
, PersistStore (PersistEntityBackend val)
|
|
||||||
, PersistEntity val
|
|
||||||
, YesodPersist master
|
|
||||||
, Typeable val
|
|
||||||
)
|
|
||||||
=> HandlerT master IO (Maybe (AuthId master))
|
=> HandlerT master IO (Maybe (AuthId master))
|
||||||
maybeAuthId = defaultMaybeAuthId
|
maybeAuthId = defaultMaybeAuthId
|
||||||
|
|
||||||
@ -193,40 +188,22 @@ credsKey = "_ID"
|
|||||||
--
|
--
|
||||||
-- Since 1.1.2
|
-- Since 1.1.2
|
||||||
defaultMaybeAuthId
|
defaultMaybeAuthId
|
||||||
:: ( YesodAuth master
|
:: (YesodAuthPersist master, Typeable (AuthEntity master))
|
||||||
, b ~ YesodPersistBackend master
|
=> HandlerT master IO (Maybe (AuthId master))
|
||||||
, b ~ PersistEntityBackend val
|
defaultMaybeAuthId = runMaybeT $ do
|
||||||
, Key val ~ AuthId master
|
s <- MaybeT $ lookupSession credsKey
|
||||||
, PersistStore b
|
aid <- MaybeT $ return $ fromPathPiece s
|
||||||
, PersistEntity val
|
_ <- MaybeT $ cachedAuth aid
|
||||||
, YesodPersist master
|
return aid
|
||||||
, Typeable val
|
|
||||||
) => HandlerT master IO (Maybe (AuthId master))
|
|
||||||
defaultMaybeAuthId = do
|
|
||||||
ms <- lookupSession credsKey
|
|
||||||
case ms of
|
|
||||||
Nothing -> return Nothing
|
|
||||||
Just s ->
|
|
||||||
case fromPathPiece s of
|
|
||||||
Nothing -> return Nothing
|
|
||||||
Just aid -> fmap (fmap entityKey) $ cachedAuth aid
|
|
||||||
|
|
||||||
cachedAuth :: ( YesodAuth master
|
cachedAuth
|
||||||
, b ~ YesodPersistBackend master
|
:: (YesodAuthPersist master, Typeable (AuthEntity master))
|
||||||
, b ~ PersistEntityBackend val
|
=> AuthId master -> HandlerT master IO (Maybe (AuthEntity master))
|
||||||
, Key val ~ AuthId master
|
cachedAuth
|
||||||
, PersistStore b
|
= fmap unCachedMaybeAuth
|
||||||
, PersistEntity val
|
. cached
|
||||||
, YesodPersist master
|
. fmap CachedMaybeAuth
|
||||||
, Typeable val
|
. getAuthEntity
|
||||||
) => AuthId master -> HandlerT master IO (Maybe (Entity val))
|
|
||||||
cachedAuth aid = runMaybeT $ do
|
|
||||||
a <- MaybeT $ fmap unCachedMaybeAuth
|
|
||||||
$ cached
|
|
||||||
$ fmap CachedMaybeAuth
|
|
||||||
$ runDB
|
|
||||||
$ get aid
|
|
||||||
return $ Entity aid a
|
|
||||||
|
|
||||||
|
|
||||||
loginErrorMessageI :: (MonadResourceBase m, YesodAuth master)
|
loginErrorMessageI :: (MonadResourceBase m, YesodAuth master)
|
||||||
@ -372,47 +349,65 @@ handlePluginR plugin pieces = do
|
|||||||
-- assumes that you are using a Persistent database.
|
-- assumes that you are using a Persistent database.
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- Since 1.1.0
|
||||||
maybeAuth :: ( YesodAuth master
|
maybeAuth :: ( YesodAuthPersist master
|
||||||
, b ~ YesodPersistBackend master
|
, val ~ AuthEntity master
|
||||||
, b ~ PersistEntityBackend val
|
|
||||||
, Key val ~ AuthId master
|
, Key val ~ AuthId master
|
||||||
, PersistStore b
|
|
||||||
, PersistEntity val
|
, PersistEntity val
|
||||||
, YesodPersist master
|
|
||||||
, Typeable val
|
, Typeable val
|
||||||
) => HandlerT master IO (Maybe (Entity val))
|
) => HandlerT master IO (Maybe (Entity val))
|
||||||
maybeAuth = runMaybeT $ do
|
maybeAuth = runMaybeT $ do
|
||||||
|
(aid, ae) <- MaybeT maybeAuthPair
|
||||||
|
return $ Entity aid ae
|
||||||
|
|
||||||
|
-- | Similar to 'maybeAuth', but doesn’t assume that you are using a
|
||||||
|
-- Persistent database.
|
||||||
|
--
|
||||||
|
-- Since 1.4.0
|
||||||
|
maybeAuthPair :: (YesodAuthPersist master, Typeable (AuthEntity master))
|
||||||
|
=> HandlerT master IO (Maybe (AuthId master, AuthEntity master))
|
||||||
|
maybeAuthPair = runMaybeT $ do
|
||||||
aid <- MaybeT maybeAuthId
|
aid <- MaybeT maybeAuthId
|
||||||
MaybeT $ cachedAuth aid
|
ae <- MaybeT $ cachedAuth aid
|
||||||
|
return (aid, ae)
|
||||||
|
|
||||||
|
|
||||||
newtype CachedMaybeAuth val = CachedMaybeAuth { unCachedMaybeAuth :: Maybe val }
|
newtype CachedMaybeAuth val = CachedMaybeAuth { unCachedMaybeAuth :: Maybe val }
|
||||||
deriving Typeable
|
deriving Typeable
|
||||||
|
|
||||||
-- | Constraint which states that the given site is an instance of @YesodAuth@
|
-- | Class which states that the given site is an instance of @YesodAuth@
|
||||||
-- and that its @AuthId@ is in fact a persistent @Key@ for the given value.
|
-- and that its @AuthId@ is a lookup key for the full user information in
|
||||||
-- This is the common case in Yesod, and means that you can easily look up the
|
-- a @YesodPersist@ database.
|
||||||
-- full informatin on a given user.
|
|
||||||
--
|
--
|
||||||
-- Since 1.2.0
|
-- The default implementation of @getAuthEntity@ assumes that the @AuthId@
|
||||||
type YesodAuthPersist master =
|
-- for the @YesodAuth@ superclass is in fact a persistent @Key@ for the
|
||||||
( YesodAuth master
|
-- given value. This is the common case in Yesod, and means that you can
|
||||||
, YesodPersistBackend master
|
-- easily look up the full information on a given user.
|
||||||
~ PersistEntityBackend (AuthEntity master)
|
--
|
||||||
, Key (AuthEntity master) ~ AuthId master
|
-- Since 1.4.0
|
||||||
, PersistStore (YesodPersistBackend master)
|
class (YesodAuth master, YesodPersist master) => YesodAuthPersist master where
|
||||||
, PersistEntity (AuthEntity master)
|
-- | If the @AuthId@ for a given site is a persistent ID, this will give the
|
||||||
, YesodPersist master
|
-- value for that entity. E.g.:
|
||||||
, Typeable (AuthEntity master)
|
--
|
||||||
)
|
-- > type AuthId MySite = UserId
|
||||||
|
-- > AuthEntity MySite ~ User
|
||||||
|
--
|
||||||
|
-- Since 1.2.0
|
||||||
|
type AuthEntity master :: *
|
||||||
|
type AuthEntity master = KeyEntity (AuthId master)
|
||||||
|
|
||||||
|
getAuthEntity :: AuthId master -> HandlerT master IO (Maybe (AuthEntity master))
|
||||||
|
|
||||||
|
default getAuthEntity
|
||||||
|
:: ( YesodPersistBackend master
|
||||||
|
~ PersistEntityBackend (AuthEntity master)
|
||||||
|
, Key (AuthEntity master) ~ AuthId master
|
||||||
|
, PersistStore (YesodPersistBackend master)
|
||||||
|
, PersistEntity (AuthEntity master)
|
||||||
|
)
|
||||||
|
=> AuthId master -> HandlerT master IO (Maybe (AuthEntity master))
|
||||||
|
getAuthEntity = runDB . get
|
||||||
|
|
||||||
|
|
||||||
-- | If the @AuthId@ for a given site is a persistent ID, this will give the
|
|
||||||
-- value for that entity. E.g.:
|
|
||||||
--
|
|
||||||
-- > type AuthId MySite = UserId
|
|
||||||
-- > AuthEntity MySite ~ User
|
|
||||||
--
|
|
||||||
-- Since 1.2.0
|
|
||||||
type AuthEntity master = KeyEntity (AuthId master)
|
|
||||||
type family KeyEntity key
|
type family KeyEntity key
|
||||||
type instance KeyEntity (Key x) = x
|
type instance KeyEntity (Key x) = x
|
||||||
|
|
||||||
@ -427,9 +422,22 @@ requireAuthId = maybeAuthId >>= maybe handleAuthLack return
|
|||||||
-- authenticated or responds with error 401 if this is an API client (expecting JSON).
|
-- authenticated or responds with error 401 if this is an API client (expecting JSON).
|
||||||
--
|
--
|
||||||
-- Since 1.1.0
|
-- Since 1.1.0
|
||||||
requireAuth :: YesodAuthPersist master => HandlerT master IO (Entity (AuthEntity master))
|
requireAuth :: ( YesodAuthPersist master
|
||||||
|
, val ~ AuthEntity master
|
||||||
|
, Key val ~ AuthId master
|
||||||
|
, PersistEntity val
|
||||||
|
, Typeable val
|
||||||
|
) => HandlerT master IO (Entity val)
|
||||||
requireAuth = maybeAuth >>= maybe handleAuthLack return
|
requireAuth = maybeAuth >>= maybe handleAuthLack return
|
||||||
|
|
||||||
|
-- | Similar to 'requireAuth', but not tied to Persistent's 'Entity' type.
|
||||||
|
-- Instead, the 'AuthId' and 'AuthEntity' are returned in a tuple.
|
||||||
|
--
|
||||||
|
-- Since 1.4.0
|
||||||
|
requireAuthPair :: (YesodAuthPersist master, Typeable (AuthEntity master))
|
||||||
|
=> HandlerT master IO (AuthId master, AuthEntity master)
|
||||||
|
requireAuthPair = maybeAuthPair >>= maybe handleAuthLack return
|
||||||
|
|
||||||
handleAuthLack :: Yesod master => HandlerT master IO a
|
handleAuthLack :: Yesod master => HandlerT master IO a
|
||||||
handleAuthLack = do
|
handleAuthLack = do
|
||||||
aj <- acceptsJson
|
aj <- acceptsJson
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user