2019-10-22 01:01:15 +00:00
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
2021-07-12 11:29:40 +00:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
2022-02-20 20:48:16 +00:00
|
|
|
{-# LANGUAGE RecordWildCards #-}
|
2019-10-22 01:01:15 +00:00
|
|
|
module Util where
|
|
|
|
|
|
|
|
import Opaleye
|
|
|
|
|
2021-07-12 11:29:40 +00:00
|
|
|
import Data.ByteString.Lazy (fromStrict)
|
|
|
|
|
2019-12-12 02:15:56 +00:00
|
|
|
import Data.Maybe (fromMaybe)
|
2019-10-22 01:01:15 +00:00
|
|
|
|
|
|
|
import Data.Profunctor.Product.Default (Default)
|
|
|
|
|
2022-04-15 18:51:22 +00:00
|
|
|
import Data.String (fromString)
|
|
|
|
|
2021-07-12 11:29:40 +00:00
|
|
|
import qualified Data.Text as T
|
|
|
|
|
|
|
|
import qualified Data.Text.Encoding as E
|
|
|
|
|
2021-02-01 01:25:08 +00:00
|
|
|
import Database.PostgreSQL.Simple
|
|
|
|
|
|
|
|
import Control.Monad (void)
|
2021-07-12 11:29:40 +00:00
|
|
|
import Control.Monad.Reader (asks)
|
|
|
|
import Control.Monad.IO.Class (liftIO)
|
|
|
|
|
|
|
|
import Network.Mail.Mime
|
|
|
|
|
|
|
|
import System.Directory (doesFileExist)
|
2021-02-01 01:25:08 +00:00
|
|
|
|
|
|
|
-- internal imports
|
|
|
|
|
|
|
|
import Model
|
2021-07-12 11:29:40 +00:00
|
|
|
import Types
|
|
|
|
|
2022-04-15 18:52:32 +00:00
|
|
|
-- | This is the internal function to check a users authorization to do certain
|
|
|
|
-- actions
|
|
|
|
checkCapability
|
|
|
|
:: Int -- ^ User Id to check
|
|
|
|
-> (Role -> Bool) -- ^ Predicate to check
|
|
|
|
-> MateHandler Bool -- ^ Result
|
|
|
|
checkCapability uid accessRule = do
|
|
|
|
conn <- asks rsConnection
|
|
|
|
assocs <- selectUserAssociations uid conn
|
|
|
|
let rids = map roleAssociationRole assocs
|
|
|
|
roles <- selectRoleList rids conn
|
|
|
|
return $ any accessRule roles
|
|
|
|
|
|
|
|
notImplemented :: MateHandler a
|
|
|
|
notImplemented = throwError $ err501
|
|
|
|
{ errBody = "Function has not yet been implemented!"
|
|
|
|
}
|
2022-02-20 20:48:16 +00:00
|
|
|
|
2019-10-22 01:01:15 +00:00
|
|
|
printSql :: Default Unpackspec a a => Select a -> IO ()
|
2022-02-20 20:03:05 +00:00
|
|
|
printSql = putStrLn . fromMaybe "Empty query" . showSql
|
2021-02-01 01:25:08 +00:00
|
|
|
|
|
|
|
initDB :: Connection -> IO ()
|
|
|
|
initDB conn = do
|
2022-02-20 20:03:05 +00:00
|
|
|
void $ execute_ conn initAvatar
|
|
|
|
void $ execute_ conn initUser
|
|
|
|
void $ execute_ conn initProduct
|
|
|
|
void $ execute_ conn initToken
|
|
|
|
void $ execute_ conn initAuthData
|
|
|
|
void $ execute_ conn initAmount
|
|
|
|
void $ execute_ conn initJournal
|
|
|
|
void $ execute_ conn initRole
|
|
|
|
void $ execute_ conn initUserToRole
|
2021-02-01 01:25:08 +00:00
|
|
|
void $ runInsertInitialRoles conn
|
2021-06-24 04:33:05 +00:00
|
|
|
|
|
|
|
-- This is only a dummy function.
|
|
|
|
-- TODO: Replace with proper translation function(s)!
|
|
|
|
__ = id
|
2021-07-12 11:29:40 +00:00
|
|
|
|
|
|
|
sendUserNotification
|
|
|
|
:: UserDetails -- ^ The recipient
|
|
|
|
-> T.Text -- ^ The mail subject
|
|
|
|
-> T.Text -- ^ The mail body
|
|
|
|
-> MateHandler ()
|
|
|
|
sendUserNotification recipient subject message =
|
|
|
|
case userDetailsEmail recipient of
|
|
|
|
Just email ->
|
|
|
|
sendNotification (Mail
|
|
|
|
{ mailFrom = Address Nothing "noreply"
|
|
|
|
, mailTo =
|
|
|
|
[ Address
|
|
|
|
(Just $ userDetailsIdent recipient)
|
2021-10-16 15:50:28 +00:00
|
|
|
email
|
2021-07-12 11:29:40 +00:00
|
|
|
]
|
|
|
|
, mailCc = []
|
|
|
|
, mailBcc = []
|
|
|
|
, mailHeaders = [("Subject", subject)]
|
|
|
|
, mailParts =
|
|
|
|
[[ Part
|
|
|
|
{ partType = "text/plain; charset=utf-8"
|
|
|
|
, partEncoding = None
|
|
|
|
, partDisposition = DefaultDisposition
|
|
|
|
, partHeaders = []
|
|
|
|
, partContent = PartContent (fromStrict $ E.encodeUtf8 message)
|
|
|
|
}
|
|
|
|
]]
|
|
|
|
}
|
|
|
|
)
|
|
|
|
Nothing ->
|
|
|
|
return ()
|
|
|
|
|
2021-07-14 01:08:58 +00:00
|
|
|
sendAdminNotification
|
|
|
|
:: T.Text -- The mail subject
|
|
|
|
-> T.Text -- The mail body
|
|
|
|
-> MateHandler ()
|
2022-02-20 20:48:16 +00:00
|
|
|
sendAdminNotification subject message = do
|
|
|
|
allUsers <- userGetAll
|
|
|
|
admins <- mapM
|
|
|
|
(\uid -> checkCapability uid roleCanManageSettings. userDetailsId)
|
|
|
|
allUsers
|
|
|
|
mapM_
|
|
|
|
(\ UserDetails {..} ->
|
|
|
|
let mail = Mail
|
|
|
|
{ mailFrom = Address Nothing "noreply"
|
|
|
|
, mailTo =
|
|
|
|
[ Address
|
|
|
|
(Just userDetailsIdent)
|
|
|
|
userDetailsEmail
|
|
|
|
]
|
|
|
|
, mailCc = []
|
|
|
|
, mailBcc =[]
|
|
|
|
, mailHeaders =
|
|
|
|
[[ Part
|
|
|
|
{ partType = "text/plain; charset=utf8"
|
|
|
|
, partEncoding = None
|
|
|
|
, partDisposition = DefaultDisposition
|
|
|
|
, partHeaders = []
|
|
|
|
, partContent = PartContent (fromString $ E.encodeUtf8 message)
|
|
|
|
}
|
|
|
|
]]
|
|
|
|
}
|
|
|
|
in
|
|
|
|
sendNotification mail
|
|
|
|
)
|
|
|
|
allUsers
|
2021-07-14 01:08:58 +00:00
|
|
|
|
2021-10-16 15:50:28 +00:00
|
|
|
sendNotification :: Mail -> MateHandler ()
|
2021-07-12 11:29:40 +00:00
|
|
|
sendNotification mail = do
|
2021-10-16 15:50:28 +00:00
|
|
|
sendmailPath <- asks rsSendmailPath
|
2021-07-12 11:29:40 +00:00
|
|
|
liftIO $ do
|
2021-10-16 15:50:28 +00:00
|
|
|
existence <- doesFileExist sendmailPath
|
2021-07-12 11:29:40 +00:00
|
|
|
if existence
|
|
|
|
then
|
2021-10-16 15:50:28 +00:00
|
|
|
renderSendMailCustom sendmailPath [] mail
|
2021-07-12 11:29:40 +00:00
|
|
|
else
|
2021-10-16 15:50:28 +00:00
|
|
|
print ("Warning: sending notification failed: Sendmail not present!"
|
|
|
|
:: String)
|