fix: add question in group check + extra create question errors service
This commit is contained in:
parent
78b65f148e
commit
566bb5a5fb
4 changed files with 47 additions and 6 deletions
|
@ -6,6 +6,7 @@ import {getLearningObjectId, getQuestionId} from "../../../controllers/questions
|
||||||
import {fetchQuestion} from "../../../services/questions";
|
import {fetchQuestion} from "../../../services/questions";
|
||||||
import {FALLBACK_SEQ_NUM} from "../../../config";
|
import {FALLBACK_SEQ_NUM} from "../../../config";
|
||||||
import {fetchAnswer} from "../../../services/answers";
|
import {fetchAnswer} from "../../../services/answers";
|
||||||
|
import {mapToUsername} from "../../../interfaces/user";
|
||||||
|
|
||||||
export const onlyAllowAuthor = authorize(
|
export const onlyAllowAuthor = authorize(
|
||||||
(auth: AuthenticationInfo, req: AuthenticatedRequest) => req.body.author === auth.username
|
(auth: AuthenticationInfo, req: AuthenticatedRequest) => req.body.author === auth.username
|
||||||
|
@ -46,3 +47,26 @@ export const onlyAllowAuthorRequestAnswer = authorize(
|
||||||
return answer.author.username == auth.username;
|
return answer.author.username == auth.username;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const onlyAllowIfHasAccessToQuestion = authorize(
|
||||||
|
async (auth, req) => {
|
||||||
|
const hruid = req.params.hruid;
|
||||||
|
const version = req.params.version;
|
||||||
|
const language = req.query.lang as string;
|
||||||
|
const seq = req.params.seq;
|
||||||
|
requireFields({ hruid });
|
||||||
|
|
||||||
|
const learningObjectId = getLearningObjectId(hruid, version, language);
|
||||||
|
const questionId = getQuestionId(learningObjectId, seq);
|
||||||
|
|
||||||
|
const question = await fetchQuestion(questionId);
|
||||||
|
const group = question.inGroup;
|
||||||
|
|
||||||
|
if (auth.accountType === "teacher") {
|
||||||
|
const cls = group.assignment.within; // TODO check if contains full objects
|
||||||
|
return cls.teachers.map(mapToUsername).includes(auth.username);
|
||||||
|
} else { // user is student
|
||||||
|
return group.members.map(mapToUsername).includes(auth.username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
import { createAnswerHandler, deleteAnswerHandler, getAnswerHandler, getAllAnswersHandler, updateAnswerHandler } from '../controllers/answers.js';
|
import { createAnswerHandler, deleteAnswerHandler, getAnswerHandler, getAllAnswersHandler, updateAnswerHandler } from '../controllers/answers.js';
|
||||||
import {adminOnly, authenticatedOnly, teachersOnly} from "../middleware/auth/checks/auth-checks";
|
import {adminOnly, authenticatedOnly, teachersOnly} from "../middleware/auth/checks/auth-checks";
|
||||||
import {onlyAllowAuthor, onlyAllowAuthorRequestAnswer} from "../middleware/auth/checks/question-checks";
|
import {
|
||||||
|
onlyAllowAuthor,
|
||||||
|
onlyAllowAuthorRequestAnswer,
|
||||||
|
onlyAllowIfHasAccessToQuestion
|
||||||
|
} from "../middleware/auth/checks/question-checks";
|
||||||
|
|
||||||
|
|
||||||
const router = express.Router({ mergeParams: true });
|
const router = express.Router({ mergeParams: true });
|
||||||
|
@ -10,7 +14,7 @@ router.get('/', adminOnly, getAllAnswersHandler);
|
||||||
|
|
||||||
router.post('/', teachersOnly, onlyAllowAuthor, createAnswerHandler);
|
router.post('/', teachersOnly, onlyAllowAuthor, createAnswerHandler);
|
||||||
|
|
||||||
router.get('/:seqAnswer', authenticatedOnly, getAnswerHandler);
|
router.get('/:seqAnswer', onlyAllowIfHasAccessToQuestion, getAnswerHandler);
|
||||||
|
|
||||||
router.delete('/:seqAnswer', teachersOnly, onlyAllowAuthorRequestAnswer, deleteAnswerHandler);
|
router.delete('/:seqAnswer', teachersOnly, onlyAllowAuthorRequestAnswer, deleteAnswerHandler);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,11 @@ import { createQuestionHandler, deleteQuestionHandler, getAllQuestionsHandler, g
|
||||||
import answerRoutes from './answers.js';
|
import answerRoutes from './answers.js';
|
||||||
import {adminOnly, authenticatedOnly, studentsOnly} from "../middleware/auth/checks/auth-checks";
|
import {adminOnly, authenticatedOnly, studentsOnly} from "../middleware/auth/checks/auth-checks";
|
||||||
import {updateAnswerHandler} from "../controllers/answers";
|
import {updateAnswerHandler} from "../controllers/answers";
|
||||||
import {onlyAllowAuthor, onlyAllowAuthorRequest} from "../middleware/auth/checks/question-checks";
|
import {
|
||||||
|
onlyAllowAuthor,
|
||||||
|
onlyAllowAuthorRequest,
|
||||||
|
onlyAllowIfHasAccessToQuestion
|
||||||
|
} from "../middleware/auth/checks/question-checks";
|
||||||
|
|
||||||
const router = express.Router({ mergeParams: true });
|
const router = express.Router({ mergeParams: true });
|
||||||
|
|
||||||
|
@ -15,7 +19,7 @@ router.get('/', adminOnly, getAllQuestionsHandler);
|
||||||
router.post('/', studentsOnly, onlyAllowAuthor, createQuestionHandler);
|
router.post('/', studentsOnly, onlyAllowAuthor, createQuestionHandler);
|
||||||
|
|
||||||
// Information about a question with id
|
// Information about a question with id
|
||||||
router.get('/:seq', authenticatedOnly, getQuestionHandler); // TODO every body in group + teachers?
|
router.get('/:seq', onlyAllowIfHasAccessToQuestion, getQuestionHandler);
|
||||||
|
|
||||||
router.delete('/:seq', studentsOnly, onlyAllowAuthorRequest, deleteQuestionHandler);
|
router.delete('/:seq', studentsOnly, onlyAllowAuthorRequest, deleteQuestionHandler);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { AssignmentDTO } from '@dwengo-1/common/interfaces/assignment';
|
||||||
import { fetchStudent } from './students.js';
|
import { fetchStudent } from './students.js';
|
||||||
import { NotFoundException } from '../exceptions/not-found-exception';
|
import { NotFoundException } from '../exceptions/not-found-exception';
|
||||||
import { FALLBACK_VERSION_NUM } from '../config.js';
|
import { FALLBACK_VERSION_NUM } from '../config.js';
|
||||||
|
import {ConflictException} from "../exceptions/conflict-exception";
|
||||||
|
|
||||||
export async function getQuestionsAboutLearningObjectInAssignment(
|
export async function getQuestionsAboutLearningObjectInAssignment(
|
||||||
loId: LearningObjectIdentifier,
|
loId: LearningObjectIdentifier,
|
||||||
|
@ -88,12 +89,20 @@ export async function createQuestion(loId: LearningObjectIdentifier, questionDat
|
||||||
|
|
||||||
const clazz = await getClassRepository().findById((questionData.inGroup.assignment as AssignmentDTO).within);
|
const clazz = await getClassRepository().findById((questionData.inGroup.assignment as AssignmentDTO).within);
|
||||||
const assignment = mapToAssignment(questionData.inGroup.assignment as AssignmentDTO, clazz!);
|
const assignment = mapToAssignment(questionData.inGroup.assignment as AssignmentDTO, clazz!);
|
||||||
const inGroup = await getGroupRepository().findByAssignmentAndGroupNumber(assignment, questionData.inGroup.groupNumber);
|
const group = await getGroupRepository().findByAssignmentAndGroupNumber(assignment, questionData.inGroup.groupNumber);
|
||||||
|
|
||||||
|
if (!group){
|
||||||
|
throw new NotFoundException("Group with id and assignment not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! group.members.contains(author)) {
|
||||||
|
throw new ConflictException("Author is not part of this group");
|
||||||
|
}
|
||||||
|
|
||||||
const question = await questionRepository.createQuestion({
|
const question = await questionRepository.createQuestion({
|
||||||
loId,
|
loId,
|
||||||
author,
|
author,
|
||||||
inGroup: inGroup!,
|
inGroup: group!,
|
||||||
content,
|
content,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue