rails-session-0.1.4.0: Decrypt Ruby on Rails sessions in Haskell
Safe HaskellSafe-Inferred
LanguageGHC2021

Web.Rails3.Session

Synopsis

Tutorial

Here's how to decode a Rail3 session/auth cookie using wai & cookie package.

import Network.Wai (requestHeaders)
import Web.Cookie (parseCookies)
...

case (fmap (lookup "_yourapp_session") $ fmap parseCookies $ lookup Cookie $ requestHeaders waiRequest) of

-- no active Rails session
Left _ -> ...

Right c -> case (decodeEither (Secret "yourSessionSecret") (Cookie c)) of

  -- something went wrong in decoding the cookie. You should log "e" for debugging!
  Left e -> ...

  Right obj -> case (lookupUserIds obj) of

     -- we have a Rails session-cookie, but the user has not signed-in
    Nothing -> ...

    -- signed-in user. This may contain muliple userIds depending up on how you have configured Devise/Warden in your Rails app.
    Just userIds -> ...

Decoding

decodeEither :: Secret -> Cookie -> Either String RubyObject Source #

Decode a cookie encoded by Rails3. You can find the Secret in a file called config/initializers/secret_token.rb in your Rail3 app.

Note: decodeMaybe has not been added on purpose. When cookie decoding fails, you would really want to know why. Please consider logging Left values returned by this function in your log, to save yourself some debugging time later.

decode :: Secret -> Cookie -> Maybe RubyObject Source #

Decode a cookie encoded by Rails3. Please read the documentation of decodeEither for more details, and consider using decodeEither instead of decode

Utilities

lookupUserIds :: Num a => RubyObject -> Maybe (NonEmpty a) Source #

Lookup the Warden/Devise UserIds from a decoded cookie. Please note, a cookie may contain multiple UserIds, because it seems that it is possible to be logged-in as multiple users simultaneously, if you define multiple user models (the underlying data-structure allows it, as well).

Throw-away data-types

These data-types exist only as a way to semantically differentiate between various ByteString arguments when they are passed to functions. This is required only because Haskell doesn't have proper keywords-arguments.