-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Authentication via encrypted cookies
--   
--   Authentication via encrypted client-side cookies, inspired by
--   client-session library by Michael Snoyman and based on ideas of the
--   paper "A Secure Cookie Protocol" by Alex Liu et al.
@package servant-auth-cookie
@version 0.5.0.5


-- | <h1>Description</h1>
--   
--   Authentication via encrypted client-side cookies, inspired by
--   client-session library by Michael Snoyman and based on ideas of the
--   paper "A Secure Cookie Protocol" by Alex Liu et al.
module Servant.Server.Experimental.Auth.Cookie

-- | A type for encryption and decryption functions operating on
--   <a>ByteString</a>s.
type CipherAlgorithm c = c -> IV c -> ByteString -> ByteString

-- | A type family that maps user-defined data to <a>AuthServerData</a>.

-- | Cookie representation.
data Cookie
Cookie :: ByteString -> UTCTime -> ByteString -> Cookie

-- | The initialization vector
[cookieIV] :: Cookie -> ByteString

-- | The cookie's expiration time
[cookieExpirationTime] :: Cookie -> UTCTime

-- | The payload
[cookiePayload] :: Cookie -> ByteString

-- | The exception is thrown when something goes wrong with this package.
data AuthCookieException

-- | Could not make <a>IV</a> for block cipher.
CannotMakeIV :: ByteString -> AuthCookieException

-- | Could not initialize a cipher context.
BadProperKey :: CryptoError -> AuthCookieException

-- | The key is too short for current cipher algorithm. Arguments of this
--   constructor: minimal key length, actual key length.
TooShortProperKey :: Int -> Int -> AuthCookieException

-- | Thrown when Message Authentication Code (MAC) is not correct.
IncorrectMAC :: ByteString -> AuthCookieException

-- | Thrown when expiration time cannot be parsed.
CannotParseExpirationTime :: ByteString -> AuthCookieException

-- | Thrown when <a>Cookie</a> has expired. Arguments of the constructor:
--   expiration time, actual time.
CookieExpired :: UTCTime -> UTCTime -> AuthCookieException

-- | This is thrown when <a>runGet</a> or <a>decode</a> blows up.
SessionDeserializationFailed :: String -> AuthCookieException

-- | Wrapper for cookies and sessions to keep some related metadata.
data WithMetadata a
WithMetadata :: a -> Bool -> WithMetadata a

-- | Value itself
[wmData] :: WithMetadata a -> a

-- | Whether we should renew cookies/session
[wmRenew] :: WithMetadata a -> Bool

-- | Helper type to wrap endpoints.
type Cookied a = Headers '[Header "Set-Cookie" EncryptedSession] a

-- | Wrapper for an implementation of an endpoint to make it automatically
--   renew the cookies.
cookied :: (Serialize a, ServerKeySet k) => AuthCookieSettings -> RandomSource -> k -> (a -> r) -> ((WithMetadata a) -> Handler (Cookied r))

-- | A wrapper of self-resetting <a>DRG</a> suitable for concurrent usage.
data RandomSource

-- | Constructor for <a>RandomSource</a> value.
mkRandomSource :: (MonadIO m, DRG d) => IO d -> Int -> m RandomSource

-- | Extract pseudo-random bytes from <a>RandomSource</a>.
getRandomBytes :: MonadIO m => RandomSource -> Int -> m ByteString

-- | Generates random sequence of bytes from new DRG
generateRandomBytes :: Int -> IO ByteString

-- | Internal representation of a server key.
type ServerKey = ByteString

-- | Interface for a set of server keys.
class ServerKeySet k

-- | Retrieve current and rotated keys respectively.
getKeys :: (ServerKeySet k, MonadThrow m, MonadIO m) => k -> m (ServerKey, [ServerKey])

-- | Non-graciously remove the key from a keyset.
removeKey :: (ServerKeySet k, MonadThrow m, MonadIO m) => k -> ServerKey -> m ()

-- | A keyset containing only one key, that doesn't change.
data PersistentServerKey

-- | Create instance of <a>PersistentServerKey</a>.
mkPersistentServerKey :: ByteString -> PersistentServerKey

-- | Customizable key set, that provides partial implementation of
--   <a>ServerKeySet</a>.
data RenewableKeySet s p

