added remaining required query params
This commit is contained in:
parent
f47e0b7cb0
commit
35ab852882
@ -3,4 +3,4 @@ module Main (main) where
|
||||
import Server
|
||||
|
||||
main :: IO ()
|
||||
main = putStrLn "Try: http://localhost:8080/auth?scopes=[ID,Profile]" >> runMockServer 8080
|
||||
main = putStrLn "Try: http://localhost:8080/auth?scope=[ID,Profile]&client_id=42&response_type=code&redirect_uri=localhost" >> runMockServer 8080
|
||||
|
||||
@ -10,11 +10,12 @@ import User
|
||||
|
||||
import Control.Concurrent
|
||||
import Control.Exception (bracket)
|
||||
import Control.Monad (unless)
|
||||
import Control.Monad.IO.Class
|
||||
|
||||
import Data.Aeson
|
||||
import Data.List (find)
|
||||
import Data.Text hiding (find, head, map)
|
||||
import Data.Text hiding (elem, find, head, map)
|
||||
import Data.Text.Encoding (decodeUtf8)
|
||||
|
||||
import qualified Data.Map.Strict as Map
|
||||
@ -24,31 +25,68 @@ import Network.Wai.Handler.Warp
|
||||
|
||||
import Servant
|
||||
import Servant.Client
|
||||
-- import Servant.API
|
||||
import Servant.API
|
||||
|
||||
import Text.ParserCombinators.ReadPrec (look)
|
||||
import Text.Read (readPrec)
|
||||
|
||||
|
||||
testUsers :: [User]
|
||||
testUsers :: [User] -- TODO move to db
|
||||
testUsers =
|
||||
[ User {name = "Fallback User", email = "foo@bar.com", password = "0000", uID = "0"}
|
||||
, User {name = "Tina Tester", email = "t@t.tt", password = "1111", uID = "1"}
|
||||
, User {name = "Max Muster", email = "m@m.mm", password = "2222", uID = "2"}]
|
||||
|
||||
trustedClients :: [Text] -- TODO move to db
|
||||
trustedClients = ["42"]
|
||||
|
||||
data ResponseType = Code -- ^ authorisation code grant
|
||||
| Token -- ^ implicit grant via access token
|
||||
| IDToken -- ^ implicit grant via access token & ID token
|
||||
deriving (Eq, Show)
|
||||
instance Read ResponseType where
|
||||
readPrec = look >>= \str -> return $ case str of
|
||||
"code" -> Code
|
||||
"token" -> Token
|
||||
"id_token" -> IDToken
|
||||
|
||||
type QScope = String
|
||||
type QClient = String
|
||||
type QResType = String
|
||||
type QRedirect = String
|
||||
|
||||
type QParam = QueryParam' [Required, Strict]
|
||||
|
||||
type Auth user userData = BasicAuth "login" user
|
||||
:> "auth"
|
||||
:> QParam "scope" QScope
|
||||
:> QParam "client_id" QClient
|
||||
:> QParam "response_type" QResType
|
||||
:> QParam "redirect_uri" QRedirect
|
||||
:> Get '[JSON] userData
|
||||
|
||||
type Auth user userData = BasicAuth "login" user :> "auth" :> QueryParam "scopes" String :> Get '[JSON] (Maybe userData) -- TODO also parametrise "auth" to (auth :: Symbol)
|
||||
type Token = "token" :> Post '[JSON] Text -- TODO post jwt token
|
||||
-- type Insert = "insert" :> Post '[JSON] User
|
||||
|
||||
authServer :: forall user userData . UserData user userData => Server (Auth user userData)
|
||||
authServer = handleAuth
|
||||
where
|
||||
handleAuth :: user -> Maybe String -> Handler (Maybe userData)
|
||||
handleAuth _ Nothing = liftIO (putStrLn "no query param given") >> return Nothing
|
||||
handleAuth u (Just x) = do
|
||||
handleAuth :: user
|
||||
-> QScope
|
||||
-> QClient
|
||||
-> QResType
|
||||
-> QRedirect
|
||||
-> Handler userData
|
||||
handleAuth u scopes client responseType url = do
|
||||
unless (pack client `elem` trustedClients) . -- TODO fetch trusted clients from db
|
||||
throwError $ err404 { errBody = "Not a trusted client."}
|
||||
let
|
||||
scopes = readScopes @user @userData x
|
||||
ud = mconcat $ map (userScope @user @userData u) scopes
|
||||
liftIO (putStrLn $ "query param: " ++ showScopes @user @userData scopes)
|
||||
return $ Just ud
|
||||
scopes' = readScopes @user @userData scopes
|
||||
uData = mconcat $ map (userScope @user @userData u) scopes'
|
||||
responseType' = read @ResponseType responseType
|
||||
|
||||
liftIO (putStrLn $ "user: " ++ show u ++ " | scopes: " ++ showScopes @user @userData scopes')
|
||||
return uData
|
||||
|
||||
exampleAuthServer :: Server (Auth User (Map.Map Text Text))
|
||||
exampleAuthServer = authServer
|
||||
@ -71,8 +109,8 @@ authenticate users = BasicAuthCheck $ \authData -> do
|
||||
Nothing -> return NoSuchUser
|
||||
Just u -> return $ if uPass == password u then Authorized u else BadPassword
|
||||
|
||||
frontend :: BasicAuthData -> ClientM (Maybe (Map.Map Text Text))
|
||||
frontend ba = client authAPI ba $ Just "[ID]"
|
||||
frontend :: BasicAuthData -> ClientM (Map.Map Text Text)
|
||||
frontend ba = client authAPI ba "[ID]" "42" "code" ""
|
||||
|
||||
runMockServer :: Int -> IO ()
|
||||
runMockServer port = run port $ insecureOAuthMock' testUsers
|
||||
|
||||
@ -12,7 +12,7 @@ import Data.Text hiding (singleton)
|
||||
import GHC.Generics
|
||||
|
||||
|
||||
class (Eq u, ToJSON a, Monoid a) => UserData u a where -- TODO Eq maybe not necessary, but currently needed for TypeApplications
|
||||
class (Show u, ToJSON a, Monoid a) => UserData u a where -- TODO Show maybe not necessary, but currently needed for TypeApplications
|
||||
data Scope u
|
||||
readScopes :: String -> [Scope u]
|
||||
showScopes :: [Scope u] -> String
|
||||
|
||||
Loading…
Reference in New Issue
Block a user