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)
Example #2
0
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
Example #3
0
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()
Example #4
0
    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
Example #5
0
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