-- | Customizable actions for <a>RenewableKeySet</a>.
data RenewableKeySetHooks s p
RenewableKeySetHooks :: (forall m. (MonadIO m, MonadThrow m) => p -> ([ServerKey], s) -> m ([ServerKey], s)) -> (forall m. (MonadIO m, MonadThrow m) => p -> ([ServerKey], s) -> m Bool) -> (forall m. (MonadIO m, MonadThrow m) => p -> ServerKey -> m ()) -> RenewableKeySetHooks s p

-- | Called when a keyset needs to refresh it's state. It's result might be
--   discarded occasionally in favour of result yielded in another thread.
[rkshNewState] :: RenewableKeySetHooks s p -> forall m. (MonadIO m, MonadThrow m) => p -> ([ServerKey], s) -> m ([ServerKey], s)

-- | Called before retrieving the keys and refreshing the state.
[rkshNeedUpdate] :: RenewableKeySetHooks s p -> forall m. (MonadIO m, MonadThrow m) => p -> ([ServerKey], s) -> m Bool

-- | Called after removing the key. This hook is called only if the key
--   belongs to a keyset and called once per key. The only purpose of it is
--   to clear the garbage after removing the key. The state might differs
--   after removing the key and before calling the hook, therefore the hook
--   doesn't rely on the state.
[rkshRemoveKey] :: RenewableKeySetHooks s p -> forall m. (MonadIO m, MonadThrow m) => p -> ServerKey -> m ()

-- | Create instance of <a>RenewableKeySet</a>.
mkRenewableKeySet :: (MonadIO m) => RenewableKeySetHooks s p -> p -> s -> m (RenewableKeySet s p)

