simple-session 0.10.0.0 → 0.10.1.0
raw patch · 2 files changed
+47/−21 lines, 2 filesdep +wai-extraPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: wai-extra
API changes (from Hackage documentation)
- Web.Simple.Session: instance HasSession (Maybe Session)
+ Web.Simple.Session: instance Web.Simple.Session.HasSession (GHC.Base.Maybe Web.Simple.Session.Session)
+ Web.Simple.Session: sessionBaseCookie :: HasSession hs => Controller hs SetCookie
- Web.Simple.Session: addCookie :: (ByteString, ByteString) -> Response -> Response
+ Web.Simple.Session: addCookie :: (ByteString, ByteString) -> SetCookie -> Response -> Response
- Web.Simple.Session: class HasSession hs where sessionKey = liftIO $ do { env <- getEnvironment; case lookup "SESSION_KEY" env of { Just key -> return $ pack key Nothing -> case lookup "ENV" env of { Just e | e == "development" -> return "test-session-key" _ -> (error "SESSION_KEY environment variable not set") } } }
+ Web.Simple.Session: class HasSession hs where sessionKey = liftIO $ do { env <- getEnvironment; case lookup "SESSION_KEY" env of { Just key -> return $ pack key Nothing -> case lookup "ENV" env of { Just e | e == "development" -> return "test-session-key" _ -> (error "SESSION_KEY environment variable not set") } } } sessionBaseCookie = defaultSessionBaseCookie
Files
- simple-session.cabal +2/−1
- src/Web/Simple/Session.hs +45/−20
simple-session.cabal view
@@ -1,5 +1,5 @@ name: simple-session-version: 0.10.0.0+version: 0.10.1.0 synopsis: Cookie-based session management for the Simple web framework description: @@ -52,6 +52,7 @@ , simple >= 0.10 , transformers , wai >= 3.0+ , wai-extra >= 3.0 default-language: Haskell2010 source-repository head
src/Web/Simple/Session.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE Trustworthy #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} @@ -38,6 +39,7 @@ import Network.HTTP.Types.Header import Network.HTTP.Types.URI import Network.Wai.Internal (Response(..))+import Network.Wai.Request (appearsSecure) import Web.Cookie import Web.Simple.Controller import System.Environment@@ -46,15 +48,24 @@ -- 'S.ByteString's. type Session = Map S.ByteString S.ByteString --- | Instances of this class can be used as states by a 'Controller' states--- to manage cookie-based user sessions. Instances must minimally implement--- 'getSession' and 'setSession'. By default, the secret session key is taken--- from the environment variable \"SESSION_KEY\", or a default dummy key is--- used if the environment variable \"ENV\" is set to \"development\". You can--- override this behaviour by implementing the 'sessionKey' method.--- If the controller state contains a dedicated field of type 'Maybe Session',--- a reasonable implementation would be:+-- | Instances of this class can be used as states by a 'Controller' to manage+-- cookie-based user sessions. Instances must minimally implement 'getSession'+-- and 'setSession'. --+-- By default, the secret session key is taken from the+-- environment variable \"SESSION_KEY\", or a default dummy key is used if the+-- environment variable \"ENV\" is set to \"development\". You can override+-- this behaviour by implementing the 'sessionKey' method.+--+-- The default generated cookie always uses the `httponly` option, and the+-- `secure` option if the request is over HTTPS. You can override this behavior,+-- as well as other cookie options (e.g. the path, expiration and domain) by+-- implementing the `sessionBaseCookie` method.+--+-- If the controller+-- state contains a dedicated field of type 'Maybe Session', a reasonable+-- implementation would be:+-- -- > data MyAppSettings = MyAppSettings { myAppSess :: Maybe Session, ...} -- > -- > instance HasSession MyAppSettings where@@ -79,7 +90,7 @@ _ -> (error "SESSION_KEY environment variable not set") -- | Returns the cached session for the current request, or nothing if the- -- session has not been set yet for this request. + -- session has not been set yet for this request. getSession :: hs -> Maybe Session -- | Stores a parsed or changed session for the remainder of the request.This@@ -87,6 +98,14 @@ -- to the \"Set-Cookie\" header when responding. setSession :: Session -> Controller hs () + sessionBaseCookie :: Controller hs SetCookie+ sessionBaseCookie = defaultSessionBaseCookie++defaultSessionBaseCookie :: Controller hs SetCookie+defaultSessionBaseCookie = do+ req <- request+ return $ def { setCookieSecure = appearsSecure req, setCookieHttpOnly = True }+ -- | A trivial implementation if the 'Controller' settings is just a Session -- store. instance HasSession (Maybe Session) where@@ -100,6 +119,7 @@ => Controller hs a -> Controller hs a withSession (ControllerT act) = do sk <- sessionKey+ baseCookie <- sessionBaseCookie ControllerT $ \st0 req -> do (eres, st) <- act st0 req case eres of@@ -107,6 +127,7 @@ let resp = case getSession st of Just sess -> addCookie ("session", dumpSession sk sess)+ baseCookie resp0 Nothing -> resp0 return (Left resp, st)@@ -115,18 +136,22 @@ -- | Adds a \"Set-Cookie\" with the given key-value tuple to the 'Response'. -- The path set on the cookie is \"/\", meaning it applies to all routes on the -- domain, and no expiration is set.-addCookie :: (S.ByteString, S.ByteString) -> Response -> Response-addCookie (key, value) (ResponseFile stat hdrs fl mfp) =- ResponseFile stat (("Set-Cookie", cookie key value):hdrs) fl mfp-addCookie (key, value) (ResponseBuilder stat hdrs bldr) =- ResponseBuilder stat (("Set-Cookie", cookie key value):hdrs) bldr-addCookie (key, value) (ResponseStream stat hdrs src) =- ResponseStream stat (("Set-Cookie", cookie key value):hdrs) src-addCookie _ resp = resp -- Can't do anything for ResponseRaw+addCookie :: (S.ByteString, S.ByteString) -> SetCookie -> Response -> Response -cookie :: S.ByteString -> S.ByteString -> S.ByteString-cookie key value = toByteString . renderSetCookie $- def { setCookieName = key+addCookie (key, value) baseCookie (ResponseFile stat hdrs fl mfp) =+ ResponseFile stat (("Set-Cookie", cookie baseCookie key value):hdrs) fl mfp++addCookie (key, value) baseCookie (ResponseBuilder stat hdrs bldr) =+ ResponseBuilder stat (("Set-Cookie", cookie baseCookie key value):hdrs) bldr++addCookie (key, value) baseCookie (ResponseStream stat hdrs src) =+ ResponseStream stat (("Set-Cookie", cookie baseCookie key value):hdrs) src++addCookie _ _ resp = resp -- Can't do anything for ResponseRaw++cookie :: SetCookie -> S.ByteString -> S.ByteString -> S.ByteString+cookie baseCookie key value = toByteString . renderSetCookie $+ baseCookie { setCookieName = key , setCookieValue = value , setCookiePath = Just "/" }