diff --git a/messages/uniworx/categories/authorization/de-de-formal.msg b/messages/uniworx/categories/authorization/de-de-formal.msg index f54b3e7eb..e889740d7 100644 --- a/messages/uniworx/categories/authorization/de-de-formal.msg +++ b/messages/uniworx/categories/authorization/de-de-formal.msg @@ -58,6 +58,7 @@ UnauthorizedSubmissionRated: Diese Abgabe ist noch nicht korrigiert. UnauthorizedSubmissionCorrector: Sie sind nicht Korrektor:in für diese Abgabe. UnauthorizedUserSubmission: Nutzer:innen dürfen für dieses Übungsblatt keine Abgaben erstellen. UnauthorizedCorrectorSubmission: Korrektor:innen dürfen für dieses Übungsblatt keine Abgaben erstellen. +UnauthorizedCorrectionAnonymous: Korrektur ist nicht anonymisiert. DeprecatedRoute: Diese Ansicht ist obsolet und könnte in Zukunft entfallen. UnfreeMaterials: Die Materialien für diese Veranstaltung sind nicht allgemein freigegeben. UnauthorizedWrite: Sie haben hierfür keine Schreibberechtigung diff --git a/messages/uniworx/categories/authorization/en-eu.msg b/messages/uniworx/categories/authorization/en-eu.msg index 15bb30df6..5d7c0cf75 100644 --- a/messages/uniworx/categories/authorization/en-eu.msg +++ b/messages/uniworx/categories/authorization/en-eu.msg @@ -58,6 +58,7 @@ UnauthorizedSubmissionRated: This submission is not yet marked. UnauthorizedSubmissionCorrector: You are no corrector for this submission. UnauthorizedUserSubmission: Users may not directly submit for this exercise sheet. UnauthorizedCorrectorSubmission: Correctors may not create submissions for this exercise sheet. +UnauthorizedCorrectionAnonymous: Correction is not anonymised. DeprecatedRoute: This view is deprecated and will be removed. UnfreeMaterials: Course material are not publicly accessable. UnauthorizedWrite: You do not have the write permission necessary to perform this action @@ -128,4 +129,4 @@ InvalidCredentialsADPasswordMustChange: Password needs to be changed InvalidCredentialsADAccountLockedOut: Account disabled by intruder detection FormFieldRequiredTip: Required fields FormFieldWorkflowDatasetTip: At least one of the marked fields must be filled -LoginTitle: Authentication \ No newline at end of file +LoginTitle: Authentication diff --git a/messages/uniworx/categories/courses/submission/de-de-formal.msg b/messages/uniworx/categories/courses/submission/de-de-formal.msg index 30d8c44a0..165cfe9a9 100644 --- a/messages/uniworx/categories/courses/submission/de-de-formal.msg +++ b/messages/uniworx/categories/courses/submission/de-de-formal.msg @@ -225,4 +225,6 @@ SubmissionAuthorshipStatementsTitle tid@TermId ssh@SchoolId csh@CourseShorthand SubmissionColumnAuthorshipStatementTime: Zeitstempel SubmissionColumnAuthorshipStatementWording: Wortlaut -SubmissionFilterAuthorshipStatementCurrent: Aktueller Wortlaut \ No newline at end of file +SubmissionFilterAuthorshipStatementCurrent: Aktueller Wortlaut + +SubmissionNoUsers: Diese Abgabe hat keine assoziierten Benutzer! \ No newline at end of file diff --git a/messages/uniworx/categories/courses/submission/en-eu.msg b/messages/uniworx/categories/courses/submission/en-eu.msg index 61fbab400..f9efeb3a0 100644 --- a/messages/uniworx/categories/courses/submission/en-eu.msg +++ b/messages/uniworx/categories/courses/submission/en-eu.msg @@ -225,3 +225,5 @@ SubmissionAuthorshipStatementsTitle tid ssh csh shn cID: #{tid}-#{ssh}-#{csh} #{ SubmissionColumnAuthorshipStatementTime: Timestamp SubmissionColumnAuthorshipStatementWording: Wording SubmissionFilterAuthorshipStatementCurrent: Current wording + +SubmissionNoUsers: This submission has no associated users! diff --git a/messages/uniworx/categories/settings/auth_settings/de-de-formal.msg b/messages/uniworx/categories/settings/auth_settings/de-de-formal.msg index be25a3cf8..b2d4f8036 100644 --- a/messages/uniworx/categories/settings/auth_settings/de-de-formal.msg +++ b/messages/uniworx/categories/settings/auth_settings/de-de-formal.msg @@ -42,6 +42,7 @@ AuthTagPersonalisedSheetFiles: Nutzer:in verfügt über personalisierte Übungsb AuthTagRated: Korrektur ist bewertet AuthTagUserSubmissions: Abgaben erfolgen durch Kursteilnehmer:innen AuthTagCorrectorSubmissions: Abgaben erfolgen durch Korrektor:innen +AuthTagCorrectionAnonymous: Korrektur ist anonymisiert AuthTagSelf: Nutzer:in greift nur auf eigene Daten zu AuthTagIsLDAP: Nutzer:in meldet sich mit Campus-Kennung an AuthTagIsPWHash: Nutzer:in meldet sich mit Uni2work-Kennung an diff --git a/messages/uniworx/categories/settings/auth_settings/en-eu.msg b/messages/uniworx/categories/settings/auth_settings/en-eu.msg index fdfd6c693..4465437d1 100644 --- a/messages/uniworx/categories/settings/auth_settings/en-eu.msg +++ b/messages/uniworx/categories/settings/auth_settings/en-eu.msg @@ -42,6 +42,7 @@ AuthTagPersonalisedSheetFiles: User has been assigned personalised sheet files AuthTagRated: Submission is marked AuthTagUserSubmissions: Submissions are made by course participants AuthTagCorrectorSubmissions: Submissions are registered by correctors +AuthTagCorrectionAnonymous: Correction is anonymised AuthTagSelf: User is only accessing their only data AuthTagIsLDAP: User logs in using their campus account AuthTagIsPWHash: User logs in using their Uni2work-internal account diff --git a/routes b/routes index bedfbaeb1..c7299e84c 100644 --- a/routes +++ b/routes @@ -218,7 +218,7 @@ /assign SubAssignR GET POST !lecturerANDtime /correction CorrectionR GET POST !corrector !ownerANDreadANDratedANDexam-time /invite SInviteR GET POST !ownerANDtimeANDuser-submissionsANDsubmission-groupANDexam-registeredANDpersonalised-sheet-files - /authorship-statements SubAuthorshipStatementsR GET !corrector + /authorship-statements SubAuthorshipStatementsR GET !owner !correctorAND¬correction-anonymous !/#SubmissionFileType SubArchiveR GET !owner !corrector !/#SubmissionFileType/*FilePath SubDownloadR GET !owner !corrector /iscorrector SIsCorrR GET !corrector -- Route is used to check for corrector access to this sheet diff --git a/src/Foundation/Authorization.hs b/src/Foundation/Authorization.hs index a51d4487f..042dcc374 100644 --- a/src/Foundation/Authorization.hs +++ b/src/Foundation/Authorization.hs @@ -1675,6 +1675,13 @@ tagAccessPredicate AuthCorrectorSubmissions = APDB $ \_ _ _ route _ -> case rout guard submissionModeCorrector return Authorized r -> $unsupportedAuthPredicate AuthCorrectorSubmissions r +tagAccessPredicate AuthCorrectionAnonymous = APDB $ \_ _ _ route _ -> case route of + CSheetR tid ssh csh shn _ -> maybeT (unauthorizedI MsgUnauthorizedCorrectionAnonymous) $ do + Entity cid _ <- $cachedHereBinary (tid, ssh, csh) . MaybeT . getBy $ TermSchoolCourseShort tid ssh csh + Entity _ Sheet{ sheetAnonymousCorrection } <- $cachedHereBinary (cid, shn) . MaybeT . getBy $ CourseSheet cid shn + guard sheetAnonymousCorrection + return Authorized + r -> $unsupportedAuthPredicate AuthCorrectionAnonymous r tagAccessPredicate AuthSelf = APDB $ \_ _ mAuthId route _ -> exceptT return return $ do referencedUser' <- case route of AdminUserR cID -> return $ Left cID diff --git a/src/Handler/Submission/Helper.hs b/src/Handler/Submission/Helper.hs index d32baf2a4..c78335edf 100644 --- a/src/Handler/Submission/Helper.hs +++ b/src/Handler/Submission/Helper.hs @@ -570,7 +570,7 @@ submissionHelper tid ssh csh shn mcid = do , formEncoding = formEnctype } - ((Entity _ Sheet{..}, _, lastEdits, maySubmit, _, _, msubmission, corrector, _), (showCorrection, correctionInvisible), mFileTable, filesCorrected, sheetTypeDesc, multipleSubmissionWarnWidget, subUsers, isLecturer, isOwner, doAuthorshipStatements) <- runDB $ do + ((Entity _ Sheet{..}, _, lastEdits, maySubmit, _, _, msubmission, corrector, _), (showCorrection, correctionInvisible), mFileTable, filesCorrected, sheetTypeDesc, multipleSubmissionWarnWidget, (subUsers, subUsersVisible), isLecturer, isOwner, doAuthorshipStatements) <- runDB $ do sheetInfo@(Entity shid Sheet{..}, buddies, _, _, isLecturer, isOwner, msubmission, _, mASDefinition) <- getSheetInfo (showCorrection, correctionInvisible) <- fmap (fromMaybe (False, Nothing)) . for ((,) <$> mcid <*> (Entity <$> msmid <*> msubmission)) $ \(cid, subEnt) -> do @@ -630,7 +630,14 @@ submissionHelper tid ssh csh shn mcid = do & mapMOf (traverse . _Right) (\uid -> (,,) <$> (encrypt uid :: DB CryptoUUIDUser) <*> getJust uid <*> getUserAuthorshipStatement uid) & fmap (sortOn . over _Right $ (,,,) <$> views _2 userSurname <*> views _2 userDisplayName <*> views _2 userEmail <*> view _1) - return (sheetInfo, (showCorrection, correctionInvisible), mFileTable, filesCorrected, sheetTypeDesc, multipleSubmissionWarnWidget, subUsers, isLecturer, isOwner, is _Just mASDefinition) + subUsersVisible <- orM + [ return isOwner + , return isLecturer + , return $ not sheetAnonymousCorrection + , hasReadAccessTo $ CSheetR tid ssh csh shn SSubsR + ] + + return (sheetInfo, (showCorrection, correctionInvisible), mFileTable, filesCorrected, sheetTypeDesc, multipleSubmissionWarnWidget, (subUsers, subUsersVisible), isLecturer, isOwner, is _Just mASDefinition) -- TODO(AuthorshipStatements): discuss whether to display prompt for user to update their authorship statement, if lecturer changed it diff --git a/src/Model/Types/Security.hs b/src/Model/Types/Security.hs index 5b83645c3..e4793092e 100644 --- a/src/Model/Types/Security.hs +++ b/src/Model/Types/Security.hs @@ -77,6 +77,7 @@ data AuthTag -- sortiert nach gewünschter Reihenfolge auf /authpreds, d.h. Prä | AuthRated | AuthUserSubmissions | AuthCorrectorSubmissions + | AuthCorrectionAnonymous | AuthSubmissionGroup | AuthCapacity | AuthRegisterGroup diff --git a/src/Utils/Icon.hs b/src/Utils/Icon.hs index d7cff02d5..d220f9f7f 100644 --- a/src/Utils/Icon.hs +++ b/src/Utils/Icon.hs @@ -99,6 +99,7 @@ data Icon | IconVideo | IconSubmissionUserDuplicate | IconNoAllocationUser + | IconSubmissionNoUsers deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic, Typeable) deriving anyclass (Universe, Finite, NFData) @@ -181,6 +182,7 @@ iconText = \case IconVideo -> "video" IconSubmissionUserDuplicate -> "copy" IconNoAllocationUser -> "user-slash" + IconSubmissionNoUsers -> "user-slash" nullaryPathPiece ''Icon $ camelToPathPiece' 1 deriveLift ''Icon diff --git a/templates/submission.hamlet b/templates/submission.hamlet index 86de7f9ec..465efab00 100644 --- a/templates/submission.hamlet +++ b/templates/submission.hamlet @@ -9,65 +9,67 @@ $maybe subCId <- mcid ^{wdgt} -
-

