forked from astro/bitlove-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBitloveAuth.hs
93 lines (84 loc) · 3.45 KB
/
BitloveAuth.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
{-# LANGUAGE TupleSections, RankNTypes #-}
module BitloveAuth where
import Prelude
import Yesod
import Data.Maybe
import qualified Data.ByteString.Char8 as BC
import qualified Network.Wai as Wai
import Web.Cookie
import qualified Database.HDBC.PostgreSQL as PostgreSQL (Connection)
import qualified Data.Text as T
import Utils
import Model.Session
import Model.User
login :: UserName -> GHandler y y' ()
login = setSession "user" . userName
sessionUser :: GHandler y y' (Maybe UserName)
sessionUser = lookupSession "user" >>=
return . maybe Nothing (Just . UserName)
canEdit :: UserName -> GHandler sub master Bool
canEdit user = maybe False (`elem` [user, UserName "astro"]) `fmap`
sessionUser
logout :: GHandler y y' ()
logout = deleteSession "user"
sessionBackend :: (forall b. (PostgreSQL.Connection -> IO b) -> IO b) -> SessionBackend a
sessionBackend withDB =
-- | App callback
SessionBackend $ \_app req _time ->
do let mSidCookie =
listToMaybe
[sid
| ("Cookie", headerValue) <- Wai.requestHeaders req,
sid <- maybeToList $ "sid" `lookup` parseCookies headerValue
]
mSid
| maybe False isHex mSidCookie =
(SessionId . fromHex . T.pack . BC.unpack) `fmap`
mSidCookie
| otherwise =
Nothing
session :: IO BackendSession
session =
case mSid of
Nothing ->
return []
Just sid ->
do users <- withDB $ validateSession sid
return $
case users of
(UserName user):_ ->
[("user", BC.pack $ T.unpack user)]
_ ->
[]
oldSession <- session
let saveSession :: BackendSession -> time -> IO [Header]
saveSession newSession _time =
let mOldUser = "user" `lookup` oldSession
mNewUser = "user" `lookup` newSession
in case (mOldUser, mNewUser) of
-- Login
(Nothing, Just user) ->
do session <- withDB $
createSession $
UserName $ T.pack $ BC.unpack user
putStrLn $ "New session for " ++
show user ++ ": " ++
show session
return [AddCookie def
{ setCookieName = "sid"
, setCookieValue = BC.pack $ T.unpack $
toHex $
unSessionId
session
}]
-- Logout
(Just user, Nothing) ->
do case mSid of
Just sid ->
withDB $ invalidateSession sid
_ ->
return ()
return [DeleteCookie "sid" "/"]
_ ->
return []
return (oldSession, saveSession)