Make Felipe's session code the default (#415)
This commit is contained in:
parent
2377d70ec8
commit
20091656aa
@ -35,7 +35,6 @@ module Yesod.Core
|
|||||||
, SessionBackend (..)
|
, SessionBackend (..)
|
||||||
, defaultClientSessionBackend
|
, defaultClientSessionBackend
|
||||||
, clientSessionBackend
|
, clientSessionBackend
|
||||||
, clientSessionBackend2
|
|
||||||
, clientSessionDateCacher
|
, clientSessionDateCacher
|
||||||
, loadClientSession
|
, loadClientSession
|
||||||
, Header(..)
|
, Header(..)
|
||||||
|
|||||||
@ -26,8 +26,6 @@ module Yesod.Internal.Core
|
|||||||
, defaultClientSessionBackend
|
, defaultClientSessionBackend
|
||||||
, clientSessionBackend
|
, clientSessionBackend
|
||||||
, loadClientSession
|
, loadClientSession
|
||||||
, clientSessionBackend2
|
|
||||||
, loadClientSession2
|
|
||||||
, clientSessionDateCacher
|
, clientSessionDateCacher
|
||||||
, BackendSession
|
, BackendSession
|
||||||
-- * jsLoader
|
-- * jsLoader
|
||||||
@ -48,7 +46,6 @@ import Yesod.Handler hiding (lift, getExpires)
|
|||||||
import Control.Monad.Logger (logErrorS)
|
import Control.Monad.Logger (logErrorS)
|
||||||
|
|
||||||
import Yesod.Routes.Class
|
import Yesod.Routes.Class
|
||||||
import Data.Time (UTCTime, addUTCTime, getCurrentTime)
|
|
||||||
|
|
||||||
import Data.Word (Word64)
|
import Data.Word (Word64)
|
||||||
import Control.Arrow ((***))
|
import Control.Arrow ((***))
|
||||||
@ -435,10 +432,9 @@ defaultYesodRunner :: Yesod master
|
|||||||
defaultYesodRunner logger handler' master sub murl toMasterRoute msb req
|
defaultYesodRunner logger handler' master sub murl toMasterRoute msb req
|
||||||
| W.KnownLength len <- W.requestBodyLength req, maxLen < len = return tooLargeResponse
|
| W.KnownLength len <- W.requestBodyLength req, maxLen < len = return tooLargeResponse
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
let dontSaveSession _ _ = return []
|
let dontSaveSession _ = return []
|
||||||
now <- liftIO getCurrentTime -- FIXME remove in next major version bump
|
|
||||||
(session, saveSession) <- liftIO $ do
|
(session, saveSession) <- liftIO $ do
|
||||||
maybe (return ([], dontSaveSession)) (\sb -> sbLoadSession sb master req now) msb
|
maybe (return ([], dontSaveSession)) (\sb -> sbLoadSession sb master req) msb
|
||||||
rr <- liftIO $ parseWaiRequest req session (isJust msb) maxLen
|
rr <- liftIO $ parseWaiRequest req session (isJust msb) maxLen
|
||||||
let h = {-# SCC "h" #-} do
|
let h = {-# SCC "h" #-} do
|
||||||
case murl of
|
case murl of
|
||||||
@ -468,7 +464,7 @@ defaultYesodRunner logger handler' master sub murl toMasterRoute msb req
|
|||||||
newSess
|
newSess
|
||||||
(\n -> Map.insert tokenKey (TE.encodeUtf8 n) newSess)
|
(\n -> Map.insert tokenKey (TE.encodeUtf8 n) newSess)
|
||||||
(reqToken rr)
|
(reqToken rr)
|
||||||
sessionHeaders <- liftIO (saveSession nsToken now)
|
sessionHeaders <- liftIO (saveSession nsToken)
|
||||||
return $ ("Content-Type", ct) : map headerToPair sessionHeaders
|
return $ ("Content-Type", ct) : map headerToPair sessionHeaders
|
||||||
_ -> return []
|
_ -> return []
|
||||||
return $ yarToResponse yar extraHeaders
|
return $ yarToResponse yar extraHeaders
|
||||||
@ -755,67 +751,25 @@ defaultClientSessionBackend = do
|
|||||||
key <- CS.getKey CS.defaultKeyFile
|
key <- CS.getKey CS.defaultKeyFile
|
||||||
let timeout = fromIntegral (120 * 60 :: Int) -- 120 minutes
|
let timeout = fromIntegral (120 * 60 :: Int) -- 120 minutes
|
||||||
(getCachedDate, _closeDateCacher) <- clientSessionDateCacher timeout
|
(getCachedDate, _closeDateCacher) <- clientSessionDateCacher timeout
|
||||||
return $ clientSessionBackend2 key getCachedDate
|
return $ clientSessionBackend key getCachedDate
|
||||||
|
|
||||||
|
|
||||||
clientSessionBackend :: Yesod master
|
clientSessionBackend :: Yesod master
|
||||||
=> CS.Key -- ^ The encryption key
|
|
||||||
-> Int -- ^ Inactive session valitity in minutes
|
|
||||||
-> SessionBackend master
|
|
||||||
clientSessionBackend key timeout = SessionBackend
|
|
||||||
{ sbLoadSession = loadClientSession key timeout "_SESSION"
|
|
||||||
}
|
|
||||||
{-# DEPRECATED clientSessionBackend "Please use clientSessionBackend2, which is more efficient." #-}
|
|
||||||
|
|
||||||
loadClientSession :: Yesod master
|
|
||||||
=> CS.Key
|
|
||||||
-> Int -- ^ timeout
|
|
||||||
-> S8.ByteString -- ^ session name
|
|
||||||
-> master
|
|
||||||
-> W.Request
|
|
||||||
-> UTCTime
|
|
||||||
-> IO (BackendSession, SaveSession)
|
|
||||||
loadClientSession key timeout sessionName master req now = return (sess, save)
|
|
||||||
where
|
|
||||||
sess = fromMaybe [] $ do
|
|
||||||
raw <- lookup "Cookie" $ W.requestHeaders req
|
|
||||||
val <- lookup sessionName $ parseCookies raw
|
|
||||||
let host = "" -- fixme, properly lock sessions to client address
|
|
||||||
decodeClientSessionOld key now host val
|
|
||||||
save sess' now' = do
|
|
||||||
-- We should never cache the IV! Be careful!
|
|
||||||
iv <- liftIO CS.randomIV
|
|
||||||
return [AddCookie def
|
|
||||||
{ setCookieName = sessionName
|
|
||||||
, setCookieValue = sessionVal iv
|
|
||||||
, setCookiePath = Just (cookiePath master)
|
|
||||||
, setCookieExpires = Just expires
|
|
||||||
, setCookieDomain = cookieDomain master
|
|
||||||
, setCookieHttpOnly = True
|
|
||||||
}]
|
|
||||||
where
|
|
||||||
host = "" -- fixme, properly lock sessions to client address
|
|
||||||
expires = fromIntegral (timeout * 60) `addUTCTime` now'
|
|
||||||
sessionVal iv = encodeClientSessionOld key iv expires host sess'
|
|
||||||
{-# DEPRECATED loadClientSession "Please use loadClientSession2, which is more efficient." #-}
|
|
||||||
|
|
||||||
clientSessionBackend2 :: Yesod master
|
|
||||||
=> CS.Key -- ^ The encryption key
|
=> CS.Key -- ^ The encryption key
|
||||||
-> IO ClientSessionDateCache -- ^ See 'clientSessionDateCacher'
|
-> IO ClientSessionDateCache -- ^ See 'clientSessionDateCacher'
|
||||||
-> SessionBackend master
|
-> SessionBackend master
|
||||||
clientSessionBackend2 key getCachedDate =
|
clientSessionBackend key getCachedDate =
|
||||||
SessionBackend {
|
SessionBackend {
|
||||||
sbLoadSession = \master req -> const $ loadClientSession2 key getCachedDate "_SESSION" master req
|
sbLoadSession = \master req -> loadClientSession key getCachedDate "_SESSION" master req
|
||||||
}
|
}
|
||||||
|
|
||||||
loadClientSession2 :: Yesod master
|
loadClientSession :: Yesod master
|
||||||
=> CS.Key
|
=> CS.Key
|
||||||
-> IO ClientSessionDateCache -- ^ See 'clientSessionDateCacher'
|
-> IO ClientSessionDateCache -- ^ See 'clientSessionDateCacher'
|
||||||
-> S8.ByteString -- ^ session name
|
-> S8.ByteString -- ^ session name
|
||||||
-> master
|
-> master
|
||||||
-> W.Request
|
-> W.Request
|
||||||
-> IO (BackendSession, SaveSession)
|
-> IO (BackendSession, SaveSession)
|
||||||
loadClientSession2 key getCachedDate sessionName master req = load
|
loadClientSession key getCachedDate sessionName master req = load
|
||||||
where
|
where
|
||||||
load = do
|
load = do
|
||||||
date <- getCachedDate
|
date <- getCachedDate
|
||||||
@ -825,7 +779,7 @@ loadClientSession2 key getCachedDate sessionName master req = load
|
|||||||
val <- lookup sessionName $ parseCookies raw
|
val <- lookup sessionName $ parseCookies raw
|
||||||
let host = "" -- fixme, properly lock sessions to client address
|
let host = "" -- fixme, properly lock sessions to client address
|
||||||
decodeClientSession key date host val
|
decodeClientSession key date host val
|
||||||
save date sess' _ = do
|
save date sess' = do
|
||||||
-- We should never cache the IV! Be careful!
|
-- We should never cache the IV! Be careful!
|
||||||
iv <- liftIO CS.randomIV
|
iv <- liftIO CS.randomIV
|
||||||
return [AddCookie def
|
return [AddCookie def
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
module Yesod.Internal.Session
|
module Yesod.Internal.Session
|
||||||
( encodeClientSession
|
( encodeClientSession
|
||||||
, encodeClientSessionOld
|
|
||||||
, decodeClientSession
|
, decodeClientSession
|
||||||
, decodeClientSessionOld
|
|
||||||
, clientSessionDateCacher
|
, clientSessionDateCacher
|
||||||
, ClientSessionDateCache(..)
|
, ClientSessionDateCache(..)
|
||||||
, BackendSession
|
, BackendSession
|
||||||
, SaveSession
|
, SaveSession
|
||||||
, SaveSessionOld
|
|
||||||
, SessionBackend(..)
|
, SessionBackend(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -30,17 +27,11 @@ import qualified Network.Wai as W
|
|||||||
type BackendSession = [(Text, S8.ByteString)]
|
type BackendSession = [(Text, S8.ByteString)]
|
||||||
|
|
||||||
type SaveSession = BackendSession -- ^ The session contents after running the handler
|
type SaveSession = BackendSession -- ^ The session contents after running the handler
|
||||||
-> UTCTime -- FIXME remove this in the next major version bump
|
|
||||||
-> IO [Header]
|
|
||||||
|
|
||||||
type SaveSessionOld = BackendSession -- ^ The session contents after running the handler
|
|
||||||
-> UTCTime
|
|
||||||
-> IO [Header]
|
-> IO [Header]
|
||||||
|
|
||||||
newtype SessionBackend master = SessionBackend
|
newtype SessionBackend master = SessionBackend
|
||||||
{ sbLoadSession :: master
|
{ sbLoadSession :: master
|
||||||
-> W.Request
|
-> W.Request
|
||||||
-> UTCTime -- FIXME remove this in the next major version bump
|
|
||||||
-> IO (BackendSession, SaveSession) -- ^ Return the session data and a function to save the session
|
-> IO (BackendSession, SaveSession) -- ^ Return the session data and a function to save the session
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,25 +128,3 @@ posixDayLength_int64 = 86400
|
|||||||
|
|
||||||
diffTimeScale :: DiffTime
|
diffTimeScale :: DiffTime
|
||||||
diffTimeScale = 1e12
|
diffTimeScale = 1e12
|
||||||
|
|
||||||
encodeClientSessionOld :: CS.Key
|
|
||||||
-> CS.IV
|
|
||||||
-> UTCTime -- ^ expire time
|
|
||||||
-> ByteString -- ^ remote host
|
|
||||||
-> [(Text, ByteString)] -- ^ session
|
|
||||||
-> ByteString -- ^ cookie value
|
|
||||||
encodeClientSessionOld key iv expire rhost session' =
|
|
||||||
CS.encrypt key iv $ encode $ SessionCookie (Left expire) rhost session'
|
|
||||||
|
|
||||||
decodeClientSessionOld :: CS.Key
|
|
||||||
-> UTCTime -- ^ current time
|
|
||||||
-> ByteString -- ^ remote host field
|
|
||||||
-> ByteString -- ^ cookie value
|
|
||||||
-> Maybe [(Text, ByteString)]
|
|
||||||
decodeClientSessionOld key now rhost encrypted = do
|
|
||||||
decrypted <- CS.decrypt key encrypted
|
|
||||||
SessionCookie (Left expire) rhost' session' <-
|
|
||||||
either (const Nothing) Just $ decode decrypted
|
|
||||||
guard $ expire > now
|
|
||||||
guard $ rhost' == rhost
|
|
||||||
return session'
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user