{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.Either (isRight)
import Data.Monoid ((<>))
import Data.Ruby.Marshal hiding (decodeEither)
import Data.Vector (fromList)
import System.IO.Unsafe (unsafePerformIO)
import Test.Tasty (defaultMain, testGroup)
import Test.Tasty.Hspec (describe, it, shouldBe, shouldSatisfy, testSpec, Spec)
import Web.Rails.Session
-- SPECS
main :: IO ()
main = do
rails4 <- testSpec "Web.Rails.Session: Rails4" $ specsFor Rails4
defaultMain (testGroup "All the Specs" [rails4])
specsFor :: Rails -> Spec
specsFor rails = do
let cookie = unsafeReadCookie rails
describe "decode" $ do
it "should be a Right(..)" $ do
let result = decodeEither Nothing secret cookie
result `shouldSatisfy` isRight
it "should be a fully-formed Ruby object" $ do
case decodeEither Nothing secret cookie of
Left _ -> error "decode failed"
Right result -> do
result `shouldBe` rubySession
describe "decrypt" $ do
it "should be a Right(..)" $ do
let result = decrypt Nothing secret cookie
result `shouldSatisfy` isRight
describe "csrfToken" $ do
it "should look up the '_csrf_token'" $ do
case decodeEither Nothing secret cookie of
Left _ -> error "lookup failed"
Right result ->
csrfToken result `shouldBe` Just csrfTokenVal
describe "sessionId" $ do
it "should look up the 'session_id'" $ do
case decodeEither Nothing secret cookie of
Left _ -> error "lookup failed"
Right result ->
sessionId result `shouldBe` Just sessionIdVal
describe "lookupString" $ do
it "should look up the '_csrf_token'" $ do
case decodeEither Nothing secret cookie of
Left _ -> error "lookup failed"
Right result ->
lookupString "_csrf_token" US_ASCII result `shouldBe`
Just csrfTokenVal
it "should look up the 'session_id'" $ do
case decodeEither Nothing secret cookie of
Left _ -> error "lookup failed"
Right result ->
lookupString "session_id" UTF_8 result `shouldBe`
Just sessionIdVal
it "should look up the 'token'" $ do
case decodeEither Nothing secret cookie of
Left _ -> error "lookup failed"
Right result ->
lookupString "token" US_ASCII result `shouldBe`
Just authToken
-- EXAMPLES
example :: FilePath -> IO (Maybe ByteString)
example path = do
rawCookie <- BS.readFile path
let appSecret = mkSecretKeyBase "development_secret_token"
let cookie = mkCookie rawCookie
case decodeEither Nothing appSecret cookie of
Left _ ->
pure Nothing
Right rubyObject ->
pure $ sessionId rubyObject
-- UTIL
data Rails = Rails4 deriving (Show)
unsafeReadCookie :: Rails -> Cookie
unsafeReadCookie rails = unsafePerformIO $
BS.readFile ("test/" <> (show rails)) >>= pure . mkCookie
-- CONFIG
secret :: SecretKeyBase
secret = mkSecretKeyBase "development_secret_token"
-- VALUES
authToken :: ByteString
authToken = "GT1EYH9X8OXYqup4HwnQIvfnh59TqNys1IvukVXpXR8="
sessionIdVal :: ByteString
sessionIdVal = "912a0abcf3d64e0d9d2bdb601b9e8224"
csrfTokenVal :: ByteString
csrfTokenVal = "c9kRzi8L7oj2MPI/QlqYpQ79WR6YfKTDob6PGl9V2pg="
rubySession :: RubyObject
rubySession =
RHash
(fromList
[ ( RIVar (RString "session_id", UTF_8)
, RIVar (RString sessionIdVal, UTF_8))
, ( RIVar (RString "_csrf_token", US_ASCII)
, RIVar
(RString csrfTokenVal, US_ASCII))
, ( RIVar (RString "token", US_ASCII)
, RIVar (RString authToken, UTF_8))
])