-- | Options that determine authentication mechanisms. Use <a>def</a> to
--   get default value of this type.
data AuthCookieSettings
[AuthCookieSettings] :: (HashAlgorithm h, BlockCipher c) => {acsSessionField :: ByteString  Name of a cookie which stores session object, acsCookieFlags :: [ByteString]  Session cookie's flags, acsMaxAge :: NominalDiffTime  For how long the cookie will be valid (corresponds to “Max-Age” attribute)., acsExpirationFormat :: String  Expiration format as in 'formatTime'., acsPath :: ByteString  Scope of the cookie (corresponds to “Path” attribute)., acsHashAlgorithm :: Proxy h  Hash algorithm that will be used in 'hmac'., acsCipher :: Proxy c  Symmetric cipher that will be used in encryption., acsEncryptAlgorithm :: CipherAlgorithm c  Algorithm to encrypt cookies., acsDecryptAlgorithm :: CipherAlgorithm c  Algorithm to decrypt cookies.} -> AuthCookieSettings

-- | A newtype wrapper over <a>ByteString</a>
newtype EncryptedSession
EncryptedSession :: ByteString -> EncryptedSession

-- | An empty <a>EncryptedSession</a>
emptyEncryptedSession :: EncryptedSession

-- | Encrypt given <a>Cookie</a> with server key.
--   
--   The function can throw the following exceptions (of type
--   <a>AuthCookieException</a>):
--   
--   <ul>
--   <li><a>TooShortProperKey</a></li>
--   <li><a>CannotMakeIV</a></li>
--   <li><a>BadProperKey</a></li>
--   </ul>
encryptCookie :: (MonadIO m, MonadThrow m, ServerKeySet k) => AuthCookieSettings -> k -> Cookie -> m (Tagged EncryptedCookie ByteString)

-- | Decrypt a <a>Cookie</a> from <a>ByteString</a>.
--   
--   The function can throw the following exceptions (of type
--   <a>AuthCookieException</a>):
--   
--   <ul>
--   <li><a>TooShortProperKey</a></li>
--   <li><a>CannotMakeIV</a></li>
--   <li><a>BadProperKey</a></li>
--   <li><a>IncorrectMAC</a></li>
--   <li><a>CannotParseExpirationTime</a></li>
--   <li><a>CookieExpired</a></li>
--   </ul>
decryptCookie :: (MonadIO m, MonadThrow m, ServerKeySet k) => AuthCookieSettings -> k -> Tagged EncryptedCookie ByteString -> m (WithMetadata Cookie)

-- | Pack session object into a cookie. The function can throw the same
--   exceptions as <a>encryptCookie</a>.
encryptSession :: (MonadIO m, MonadThrow m, Serialize a, ServerKeySet k) => AuthCookieSettings -> RandomSource -> k -> a -> m (Tagged SerializedEncryptedCookie ByteString)

-- | Unpack session value from a cookie. The function can throw the same
--   exceptions as <a>decryptCookie</a>.
decryptSession :: (MonadIO m, MonadThrow m, Serialize a, ServerKeySet k) => AuthCookieSettings -> k -> Tagged SerializedEncryptedCookie ByteString -> m (WithMetadata a)

-- | Add cookie header to response. The function can throw the same
--   exceptions as <a>encryptSession</a>.
addSession :: (MonadIO m, MonadThrow m, Serialize a, AddHeader (e :: Symbol) EncryptedSession s r, ServerKeySet k) => AuthCookieSettings -> RandomSource -> k -> a -> s -> m r

-- | <a>Remove</a> a session by invalidating the cookie.
removeSession :: (Monad m, AddHeader (e :: Symbol) EncryptedSession s r) => AuthCookieSettings -> s -> m r

-- | Add cookie session to error allowing to set cookie even if response is
--   not 200.
addSessionToErr :: (MonadIO m, MonadThrow m, Serialize a, ServerKeySet k) => AuthCookieSettings -> RandomSource -> k -> a -> ServantErr -> m ServantErr

-- | <a>Remove</a> a session by invalidating the cookie. Cookie expiry date
--   is set at 0 and content is wiped
removeSessionFromErr :: (Monad m) => AuthCookieSettings -> ServantErr -> m ServantErr

-- | Request handler that checks cookies. If <a>Cookie</a> is just missing,
--   you get <a>Nothing</a>, but if something is wrong with its format,
--   <a>getSession</a> can throw the same exceptions as
--   <a>decryptSession</a>.
getSession :: (MonadIO m, MonadThrow m, Serialize a, ServerKeySet k) => AuthCookieSettings -> k -> Request -> m (Maybe (WithMetadata a))

-- | Cookie authentication handler.
defaultAuthHandler :: (Serialize a, ServerKeySet k) => AuthCookieSettings -> k -> AuthHandler Request (WithMetadata a)

-- | Render session cookie to <a>ByteString</a>.
renderSession :: (MonadIO m, MonadThrow m, Serialize a, ServerKeySet k) => AuthCookieSettings -> RandomSource -> k -> a -> m ByteString

-- | Parse session cookie from <a>RequestHeaders</a>.
parseSessionRequest :: AuthCookieSettings -> RequestHeaders -> Maybe (Tagged SerializedEncryptedCookie ByteString)

-- | Parse session cookie from <a>ResponseHeaders</a>.
parseSessionResponse :: AuthCookieSettings -> ResponseHeaders -> Maybe (Tagged SerializedEncryptedCookie ByteString)
instance GHC.Show.Show Servant.Server.Experimental.Auth.Cookie.AuthCookieException
instance GHC.Classes.Eq Servant.Server.Experimental.Auth.Cookie.AuthCookieException
instance GHC.Show.Show Servant.Server.Experimental.Auth.Cookie.EncryptedSession
instance GHC.Classes.Eq Servant.Server.Experimental.Auth.Cookie.EncryptedSession
instance GHC.Show.Show Servant.Server.Experimental.Auth.Cookie.Cookie
instance GHC.Classes.Eq Servant.Server.Experimental.Auth.Cookie.Cookie
instance Web.Internal.HttpApiData.ToHttpApiData Servant.Server.Experimental.Auth.Cookie.EncryptedSession
instance GHC.Exception.Exception Servant.Server.Experimental.Auth.Cookie.AuthCookieException
instance Servant.Server.Experimental.Auth.Cookie.ServerKeySet Servant.Server.Experimental.Auth.Cookie.PersistentServerKey
instance GHC.Classes.Eq s => Servant.Server.Experimental.Auth.Cookie.ServerKeySet (Servant.Server.Experimental.Auth.Cookie.RenewableKeySet s p)
instance Data.Default.Class.Default Servant.Server.Experimental.Auth.Cookie.AuthCookieSettings
