const { Forbidden } = require('@feathersjs/errors');

const { ScopePermissionService } = require('../../helpers/scopePermissions');

/**
 * Role names used in the database
 */
const courseRoles = {
	teacher: 'courseTeacher',
	substitutionTeacher: 'courseSubstitutionTeacher',
	student: 'courseStudent',
	administrator: 'courseAdministrator',
	superhero: 'courseAdministrator', // Not a typo. There is no dedicated superhero role
};

const compareIds = (s) => (f) => f.toString() === s.toString();
const belongsToSameSchool = (user, course) => compareIds(user.schoolId, course.schoolId);
const userIsAdmin = (u) => u.roles.some((role) => role.name === 'administrator');
const userIsSuperhero = (u) => u.roles.some((role) => role.name === 'superhero');

/**
 * Setup the userPermissions service for the course scope
 */
const setup = (app) => {
	const getPermissions = async (roleName) => {
		const permissions = await app.service('roles/:roleName/permissions').find({
			route: {
				roleName,
			},
		});
		return permissions;
	};

	/**
	 * Determine the permissions a specific user has in a specific course
	 * @param {ObjectId} userId a userId
	 * @param {Course} course a course object
	 * @returns {Array<String>} array of permissions (strings)
	 */
	const determineCoursePermissions = async (userId, course) => {
		if (!userId || !course) return [];

		const user = await app.service('users').get(userId, { query: { $populate: 'roles' } });
		if (userIsSuperhero(user)) {
			return getPermissions(courseRoles.superhero);
		}
		if ((userIsAdmin(user) && belongsToSameSchool(user, course))) {
			return getPermissions(courseRoles.administrator);
		}

		if (course.teacherIds.some(compareIds(userId))) {
			return getPermissions(courseRoles.teacher);
		}
		if (course.substitutionIds.some(compareIds(userId))) {
			return getPermissions(courseRoles.substitutionTeacher);
		}
		if (course.userIds.some(compareIds(userId))) {
			return getPermissions(courseRoles.student);
		}
		throw new Forbidden(`User ${userId} ist nicht Teil des Kurses`);
	};

	ScopePermissionService.initialize(app, '/courses/:scopeId/userPermissions', determineCoursePermissions);
};

module.exports = {
	setup,
	courseRoles,
};

@@ -1648,24 +1648,25 @@
 ;%0A%09%09%7D%0A%0A%09%09if 
+(
 (course.teac
@@ -1667,24 +1667,31 @@
 e.teacherIds
+ %7C%7C %5B%5D)
 .some(compar
@@ -1755,32 +1755,33 @@
 cher);%0A%09%09%7D%0A%09%09if 
+(
 (course.substitu
@@ -1787,16 +1787,23 @@
 utionIds
+ %7C%7C %5B%5D)
 .some(co
@@ -1891,16 +1891,17 @@
 %09%7D%0A%09%09if 
+(
 (course.
@@ -1907,16 +1907,23 @@
 .userIds
+ %7C%7C %5B%5D)
 .some(co

Fix course permissions in case of missing values