wai-secure-cookies 0.1.0.2 → 0.1.0.3
raw patch · 5 files changed
+123/−9 lines, 5 filesdep +hspecdep +hspec-expectationsdep +hspec-waidep ~http-typesPVP ok
version bump matches the API change (PVP)
Dependencies added: hspec, hspec-expectations, hspec-wai, wai-extra, wai-secure-cookies
Dependency ranges changed: http-types
API changes (from Hackage documentation)
Files
- spec/Main.hs +1/−0
- spec/MiddlewareSpec.hs +89/−0
- src/Cookie/Secure.hs +1/−1
- src/Cookie/Secure/Middleware.hs +12/−5
- wai-secure-cookies.cabal +20/−3
+ spec/Main.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
+ spec/MiddlewareSpec.hs view
@@ -0,0 +1,89 @@+{-# LANGUAGE OverloadedStrings #-}++module MiddlewareSpec where++import Test.Hspec+import Test.Hspec.Wai+import Test.Hspec.Wai.Internal (withApplication)+import System.Environment+import Cookie.Secure.Middleware+import Network.Wai+import Network.Wai.Test hiding (request)+import Network.HTTP.Types+import Network.HTTP.Types.Status+import Network.HTTP.Types.Header+import Data.Foldable+import Data.Maybe+import qualified Data.ByteString.Char8 as B+import qualified Data.ByteString.Lazy.Char8 as LB++spec :: Spec+spec = do+ before_ setupEnvironment $ do+ describe "secureCookies middleware" $ do+ it "does not encrypt cookie names" $ do+ cookie <- getResponseCookie+ cookie `shouldStartWith` "SessionId="++ it "encrypts cookie values" $ do+ cookie <- getResponseCookie+ cookie `shouldNotContain` sessionId++ it "does not decrypt cookie names" $ do+ cookie <- getRequestCookie+ cookie `shouldStartWith` "SessionId="++ it "decrypts cookie values" $ do+ cookie <- getRequestCookie+ cookie `shouldEndWith` sessionId++setupEnvironment :: IO ()+setupEnvironment =+ setEnv "WAI_COOKIE_ENCRYPTION_KEY" "00000000000000000000000000000000"+ >> setEnv "WAI_COOKIE_VALIDATION_KEY" "00000000000000000000000000000000"++getResponseCookie :: IO String+getResponseCookie =+ withApplication secureApp+ $ getHeaderValue hSetCookie . simpleHeaders <$> get "/"++getRequestCookie :: IO String+getRequestCookie =+ withApplication secureApp+ $ LB.unpack . simpleBody+ <$> request+ methodGet+ "/"+ [ ( hCookie+ , B.pack exampleSignedEncryptedCookieValue+ )+ ]+ ""++exampleSignedEncryptedCookieValue :: String+exampleSignedEncryptedCookieValue = "SessionId=aXYsUWxmbDhWLW90alJDTGtHSUh2Uno5Z3xPSkhTYjZsOTFsVnA|signature,be2ee0eb3d894ef671a8475d78c635d28e844011eda7ae16c47830333466d1e0"++getHeaderValue :: HeaderName -> [Header] -> String+getHeaderValue header =+ B.unpack+ . snd+ . fromMaybe ("", "")+ . findHeader header+ where+ findHeader header = find $ (== header) . fst++secureApp :: Application+secureApp = secureCookies app++app :: Application+app request responder = responder+ $ responseLBS+ status200+ [ ( hSetCookie+ , B.pack $ "SessionId=" ++ sessionId ++ "; Max-Age=86400"+ )+ ]+ (LB.pack . getHeaderValue hCookie $ requestHeaders request)++sessionId :: String+sessionId = "123456789"
src/Cookie/Secure.hs view
@@ -37,7 +37,7 @@ verifyAndDecrypt authKey encryptKey message = deserialize message >>= verifyAndDecryptDeserialized where- verifyAndDecryptDeserialized signed = + verifyAndDecryptDeserialized signed = if verify authKey signed then maybeCryptoError $ decrypt encryptKey (getSignable signed) else Nothing
src/Cookie/Secure/Middleware.hs view
@@ -87,12 +87,19 @@ <*> verifyAndDecryptCookieHeaderValue value where verifyAndDecryptCookieHeaderValue value =- BS.intercalate "; "+ BS.intercalate "; " . catMaybes <$> mapM verifyAndDecryptCookie (splitOn "; " (BS.unpack value))- verifyAndDecryptCookie cookie =+ verifyAndDecryptCookie cookie = do+ let cookieNameValueList = map BS.pack $ splitOn "=" cookie+ let cName = head cookieNameValueList+ let cValue = last cookieNameValueList++ encryptedValue <- verifyAndDecryptIO cValue+ -- OPTIMIZE: maybe silently dropping cookies which fail to verify -- or decrypt isn't the best idea?- BS.intercalate "=" . catMaybes- <$> mapM verifyAndDecryptIO- (map BS.pack (splitOn "=" cookie))+ case encryptedValue of+ Nothing -> pure Nothing+ Just encryptedValue' ->+ return . Just $ BS.intercalate "=" [cName, encryptedValue']
wai-secure-cookies.cabal view
@@ -1,12 +1,12 @@ name: wai-secure-cookies-version: 0.1.0.2+version: 0.1.0.3 description: WAI middleware to automatically encrypt and sign cookies homepage: https://github.com/habibalamin/wai-secure-cookies license: MIT license-file: LICENSE author: Habib Alamin maintainer: ha.alamin@gmail.com-copyright: © حبيب الامين 2017+copyright: © حبيب الامين 2017 category: Web build-type: Simple cabal-version: >=1.10@@ -28,7 +28,24 @@ , memory >= 0.14 && < 0.15 , random >= 1.1 && < 2 , split >= 0.2 && < 0.3- , http-types >= 0.9 && < 0.10+ , http-types >= 0.12.1 && < 0.13++test-suite wai-secure-cookies-test+ hs-source-dirs: spec+ default-language: Haskell2010+ other-modules: MiddlewareSpec+ type: exitcode-stdio-1.0+ main-is: Main.hs+ build-depends: base >= 4.7 && < 5+ , bytestring >= 0.10 && < 0.11+ , wai >= 3.2 && < 4+ , wai-extra >= 3.0 && < 4+ , http-types >= 0.12.1 && < 0.13+ , wai-secure-cookies+ , hspec+ , hspec-expectations+ , hspec-wai+ ghc-options: -threaded -O2 -rtsopts -with-rtsopts=-N executable waicookie-genkey hs-source-dirs: keygensrc