fix(submissions): maintain anonymity
This commit is contained in:
parent
79edcf44c6
commit
0184a5fe3b
@ -58,6 +58,7 @@ UnauthorizedSubmissionRated: Diese Abgabe ist noch nicht korrigiert.
|
|||||||
UnauthorizedSubmissionCorrector: Sie sind nicht Korrektor:in für diese Abgabe.
|
UnauthorizedSubmissionCorrector: Sie sind nicht Korrektor:in für diese Abgabe.
|
||||||
UnauthorizedUserSubmission: Nutzer:innen dürfen für dieses Übungsblatt keine Abgaben erstellen.
|
UnauthorizedUserSubmission: Nutzer:innen dürfen für dieses Übungsblatt keine Abgaben erstellen.
|
||||||
UnauthorizedCorrectorSubmission: Korrektor: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.
|
DeprecatedRoute: Diese Ansicht ist obsolet und könnte in Zukunft entfallen.
|
||||||
UnfreeMaterials: Die Materialien für diese Veranstaltung sind nicht allgemein freigegeben.
|
UnfreeMaterials: Die Materialien für diese Veranstaltung sind nicht allgemein freigegeben.
|
||||||
UnauthorizedWrite: Sie haben hierfür keine Schreibberechtigung
|
UnauthorizedWrite: Sie haben hierfür keine Schreibberechtigung
|
||||||
|
|||||||
@ -58,6 +58,7 @@ UnauthorizedSubmissionRated: This submission is not yet marked.
|
|||||||
UnauthorizedSubmissionCorrector: You are no corrector for this submission.
|
UnauthorizedSubmissionCorrector: You are no corrector for this submission.
|
||||||
UnauthorizedUserSubmission: Users may not directly submit for this exercise sheet.
|
UnauthorizedUserSubmission: Users may not directly submit for this exercise sheet.
|
||||||
UnauthorizedCorrectorSubmission: Correctors may not create submissions 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.
|
DeprecatedRoute: This view is deprecated and will be removed.
|
||||||
UnfreeMaterials: Course material are not publicly accessable.
|
UnfreeMaterials: Course material are not publicly accessable.
|
||||||
UnauthorizedWrite: You do not have the write permission necessary to perform this action
|
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
|
InvalidCredentialsADAccountLockedOut: Account disabled by intruder detection
|
||||||
FormFieldRequiredTip: Required fields
|
FormFieldRequiredTip: Required fields
|
||||||
FormFieldWorkflowDatasetTip: At least one of the marked fields must be filled
|
FormFieldWorkflowDatasetTip: At least one of the marked fields must be filled
|
||||||
LoginTitle: Authentication
|
LoginTitle: Authentication
|
||||||
|
|||||||
@ -225,4 +225,6 @@ SubmissionAuthorshipStatementsTitle tid@TermId ssh@SchoolId csh@CourseShorthand
|
|||||||
|
|
||||||
SubmissionColumnAuthorshipStatementTime: Zeitstempel
|
SubmissionColumnAuthorshipStatementTime: Zeitstempel
|
||||||
SubmissionColumnAuthorshipStatementWording: Wortlaut
|
SubmissionColumnAuthorshipStatementWording: Wortlaut
|
||||||
SubmissionFilterAuthorshipStatementCurrent: Aktueller Wortlaut
|
SubmissionFilterAuthorshipStatementCurrent: Aktueller Wortlaut
|
||||||
|
|
||||||
|
SubmissionNoUsers: Diese Abgabe hat keine assoziierten Benutzer!
|
||||||
@ -225,3 +225,5 @@ SubmissionAuthorshipStatementsTitle tid ssh csh shn cID: #{tid}-#{ssh}-#{csh} #{
|
|||||||
SubmissionColumnAuthorshipStatementTime: Timestamp
|
SubmissionColumnAuthorshipStatementTime: Timestamp
|
||||||
SubmissionColumnAuthorshipStatementWording: Wording
|
SubmissionColumnAuthorshipStatementWording: Wording
|
||||||
SubmissionFilterAuthorshipStatementCurrent: Current wording
|
SubmissionFilterAuthorshipStatementCurrent: Current wording
|
||||||
|
|
||||||
|
SubmissionNoUsers: This submission has no associated users!
|
||||||
|
|||||||
@ -42,6 +42,7 @@ AuthTagPersonalisedSheetFiles: Nutzer:in verfügt über personalisierte Übungsb
|
|||||||
AuthTagRated: Korrektur ist bewertet
|
AuthTagRated: Korrektur ist bewertet
|
||||||
AuthTagUserSubmissions: Abgaben erfolgen durch Kursteilnehmer:innen
|
AuthTagUserSubmissions: Abgaben erfolgen durch Kursteilnehmer:innen
|
||||||
AuthTagCorrectorSubmissions: Abgaben erfolgen durch Korrektor:innen
|
AuthTagCorrectorSubmissions: Abgaben erfolgen durch Korrektor:innen
|
||||||
|
AuthTagCorrectionAnonymous: Korrektur ist anonymisiert
|
||||||
AuthTagSelf: Nutzer:in greift nur auf eigene Daten zu
|
AuthTagSelf: Nutzer:in greift nur auf eigene Daten zu
|
||||||
AuthTagIsLDAP: Nutzer:in meldet sich mit Campus-Kennung an
|
AuthTagIsLDAP: Nutzer:in meldet sich mit Campus-Kennung an
|
||||||
AuthTagIsPWHash: Nutzer:in meldet sich mit Uni2work-Kennung an
|
AuthTagIsPWHash: Nutzer:in meldet sich mit Uni2work-Kennung an
|
||||||
|
|||||||
@ -42,6 +42,7 @@ AuthTagPersonalisedSheetFiles: User has been assigned personalised sheet files
|
|||||||
AuthTagRated: Submission is marked
|
AuthTagRated: Submission is marked
|
||||||
AuthTagUserSubmissions: Submissions are made by course participants
|
AuthTagUserSubmissions: Submissions are made by course participants
|
||||||
AuthTagCorrectorSubmissions: Submissions are registered by correctors
|
AuthTagCorrectorSubmissions: Submissions are registered by correctors
|
||||||
|
AuthTagCorrectionAnonymous: Correction is anonymised
|
||||||
AuthTagSelf: User is only accessing their only data
|
AuthTagSelf: User is only accessing their only data
|
||||||
AuthTagIsLDAP: User logs in using their campus account
|
AuthTagIsLDAP: User logs in using their campus account
|
||||||
AuthTagIsPWHash: User logs in using their Uni2work-internal account
|
AuthTagIsPWHash: User logs in using their Uni2work-internal account
|
||||||
|
|||||||
2
routes
2
routes
@ -218,7 +218,7 @@
|
|||||||
/assign SubAssignR GET POST !lecturerANDtime
|
/assign SubAssignR GET POST !lecturerANDtime
|
||||||
/correction CorrectionR GET POST !corrector !ownerANDreadANDratedANDexam-time
|
/correction CorrectionR GET POST !corrector !ownerANDreadANDratedANDexam-time
|
||||||
/invite SInviteR GET POST !ownerANDtimeANDuser-submissionsANDsubmission-groupANDexam-registeredANDpersonalised-sheet-files
|
/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 SubArchiveR GET !owner !corrector
|
||||||
!/#SubmissionFileType/*FilePath SubDownloadR GET !owner !corrector
|
!/#SubmissionFileType/*FilePath SubDownloadR GET !owner !corrector
|
||||||
/iscorrector SIsCorrR GET !corrector -- Route is used to check for corrector access to this sheet
|
/iscorrector SIsCorrR GET !corrector -- Route is used to check for corrector access to this sheet
|
||||||
|
|||||||
@ -1675,6 +1675,13 @@ tagAccessPredicate AuthCorrectorSubmissions = APDB $ \_ _ _ route _ -> case rout
|
|||||||
guard submissionModeCorrector
|
guard submissionModeCorrector
|
||||||
return Authorized
|
return Authorized
|
||||||
r -> $unsupportedAuthPredicate AuthCorrectorSubmissions r
|
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
|
tagAccessPredicate AuthSelf = APDB $ \_ _ mAuthId route _ -> exceptT return return $ do
|
||||||
referencedUser' <- case route of
|
referencedUser' <- case route of
|
||||||
AdminUserR cID -> return $ Left cID
|
AdminUserR cID -> return $ Left cID
|
||||||
|
|||||||
@ -570,7 +570,7 @@ submissionHelper tid ssh csh shn mcid = do
|
|||||||
, formEncoding = formEnctype
|
, 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
|
sheetInfo@(Entity shid Sheet{..}, buddies, _, _, isLecturer, isOwner, msubmission, _, mASDefinition) <- getSheetInfo
|
||||||
|
|
||||||
(showCorrection, correctionInvisible) <- fmap (fromMaybe (False, Nothing)) . for ((,) <$> mcid <*> (Entity <$> msmid <*> msubmission)) $ \(cid, subEnt) -> do
|
(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)
|
& 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)
|
& 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
|
-- TODO(AuthorshipStatements): discuss whether to display prompt for user to update their authorship statement, if lecturer changed it
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,7 @@ data AuthTag -- sortiert nach gewünschter Reihenfolge auf /authpreds, d.h. Prä
|
|||||||
| AuthRated
|
| AuthRated
|
||||||
| AuthUserSubmissions
|
| AuthUserSubmissions
|
||||||
| AuthCorrectorSubmissions
|
| AuthCorrectorSubmissions
|
||||||
|
| AuthCorrectionAnonymous
|
||||||
| AuthSubmissionGroup
|
| AuthSubmissionGroup
|
||||||
| AuthCapacity
|
| AuthCapacity
|
||||||
| AuthRegisterGroup
|
| AuthRegisterGroup
|
||||||
|
|||||||
@ -99,6 +99,7 @@ data Icon
|
|||||||
| IconVideo
|
| IconVideo
|
||||||
| IconSubmissionUserDuplicate
|
| IconSubmissionUserDuplicate
|
||||||
| IconNoAllocationUser
|
| IconNoAllocationUser
|
||||||
|
| IconSubmissionNoUsers
|
||||||
deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic, Typeable)
|
deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic, Typeable)
|
||||||
deriving anyclass (Universe, Finite, NFData)
|
deriving anyclass (Universe, Finite, NFData)
|
||||||
|
|
||||||
@ -181,6 +182,7 @@ iconText = \case
|
|||||||
IconVideo -> "video"
|
IconVideo -> "video"
|
||||||
IconSubmissionUserDuplicate -> "copy"
|
IconSubmissionUserDuplicate -> "copy"
|
||||||
IconNoAllocationUser -> "user-slash"
|
IconNoAllocationUser -> "user-slash"
|
||||||
|
IconSubmissionNoUsers -> "user-slash"
|
||||||
|
|
||||||
nullaryPathPiece ''Icon $ camelToPathPiece' 1
|
nullaryPathPiece ''Icon $ camelToPathPiece' 1
|
||||||
deriveLift ''Icon
|
deriveLift ''Icon
|
||||||
|
|||||||
@ -9,65 +9,67 @@ $maybe subCId <- mcid
|
|||||||
|
|
||||||
^{wdgt}
|
^{wdgt}
|
||||||
|
|
||||||
<section>
|
$if subUsersVisible
|
||||||
<h2>
|
<section>
|
||||||
_{MsgSubmissionUserTable}
|
<h2>
|
||||||
|
_{MsgSubmissionUserTable}
|
||||||
|
|
||||||
^{maybeVoid multipleSubmissionWarnWidget}
|
^{maybeVoid multipleSubmissionWarnWidget}
|
||||||
|
|
||||||
$if not (null subUsers)
|
$if not (null subUsers)
|
||||||
<div .scrolltable>
|
<div .scrolltable>
|
||||||
<table .table .table--striped .table--hover>
|
<table .table .table--striped .table--hover>
|
||||||
<thead>
|
<thead>
|
||||||
<tr .table__row .table__row--head>
|
<tr .table__row .table__row--head>
|
||||||
<th .table__th>
|
|
||||||
<div .table__td-content>
|
|
||||||
_{MsgSubmissionUserDisplayName}
|
|
||||||
$if isLecturer
|
|
||||||
<th .table__th>
|
<th .table__th>
|
||||||
<div .table__td-content>
|
<div .table__td-content>
|
||||||
_{MsgSubmissionUserMatriculation}
|
_{MsgSubmissionUserDisplayName}
|
||||||
<th .table__th>
|
$if isLecturer
|
||||||
<div .table__td-content>
|
<th .table__th>
|
||||||
_{MsgSubmissionUserEmail}
|
<div .table__td-content>
|
||||||
$if doAuthorshipStatements
|
_{MsgSubmissionUserMatriculation}
|
||||||
<th .table__th>
|
<th .table__th>
|
||||||
<div .table__td-content>
|
<div .table__td-content>
|
||||||
^{simpleLinkI MsgSubmissionUserAuthorshipStatementState (CSubmissionR tid ssh csh shn subCId SubAuthorshipStatementsR)}
|
_{MsgSubmissionUserEmail}
|
||||||
^{iconTooltip asStatusExplainWdgt Nothing True}
|
$if doAuthorshipStatements
|
||||||
<tbody>
|
<th .table__th>
|
||||||
$forall subUser <- subUsers
|
<div .table__td-content>
|
||||||
$case subUser
|
^{simpleLinkI MsgSubmissionUserAuthorshipStatementState (CSubmissionR tid ssh csh shn subCId SubAuthorshipStatementsR)}
|
||||||
$of Left email
|
^{iconTooltip asStatusExplainWdgt Nothing True}
|
||||||
<tr .table__row>
|
<tbody>
|
||||||
<td .table__td>
|
$forall subUser <- subUsers
|
||||||
$if isLecturer
|
$case subUser
|
||||||
|
$of Left email
|
||||||
|
<tr .table__row>
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
<td .table__td>
|
$if isLecturer
|
||||||
<div .table__td-content .email>
|
<td .table__td>
|
||||||
<a href="mailto:#{email}">
|
|
||||||
#{email}
|
|
||||||
$if isLecturer && doAuthorshipStatements
|
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
$of Right (uCId, User{userDisplayName, userSurname, userEmail, userMatrikelnummer}, stmt)
|
<div .table__td-content .email>
|
||||||
<tr .table__row>
|
<a href="mailto:#{email}">
|
||||||
<td .table__td>
|
#{email}
|
||||||
<div .table__td-content>
|
$if isLecturer && doAuthorshipStatements
|
||||||
^{simpleLink (nameWidget userDisplayName userSurname) (CourseR tid ssh csh (CUserR uCId))}
|
<td .table__td>
|
||||||
$if isLecturer
|
$of Right (uCId, User{userDisplayName, userSurname, userEmail, userMatrikelnummer}, stmt)
|
||||||
|
<tr .table__row>
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
<div .table__td-content>
|
<div .table__td-content>
|
||||||
$maybe matriculation <- userMatrikelnummer
|
^{simpleLink (nameWidget userDisplayName userSurname) (CourseR tid ssh csh (CUserR uCId))}
|
||||||
#{matriculation}
|
$if isLecturer
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
<div .table__td-content .email>
|
<div .table__td-content>
|
||||||
<a href="mailto:#{userEmail}">
|
$maybe matriculation <- userMatrikelnummer
|
||||||
#{userEmail}
|
#{matriculation}
|
||||||
$# TODO(AuthorshipStatements): show authorship statements to submittors?
|
<td .table__td>
|
||||||
$if doAuthorshipStatements
|
<div .table__td-content .email>
|
||||||
<td .table__td .heated style="--hotness: #{boolHeat (stmt /= ASExists)}">
|
<a href="mailto:#{userEmail}">
|
||||||
<div .table__td-content>
|
#{userEmail}
|
||||||
_{stmt}
|
$if doAuthorshipStatements
|
||||||
|
<td .table__td .heated style="--hotness: #{boolHeat (stmt /= ASExists)}">
|
||||||
|
<div .table__td-content>
|
||||||
|
_{stmt}
|
||||||
|
$else
|
||||||
|
^{notification NotificationBroad =<< messageIconI Error IconSubmissionNoUsers MsgSubmissionNoUsers}
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
$case sheetSubmissionMode
|
$case sheetSubmissionMode
|
||||||
|
|||||||
Reference in New Issue
Block a user