working things out

This commit is contained in:
nek0 2019-05-09 01:24:58 +02:00
parent 221c41b7db
commit 770c20dde0
4 changed files with 62 additions and 20 deletions

View file

@ -35,7 +35,7 @@ executable mateamt
, opaleye , opaleye
, aeson , aeson
, text , text
, time ^>=1.9 , time
, product-profunctors , product-profunctors
, postgresql-simple , postgresql-simple
, warp , warp

View file

@ -20,7 +20,6 @@ let
mtl opaleye postgresql-simple product-profunctors random-bytestring mtl opaleye postgresql-simple product-profunctors random-bytestring
servant servant-server stm text time wai wai-logger warp servant servant-server stm text time wai wai-logger warp
]; ];
jailbreak = true;
description = "A whole new matemat"; description = "A whole new matemat";
license = stdenv.lib.licenses.agpl3; license = stdenv.lib.licenses.agpl3;
}; };

View file

@ -25,6 +25,8 @@ import Control.Monad.IO.Class (liftIO)
import Control.Monad (void) import Control.Monad (void)
import Control.Monad.Reader
import Control.Concurrent.STM.TVar import Control.Concurrent.STM.TVar
-- internal imports -- internal imports
@ -53,7 +55,7 @@ main = do
app :: ReadState -> Application app :: ReadState -> Application
-- app conn = serveWithContext userApi genAuthServerContext (users conn) -- app conn = serveWithContext userApi genAuthServerContext (users conn)
app initState = serveWithContext userApi genAuthServerContext $ app initState = serveWithContext userApi genAuthServerContext $
hoistServer (runReaderT initState) users hoistServer userApi (`runReaderT` initState) users
userApi :: Proxy UserAPI userApi :: Proxy UserAPI
userApi = Proxy userApi = Proxy
@ -74,7 +76,7 @@ authHandler = mkAuthHandler handler
return res return res
users :: ServerT UserAPI (ReaderT ReadState Handler) users :: ServerT UserAPI (ReaderT ReadState Handler)
users conn = users =
( userList :<|> ( userList :<|>
userNew :<|> userNew :<|>
userUpdate userUpdate
@ -83,22 +85,27 @@ users conn =
authSend authSend
) )
where where
userList :: Maybe Refine -> Bool -> Handler [User] userList :: Maybe Refine -> Bool -> MateHandler [User]
userList ref sw = liftIO $ userSelect conn ref sw userList ref sw = liftIO $ do
conn <- rsConnection <$> ask
userSelect conn ref sw
userNew :: UserSubmit -> Handler Int userNew :: UserSubmit -> MateHandler Int
userNew us = liftIO $ do userNew us = liftIO $ do
now <- getCurrentTime now <- getCurrentTime
randSalt <- random 8 randSalt <- random 8
conn <- rsConnection <$> ask
head <$> runInsert_ conn (insertUser us (utctDay now) randSalt) head <$> runInsert_ conn (insertUser us (utctDay now) randSalt)
userUpdate :: (Int, UserSubmit) -> Handler () userUpdate :: (Int, UserSubmit) -> MateHandler ()
userUpdate (id, us) = liftIO $ do userUpdate (id, us) = liftIO $ do
now <- getCurrentTime now <- getCurrentTime
conn <- rsConnection <$> ask
void $ runUpdate_ conn (updateUser id us (utctDay now)) void $ runUpdate_ conn (updateUser id us (utctDay now))
authGet :: Int -> Handler AuthInfo authGet :: Int -> MateHandler AuthInfo
authGet = liftIO . getUserAuthInfo conn authGet id =
getUserAuthInfo id
authSend :: AuthRequest -> Handler AuthResult authSend :: AuthRequest -> MateHandler AuthResult
authSend _ = liftIO $ Granted <$> AuthToken <$> random 8 authSend _ = liftIO $ Granted <$> AuthToken <$> random 8

View file

@ -10,16 +10,18 @@ import Control.Monad.IO.Class (liftIO)
import Control.Monad.Reader (ask) import Control.Monad.Reader (ask)
import Control.Concurrent.STM
import Data.Profunctor.Product (p3) import Data.Profunctor.Product (p3)
import qualified Database.PostgreSQL.Simple as PGS import qualified Database.PostgreSQL.Simple as PGS
import Data.Text (Text) import Data.Text (Text)
import Data.Fixed (Fixed(..)) import qualified Data.Set as S
import Data.Time.Calendar (Day) import Data.Time.Calendar (Day)
import Data.Time.Clock (secondsToNominalDiffTime) import Data.Time.Clock
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Data.ByteString.Random import Data.ByteString.Random
@ -60,11 +62,12 @@ getUserAuthInfo
:: PGS.Connection :: PGS.Connection
-> Int -> Int
-> MateHandler AuthInfo -> MateHandler AuthInfo
getUserAuthInfo conn id = do getUserAuthInfo id = do
conn <- rsConnection <$> ask
users <- liftIO $ runSelect conn ( users <- liftIO $ runSelect conn (
keepWhen (\(uid, _, _, _, _, _, _, _, _) -> keepWhen (\(uid, _, _, _, _, _, _, _, _) ->
uid .== C.constant id) <<< queryTable userTable uid .== C.constant id) <<< queryTable userTable
) :: IO ) :: MateHandler
[ ( Int [ ( Int
, Text , Text
, Int , Int
@ -81,15 +84,48 @@ getUserAuthInfo conn id = do
) )
users users
checkTicket
:: Ticket
-> AuthHash
-> MateHandler Token
generateToken (Ticket _ id exp) hash = do
conn <- rsConnection <$> ask
users <- liftIO $ runSelect conn (
keepWhen (\(uid, _, _, _, _, _, _, _, _) ->
uid .== C.cinstant id) <<< queryTable userTable
) :: MateHandler
[ ( Int
, Text
, Int
, Day
, Maybe Text
, Maybe Int
, ByteString
, Maybe ByteString
, Maybe Int
)
]
let userHash = head $ map (\(i1, i2, i3, i4, i5, i6, i7, i8, i9) -> i8)
newTicket :: Int -> MateHandler AuthTicket newTicket :: Int -> MateHandler AuthTicket
newTicket id = do newTicket id = do
store <- rsTicketStore <$> ask store <- rsTicketStore <$> ask
rand <- liftIO $ random 23 rand <- liftIO $ random 23
later <- liftIO $ (addUTCTime (secondsToNominalDiffTime (MkFixed 23)) <$> getCurrentTime) later <- liftIO $ (addUTCTime (23/60) <$> getCurrentTime)
let ticket = AuthTicket let ticket = Ticket
{ ticketId = rand { ticketId = AuthTicket rand
, ticketUser = id , ticketUser = id
, ticketExpiry = later , ticketExpiry = later
} }
liftIO $ modifyTVar store (\s -> insert tocket store) liftIO $ atomically $ modifyTVar store (\s -> S.insert ticket s)
retur ticket return (AuthTicket rand)
processAuthRequest
:: AuthRequest
-> MateHandler AuthResult
processAuthRequest (AuthRequest aticket hash) = do
store <- (liftIO . readTVarIO) <$> rsTicketStore <$> ask
let mticket = S.filter (\st -> ticketId st == aticket) store
case toList mticket of
[ticket] -> checkTicket ticket hash
_ -> return Denied