diff --git a/backend/src/middleware/auth/checks/group-auth-checker.ts b/backend/src/middleware/auth/checks/group-auth-checker.ts index 0f42741e..73df4fb5 100644 --- a/backend/src/middleware/auth/checks/group-auth-checker.ts +++ b/backend/src/middleware/auth/checks/group-auth-checker.ts @@ -18,8 +18,8 @@ export const onlyAllowIfHasAccessToGroup = authorize( const clazz = await fetchClass(classId); return clazz.teachers.map(mapToUsername).includes(auth.username); } else { // user is student - const group = await fetchGroup(classId, assignmentId, groupId, false); - return clazz.students.map(mapToUsername).includes(auth.username); + const group = await fetchGroup(classId, assignmentId, groupId); + return group.members.map(mapToUsername).includes(auth.username); } } ); diff --git a/backend/src/middleware/auth/checks/question-checks.ts b/backend/src/middleware/auth/checks/question-checks.ts index bfe76061..c83e1de2 100644 --- a/backend/src/middleware/auth/checks/question-checks.ts +++ b/backend/src/middleware/auth/checks/question-checks.ts @@ -9,11 +9,11 @@ import {fetchAnswer} from "../../../services/answers"; import {mapToUsername} from "../../../interfaces/user"; export const onlyAllowAuthor = authorize( - (auth: AuthenticationInfo, req: AuthenticatedRequest) => req.body.author === auth.username + (auth: AuthenticationInfo, req: AuthenticatedRequest) => (req.body as { author: string }).author === auth.username ); export const onlyAllowAuthorRequest = authorize( - (auth: AuthenticationInfo, req: AuthenticatedRequest) => { + async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { const hruid = req.params.hruid; const version = req.params.version; const language = req.query.lang as string; @@ -30,7 +30,7 @@ export const onlyAllowAuthorRequest = authorize( ); export const onlyAllowAuthorRequestAnswer = authorize( - (auth: AuthenticationInfo, req: AuthenticatedRequest) => { + async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { const hruid = req.params.hruid; const version = req.params.version; const language = req.query.lang as string; @@ -49,7 +49,7 @@ export const onlyAllowAuthorRequestAnswer = authorize( ); export const onlyAllowIfHasAccessToQuestion = authorize( - async (auth, req) => { + async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { const hruid = req.params.hruid; const version = req.params.version; const language = req.query.lang as string; diff --git a/backend/src/middleware/auth/checks/submission-checks.ts b/backend/src/middleware/auth/checks/submission-checks.ts new file mode 100644 index 00000000..78087fa9 --- /dev/null +++ b/backend/src/middleware/auth/checks/submission-checks.ts @@ -0,0 +1,29 @@ +import { languageMap } from "dwengo-1-common/util/language"; +import { LearningObjectIdentifier } from "../../../entities/content/learning-object-identifier"; +import { fetchSubmission } from "../../../services/submissions"; +import { AuthenticatedRequest } from "../authenticated-request"; +import { AuthenticationInfo } from "../authentication-info"; +import { authorize } from "./auth-checks"; +import { FALLBACK_LANG } from "../../../config"; +import { mapToUsername } from "../../../interfaces/user"; + +export const onlyAllowSubmitter = authorize( + (auth: AuthenticationInfo, req: AuthenticatedRequest) => (req.body as { submitter: string }).submitter === auth.username +); + +export const onlyAllowIfHasAccessToSubmission = authorize( + async (auth: AuthenticationInfo, req: AuthenticatedRequest) => { + const { hruid: lohruid, id: submissionNumber } = req.params; + const { language: lang, version: version } = req.query; + + const loId = new LearningObjectIdentifier(lohruid, languageMap[lang as string] ?? FALLBACK_LANG, Number(version)) + const submission = await fetchSubmission(loId, Number(submissionNumber)); + + if (auth.accountType === "teacher") { + // Dit kan niet werken om dat al deze objecten niet gepopulate zijn. + return submission.onBehalfOf.assignment.within.teachers.map(mapToUsername).includes(auth.username); + } + + return submission.onBehalfOf.members.map(mapToUsername).includes(auth.username); + } +) \ No newline at end of file diff --git a/backend/src/routes/groups.ts b/backend/src/routes/groups.ts index 8264e584..5d3d8ed0 100644 --- a/backend/src/routes/groups.ts +++ b/backend/src/routes/groups.ts @@ -13,17 +13,15 @@ import {onlyAllowIfHasAccessToAssignment} from "../middleware/auth/checks/assign const router = express.Router({ mergeParams: true }); -// Root endpoint used to search objects router.get('/', onlyAllowIfHasAccessToAssignment, getAllGroupsHandler); router.post('/', teachersOnly, onlyAllowIfHasAccessToAssignment, createGroupHandler); -// Information about a group (members, ... [TODO DOC]) -router.get('/:groupid', onlyAllowIfHasAccessToGroup, getGroupHandler); +router.get('/:groupid', onlyAllowIfHasAccessToAssignment, getGroupHandler); -router.put('/:groupid', putGroupHandler); +router.put('/:groupid', teachersOnly, onlyAllowIfHasAccessToAssignment, putGroupHandler); -router.delete('/:groupid', deleteGroupHandler); +router.delete('/:groupid', teachersOnly, onlyAllowIfHasAccessToAssignment, deleteGroupHandler); router.get('/:groupid/submissions', onlyAllowIfHasAccessToGroup, getGroupSubmissionsHandler); diff --git a/backend/src/routes/submissions.ts b/backend/src/routes/submissions.ts index 492b6439..8030f9f8 100644 --- a/backend/src/routes/submissions.ts +++ b/backend/src/routes/submissions.ts @@ -1,15 +1,16 @@ import express from 'express'; import { createSubmissionHandler, deleteSubmissionHandler, getSubmissionHandler, getSubmissionsHandler } from '../controllers/submissions.js'; +import { onlyAllowAuthor } from '../middleware/auth/checks/question-checks.js'; +import { onlyAllowIfHasAccessToSubmission, onlyAllowSubmitter } from '../middleware/auth/checks/submission-checks.js'; +import { adminOnly, studentsOnly } from '../middleware/auth/checks/auth-checks.js'; const router = express.Router({ mergeParams: true }); -// Root endpoint used to search objects -router.get('/', getSubmissionsHandler); +router.get('/', adminOnly, getSubmissionsHandler); -router.post('/:id', createSubmissionHandler); +router.post('/:id', studentsOnly, onlyAllowSubmitter, createSubmissionHandler); -// Information about an submission with id 'id' -router.get('/:id', getSubmissionHandler); +router.get('/:id', onlyAllowIfHasAccessToSubmission, getSubmissionHandler); -router.delete('/:id', deleteSubmissionHandler); +router.delete('/:id', onlyAllowIfHasAccessToSubmission, deleteSubmissionHandler); export default router;