{-# LANGUAGE CPP, QuasiQuotes, TypeFamilies, GeneralizedNewtypeDeriving #-}
{-# LANGUAGE FlexibleContexts, FlexibleInstances, TemplateHaskell, OverloadedStrings #-}
{-# LANGUAGE GADTs, MultiParamTypeClasses, TypeSynonymInstances #-}
module Foundation where
import Data.Text (Text)
import Data.ByteString (ByteString)
import Database.Persist.Sqlite
import Data.IORef
import System.IO.Unsafe (unsafePerformIO)
import Yesod
import Yesod.Auth
import Yesod.Auth.Account
import Yesod.Test
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
User
username Text
UniqueUsername username
password ByteString
emailAddress Text
UniqueEmailAddress emailAddress
verified Bool
verifyKey Text
resetPasswordKey Text
deriving Show
|]
instance PersistUserCredentials User where
userUsernameF = UserUsername
userPasswordHashF = UserPassword
userEmailF = UserEmailAddress
userEmailVerifiedF = UserVerified
userEmailVerifyKeyF = UserVerifyKey
userResetPwdKeyF = UserResetPasswordKey
uniqueUsername = UniqueUsername
uniqueEmailaddress = UniqueEmailAddress
userCreate name email key pwd = User name pwd email False key ""
data MyApp = MyApp ConnectionPool
lastVerifyEmailR :: IORef (Username, Text, Text) -- ^ (username, email, verify url)
{-# NOINLINE lastVerifyEmailR #-}
lastVerifyEmailR = unsafePerformIO (newIORef ("", "", ""))
lastNewPwdEmailR :: IORef (Username, Text, Text) -- ^ (username, email, verify url)
{-# NOINLINE lastNewPwdEmailR #-}
lastNewPwdEmailR = unsafePerformIO (newIORef ("", "", ""))
lastVerifyEmail :: MonadIO m => m (Username, Text, Text)
lastVerifyEmail = liftIO $ readIORef lastVerifyEmailR
lastNewPwdEmail :: MonadIO m => m (Username, Text, Text)
lastNewPwdEmail = liftIO $ readIORef lastNewPwdEmailR
mkYesod "MyApp" [parseRoutes|
/ HomeR GET
/auth AuthR Auth getAuth
|]
instance Yesod MyApp
instance RenderMessage MyApp FormMessage where
renderMessage _ _ = defaultFormMessage
instance YesodPersist MyApp where
#if MIN_VERSION_yesod(1,4,0)
type YesodPersistBackend MyApp = SqlBackend
#else
type YesodPersistBackend MyApp = SqlPersistT
#endif
runDB action = do
MyApp pool <- getYesod
runSqlPool action pool
instance YesodAuth MyApp where
type AuthId MyApp = Username
getAuthId = return . Just . credsIdent
loginDest _ = HomeR
logoutDest _ = HomeR
authPlugins _ = [accountPlugin]
authHttpManager _ = error "No manager needed"
onLogin = return ()
maybeAuthId = lookupSession "_ID"
instance AccountSendEmail MyApp where
sendVerifyEmail name email url =
liftIO $ writeIORef lastVerifyEmailR (name, email, url)
sendNewPasswordEmail name email url =
liftIO $ writeIORef lastNewPwdEmailR (name, email, url)
instance YesodAuthAccount (AccountPersistDB MyApp User) MyApp where
runAccountDB = runAccountPersistDB
getTextId _ = return
getHomeR :: Handler Html
getHomeR = do
maid <- maybeAuthId
case maid of
Nothing -> defaultLayout $ [whamlet|
<p>Please visit the <a href="@{AuthR LoginR}">Login page</a>
|]
Just u -> defaultLayout $ [whamlet|
<p>You are logged in as #{u}
<p><a href="@{AuthR LogoutR}">Logout</a>
|]
-- Temporary helpers for testing
get' :: Yesod site => Text -> YesodExample site ()
get' url = Yesod.Test.get url
post' :: Yesod site => Text -> RequestBuilder site () -> YesodExample site ()
post' url builder = request $ do
setUrl url
setMethod "POST"
builder