- _{MsgSubmissionUserTable} + $if subUsersVisible +
+

+ _{MsgSubmissionUserTable} - ^{maybeVoid multipleSubmissionWarnWidget} + ^{maybeVoid multipleSubmissionWarnWidget} - $if not (null subUsers) -
- - - -
-
- _{MsgSubmissionUserDisplayName} - $if isLecturer + $if not (null subUsers) +
+ + + - $forall subUser <- subUsers - $case subUser - $of Left email - - + $forall subUser <- subUsers + $case subUser + $of Left email + -
- _{MsgSubmissionUserMatriculation} -
-
- _{MsgSubmissionUserEmail} - $if doAuthorshipStatements + _{MsgSubmissionUserDisplayName} + $if isLecturer +
+
+ _{MsgSubmissionUserMatriculation}
- ^{simpleLinkI MsgSubmissionUserAuthorshipStatementState (CSubmissionR tid ssh csh shn subCId SubAuthorshipStatementsR)} - ^{iconTooltip asStatusExplainWdgt Nothing True} -
- $if isLecturer + _{MsgSubmissionUserEmail} + $if doAuthorshipStatements + +
+ ^{simpleLinkI MsgSubmissionUserAuthorshipStatementState (CSubmissionR tid ssh csh shn subCId SubAuthorshipStatementsR)} + ^{iconTooltip asStatusExplainWdgt Nothing True} +
- - - $of Right (uCId, User{userDisplayName, userSurname, userEmail, userMatrikelnummer}, stmt) -
-
- ^{simpleLink (nameWidget userDisplayName userSurname) (CourseR tid ssh csh (CUserR uCId))} - $if isLecturer +
+ $of Right (uCId, User{userDisplayName, userSurname, userEmail, userMatrikelnummer}, stmt) +
- $maybe matriculation <- userMatrikelnummer - #{matriculation} -
- -
- _{stmt} + ^{simpleLink (nameWidget userDisplayName userSurname) (CourseR tid ssh csh (CUserR uCId))} + $if isLecturer +
+
+ $maybe matriculation <- userMatrikelnummer + #{matriculation} +
+ +
+ _{stmt} + $else + ^{notification NotificationBroad =<< messageIconI Error IconSubmissionNoUsers MsgSubmissionNoUsers}
$case sheetSubmissionMode