wai-session-clientsession-deferred (empty) → 1.0.0
raw patch · 5 files changed
+111/−0 lines, 5 filesdep +basedep +bytestringdep +cerealsetup-changed
Dependencies added: base, bytestring, cereal, clientsession, transformers, wai-session-maybe
Files
- COPYING +13/−0
- Network/Wai/Session/ClientSession/Deferred.hs +53/−0
- README +3/−0
- Setup.hs +3/−0
- wai-session-clientsession-deferred.cabal +39/−0
+ COPYING view
@@ -0,0 +1,13 @@+Copyright © 2012, Stephen Paul Weber <singpolyma.net>++Permission to use, copy, modify, and/or distribute this software for any+purpose with or without fee is hereby granted, provided that the above+copyright notice and this permission notice appear in all copies.++THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ Network/Wai/Session/ClientSession/Deferred.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE LambdaCase #-}++module Network.Wai.Session.ClientSession.Deferred (clientsessionStore) where++import Control.Monad+import Data.ByteString (ByteString)+import Control.Monad.IO.Class (liftIO, MonadIO)+import Network.Wai.Session.Maybe (Session, SessionStore)+import Data.IORef++import Web.ClientSession (Key, encryptIO, decrypt)+import Data.Serialize (encode, decode, Serialize) -- Use cereal because clientsession does++-- | Convert an Either to a Maybe, discarding the error.+hush :: Either a b -> Maybe b+hush = either (const Nothing) Just++-- | Session store that keeps all content in a 'Serialize'd cookie encrypted+-- with 'Web.ClientSession'+--+-- Decryption is deferred until the session is first read or written.+-- The Set-Cookie header is skipped when the session is never accessed.+--+-- WARNING: This session is vulnerable to sidejacking,+-- use with TLS for security.+clientsessionStore :: (Serialize k, Serialize v, Eq k, MonadIO m) => Key -> SessionStore m k v+clientsessionStore cryptKey maybeCookie = do+ -- Pure + lazy: decryption thunk evaluated only when initialPairs is forced+ let initialPairs = case maybeCookie of+ Nothing -> []+ Just encoded -> case hush . decode =<< decrypt cryptKey encoded of+ Just sessionData -> sessionData+ Nothing -> []++ -- Nothing = never accessed; Just (pairs, dirty) = accessed+ ref <- newIORef Nothing++ let ensureLoaded = readIORef ref >>= \case+ Just (pairs, _) -> pure pairs+ Nothing -> do+ writeIORef ref (Just (initialPairs, False))+ pure initialPairs++ return ((+ (\k -> lookup k `liftM` liftIO ensureLoaded),+ (\k v -> liftIO $ do+ pairs <- ensureLoaded+ writeIORef ref (Just (((k,v):) . filter ((/=k) . fst) $ pairs, True)))+ ), readIORef ref >>= \case+ Nothing -> return Nothing -- never accessed: skip Set-Cookie+ Just (_, False) -> return maybeCookie -- read-only: echo original bytes+ Just (pairs, True) -> Just <$> (encryptIO cryptKey $ encode pairs)+ )
+ README view
@@ -0,0 +1,3 @@+Provides a session store for use with wai-session.++See example/Main.hs in git for example usage.
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple++main = defaultMain
+ wai-session-clientsession-deferred.cabal view
@@ -0,0 +1,39 @@+name: wai-session-clientsession-deferred+version: 1.0.0+cabal-version: >= 1.10+license: OtherLicense+license-file: COPYING+category: Web+copyright: © 2012 Stephen Paul Weber+author: Stephen Paul Weber <singpolyma@singpolyma.net>+maintainer: support@digitallyinduced.com+stability: experimental+tested-with: GHC == 7.0.3+synopsis: Session store based on clientsession with deferred decryption+homepage: https://github.com/digitallyinduced/wai-session-clientsession-deferred+bug-reports: https://github.com/digitallyinduced/wai-session-clientsession-deferred/issues+build-type: Simple+description:+ Provides a session store for use with wai-session.+ .+ See example/Main.hs in git for example usage.++extra-source-files:+ README++library+ default-language: Haskell2010+ exposed-modules:+ Network.Wai.Session.ClientSession.Deferred++ build-depends:+ base == 4.*,+ bytestring,+ transformers,+ cereal,+ clientsession,+ wai-session-maybe++source-repository head+ type: git+ location: https://github.com/digitallyinduced/wai-session-clientsession-deferred.git