{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
module Yesod.Auth.Hardcoded
( YesodAuthHardcoded(..)
, authHardcoded
, loginR )
where
import Yesod.Auth (AuthPlugin (..), AuthRoute,
Creds (..), Route (..), YesodAuth,
loginErrorMessageI, setCredsRedirect,
AuthHandler)
import qualified Yesod.Auth.Message as Msg
import Yesod.Core
import Yesod.Form (ireq, runInputPost, textField)
import Control.Applicative ((<$>), (<*>))
import Data.Text (Text)
loginR :: AuthRoute
loginR :: AuthRoute
loginR = Text -> Texts -> AuthRoute
PluginR Text
"hardcoded" [Text
"login"]
class (YesodAuth site) => YesodAuthHardcoded site where
doesUserNameExist :: Text -> AuthHandler site Bool
validatePassword :: Text -> Text -> AuthHandler site Bool
authHardcoded :: YesodAuthHardcoded m => AuthPlugin m
authHardcoded :: AuthPlugin m
authHardcoded =
Text
-> (Text -> Texts -> AuthHandler m TypedContent)
-> ((AuthRoute -> Route m) -> WidgetFor m ())
-> AuthPlugin m
forall master.
Text
-> (Text -> Texts -> AuthHandler master TypedContent)
-> ((AuthRoute -> Route master) -> WidgetFor master ())
-> AuthPlugin master
AuthPlugin Text
"hardcoded" Text -> Texts -> AuthHandler m TypedContent
forall a a (m :: * -> *) b.
(IsString a, IsString a, YesodAuthHardcoded (HandlerSite m),
MonadHandler m, MonadUnliftIO m, Eq a, Eq a,
SubHandlerSite m ~ Auth) =>
a -> [a] -> m b
dispatch (AuthRoute -> Route m) -> WidgetFor m ()
forall site.
YesodAuth site =>
(AuthRoute -> Route site) -> WidgetFor site ()
loginWidget
where
dispatch :: a -> [a] -> m b
dispatch a
"POST" [a
"login"] = m TypedContent
forall site.
YesodAuthHardcoded site =>
AuthHandler site TypedContent
postLoginR m TypedContent -> (TypedContent -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= TypedContent -> m b
forall (m :: * -> *) c a.
(MonadHandler m, ToTypedContent c) =>
c -> m a
sendResponse
dispatch a
_ [a]
_ = m b
forall (m :: * -> *) a. MonadHandler m => m a
notFound
loginWidget :: (AuthRoute -> Route site) -> WidgetFor site ()
loginWidget AuthRoute -> Route site
toMaster = do
YesodRequest
request <- WidgetFor site YesodRequest
forall (m :: * -> *). MonadHandler m => m YesodRequest
getRequest
[whamlet|
$newline never
<form method="post" action="@{toMaster loginR}">
$maybe t <- reqToken request
<input type=hidden name=#{defaultCsrfParamName} value=#{t}>
<table>
<tr>
<th>_{Msg.UserName}
<td>
<input type="text" name="username" required>
<tr>
<th>_{Msg.Password}
<td>
<input type="password" name="password" required>
<tr>
<td colspan="2">
<button type="submit" .btn .btn-success>_{Msg.LoginTitle}
|]
postLoginR :: YesodAuthHardcoded site
=> AuthHandler site TypedContent
postLoginR :: AuthHandler site TypedContent
postLoginR =
do (Text
username, Text
password) <- FormInput m (Text, Text) -> m (Text, Text)
forall (m :: * -> *) a. MonadHandler m => FormInput m a -> m a
runInputPost
((,) (Text -> Text -> (Text, Text))
-> FormInput m Text -> FormInput m (Text -> (Text, Text))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
Control.Applicative.<$> Field m Text -> Text -> FormInput m Text
forall (m :: * -> *) a.
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m a -> Text -> FormInput m a
ireq Field m Text
forall (m :: * -> *).
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m Text
textField Text
"username"
FormInput m (Text -> (Text, Text))
-> FormInput m Text -> FormInput m (Text, Text)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
Control.Applicative.<*> Field m Text -> Text -> FormInput m Text
forall (m :: * -> *) a.
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m a -> Text -> FormInput m a
ireq Field m Text
forall (m :: * -> *).
(Monad m, RenderMessage (HandlerSite m) FormMessage) =>
Field m Text
textField Text
"password")
Bool
isValid <- Text -> Text -> AuthHandler site Bool
forall site.
YesodAuthHardcoded site =>
Text -> Text -> AuthHandler site Bool
validatePassword Text
username Text
password
if Bool
isValid
then Creds (HandlerSite m) -> m TypedContent
forall (m :: * -> *).
(MonadHandler m, YesodAuth (HandlerSite m)) =>
Creds (HandlerSite m) -> m TypedContent
setCredsRedirect (Text -> Text -> [(Text, Text)] -> Creds site
forall master. Text -> Text -> [(Text, Text)] -> Creds master
Creds Text
"hardcoded" Text
username [])
else do Bool
isExists <- Text -> AuthHandler site Bool
forall site.
YesodAuthHardcoded site =>
Text -> AuthHandler site Bool
doesUserNameExist Text
username
AuthRoute -> AuthMessage -> AuthHandler site TypedContent
forall master.
AuthRoute -> AuthMessage -> AuthHandler master TypedContent
loginErrorMessageI AuthRoute
LoginR
(if Bool
isExists
then AuthMessage
Msg.InvalidUsernamePass
else Text -> AuthMessage
Msg.IdentifierNotFound Text
username)