def test_has_permission_filter(describe, test_client, session, admin_user, logged_in, perm): with describe('setup'), logged_in(admin_user): course = helpers.to_db_object(helpers.create_course(test_client), m.Course) rol1 = m.CourseRole('rol1', course, hidden=False) rol2 = m.CourseRole('rol2', course, hidden=False) session.add(rol1) session.add(rol2) session.commit() user1 = helpers.create_user_with_role(session, 'rol1', course) user2 = helpers.create_user_with_role(session, 'rol2', course) rol1.set_permission(perm, True) rol2.set_permission(perm, False) session.commit() with describe('Role is include if (and only if) the permission is true'): roles = m.CourseRole.get_roles_with_permission(perm).all() assert rol1 in roles assert rol2 not in roles with describe('Can be filtered further'): roles = m.CourseRole.get_roles_with_permission(perm).filter( m.CourseRole.course == course).all() assert all(r.course_id == course.id for r in roles) assert 'rol1' in [r.name for r in roles] assert 'Teacher' in [r.name for r in roles] with describe('User show up if permission is true not otherwise'): query = course.get_all_users_in_course( include_test_students=False, with_permission=perm, ) assert sorted([user1.id, admin_user.id]) == sorted(user.id for user, _ in query)
def create_user_with_perms(session, perms, courses, name=None): role_name = f'NEW-COURSE-ROLE-{uuid.uuid4().hex}' courses = courses if isinstance(courses, list) else [courses] for course in courses: if isinstance(course, dict): course = m.Course.query.get(course['id']) crole = m.CourseRole(name=role_name, course=course, hidden=False) for perm in CPerm: crole.set_permission(perm, perm in perms) session.add(crole) session.flush() user = create_user_with_role(session, role_name, courses, name) print('Created user', user.id, 'with permissions:', perms) return user
def add_role(course_id: int) -> EmptyResponse: """Add a new :class:`.models.CourseRole` to the given :class:`.models.Course`. .. :quickref: Course; Add a new course role to a course. :param int course_id: The id of the course :returns: An empty response with return code 204. :<json str name: The name of the new course role. :raises APIException: If the name parameter was not in the request. (MISSING_REQUIRED_PARAM) :raises APIException: If the course with the given id was not found. (OBJECT_NOT_FOUND) :raises APIException: If the course already has a role with the submitted name. (INVALID_PARAM) :raises PermissionException: If there is no logged in user. (NOT_LOGGED_IN) :raises PermissionException: If the user can not manage the course with the given id. (INCORRECT_PERMISSION) """ auth.ensure_permission(CPerm.can_edit_course_roles, course_id) content = get_json_dict_from_request() ensure_keys_in_dict(content, [('name', str)]) name = t.cast(str, content['name']) course = helpers.get_or_404( models.Course, course_id, also_error=lambda c: c.virtual, ) if models.CourseRole.query.filter_by( name=name, course_id=course_id).first() is not None: raise APIException( 'This course already has a role with this name', 'The course "{}" already has a role named "{}"'.format( course_id, name), APICodes.INVALID_PARAM, 400) role = models.CourseRole(name=name, course=course, hidden=False) db.session.add(role) db.session.commit() return make_empty_response()
def set_user_course_role(self, user: models.User, course: models.Course) -> t.Union[str, bool]: """Set the course role for the given course and user if there is no such role just yet. The mapping is done using :py:data:`.LTI_ROLE_LOOKUPS`. If no role could be found a new role is created with the default permissions. :param models.User user: The user to set the course role for. :param models.Course course: The course to connect to user to. :returns: True if a new role was created. """ if course.id not in user.courses: unkown_roles = [] for role in self.roles: if role not in LTI_ROLE_LOOKUPS: unkown_roles.append(role) continue role_lookup = LTI_ROLE_LOOKUPS[role] if not role_lookup['course_role']: # This is not a course role continue crole = models.CourseRole.query.filter_by( course_id=course.id, name=role_lookup['role']).one() user.courses[course.id] = crole return False if not psef.app.config['FEATURES']['AUTOMATIC_LTI_ROLE']: raise APIException( 'The given LTI role was not valid found, please ' 'ask your instructor or site admin.', f'No role in "{list(self.roles)}" is a known LTI role', APICodes.INVALID_STATE, 400) # Add a new course role new_created: t.Union[bool, str] = False new_role = (unkown_roles + ['New LTI Role'])[0] existing_role = models.CourseRole.query.filter_by( course_id=course.id, name=new_role).first() if existing_role is None: existing_role = models.CourseRole(course=course, name=new_role) db.session.add(existing_role) new_created = new_role user.courses[course.id] = existing_role return new_created return False
def test_user_is_enrolled(): user = User('', '', '', '', active=True) assert not user.virtual course = m.Course(id=5) crole = m.CourseRole(name='Hello', course=course, hidden=False) assert not user.is_enrolled(course) assert not user.is_enrolled(5) user.enroll_in_course(course_role=crole) assert course.id in user.courses assert user.is_enrolled(course) assert user.is_enrolled(5) assert not user.is_enrolled(6) user.virtual = True # Virtual users are never enrolled assert not user.is_enrolled(course) assert not user.is_enrolled(5) # But the connection still exists assert course.id in user.courses