clientsession 0.9.0.5 → 0.9.1
raw patch · 5 files changed
+74/−1 lines, 5 filesdep +setenvdep ~basenew-component:exe:clientsession-generatePVP ok
version bump matches the API change (PVP)
Dependencies added: setenv
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Web.ClientSession: getKeyEnv :: String -> IO Key
+ Web.ClientSession: randomKeyEnv :: String -> IO Key
Files
- bin/generate.hs +9/−0
- clientsession.cabal +10/−1
- src/System/LookupEnv.hs +6/−0
- src/Web/ClientSession.hs +41/−0
- tests/runtests.hs +8/−0
+ bin/generate.hs view
@@ -0,0 +1,9 @@+module Main where++import Data.Maybe (fromMaybe, listToMaybe)+import Control.Monad (void)+import System.Environment (getArgs)+import Web.ClientSession (randomKeyEnv)++main :: IO ()+main = void $ randomKeyEnv . fromMaybe "SESSION_KEY" . listToMaybe =<< getArgs
clientsession.cabal view
@@ -1,5 +1,5 @@ name: clientsession-version: 0.9.0.5+version: 0.9.1 license: BSD3 license-file: LICENSE author: Michael Snoyman <michael@snoyman.com>, Felipe Lessa <felipe.lessa@gmail.com>@@ -20,6 +20,13 @@ description: Build the executable to run unit tests default: False +executable clientsession-generate+ main-is: generate.hs+ build-depends: base+ , clientsession+ ghc-options: -Wall+ hs-source-dirs: bin+ library build-depends: base >=4 && < 5 , bytestring >= 0.9@@ -33,7 +40,9 @@ , cprng-aes >= 0.2 , cipher-aes >= 0.1.7 , crypto-random+ , setenv exposed-modules: Web.ClientSession+ other-modules: System.LookupEnv ghc-options: -Wall hs-source-dirs: src
+ src/System/LookupEnv.hs view
@@ -0,0 +1,6 @@+module System.LookupEnv (lookupEnv) where++import System.Environment (getEnvironment)++lookupEnv :: String -> IO (Maybe String)+lookupEnv envVar = fmap (lookup envVar) $ getEnvironment
src/Web/ClientSession.hs view
@@ -45,10 +45,12 @@ , randomIV , mkIV , getKey+ , getKeyEnv , defaultKeyFile , getDefaultKey , initKey , randomKey+ , randomKeyEnv -- * Actual encryption/decryption , encrypt , encryptIO@@ -60,6 +62,17 @@ import Control.Concurrent (forkIO) import Control.Monad (guard, when) import Data.Function (on)++#if MIN_VERSION_base(4,7,0)+import System.Environment (lookupEnv, setEnv)+#elif MIN_VERSION_base(4,6,0)+import System.Environment (lookupEnv)+import System.SetEnv (setEnv)+#else+import System.LookupEnv (lookupEnv)+import System.SetEnv (setEnv)+#endif+ import System.IO.Unsafe (unsafePerformIO) import qualified Data.IORef as I @@ -68,6 +81,7 @@ -- from bytestring import qualified Data.ByteString as S+import qualified Data.ByteString.Char8 as C import qualified Data.ByteString.Base64 as B -- from cereal@@ -195,6 +209,22 @@ S.writeFile keyFile bs return key' +-- | Get the key from the named environment variable+--+-- Assumes the value is a Base64-encoded string. If the variable is not set, a+-- random key will be generated, set in the environment, and the Base64-encoded+-- version printed on @/dev/stdout@.+getKeyEnv :: String -- ^ Name of the environment variable+ -> IO Key -- ^ The actual key.+getKeyEnv envVar = do+ mvalue <- lookupEnv envVar+ case mvalue of+ Just value -> either (const newKey) return $ initKey =<< decode value+ Nothing -> newKey+ where+ decode = B.decode . C.pack+ newKey = randomKeyEnv envVar+ -- | Generate a random 'Key'. Besides the 'Key', the -- 'ByteString' passed to 'initKey' is returned so that it can be -- saved for later use.@@ -204,6 +234,17 @@ case initKey bs of Left e -> error $ "Web.ClientSession.randomKey: never here, " ++ e Right key -> return (bs, key)++-- | Generate a random 'Key', set a Base64-encoded version of it in the given+-- environment variable, then return it. Also prints the generated string to+-- @/dev/stdout@.+randomKeyEnv :: String -> IO Key+randomKeyEnv envVar = do+ (bs, key) <- randomKey+ let encoded = C.unpack $ B.encode bs+ setEnv envVar encoded+ putStrLn $ envVar ++ "=" ++ encoded+ return key -- | Initializes a 'Key' from a random 'S.ByteString'. Fails if -- there isn't exactly 96 bytes (256 bits for AES and 512 bits
tests/runtests.hs view
@@ -22,6 +22,7 @@ main :: IO () main = hspec $ describe "client session" $ do it "encrypt/decrypt success" $ property propEncDec+ it "encrypt/decrypt success (environment key)" $ property propEncDecEnv it "encrypt/decrypt failure" $ property propEncDecFailure it "AES encrypt/decrypt success" $ property propAES it "AES encryption changes bs" $ property propAESChanges@@ -32,6 +33,13 @@ propEncDec :: S.ByteString -> Bool propEncDec bs = unsafePerformIO $ do key <- getDefaultKey+ s <- encryptIO key bs+ let bs' = decrypt key s+ return $ Just bs == bs'++propEncDecEnv :: S.ByteString -> Bool+propEncDecEnv bs = unsafePerformIO $ do+ key <- getKeyEnv "SESSION_KEY" s <- encryptIO key bs let bs' = decrypt key s return $ Just bs == bs'