From dcb947b1fb279a9c9c896f2ad1156e3c785c8ce2 Mon Sep 17 00:00:00 2001 From: Steffen Date: Tue, 12 Mar 2024 13:02:38 +0100 Subject: [PATCH] refactor(email): eliminate userAddress function due to user company linked email --- models/users.model | 2 +- src/Handler/Admin.hs | 2 +- src/Handler/Utils/Avs.hs | 16 +- src/Handler/Utils/Communication.hs | 4 +- src/Handler/Utils/Mail.hs | 36 +- src/Handler/Utils/Users.hs | 30 +- src/Jobs/Handler/ChangeUserDisplayEmail.hs | 8 +- src/Jobs/Handler/Invitation.hs | 10 +- src/Jobs/Handler/QueueNotification.hs | 7 +- src/Jobs/Handler/SendCourseCommunication.hs | 20 +- .../SendNotification/SubmissionEdited.hs | 19 +- .../SendNotification/SubmissionRated.hs | 14 +- src/Utils.hs | 4 + src/Utils/Mail.hs | 2 +- uniworx.cabal.bak | 2137 +++++++++++++++++ 15 files changed, 2244 insertions(+), 67 deletions(-) create mode 100644 uniworx.cabal.bak diff --git a/models/users.model b/models/users.model index a2b03cc67..97734a347 100644 --- a/models/users.model +++ b/models/users.model @@ -92,7 +92,7 @@ UserCompany supervisor Bool default=false -- should this user be made supervisor for all _new_ users associated with this company? supervisorReroute Bool default=false -- if supervisor is true, should this supervisor receive email for _new_ company users? priority Int default=0 -- higher number, higher priority - useCompanyAddress Bool default=true -- if true, CompanyPostalAddress is used if UserPostalAddress is Nothing, respects priority + useCompanyAddress Bool default=true -- if true, CompanyPostalAddress and CompanyEmail are used if UserPostalAddress/UserDisplayEmail are Nothing, respects priority UniqueUserCompany user company -- a user may belong to multiple companies, but to each one only once deriving Generic UserSupervisor diff --git a/src/Handler/Admin.hs b/src/Handler/Admin.hs index 6d011bc68..def7ff98f 100644 --- a/src/Handler/Admin.hs +++ b/src/Handler/Admin.hs @@ -170,7 +170,7 @@ retrieveUnreachableUsers = do return user filterM hasInvalidEmail emailOnlyUsers where - hasInvalidEmail = fmap isNothing . getEmailAddress + hasInvalidEmail = fmap isNothing . getUserEmail allDriversHaveAvsId :: UTCTime -> DB Bool diff --git a/src/Handler/Utils/Avs.hs b/src/Handler/Utils/Avs.hs index 3f57a9f51..9c1d5cccc 100644 --- a/src/Handler/Utils/Avs.hs +++ b/src/Handler/Utils/Avs.hs @@ -494,12 +494,11 @@ updateAvsUserByIds apids = do eml_new = (newAvsFirmInfo ^. _avsFirmPrimaryEmail) <|> (newAvsPersonInfo ^. _avsInfoPersonEMail) in mkUpdate usr eml_new eml_old $ CheckAvsUpdate UserDisplayEmail $ to (fromMaybe mempty) . from _CI -- Maybe nicht im User, aber im AvsInfo PROBLEM: Hängt auch von der FirmenEmail ab und muss daher im Verbund betrachtet werden. - -- TODO: company address no longer stored with each individual user - frm_ups = maybeEmpty oldAvsFirmInfo $ \oldAvsFirmInfo' -> mapMaybe (mkUpdate usr newAvsFirmInfo oldAvsFirmInfo') - [ CheckAvsUpdate UserPostAddress _avsFirmPostAddress - ] - - usr_ups = mcons eml_up $ frm_ups <> per_ups + -- Note: company address no longer stored with each individual user; referenced with UserCompany instead + -- frm_ups = maybeEmpty oldAvsFirmInfo $ \oldAvsFirmInfo' -> mapMaybe (mkUpdate usr newAvsFirmInfo oldAvsFirmInfo') + -- [ CheckAvsUpdate UserPostAddress _avsFirmPostAddress + -- ] + usr_ups = mcons eml_up per_ups -- <> frm_ups avs_ups = ((UserAvsNoPerson =.) <$> readMay (avsInfoPersonNo newAvsPersonInfo)) `mcons` [ UserAvsLastSynch =. now , UserAvsLastSynchError =. Nothing @@ -523,6 +522,7 @@ updateAvsUserByIds apids = do -- Add function to use a secondary company post address that won't be updated -- TODO #76 -- aktuelle Firmen löschen -- TODO #36 + -- TODO add EmailSuperior to UserSupervisor if not alreadu, using failsafe LDAP lookup if possible (Just oafi) | ((==) `on` view _avsFirmPostAddressSimple) oafi newAvsFirmInfo -- company address unchanged -> return () (Just oafi) | ((==) `on` view _avsFirmPrimaryEmail) oafi newAvsFirmInfo -- company primary email unchanged @@ -583,8 +583,8 @@ upsertAvsCompany newAvsFirmInfo mbOldAvsFirmInfo = do , companyShorthand = newAvsFirmInfo ^. _avsFirmAbbreviation . from _CI , companyAvsId = newAvsFirmInfo ^. _avsFirmFirmNo , companyPrefersPostal = True - , companyPostAddress = Nothing - , companyEmail = Nothing + , companyPostAddress = newAvsFirmInfo ^. _avsFirmPostAddress + , companyEmail = newAvsFirmInfo ^. _avsFirmPrimaryEmail . _Just . from _CI . re _Just } insert $ foldl' upd dmy firmInfo2company diff --git a/src/Handler/Utils/Communication.hs b/src/Handler/Utils/Communication.hs index 6aab48225..7e5a60004 100644 --- a/src/Handler/Utils/Communication.hs +++ b/src/Handler/Utils/Communication.hs @@ -102,7 +102,7 @@ crJobsCourseCommunication jCourse Communication{..} = do adrReceiverMails = Set.map (Address Nothing . CI.original) rawReceiverMails netReceiverAddresses <- lift $ do netReceiverIds <- getReceiversFor $ jSender : Set.toList rawReceiverIds -- ensure supervisors get only one email - (userAddress . entityVal) <<$>> selectList [UserId <-. netReceiverIds] [] -- TODO + maybeMapM getEmailAddressFor netReceiverIds -- let jAllRecipientAddresses = Set.fromList netReceiverAddresses <> adrReceiverMails let jAllRecipientAddresses = Set.map getAddress (Set.fromList (AddressEqIgnoreName <$> netReceiverAddresses) <> Set.map AddressEqIgnoreName adrReceiverMails) forM_ jAllRecipientAddresses $ \raddr -> @@ -124,7 +124,7 @@ crJobsFirmCommunication jCompanies Communication{..} = do adrReceiverMails = Set.map (Address Nothing . CI.original) rawReceiverMails netReceiverAddresses <- lift $ do netReceiverIds <- getReceiversFor $ jSender : Set.toList rawReceiverIds -- ensure supervisors get only one email - (userAddress . entityVal) <<$>> selectList [UserId <-. netReceiverIds] [] + maybeMapM getEmailAddressFor netReceiverIds -- let jAllRecipientAddresses = Set.fromList netReceiverAddresses <> adrReceiverMails let jAllRecipientAddresses = Set.map getAddress (Set.fromList (AddressEqIgnoreName <$> netReceiverAddresses) <> Set.map AddressEqIgnoreName adrReceiverMails) forM_ jAllRecipientAddresses $ \raddr -> diff --git a/src/Handler/Utils/Mail.hs b/src/Handler/Utils/Mail.hs index 114b8b0c9..cbac6b337 100644 --- a/src/Handler/Utils/Mail.hs +++ b/src/Handler/Utils/Mail.hs @@ -3,9 +3,7 @@ -- SPDX-License-Identifier: AGPL-3.0-or-later module Handler.Utils.Mail - ( addRecipientsDB - , userAddress, userAddress' - , userAddressFrom + ( addRecipientsDB , userMailT, userMailTdirect , addFileDB , addHtmlMarkdownAlternatives @@ -16,7 +14,7 @@ import Import import Handler.Utils.Pandoc import Handler.Utils.Files import Handler.Utils.Widgets (nameHtml') -- TODO: how to use name widget here? -import Handler.Utils.Users (getReceivers, getEmailAddress) +import Handler.Utils.Users (getReceivers, getUserEmail) import Handler.Utils.Profile import qualified Data.CaseInsensitive as CI @@ -40,30 +38,30 @@ addRecipientsDB uFilter = runConduit $ transPipe (liftHandler . runDB) (selectSo let addr = Address (Just userDisplayName) $ CI.original $ pickValidUserEmail userDisplayEmail userEmail _mailTo %= flip snoc addr -userAddressFrom :: User -> Address +-- -- These pure functions may no longer be used, since they ignore company emails address indirections via UserCompany es +-- +-- userAddressFrom :: User -> Address -- ^ Format an e-mail address suitable for usage in a @From@-header -- -- Uses `userDisplayEmail` only -userAddressFrom User{userDisplayEmail, userDisplayName} = Address (Just userDisplayName) $ CI.original userDisplayEmail +-- userAddressFrom User{userDisplayEmail, userDisplayName} = Address (Just userDisplayName) $ CI.original userDisplayEmail +-- userAddress :: User -> Address +-- -- ^ Format an e-mail address suitable for usage as a recipient +-- -- +-- -- Like userAddressFrom, but prefers `userDisplayEmail` (if valid) and otherwise uses `userEmail`. Unlike Uni2work, userEmail from LDAP is untrustworthy. +-- userAddress User{userEmail, userDisplayEmail, userDisplayName} +-- = Address (Just userDisplayName) $ CI.original $ pickValidUserEmail userDisplayEmail userEmail --- TODO: Check that these functions can be used or are replaced, since they ignore company emails addresses -userAddress :: User -> Address --- ^ Format an e-mail address suitable for usage as a recipient --- --- Like userAddressFrom, but prefers `userDisplayEmail` (if valid) and otherwise uses `userEmail`. Unlike Uni2work, userEmail from LDAP is untrustworthy. -userAddress User{userEmail, userDisplayEmail, userDisplayName} - = Address (Just userDisplayName) $ CI.original $ pickValidUserEmail userDisplayEmail userEmail - -userAddress' :: UserEmail -> UserEmail -> UserDisplayName -> Address --- Like userAddress', but does not require a complete entity -userAddress' userEmail userDisplayEmail userDisplayName - = Address (Just userDisplayName) $ CI.original $ pickValidUserEmail userDisplayEmail userEmail +-- userAddress' :: UserEmail -> UserEmail -> UserDisplayName -> Address +-- -- Like userAddress', but does not require a complete entity +-- userAddress' userEmail userDisplayEmail userDisplayName +-- = Address (Just userDisplayName) $ CI.original $ pickValidUserEmail userDisplayEmail userEmail userAddressError :: (MonadHandler m, HandlerSite m ~ UniWorX, m ~ HandlerFor UniWorX) => Entity User -> m (Bool, Address) userAddressError usr@Entity{entityVal=User{userEmail, userDisplayEmail, userDisplayName}} = - runDB (getEmailAddress usr) >>= \case + runDB (getUserEmail usr) >>= \case Just okEmail -> pure (True, Address (Just userDisplayName) $ CI.original okEmail) Nothing -> do $logErrorS "Mail" $ "Attempt to email invalid address: " <> tshow userDisplayEmail <> " / " <> tshow userEmail <> ". Sent to support instead." -- <> " with subject " <> tshow failedSubject diff --git a/src/Handler/Utils/Users.hs b/src/Handler/Utils/Users.hs index 24cd181c5..df3de339c 100644 --- a/src/Handler/Utils/Users.hs +++ b/src/Handler/Utils/Users.hs @@ -15,7 +15,9 @@ module Handler.Utils.Users , guessUser , UserAssimilateException(..), UserAssimilateExceptionReason(..) , assimilateUser - , getEmailAddress + , getUserEmail + , getEmailAddress, getJustEmailAddress + , getEmailAddressFor, getJustEmailAddressFor , getPostalAddress, getPostalAddress' , getPostalPreferenceAndAddress, getPostalPreferenceAndAddress' , abbrvName @@ -55,6 +57,12 @@ import Handler.Utils.Profile import Jobs.Types(Job, JobChildren) +data ExceptionUserHandling + = ExceptionUserHasNoEmail + deriving (Eq, Ord, Read, Show, Generic) -- Enum, Bounded, +instance Exception ExceptionUserHandling + + abbrvName :: User -> Text abbrvName User{userDisplayName, userFirstName, userSurname} = if | (lastDisplayName : tsrif) <- reverse nameParts @@ -81,7 +89,7 @@ getUserCompanyAddress uid prj = runMaybeT $ do getPostalPreferenceAndAddress :: Entity User -> DB (Bool, Maybe [Text], Maybe UserEmail) getPostalPreferenceAndAddress usr = do pa <- getPostalAddress usr - em <- getEmailAddress usr + em <- getUserEmail usr let usrPrefPost = usr ^. _entityVal . _userPrefersPostal finalPref = (usrPrefPost && isJust pa) || isNothing em -- finalPref = isJust pa && (usrPrefPost || isNothing em) @@ -92,15 +100,27 @@ getPostalPreferenceAndAddress usr = do getPostalPreferenceAndAddress' :: Entity User -> DB (Bool, Maybe StoredMarkup, Maybe UserEmail) getPostalPreferenceAndAddress' usr = do pa <- getPostalAddress' usr - em <- getEmailAddress usr + em <- getUserEmail usr let usrPrefPost = usr ^. _entityVal . _userPrefersPostal finalPref = (usrPrefPost && isJust pa) || isNothing em -- finalPref = isJust pa && (usrPrefPost || isNothing em) return (finalPref, pa, em) +getEmailAddressFor :: UserId -> DB (Maybe Address) +getEmailAddressFor = maybeM (return Nothing) getEmailAddress . getEntity + +getJustEmailAddressFor :: UserId -> DB Address +getJustEmailAddressFor = maybeThrowM ExceptionUserHasNoEmail . getEmailAddressFor -getEmailAddress :: Entity User -> DB (Maybe UserEmail) -getEmailAddress Entity{entityKey=uid, entityVal=User{userDisplayEmail, userEmail}} +getJustEmailAddress :: Entity User -> DB Address +getJustEmailAddress = maybeThrowM ExceptionUserHasNoEmail . getEmailAddress + +getEmailAddress :: Entity User -> DB (Maybe Address) +getEmailAddress usr@Entity{entityVal=User{userDisplayName}} = toAddress <<$>> getUserEmail usr + where toAddress = Address (Just userDisplayName) . CI.original + +getUserEmail :: Entity User -> DB (Maybe UserEmail) +getUserEmail Entity{entityKey=uid, entityVal=User{userDisplayEmail, userEmail}} | validEmail' userDisplayEmail = return $ Just userDisplayEmail | otherwise diff --git a/src/Jobs/Handler/ChangeUserDisplayEmail.hs b/src/Jobs/Handler/ChangeUserDisplayEmail.hs index ec735be34..ccdc2b65d 100644 --- a/src/Jobs/Handler/ChangeUserDisplayEmail.hs +++ b/src/Jobs/Handler/ChangeUserDisplayEmail.hs @@ -9,6 +9,7 @@ module Jobs.Handler.ChangeUserDisplayEmail import Import import Handler.Utils.Mail +import Handler.Utils.Users import qualified Data.HashSet as HashSet import qualified Data.HashMap.Strict as HashMap import qualified Data.CaseInsensitive as CI @@ -24,10 +25,13 @@ dispatchJobChangeUserDisplayEmail jUser jDisplayEmail = JobHandlerException $ do setDisplayEmailUrl = SomeRoute (SetDisplayEmailR, [(toPathPiece GetBearer, toPathPiece jwt)]) setDisplayEmailUrl' <- toTextUrl setDisplayEmailUrl - user@User{..} <- runDB $ getJust jUser + (Entity{entityVal=User{..}}, userAddress) <- runDB $ do + usrEnt <- getJustEntity jUser -- error aborts job + usrAdr <- getJustEmailAddress usrEnt + return (usrEnt, usrAdr) userMailT jUser $ do - _mailTo .= pure (userAddress user & _addressEmail .~ CI.original jDisplayEmail) + _mailTo .= pure (userAddress & _addressEmail .~ CI.original jDisplayEmail) replaceMailHeader "Auto-Submitted" $ Just "auto-generated" setSubjectI MsgMailSubjectChangeUserDisplayEmail addHtmlMarkdownAlternatives ($(ihamletFile "templates/mail/changeUserDisplayEmail.hamlet") :: HtmlUrlI18n (SomeMessage UniWorX) (Route UniWorX)) diff --git a/src/Jobs/Handler/Invitation.hs b/src/Jobs/Handler/Invitation.hs index 783b035dd..4e6afeb67 100644 --- a/src/Jobs/Handler/Invitation.hs +++ b/src/Jobs/Handler/Invitation.hs @@ -8,6 +8,7 @@ module Jobs.Handler.Invitation import Import import Handler.Utils.Mail +import Handler.Utils.Users import qualified Data.CaseInsensitive as CI import Text.Hamlet @@ -20,12 +21,15 @@ dispatchJobInvitation :: Maybe UserId -> Html -> JobHandler UniWorX dispatchJobInvitation jInviter jInvitee jInvitationUrl jInvitationSubject jInvitationExplanation = JobHandlerException $ do - mInviter <- join <$> traverse (runDB . get) jInviter + (mInviter, mInviterAddress) <- ifMaybeM jInviter (Nothing,Nothing) $ \uid -> runDB $ do + usrEnt <- getEntity uid + usrAdr <- join <$> traverse getEmailAddress usrEnt + return (usrEnt ^? _Just . _entityVal, usrAdr) mailT def $ do _mailTo .= [Address Nothing $ CI.original jInvitee] - whenIsJust mInviter $ \jInviter' -> - replaceMailHeader "Reply-To" . Just . renderAddress $ userAddressFrom jInviter' + whenIsJust mInviterAddress $ \jInviterAddress -> + replaceMailHeader "Reply-To" . Just $ renderAddress jInviterAddress replaceMailHeader "Auto-Submitted" $ Just "auto-generated" replaceMailHeader "Subject" $ Just jInvitationSubject addHtmlMarkdownAlternatives ($(ihamletFile "templates/mail/invitation.hamlet") :: HtmlUrlI18n (SomeMessage UniWorX) (Route UniWorX)) diff --git a/src/Jobs/Handler/QueueNotification.hs b/src/Jobs/Handler/QueueNotification.hs index d6dbb36b9..fb1b0f75b 100644 --- a/src/Jobs/Handler/QueueNotification.hs +++ b/src/Jobs/Handler/QueueNotification.hs @@ -16,7 +16,8 @@ import Jobs.Queue import qualified Data.Set as Set -import Handler.Utils.Profile (pickValidUserEmail') +-- import Handler.Utils.Profile (pickValidUserEmail') +import Handler.Utils.Users (getUserEmail) import Handler.Utils.ExamOffice.Exam import Handler.Utils.ExamOffice.ExternalExam @@ -27,8 +28,8 @@ dispatchJobQueueNotification :: Notification -> JobHandler UniWorX dispatchJobQueueNotification jNotification = JobHandlerAtomic $ runConduit $ yield jNotification .| transPipe (hoist lift) determineNotificationCandidates - .| C.filterM (\(notification', override, Entity _ User{userNotificationSettings,userDisplayEmail,userEmail}) -> - and2M (return $ isJust $ pickValidUserEmail' userDisplayEmail userEmail) $ -- TODO: use getEmailAddress instead - although it is a DB action! + .| C.filterM (\(notification', override, usr@(Entity _ User{userNotificationSettings})) -> + and2M (isJust <$> hoist lift (getUserEmail usr)) $ or2M (return override) $ notificationAllowed userNotificationSettings <$> hoist lift (classifyNotification notification')) .| C.map (\(notification', _, Entity uid _) -> JobSendNotification uid notification') .| sinkDBJobs diff --git a/src/Jobs/Handler/SendCourseCommunication.hs b/src/Jobs/Handler/SendCourseCommunication.hs index 1a065726c..cd5badf96 100644 --- a/src/Jobs/Handler/SendCourseCommunication.hs +++ b/src/Jobs/Handler/SendCourseCommunication.hs @@ -12,6 +12,7 @@ import Import import Text.Hamlet import Handler.Utils +import Handler.Utils.Users import qualified Data.CaseInsensitive as CI import Handler.Utils.Csv (partIsAttachmentCsv) @@ -28,14 +29,17 @@ dispatchJobSendCourseCommunication :: Either UserEmail UserId -> CommunicationContent -> JobHandler UniWorX dispatchJobSendCourseCommunication jRecipientEmail jAllRecipientAddresses jCourse jSender jMailObjectUUID CommunicationContent{..} = JobHandlerException $ do - (sender, Course{..}) <- runDB $ (,) - <$> getJust jSender - <*> getJust jCourse + (Course{..}, senderAddress) <- runDB $ do + crs <- getJust jCourse + usr <- getJustEntity jSender + adr <- getJustEmailAddress usr + return (crs, adr) + either (\email -> mailT def . (assign _mailTo (pure . Address Nothing $ CI.original email) *>)) userMailT jRecipientEmail $ do -- userMailT obeys reroutes, userMailT direct does not MsgRenderer mr <- getMailMsgRenderer void $ setMailObjectUUID jMailObjectUUID - _mailFrom .= userAddressFrom sender + _mailFrom .= senderAddress addMailHeader "Cc" [st|#{mr MsgCommUndisclosedRecipients}:;|] addMailHeader "Auto-Submitted" "no" setSubjectI . prependCourseTitle courseTerm courseSchool courseShorthand $ maybe (SomeMessage MsgUtilCommCourseSubject) SomeMessage ccSubject @@ -55,15 +59,13 @@ dispatchJobSendFirmCommunication :: Either UserEmail UserId -> CommunicationContent -> JobHandler UniWorX dispatchJobSendFirmCommunication jRecipientEmail jAllRecipientAddresses _jCompanies jSender jMailObjectUUID CommunicationContent{..} = JobHandlerException $ do - -- (sender,mbComp) <- runDB $ (,) - -- <$> getJust jSender - -- <*> ifMaybeM jCompany Nothing get - sender <- runDB $ getJust jSender + senderAddress <- runDB $ getJustEmailAddressFor jSender + either (\email -> mailT def . (assign _mailTo (pure . Address Nothing $ CI.original email) *>)) userMailT jRecipientEmail $ do -- userMailT obeys reroutes, userMailT direct does not MsgRenderer mr <- getMailMsgRenderer void $ setMailObjectUUID jMailObjectUUID - _mailFrom .= userAddressFrom sender + _mailFrom .= senderAddress addMailHeader "Cc" [st|#{mr MsgCommUndisclosedRecipients}:;|] addMailHeader "Auto-Submitted" "no" setSubjectI $ maybe (SomeMessage MsgUtilCommFirmSubject) SomeMessage ccSubject diff --git a/src/Jobs/Handler/SendNotification/SubmissionEdited.hs b/src/Jobs/Handler/SendNotification/SubmissionEdited.hs index 94679e01a..854a519e2 100644 --- a/src/Jobs/Handler/SendNotification/SubmissionEdited.hs +++ b/src/Jobs/Handler/SendNotification/SubmissionEdited.hs @@ -13,6 +13,7 @@ module Jobs.Handler.SendNotification.SubmissionEdited import Import import Handler.Utils +import Handler.Utils.Users import Jobs.Handler.SendNotification.Utils import Text.Hamlet @@ -36,10 +37,11 @@ dispatchNotificationSubmissionEdited nInitiator nSubmission jRecipient = userMai E.where_ $ submissionUser E.^. SubmissionUserSubmission E.==. E.val nSubmission E.&&. user E.^. UserId E.!=. E.val jRecipient return user + coSubmittorsAddrs <- maybeMapM getEmailAddress coSubmittors - return (course, sheet, submission, initiator, coSubmittors) + return (course, sheet, submission, initiator, coSubmittorsAddrs) - let allCoSubmittors = Text.intercalate ", " $ map (renderAddress . userAddressFrom . entityVal) coSubmittors + let allCoSubmittors = Text.intercalate ", " $ map renderAddress coSubmittors addMailHeader "Reply-To" allCoSubmittors replaceMailHeader "Auto-Submitted" $ Just "auto-generated" @@ -69,14 +71,15 @@ dispatchNotificationSubmissionUserCreated nUser nSubmission jRecipient = userMai E.where_ $ submissionUser E.^. SubmissionUserSubmission E.==. E.val nSubmission E.&&. user E.^. UserId E.!=. E.val jRecipient return user + coSubmittorsAddrs <- maybeMapM getEmailAddress coSubmittors user <- getJust nUser - return (user, course, sheet, submission, coSubmittors) + return (user, course, sheet, submission, coSubmittorsAddrs) let isSelf = nUser == jRecipient - let allCoSubmittors = Text.intercalate ", " $ map (renderAddress . userAddressFrom . entityVal) coSubmittors + let allCoSubmittors = Text.intercalate ", " $ map renderAddress coSubmittors addMailHeader "Reply-To" allCoSubmittors replaceMailHeader "Auto-Submitted" $ Just "auto-generated" @@ -99,7 +102,7 @@ dispatchNotificationSubmissionUserCreated nUser nSubmission jRecipient = userMai dispatchNotificationSubmissionUserDeleted :: UserId -> SheetId -> SubmissionId -> UserId -> Handler () dispatchNotificationSubmissionUserDeleted nUser nSheet nSubmission jRecipient = userMailT jRecipient $ do - (User{..}, Course{..}, Sheet{..}, mSubmission, coSubmittors) <- liftHandler . runDB $ do + (User{..}, Course{..}, Sheet{..}, mSubmission, coSubmittors, coSubmittorsAddrs) <- liftHandler . runDB $ do submission <- get nSubmission sheet <- maybe (getJust nSheet) (belongsToJust submissionSheet) submission @@ -110,15 +113,15 @@ dispatchNotificationSubmissionUserDeleted nUser nSheet nSubmission jRecipient = E.where_ $ submissionUser E.^. SubmissionUserSubmission E.==. E.val nSubmission E.&&. user E.^. UserId E.!=. E.val jRecipient return user - + coSubmittorsAddrs <- maybeMapM getEmailAddress coSubmittors user <- getJust nUser - return (user, course, sheet, submission, coSubmittors) + return (user, course, sheet, submission, coSubmittors, coSubmittorsAddrs) let isSelf = nUser == jRecipient unless (null coSubmittors) $ do - let allCoSubmittors = Text.intercalate ", " $ map (renderAddress . userAddressFrom . entityVal) coSubmittors + let allCoSubmittors = Text.intercalate ", " $ map renderAddress coSubmittorsAddrs addMailHeader "Reply-To" allCoSubmittors replaceMailHeader "Auto-Submitted" $ Just "auto-generated" diff --git a/src/Jobs/Handler/SendNotification/SubmissionRated.hs b/src/Jobs/Handler/SendNotification/SubmissionRated.hs index efbb0a5fc..fd04a4b92 100644 --- a/src/Jobs/Handler/SendNotification/SubmissionRated.hs +++ b/src/Jobs/Handler/SendNotification/SubmissionRated.hs @@ -11,6 +11,7 @@ module Jobs.Handler.SendNotification.SubmissionRated import Import import Handler.Utils +import Handler.Utils.Users import Jobs.Handler.SendNotification.Utils import Text.Hamlet @@ -19,22 +20,25 @@ import qualified Data.CaseInsensitive as CI dispatchNotificationSubmissionRated :: SubmissionId -> UserId -> Handler () dispatchNotificationSubmissionRated nSubmission jRecipient = maybeT_ $ do - (Course{..}, Sheet{..}, Submission{..}, corrector, sheetTypeDesc, hasAccess, csid) <- lift . runDB $ do + (Course{..}, Sheet{..}, Submission{..}, corrector, correctorAddr, sheetTypeDesc, hasAccess, csid) <- lift . runDB $ do submission@Submission{submissionRatingBy} <- getJust nSubmission sheet@Sheet{sheetName} <- belongsToJust submissionSheet submission course@Course{..} <- belongsToJust sheetCourse sheet - corrector <- traverse getJust submissionRatingBy + correctorEnt <- traverse getJustEntity submissionRatingBy + correctorAddr <- join <$> traverse getEmailAddress correctorEnt + let corrector = correctorEnt ^? _Just . _entityVal + sheetTypeDesc <- sheetTypeDescription (sheetCourse sheet) (sheetType sheet) csid <- encrypt nSubmission hasAccess <- is _Authorized <$> evalAccessForDB (Just jRecipient) (CSubmissionR courseTerm courseSchool courseShorthand sheetName csid CorrectionR) False - return (course, sheet, submission, corrector, sheetTypeDesc, hasAccess, csid) + return (course, sheet, submission, corrector, correctorAddr, sheetTypeDesc, hasAccess, csid) guard hasAccess lift . userMailT jRecipient $ do - whenIsJust corrector $ \corrector' -> - addMailHeader "Reply-To" . renderAddress $ userAddressFrom corrector' + whenIsJust correctorAddr $ \correctorAddr' -> + addMailHeader "Reply-To" $ renderAddress correctorAddr' replaceMailHeader "Auto-Submitted" $ Just "auto-generated" setSubjectI $ MsgMailSubjectSubmissionRated courseShorthand diff --git a/src/Utils.hs b/src/Utils.hs index 2f708775a..a8393c4ba 100644 --- a/src/Utils.hs +++ b/src/Utils.hs @@ -1006,6 +1006,10 @@ maybeThrow exc = maybe (throwM exc) return maybeThrowM :: (Exception e, MonadThrow m) => e -> m (Maybe a) -> m a maybeThrowM = fromMaybeM . throwM +maybeMapM :: Applicative m => (a -> m (Maybe b)) -> [a] -> m [b] +maybeMapM f = foldr go (pure []) + where + go = liftA2 (maybe id (:)) . f mapMaybeM :: ( Monad m , MonoFoldable (f a) diff --git a/src/Utils/Mail.hs b/src/Utils/Mail.hs index 2e34c69b1..6f172a5ac 100644 --- a/src/Utils/Mail.hs +++ b/src/Utils/Mail.hs @@ -13,7 +13,7 @@ import qualified Data.CaseInsensitive as CI import qualified Text.Email.Validate as Email --- also see `Handler.Utils.Users.getEmailAddress` for Tests accepting User Type +-- also see `Handler.Utils.Users.getUserEmail` for Tests accepting User Type validEmail :: Text -> Bool -- Email = Text validEmail email = validRFC5322 && not invalidFraport where diff --git a/uniworx.cabal.bak b/uniworx.cabal.bak new file mode 100644 index 000000000..58d80a244 --- /dev/null +++ b/uniworx.cabal.bak @@ -0,0 +1,2137 @@ +cabal-version: 1.12 + +-- This file has been generated from package.yaml by hpack version 0.35.0. +-- +-- see: https://github.com/sol/hpack + +name: uniworx +version: 27.4.58 +build-type: Simple +data-files: + testdata/AbgabeH10-1.hs + testdata/avs_json.hs + testdata/fradrive_f_results_2022051910.csv + testdata/fradrive_f_results_2022051910.csv.license + testdata/H10-2.hs + testdata/H10-3.hs + testdata/ProMo_Uebung10.pdf + testdata/ProMo_Uebung10.pdf.license + testdata/test.pdf + testdata/test.pdf.license + testdata/test_letters.hs + testdata/test_results.csv + testdata/test_results.csv.license + +flag dev + description: Turn on development settings, like auto-reload templates. + manual: False + default: False + +flag library-only + description: Build for use with "yesod devel" + manual: False + default: False + +flag pedantic + description: Be very pedantic about warnings and errors + manual: False + default: True + +library + exposed-modules: + Application + Audit + Audit.Types + Auth.Dummy + Auth.LDAP + Auth.LDAP.AD + Auth.PWHash + Colonnade.Instances + Control.Arrow.Instances + Control.Monad.Catch.Instances + Control.Monad.Trans.Except.Instances + Control.Monad.Trans.Memo.StateCache.Instances + Control.Monad.Trans.Random.Instances + Cron + Cron.Types + Crypto.Hash.Instances + Crypto.Random.Instances + CryptoID + CryptoID.Cached + CryptoID.TH + Data.Aeson.Types.Instances + Data.Bool.Instances + Data.CaseInsensitive.Instances + Data.CryptoID.Instances + Data.Encoding.Instances + Data.Fixed.Instances + Data.HashSet.Instances + Data.Maybe.Instances + Data.Monoid.Instances + Data.MonoTraversable.Instances + Data.MultiSet.Instances + Data.NonNull.Instances + Data.Scientific.Instances + Data.SemVer.Instances + Data.Set.Instances + Data.Sum.Instances + Data.Time.Calendar.Instances + Data.Time.Clock.Instances + Data.Time.Clock.Instances.TH + Data.Time.Format.Instances + Data.Time.LocalTime.Instances + Data.Universe.Instances.Reverse.Hashable + Data.Universe.Instances.Reverse.JSON + Data.Universe.Instances.Reverse.MonoTraversable + Data.Universe.Instances.Reverse.WithIndex + Data.Universe.TH + Data.UUID.Instances + Data.Void.Instances + Data.Word.Word24.Instances + Database.Esqueleto.Instances + Database.Esqueleto.Utils + Database.Esqueleto.Utils.TH + Database.Persist.Class.Instances + Database.Persist.Sql.Types.Instances + Database.Persist.TH.Directory + Database.Persist.Types.Instances + Foundation + Foundation.Authorization + Foundation.DB + Foundation.I18n + Foundation.I18n.TH + Foundation.Instances + Foundation.Instances.ButtonClass + Foundation.Navigation + Foundation.Routes + Foundation.Routes.Definitions + Foundation.Servant + Foundation.Servant.Types + Foundation.SiteLayout + Foundation.Type + Foundation.Types + Foundation.Yesod.Auth + Foundation.Yesod.ErrorHandler + Foundation.Yesod.Middleware + Foundation.Yesod.Persist + Foundation.Yesod.Session + Foundation.Yesod.StaticContent + Handler.Admin + Handler.Admin.Avs + Handler.Admin.Crontab + Handler.Admin.ErrorMessage + Handler.Admin.Ldap + Handler.Admin.Test + Handler.Admin.Test.Download + Handler.Admin.Tokens + Handler.ApiDocs + Handler.Course + Handler.Course.Communication + Handler.Course.Delete + Handler.Course.Edit + Handler.Course.Events + Handler.Course.Events.Delete + Handler.Course.Events.Edit + Handler.Course.Events.Form + Handler.Course.Events.New + Handler.Course.LecturerInvite + Handler.Course.List + Handler.Course.News + Handler.Course.News.Delete + Handler.Course.News.Download + Handler.Course.News.Edit + Handler.Course.News.Form + Handler.Course.News.New + Handler.Course.News.Show + Handler.Course.ParticipantInvite + Handler.Course.Register + Handler.Course.Show + Handler.Course.User + Handler.Course.Users + Handler.CryptoIDDispatch + Handler.Error + Handler.Exam + Handler.Exam.AddUser + Handler.Exam.AutoOccurrence + Handler.Exam.Correct + Handler.Exam.CorrectorInvite + Handler.Exam.Edit + Handler.Exam.Form + Handler.Exam.List + Handler.Exam.New + Handler.Exam.Register + Handler.Exam.RegistrationInvite + Handler.Exam.Show + Handler.Exam.Users + Handler.ExamOffice + Handler.ExamOffice.Course + Handler.ExamOffice.Exam + Handler.ExamOffice.Exams + Handler.ExamOffice.ExternalExam + Handler.ExamOffice.Fields + Handler.ExamOffice.Users + Handler.ExternalExam + Handler.ExternalExam.Correct + Handler.ExternalExam.Edit + Handler.ExternalExam.Form + Handler.ExternalExam.List + Handler.ExternalExam.New + Handler.ExternalExam.Show + Handler.ExternalExam.StaffInvite + Handler.ExternalExam.Users + Handler.Firm + Handler.Health + Handler.Health.Interface + Handler.Help + Handler.Info + Handler.Info.TH + Handler.LMS + Handler.LMS.Fake + Handler.LMS.Learners + Handler.LMS.Report + Handler.LMS.Users + Handler.Material + Handler.Metrics + Handler.News + Handler.Participants + Handler.PrintCenter + Handler.Profile + Handler.Qualification + Handler.SAP + Handler.School + Handler.Sheet + Handler.Sheet.CorrectorInvite + Handler.Sheet.Current + Handler.Sheet.Delete + Handler.Sheet.Download + Handler.Sheet.Edit + Handler.Sheet.Form + Handler.Sheet.List + Handler.Sheet.New + Handler.Sheet.PersonalisedFiles + Handler.Sheet.PersonalisedFiles.Meta + Handler.Sheet.PersonalisedFiles.Types + Handler.Sheet.Pseudonym + Handler.Sheet.Show + Handler.StorageKey + Handler.Submission + Handler.Submission.Assign + Handler.Submission.AuthorshipStatements + Handler.Submission.Correction + Handler.Submission.Create + Handler.Submission.Delete + Handler.Submission.Download + Handler.Submission.Grade + Handler.Submission.Helper + Handler.Submission.Helper.ArchiveTable + Handler.Submission.List + Handler.Submission.New + Handler.Submission.Show + Handler.Submission.SubmissionUserInvite + Handler.Submission.Upload + Handler.Swagger + Handler.SystemMessage + Handler.Term + Handler.Tutorial + Handler.Tutorial.Communication + Handler.Tutorial.Delete + Handler.Tutorial.Edit + Handler.Tutorial.Form + Handler.Tutorial.List + Handler.Tutorial.New + Handler.Tutorial.Register + Handler.Tutorial.TutorInvite + Handler.Tutorial.Users + Handler.Upload + Handler.Users + Handler.Users.Add + Handler.Utils + Handler.Utils.AuthorshipStatement + Handler.Utils.Avs + Handler.Utils.Communication + Handler.Utils.Company + Handler.Utils.Concurrent + Handler.Utils.ContentDisposition + Handler.Utils.Corrections + Handler.Utils.Course + Handler.Utils.Csv + Handler.Utils.Database + Handler.Utils.DateTime + Handler.Utils.Delete + Handler.Utils.Download + Handler.Utils.Exam + Handler.Utils.ExamOffice.Course + Handler.Utils.ExamOffice.Exam + Handler.Utils.ExamOffice.ExternalExam + Handler.Utils.ExternalExam + Handler.Utils.ExternalExam.Users + Handler.Utils.Files + Handler.Utils.Form + Handler.Utils.Form.MassInput + Handler.Utils.Form.MassInput.Liveliness + Handler.Utils.Form.MassInput.TH + Handler.Utils.Form.Occurrences + Handler.Utils.Form.Types + Handler.Utils.I18n + Handler.Utils.Invitations + Handler.Utils.LdapSystemFunctions + Handler.Utils.LMS + Handler.Utils.Mail + Handler.Utils.Memcached + Handler.Utils.Minio + Handler.Utils.News + Handler.Utils.Occurrences + Handler.Utils.Pandoc + Handler.Utils.Profile + Handler.Utils.Qualification + Handler.Utils.Random + Handler.Utils.Rating + Handler.Utils.Rating.Format + Handler.Utils.Rating.Format.Legacy + Handler.Utils.Routes + Handler.Utils.Sheet + Handler.Utils.SheetType + Handler.Utils.StudyFeatures + Handler.Utils.Submission + Handler.Utils.Table + Handler.Utils.Table.Cells + Handler.Utils.Table.Columns + Handler.Utils.Table.Pagination + Handler.Utils.Table.Pagination.CsvColumnExplanations + Handler.Utils.Table.Pagination.Types + Handler.Utils.Term + Handler.Utils.TermCandidates + Handler.Utils.Tutorial + Handler.Utils.Users + Handler.Utils.Widgets + Handler.Utils.Zip + Import + Import.NoFoundation + Import.NoModel + Import.Servant + Import.Servant.NoFoundation + Jobs + Jobs.Crontab + Jobs.Handler.ChangeUserDisplayEmail + Jobs.Handler.DistributeCorrections + Jobs.Handler.ExternalApis + Jobs.Handler.Files + Jobs.Handler.HelpRequest + Jobs.Handler.Intervals.Utils + Jobs.Handler.Invitation + Jobs.Handler.LMS + Jobs.Handler.PersonalisedSheetFiles + Jobs.Handler.Print + Jobs.Handler.PruneInvitations + Jobs.Handler.PruneOldSentMails + Jobs.Handler.QueueNotification + Jobs.Handler.SendCourseCommunication + Jobs.Handler.SendNotification + Jobs.Handler.SendNotification.CorrectionsAssigned + Jobs.Handler.SendNotification.CorrectionsNotDistributed + Jobs.Handler.SendNotification.CourseRegistered + Jobs.Handler.SendNotification.ExamActive + Jobs.Handler.SendNotification.ExamOffice + Jobs.Handler.SendNotification.ExamResult + Jobs.Handler.SendNotification.Qualification + Jobs.Handler.SendNotification.SheetActive + Jobs.Handler.SendNotification.SheetInactive + Jobs.Handler.SendNotification.SubmissionEdited + Jobs.Handler.SendNotification.SubmissionRated + Jobs.Handler.SendNotification.UserAuthModeUpdate + Jobs.Handler.SendNotification.UserRightsUpdate + Jobs.Handler.SendNotification.Utils + Jobs.Handler.SendPasswordReset + Jobs.Handler.SendTestEmail + Jobs.Handler.SetLogSettings + Jobs.Handler.StudyFeatures + Jobs.Handler.SynchroniseAvs + Jobs.Handler.SynchroniseLdap + Jobs.Handler.TransactionLog + Jobs.HealthReport + Jobs.Offload + Jobs.Queue + Jobs.Types + Jose.Jwk.Instances + Jose.Jwt.Instances + Language.Haskell.TH.Instances + Ldap.Client.Instances + Ldap.Client.Pool + Mail + Model + Model.Migration + Model.Migration.Definitions + Model.Migration.Types + Model.Migration.Version + Model.Rating + Model.Submission + Model.Tokens + Model.Tokens.Bearer + Model.Tokens.Lens + Model.Tokens.Session + Model.Tokens.Upload + Model.Types + Model.Types.Apis + Model.Types.Avs + Model.Types.Changelog + Model.Types.Common + Model.Types.Communication + Model.Types.Course + Model.Types.Csv + Model.Types.DateTime + Model.Types.Exam + Model.Types.ExamOffice + Model.Types.File + Model.Types.Health + Model.Types.Languages + Model.Types.Lms + Model.Types.Mail + Model.Types.Markup + Model.Types.Misc + Model.Types.Room + Model.Types.School + Model.Types.Security + Model.Types.Sheet + Model.Types.Submission + Model.Types.SystemMessage + Model.Types.TH.Binary + Model.Types.TH.JSON + Model.Types.TH.PathPiece + Model.Types.TH.Wordlist + Model.Types.Upload + Model.Types.User + Network.HTTP.Types.Method.Instances + Network.IP.Addr.Instances + Network.Mail.Mime.Instances + Network.Mime.TH + Network.Minio.Instances + Network.URI.Instances + Numeric.Natural.Instances + Prometheus.Instances + Servant.Client.Core.BaseUrl.Instances + Servant.Docs.Internal.Pretty.Instances + Servant.Server.Instances + ServantApi + ServantApi.ExternalApis + ServantApi.ExternalApis.Type + Settings + Settings.Cluster + Settings.Cluster.Volatile + Settings.Cookies + Settings.Locale + Settings.Log + Settings.Mime + Settings.StaticFiles + Settings.StaticFiles.Generator + Settings.StaticFiles.Webpack + Settings.WellKnownFiles + Settings.WellKnownFiles.TH + System.Clock.Instances + System.FilePath.Glob.TH + System.FilePath.Instances + Text.Blaze.Instances + Text.Shakespeare.Text.Instances + UnliftIO.Async.Utils + Utils + Utils.Approot + Utils.ARC + Utils.Auth + Utils.Avs + Utils.Cookies + Utils.Cookies.Registered + Utils.Course + Utils.Csv + Utils.Csv.Mail + Utils.DateTime + Utils.DB + Utils.Exam.Correct + Utils.Failover + Utils.Files + Utils.Form + Utils.Frontend.I18n + Utils.Frontend.Modal + Utils.Frontend.Notification + Utils.Holidays + Utils.HttpConditional + Utils.I18n + Utils.Icon + Utils.Lang + Utils.Lens + Utils.Lens.TH + Utils.LRU + Utils.Mail + Utils.Memo + Utils.Message + Utils.Metrics + Utils.NTop + Utils.Occurrences + Utils.Pandoc + Utils.Parameters + Utils.PathPiece + Utils.Persist + Utils.PersistentTokenBucket + Utils.Pool + Utils.Postgresql + Utils.Print + Utils.Print.CourseCertificate + Utils.Print.ExpireQualification + Utils.Print.Instances + Utils.Print.Letters + Utils.Print.RenewQualification + Utils.Print.SomeLetter + Utils.Room + Utils.Route + Utils.Session + Utils.Set + Utils.Sheet + Utils.Sql + Utils.SystemMessage + Utils.Term + Utils.TH + Utils.TH.AlphaConversion + Utils.TH.Routes + Utils.Tokens + Utils.Users + Utils.VolatileClusterSettings + Utils.Widgets + Web.Cookie.Instances + Web.PathPieces.Instances + Web.ServerSession.Backend.Persistent.Memcached + Web.ServerSession.Frontend.Yesod.Jwt + Yesod.Core.Instances + Yesod.Core.Types.Instances + Yesod.Core.Types.Instances.Catch + Yesod.Form.Fields.Instances + Yesod.Form.Types.Instances + Yesod.Servant + Yesod.Servant.HttpApiDataInjective + other-modules: + Paths_uniworx + hs-source-dirs: + src + default-extensions: + OverloadedStrings + PartialTypeSignatures + ScopedTypeVariables + TemplateHaskell + QuasiQuotes + CPP + TypeSynonymInstances + KindSignatures + ConstraintKinds + ViewPatterns + TypeOperators + TupleSections + TypeFamilies + GADTs + StandaloneDeriving + RecordWildCards + RankNTypes + PatternGuards + PatternSynonyms + ParallelListComp + NumDecimals + MultiWayIf + NamedFieldPuns + NoImplicitPrelude + LambdaCase + MultiParamTypeClasses + FlexibleContexts + FlexibleInstances + FunctionalDependencies + EmptyDataDecls + ExistentialQuantification + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + DeriveLift + DeriveFunctor + DeriveFoldable + DeriveTraversable + DeriveAnyClass + DerivingStrategies + DerivingVia + GeneralizedNewtypeDeriving + DataKinds + BinaryLiterals + PolyKinds + PackageImports + TypeApplications + RecursiveDo + TypeFamilyDependencies + QuantifiedConstraints + EmptyDataDeriving + StandaloneKindSignatures + NoStarIsType + other-extensions: + GeneralizedNewtypeDeriving + IncoherentInstances + OverloadedLists + UndecidableInstances + ApplicativeDo + ghc-options: -Wall -Wmissing-home-modules -Wredundant-constraints -Widentities -Wincomplete-uni-patterns -fno-warn-type-defaults -fno-warn-unrecognised-pragmas -fno-warn-partial-type-signatures -fno-max-relevant-binds -j -freduction-depth=0 -fprof-auto-calls -g + build-depends: + Glob + , HaskellNet + , HaskellNet-SSL + , HsYAML + , HsYAML-aeson + , IntervalMap + , MonadRandom + , acid-state + , aeson >=1.5 + , aeson-pretty + , array + , async + , attoparsec + , base + , base32 + , base64-bytestring + , bimap + , binary + , binary-instances + , binary-orphans + , blaze-html + , blaze-markup + , bytestring + , case-insensitive + , cassava + , cassava-conduit + , classy-prelude + , classy-prelude-yesod + , clock + , colonnade >=1.1.1 + , conduit + , conduit-resumablesink >=0.2 + , connection + , constraints + , containers + , cookie + , cryptoids + , cryptoids-class + , cryptoids-types + , cryptonite + , cryptonite-conduit + , data-default + , data-textual + , deepseq + , directory + , directory-tree + , doclayout + , doctemplates + , either + , email-validate + , encoding + , esqueleto >=3.1.0 + , exceptions + , extended-reals + , fast-logger + , fastcdc + , file-embed + , filepath + , filepath-crypto + , foreign-store + , generic-deriving + , generic-lens + , gitrev + , hashable + , haskell-src-meta + , hsass + , http-api-data + , http-client + , http-client-tls + , http-conduit + , http-types + , insert-ordered-containers + , jose-jwt + , lattices + , ldap-client + , lens + , lens-aeson + , list-t + , memcached-binary + , memory + , mime-mail + , mime-types + , minio-hs + , mmorph + , monad-control + , monad-logger + , monad-memo + , mono-traversable + , mono-traversable-keys + , mtl + , multiset + , network >=3 + , network-bsd + , network-ip + , network-uri + , nonce + , pandoc + , pandoc-types + , parsec + , parsec-numbers + , path-pieces + , persistent + , persistent-postgresql + , persistent-qq + , persistent-template + , pkcs7 + , pointedlist + , postgresql-simple + , pqueue + , profunctors + , prometheus-client + , prometheus-metrics-ghc + , psqueues + , random + , random-shuffle + , resourcet + , retry + , rfc5051 + , saltine + , scientific + , semigroupoids + , semver + , servant + , servant-client + , servant-client-core + , servant-docs + , servant-quickcheck + , servant-server + , servant-swagger + , serversession + , serversession-backend-acid-state + , shakespeare + , stm + , stm-delay + , streaming-commons + , swagger2 + , system-locale + , systemd + , tagged + , template-haskell + , text + , text-metrics + , th-abstraction + , th-lift + , th-lift-instances + , time + , token-bucket + , topograph + , transformers + , transformers-base + , typed-process + , tz + , unidecode + , universe + , universe-base + , unix + , unliftio + , unliftio-pool + , unordered-containers + , uuid + , uuid-crypto + , uuid-types + , vault + , vector + , wai + , wai-extra + , wai-logger + , wai-middleware-prometheus + , warp + , wl-pprint-text + , word24 + , xlsx + , xss-sanitize + , yaml + , yesod + , yesod-auth + , yesod-core + , yesod-form + , yesod-persistent + , yesod-static + , zip-stream + default-language: Haskell2010 + if flag(pedantic) + ghc-options: -Werror -fwarn-tabs + if flag(dev) + ghc-options: -O0 -ddump-splices -ddump-to-file -Wderiving-typeable + cpp-options: -DDEVELOPMENT + else + ghc-options: -O -fllvm +RTS -K0 -RTS + +executable uniworx + main-is: main.hs + other-modules: + DevelMain + Paths_uniworx + hs-source-dirs: + app + default-extensions: + OverloadedStrings + PartialTypeSignatures + ScopedTypeVariables + TemplateHaskell + QuasiQuotes + CPP + TypeSynonymInstances + KindSignatures + ConstraintKinds + ViewPatterns + TypeOperators + TupleSections + TypeFamilies + GADTs + StandaloneDeriving + RecordWildCards + RankNTypes + PatternGuards + PatternSynonyms + ParallelListComp + NumDecimals + MultiWayIf + NamedFieldPuns + NoImplicitPrelude + LambdaCase + MultiParamTypeClasses + FlexibleContexts + FlexibleInstances + FunctionalDependencies + EmptyDataDecls + ExistentialQuantification + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + DeriveLift + DeriveFunctor + DeriveFoldable + DeriveTraversable + DeriveAnyClass + DerivingStrategies + DerivingVia + GeneralizedNewtypeDeriving + DataKinds + BinaryLiterals + PolyKinds + PackageImports + TypeApplications + RecursiveDo + TypeFamilyDependencies + QuantifiedConstraints + EmptyDataDeriving + StandaloneKindSignatures + NoStarIsType + other-extensions: + GeneralizedNewtypeDeriving + IncoherentInstances + OverloadedLists + UndecidableInstances + ApplicativeDo + ghc-options: -Wall -Wmissing-home-modules -Wredundant-constraints -Widentities -Wincomplete-uni-patterns -fno-warn-type-defaults -fno-warn-unrecognised-pragmas -fno-warn-partial-type-signatures -fno-max-relevant-binds -j -freduction-depth=0 -fprof-auto-calls -g -threaded -rtsopts "-with-rtsopts=-N -T" + build-depends: + Glob + , HaskellNet + , HaskellNet-SSL + , HsYAML + , HsYAML-aeson + , IntervalMap + , MonadRandom + , acid-state + , aeson >=1.5 + , aeson-pretty + , array + , async + , attoparsec + , base + , base32 + , base64-bytestring + , bimap + , binary + , binary-instances + , binary-orphans + , blaze-html + , blaze-markup + , bytestring + , case-insensitive + , cassava + , cassava-conduit + , classy-prelude + , classy-prelude-yesod + , clock + , colonnade >=1.1.1 + , conduit + , conduit-resumablesink >=0.2 + , connection + , constraints + , containers + , cookie + , cryptoids + , cryptoids-class + , cryptoids-types + , cryptonite + , cryptonite-conduit + , data-default + , data-textual + , deepseq + , directory + , directory-tree + , doclayout + , doctemplates + , either + , email-validate + , encoding + , esqueleto >=3.1.0 + , exceptions + , extended-reals + , fast-logger + , fastcdc + , file-embed + , filepath + , filepath-crypto + , foreign-store + , generic-deriving + , generic-lens + , gitrev + , hashable + , haskell-src-meta + , hsass + , http-api-data + , http-client + , http-client-tls + , http-conduit + , http-types + , insert-ordered-containers + , jose-jwt + , lattices + , ldap-client + , lens + , lens-aeson + , list-t + , memcached-binary + , memory + , mime-mail + , mime-types + , minio-hs + , mmorph + , monad-control + , monad-logger + , monad-memo + , mono-traversable + , mono-traversable-keys + , mtl + , multiset + , network >=3 + , network-bsd + , network-ip + , network-uri + , nonce + , pandoc + , pandoc-types + , parsec + , parsec-numbers + , path-pieces + , persistent + , persistent-postgresql + , persistent-qq + , persistent-template + , pkcs7 + , pointedlist + , postgresql-simple + , pqueue + , profunctors + , prometheus-client + , prometheus-metrics-ghc + , psqueues + , random + , random-shuffle + , resourcet + , retry + , rfc5051 + , saltine + , scientific + , semigroupoids + , semver + , servant + , servant-client + , servant-client-core + , servant-docs + , servant-quickcheck + , servant-server + , servant-swagger + , serversession + , serversession-backend-acid-state + , shakespeare + , stm + , stm-delay + , streaming-commons + , swagger2 + , system-locale + , systemd + , tagged + , template-haskell + , text + , text-metrics + , th-abstraction + , th-lift + , th-lift-instances + , time + , token-bucket + , topograph + , transformers + , transformers-base + , typed-process + , tz + , unidecode + , universe + , universe-base + , uniworx + , unix + , unliftio + , unliftio-pool + , unordered-containers + , uuid + , uuid-crypto + , uuid-types + , vault + , vector + , wai + , wai-extra + , wai-logger + , wai-middleware-prometheus + , warp + , wl-pprint-text + , word24 + , xlsx + , xss-sanitize + , yaml + , yesod + , yesod-auth + , yesod-core + , yesod-form + , yesod-persistent + , yesod-static + , zip-stream + default-language: Haskell2010 + if flag(pedantic) + ghc-options: -Werror -fwarn-tabs + if flag(dev) + ghc-options: -O0 -ddump-splices -ddump-to-file -Wderiving-typeable + cpp-options: -DDEVELOPMENT + else + ghc-options: -O -fllvm +RTS -K0 -RTS + if flag(library-only) + buildable: False + +executable uniworxdb + main-is: Database.hs + other-modules: + Database.Fill + Paths_uniworx + hs-source-dirs: + test + default-extensions: + OverloadedStrings + PartialTypeSignatures + ScopedTypeVariables + TemplateHaskell + QuasiQuotes + CPP + TypeSynonymInstances + KindSignatures + ConstraintKinds + ViewPatterns + TypeOperators + TupleSections + TypeFamilies + GADTs + StandaloneDeriving + RecordWildCards + RankNTypes + PatternGuards + PatternSynonyms + ParallelListComp + NumDecimals + MultiWayIf + NamedFieldPuns + NoImplicitPrelude + LambdaCase + MultiParamTypeClasses + FlexibleContexts + FlexibleInstances + FunctionalDependencies + EmptyDataDecls + ExistentialQuantification + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + DeriveLift + DeriveFunctor + DeriveFoldable + DeriveTraversable + DeriveAnyClass + DerivingStrategies + DerivingVia + GeneralizedNewtypeDeriving + DataKinds + BinaryLiterals + PolyKinds + PackageImports + TypeApplications + RecursiveDo + TypeFamilyDependencies + QuantifiedConstraints + EmptyDataDeriving + StandaloneKindSignatures + NoStarIsType + other-extensions: + GeneralizedNewtypeDeriving + IncoherentInstances + OverloadedLists + UndecidableInstances + ApplicativeDo + ghc-options: -Wall -Wmissing-home-modules -Wredundant-constraints -Widentities -Wincomplete-uni-patterns -fno-warn-type-defaults -fno-warn-unrecognised-pragmas -fno-warn-partial-type-signatures -fno-max-relevant-binds -j -freduction-depth=0 -fprof-auto-calls -g -main-is Database -threaded -rtsopts "-with-rtsopts=-N -T" + build-depends: + Glob + , HaskellNet + , HaskellNet-SSL + , HsYAML + , HsYAML-aeson + , IntervalMap + , MonadRandom + , acid-state + , aeson >=1.5 + , aeson-pretty + , array + , async + , attoparsec + , base + , base32 + , base64-bytestring + , bimap + , binary + , binary-instances + , binary-orphans + , blaze-html + , blaze-markup + , bytestring + , case-insensitive + , cassava + , cassava-conduit + , classy-prelude + , classy-prelude-yesod + , clock + , colonnade >=1.1.1 + , conduit + , conduit-resumablesink >=0.2 + , connection + , constraints + , containers + , cookie + , cryptoids + , cryptoids-class + , cryptoids-types + , cryptonite + , cryptonite-conduit + , data-default + , data-textual + , deepseq + , directory + , directory-tree + , doclayout + , doctemplates + , either + , email-validate + , encoding + , esqueleto >=3.1.0 + , exceptions + , extended-reals + , fast-logger + , fastcdc + , file-embed + , filepath + , filepath-crypto + , foreign-store + , generic-deriving + , generic-lens + , gitrev + , hashable + , haskell-src-meta + , hsass + , http-api-data + , http-client + , http-client-tls + , http-conduit + , http-types + , insert-ordered-containers + , jose-jwt + , lattices + , ldap-client + , lens + , lens-aeson + , list-t + , memcached-binary + , memory + , mime-mail + , mime-types + , minio-hs + , mmorph + , monad-control + , monad-logger + , monad-memo + , mono-traversable + , mono-traversable-keys + , mtl + , multiset + , network >=3 + , network-bsd + , network-ip + , network-uri + , nonce + , pandoc + , pandoc-types + , parsec + , parsec-numbers + , path-pieces + , persistent + , persistent-postgresql + , persistent-qq + , persistent-template + , pkcs7 + , pointedlist + , postgresql-simple + , pqueue + , profunctors + , prometheus-client + , prometheus-metrics-ghc + , psqueues + , random + , random-shuffle + , resourcet + , retry + , rfc5051 + , saltine + , scientific + , semigroupoids + , semver + , servant + , servant-client + , servant-client-core + , servant-docs + , servant-quickcheck + , servant-server + , servant-swagger + , serversession + , serversession-backend-acid-state + , shakespeare + , stm + , stm-delay + , streaming-commons + , swagger2 + , system-locale + , systemd + , tagged + , template-haskell + , text + , text-metrics + , th-abstraction + , th-lift + , th-lift-instances + , time + , token-bucket + , topograph + , transformers + , transformers-base + , typed-process + , tz + , unidecode + , universe + , universe-base + , uniworx + , unix + , unliftio + , unliftio-pool + , unordered-containers + , uuid + , uuid-crypto + , uuid-types + , vault + , vector + , wai + , wai-extra + , wai-logger + , wai-middleware-prometheus + , warp + , wl-pprint-text + , word24 + , xlsx + , xss-sanitize + , yaml + , yesod + , yesod-auth + , yesod-core + , yesod-form + , yesod-persistent + , yesod-static + , zip-stream + default-language: Haskell2010 + if flag(pedantic) + ghc-options: -Werror -fwarn-tabs + if flag(dev) + ghc-options: -O0 -ddump-splices -ddump-to-file -Wderiving-typeable + cpp-options: -DDEVELOPMENT + else + ghc-options: -O -fllvm +RTS -K0 -RTS + if flag(library-only) + buildable: False + +executable uniworxload + main-is: Load.hs + hs-source-dirs: + load + default-extensions: + OverloadedStrings + PartialTypeSignatures + ScopedTypeVariables + TemplateHaskell + QuasiQuotes + CPP + TypeSynonymInstances + KindSignatures + ConstraintKinds + ViewPatterns + TypeOperators + TupleSections + TypeFamilies + GADTs + StandaloneDeriving + RecordWildCards + RankNTypes + PatternGuards + PatternSynonyms + ParallelListComp + NumDecimals + MultiWayIf + NamedFieldPuns + NoImplicitPrelude + LambdaCase + MultiParamTypeClasses + FlexibleContexts + FlexibleInstances + FunctionalDependencies + EmptyDataDecls + ExistentialQuantification + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + DeriveLift + DeriveFunctor + DeriveFoldable + DeriveTraversable + DeriveAnyClass + DerivingStrategies + DerivingVia + GeneralizedNewtypeDeriving + DataKinds + BinaryLiterals + PolyKinds + PackageImports + TypeApplications + RecursiveDo + TypeFamilyDependencies + QuantifiedConstraints + EmptyDataDeriving + StandaloneKindSignatures + NoStarIsType + other-extensions: + GeneralizedNewtypeDeriving + IncoherentInstances + OverloadedLists + UndecidableInstances + ApplicativeDo + ghc-options: -Wall -Wmissing-home-modules -Wredundant-constraints -Widentities -Wincomplete-uni-patterns -fno-warn-type-defaults -fno-warn-unrecognised-pragmas -fno-warn-partial-type-signatures -fno-max-relevant-binds -j -freduction-depth=0 -fprof-auto-calls -g -main-is Load -threaded -rtsopts "-with-rtsopts=-N -T" + build-depends: + Glob + , HaskellNet + , HaskellNet-SSL + , HsYAML + , HsYAML-aeson + , IntervalMap + , MonadRandom + , acid-state + , aeson >=1.5 + , aeson-pretty + , array + , async + , attoparsec + , base + , base32 + , base64-bytestring + , bimap + , binary + , binary-instances + , binary-orphans + , blaze-html + , blaze-markup + , bytestring + , case-insensitive + , cassava + , cassava-conduit + , classy-prelude + , classy-prelude-yesod + , clock + , colonnade >=1.1.1 + , conduit + , conduit-resumablesink >=0.2 + , connection + , constraints + , containers + , cookie + , cryptoids + , cryptoids-class + , cryptoids-types + , cryptonite + , cryptonite-conduit + , data-default + , data-textual + , deepseq + , directory + , directory-tree + , doclayout + , doctemplates + , either + , email-validate + , encoding + , esqueleto >=3.1.0 + , exceptions + , extended-reals + , fast-logger + , fastcdc + , file-embed + , filepath + , filepath-crypto + , foreign-store + , generic-deriving + , generic-lens + , gitrev + , hashable + , haskell-src-meta + , hsass + , http-api-data + , http-client + , http-client-tls + , http-conduit + , http-types + , insert-ordered-containers + , jose-jwt + , lattices + , ldap-client + , lens + , lens-aeson + , list-t + , memcached-binary + , memory + , mime-mail + , mime-types + , minio-hs + , mmorph + , monad-control + , monad-logger + , monad-memo + , mono-traversable + , mono-traversable-keys + , mtl + , multiset + , network >=3 + , network-bsd + , network-ip + , network-uri + , nonce + , normaldistribution + , pandoc + , pandoc-types + , parsec + , parsec-numbers + , path-pieces + , persistent + , persistent-postgresql + , persistent-qq + , persistent-template + , pkcs7 + , pointedlist + , postgresql-simple + , pqueue + , profunctors + , prometheus-client + , prometheus-metrics-ghc + , psqueues + , random + , random-shuffle + , resourcet + , retry + , rfc5051 + , saltine + , scalpel + , scientific + , semigroupoids + , semver + , servant + , servant-client + , servant-client-core + , servant-docs + , servant-quickcheck + , servant-server + , servant-swagger + , serversession + , serversession-backend-acid-state + , shakespeare + , stm + , stm-delay + , streaming-commons + , swagger2 + , system-locale + , systemd + , tagged + , template-haskell + , text + , text-metrics + , th-abstraction + , th-lift + , th-lift-instances + , time + , token-bucket + , topograph + , transformers + , transformers-base + , typed-process + , tz + , unidecode + , universe + , universe-base + , uniworx + , unix + , unliftio + , unliftio-pool + , unordered-containers + , uuid + , uuid-crypto + , uuid-types + , vault + , vector + , wai + , wai-extra + , wai-logger + , wai-middleware-prometheus + , warp + , wl-pprint-text + , word24 + , wreq + , xlsx + , xss-sanitize + , yaml + , yesod + , yesod-auth + , yesod-core + , yesod-form + , yesod-persistent + , yesod-static + , zip-stream + default-language: Haskell2010 + if flag(pedantic) + ghc-options: -Werror -fwarn-tabs + if flag(dev) + ghc-options: -O0 -ddump-splices -ddump-to-file -Wderiving-typeable + cpp-options: -DDEVELOPMENT + else + ghc-options: -O -fllvm +RTS -K0 -RTS + if flag(library-only) + buildable: False + +test-suite hlint + type: exitcode-stdio-1.0 + main-is: Hlint.hs + hs-source-dirs: + hlint + default-extensions: + OverloadedStrings + PartialTypeSignatures + ScopedTypeVariables + TemplateHaskell + QuasiQuotes + CPP + TypeSynonymInstances + KindSignatures + ConstraintKinds + ViewPatterns + TypeOperators + TupleSections + TypeFamilies + GADTs + StandaloneDeriving + RecordWildCards + RankNTypes + PatternGuards + PatternSynonyms + ParallelListComp + NumDecimals + MultiWayIf + NamedFieldPuns + NoImplicitPrelude + LambdaCase + MultiParamTypeClasses + FlexibleContexts + FlexibleInstances + FunctionalDependencies + EmptyDataDecls + ExistentialQuantification + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + DeriveLift + DeriveFunctor + DeriveFoldable + DeriveTraversable + DeriveAnyClass + DerivingStrategies + DerivingVia + GeneralizedNewtypeDeriving + DataKinds + BinaryLiterals + PolyKinds + PackageImports + TypeApplications + RecursiveDo + TypeFamilyDependencies + QuantifiedConstraints + EmptyDataDeriving + StandaloneKindSignatures + NoStarIsType + other-extensions: + GeneralizedNewtypeDeriving + IncoherentInstances + OverloadedLists + UndecidableInstances + ApplicativeDo + ghc-options: -Wall -Wmissing-home-modules -Wredundant-constraints -Widentities -Wincomplete-uni-patterns -fno-warn-type-defaults -fno-warn-unrecognised-pragmas -fno-warn-partial-type-signatures -fno-max-relevant-binds -j -freduction-depth=0 -fprof-auto-calls -g + build-depends: + Glob + , HaskellNet + , HaskellNet-SSL + , HsYAML + , HsYAML-aeson + , IntervalMap + , MonadRandom + , acid-state + , aeson >=1.5 + , aeson-pretty + , array + , async + , attoparsec + , base + , base32 + , base64-bytestring + , bimap + , binary + , binary-instances + , binary-orphans + , blaze-html + , blaze-markup + , bytestring + , case-insensitive + , cassava + , cassava-conduit + , classy-prelude + , classy-prelude-yesod + , clock + , colonnade >=1.1.1 + , conduit + , conduit-resumablesink >=0.2 + , connection + , constraints + , containers + , cookie + , cryptoids + , cryptoids-class + , cryptoids-types + , cryptonite + , cryptonite-conduit + , data-default + , data-textual + , deepseq + , directory + , directory-tree + , doclayout + , doctemplates + , either + , email-validate + , encoding + , esqueleto >=3.1.0 + , exceptions + , extended-reals + , fast-logger + , fastcdc + , file-embed + , filepath + , filepath-crypto + , foreign-store + , generic-deriving + , generic-lens + , gitrev + , hashable + , haskell-src-meta + , hlint-test + , hsass + , http-api-data + , http-client + , http-client-tls + , http-conduit + , http-types + , insert-ordered-containers + , jose-jwt + , lattices + , ldap-client + , lens + , lens-aeson + , list-t + , memcached-binary + , memory + , mime-mail + , mime-types + , minio-hs + , mmorph + , monad-control + , monad-logger + , monad-memo + , mono-traversable + , mono-traversable-keys + , mtl + , multiset + , network >=3 + , network-bsd + , network-ip + , network-uri + , nonce + , pandoc + , pandoc-types + , parsec + , parsec-numbers + , path-pieces + , persistent + , persistent-postgresql + , persistent-qq + , persistent-template + , pkcs7 + , pointedlist + , postgresql-simple + , pqueue + , profunctors + , prometheus-client + , prometheus-metrics-ghc + , psqueues + , random + , random-shuffle + , resourcet + , retry + , rfc5051 + , saltine + , scientific + , semigroupoids + , semver + , servant + , servant-client + , servant-client-core + , servant-docs + , servant-quickcheck + , servant-server + , servant-swagger + , serversession + , serversession-backend-acid-state + , shakespeare + , stm + , stm-delay + , streaming-commons + , swagger2 + , system-locale + , systemd + , tagged + , template-haskell + , text + , text-metrics + , th-abstraction + , th-lift + , th-lift-instances + , time + , token-bucket + , topograph + , transformers + , transformers-base + , typed-process + , tz + , unidecode + , universe + , universe-base + , unix + , unliftio + , unliftio-pool + , unordered-containers + , uuid + , uuid-crypto + , uuid-types + , vault + , vector + , wai + , wai-extra + , wai-logger + , wai-middleware-prometheus + , warp + , wl-pprint-text + , word24 + , xlsx + , xss-sanitize + , yaml + , yesod + , yesod-auth + , yesod-core + , yesod-form + , yesod-persistent + , yesod-static + , zip-stream + default-language: Haskell2010 + if flag(pedantic) + ghc-options: -Werror -fwarn-tabs + if flag(dev) + ghc-options: -O0 -ddump-splices -ddump-to-file -Wderiving-typeable + cpp-options: -DDEVELOPMENT + else + ghc-options: -O -fllvm +RTS -K0 -RTS + if !flag(pedantic) + buildable: False + +test-suite yesod + type: exitcode-stdio-1.0 + main-is: Main.hs + other-modules: + Auth.LDAP.ADSpec + CronSpec + Crypto.Hash.TestInstances + Data.NonNull.TestInstances + Data.Scientific.InstancesSpec + Database + Database.Fill + Database.Persist.Sql.Types.TestInstances + Foundation.ServantSpec + FoundationSpec + Handler.CommonSpec + Handler.CorrectionsSpec + Handler.Exam.FormSpec + Handler.HomeSpec + Handler.ProfileSpec + Handler.SAPSpec + Handler.Sheet.PersonalisedFilesSpec + Handler.Utils.ExamSpec + Handler.Utils.FilesSpec + Handler.Utils.RatingSpec + Handler.Utils.SubmissionSpec + Handler.Utils.Table.Pagination.TypesSpec + Handler.Utils.Table.PaginationSpec + Handler.Utils.ZipSpec + Jose.Jwk.TestInstances + MailSpec + Model.MigrationSpec + Model.RatingSpec + Model.Tokens.UploadSpec + Model.Types.FileSpec + Model.Types.LanguagesSpec + Model.TypesSpec + ModelSpec + PandocSpec + Servant.Client.Core.BaseUrl.TestInstances + ServantApi.ExternalApis.TypeSpec + ServantApi.ExternalApisSpec + ServantApiSpec + Test.QuickCheck.Classes.Binary + Test.QuickCheck.Classes.Csv + Test.QuickCheck.Classes.Hashable + Test.QuickCheck.Classes.HttpApiData + Test.QuickCheck.Classes.JSON + Test.QuickCheck.Classes.PathPiece + Test.QuickCheck.Classes.PersistField + Test.QuickCheck.Classes.Universe + TestImport + TestInstances + Text.Blaze.TestInstances + User + Utils.CsvSpec + Utils.DateTimeSpec + Utils.I18nSpec + Utils.PathPieceSpec + Utils.TypesSpec + UtilsSpec + Paths_uniworx + hs-source-dirs: + test + default-extensions: + OverloadedStrings + PartialTypeSignatures + ScopedTypeVariables + TemplateHaskell + QuasiQuotes + CPP + TypeSynonymInstances + KindSignatures + ConstraintKinds + ViewPatterns + TypeOperators + TupleSections + TypeFamilies + GADTs + StandaloneDeriving + RecordWildCards + RankNTypes + PatternGuards + PatternSynonyms + ParallelListComp + NumDecimals + MultiWayIf + NamedFieldPuns + NoImplicitPrelude + LambdaCase + MultiParamTypeClasses + FlexibleContexts + FlexibleInstances + FunctionalDependencies + EmptyDataDecls + ExistentialQuantification + DefaultSignatures + DeriveDataTypeable + DeriveGeneric + DeriveLift + DeriveFunctor + DeriveFoldable + DeriveTraversable + DeriveAnyClass + DerivingStrategies + DerivingVia + GeneralizedNewtypeDeriving + DataKinds + BinaryLiterals + PolyKinds + PackageImports + TypeApplications + RecursiveDo + TypeFamilyDependencies + QuantifiedConstraints + EmptyDataDeriving + StandaloneKindSignatures + NoStarIsType + other-extensions: + GeneralizedNewtypeDeriving + IncoherentInstances + OverloadedLists + UndecidableInstances + ApplicativeDo + ghc-options: -Wall -Wmissing-home-modules -Wredundant-constraints -Widentities -Wincomplete-uni-patterns -fno-warn-type-defaults -fno-warn-unrecognised-pragmas -fno-warn-partial-type-signatures -fno-max-relevant-binds -j -freduction-depth=0 -fprof-auto-calls -g -fno-warn-orphans -threaded -rtsopts "-with-rtsopts=-N -T" + build-depends: + Glob + , HUnit + , HaskellNet + , HaskellNet-SSL + , HsYAML + , HsYAML-aeson + , IntervalMap + , MonadRandom + , QuickCheck + , acid-state + , aeson >=1.5 + , aeson-pretty + , array + , async + , attoparsec + , base + , base32 + , base64-bytestring + , bimap + , binary + , binary-instances + , binary-orphans + , blaze-html + , blaze-markup + , bytestring + , case-insensitive + , cassava + , cassava-conduit + , classy-prelude + , classy-prelude-yesod + , clock + , colonnade >=1.1.1 + , conduit + , conduit-extra + , conduit-resumablesink >=0.2 + , connection + , constraints + , containers + , cookie + , cryptoids + , cryptoids-class + , cryptoids-types + , cryptonite + , cryptonite-conduit + , data-default + , data-textual + , deepseq + , directory + , directory-tree + , doclayout + , doctemplates + , either + , email-validate + , encoding + , esqueleto >=3.1.0 + , exceptions + , extended-reals + , fast-logger + , fastcdc + , file-embed + , filepath + , filepath-crypto + , foreign-store + , generic-arbitrary + , generic-deriving + , generic-lens + , gitrev + , hashable + , haskell-src-meta + , hsass + , hspec >=2.0.0 + , http-api-data + , http-client + , http-client-tls + , http-conduit + , http-media + , http-types + , insert-ordered-containers + , jose-jwt + , lattices + , ldap-client + , lens + , lens-aeson + , lens-properties + , list-t + , memcached-binary + , memory + , mime-mail + , mime-types + , minio-hs + , mmorph + , monad-control + , monad-logger + , monad-memo + , mono-traversable + , mono-traversable-keys + , mtl + , multiset + , network >=3 + , network-arbitrary + , network-bsd + , network-ip + , network-uri + , nonce + , pandoc + , pandoc-types + , parsec + , parsec-numbers + , path-pieces + , persistent + , persistent-postgresql + , persistent-qq + , persistent-template + , pkcs7 + , pointedlist + , postgresql-simple + , pqueue + , profunctors + , prometheus-client + , prometheus-metrics-ghc + , psqueues + , quickcheck-classes + , quickcheck-instances + , quickcheck-io + , random + , random-shuffle + , resourcet + , retry + , rfc5051 + , saltine + , scientific + , semigroupoids + , semver + , servant + , servant-client + , servant-client-core + , servant-docs + , servant-quickcheck + , servant-server + , servant-swagger + , serversession + , serversession-backend-acid-state + , shakespeare + , splitmix + , stm + , stm-delay + , streaming-commons + , swagger2 + , system-locale + , systemd + , tagged + , template-haskell + , text + , text-metrics + , th-abstraction + , th-lift + , th-lift-instances + , time + , token-bucket + , topograph + , transformers + , transformers-base + , typed-process + , tz + , unidecode + , universe + , universe-base + , uniworx + , unix + , unliftio + , unliftio-pool + , unordered-containers + , uuid + , uuid-crypto + , uuid-types + , vault + , vector + , wai + , wai-extra + , wai-logger + , wai-middleware-prometheus + , warp + , wl-pprint-text + , word24 + , xlsx + , xss-sanitize + , yaml + , yesod + , yesod-auth + , yesod-core + , yesod-form + , yesod-persistent + , yesod-static + , yesod-test + , zip-stream + default-language: Haskell2010 + if flag(pedantic) + ghc-options: -Werror -fwarn-tabs + if flag(dev) + ghc-options: -O0 -ddump-splices -ddump-to-file -Wderiving-typeable + cpp-options: -DDEVELOPMENT + else + ghc-options: -O -fllvm +RTS -K0 -RTS