def test_get_all_users(self): """ Test getting all authors for a course where their permissions run the gamut of allowed group types. """ # first check the course creator.has explicit access (don't use has_access as is_staff # will trump the actual test) self.assertTrue(CourseInstructorRole(self.course_key).has_user(self.user), "Didn't add creator as instructor.") users = copy.copy(self.users) # doesn't use role.users_with_role b/c it's verifying the roles.py behavior user_by_role = {} # add the misc users to the course in different groups for role in [CourseInstructorRole, CourseStaffRole, OrgStaffRole, OrgInstructorRole]: user_by_role[role] = [] # Org-based roles are created via org name, rather than course_key if (role is OrgStaffRole) or (role is OrgInstructorRole): group = role(self.course_key.org) else: group = role(self.course_key) # NOTE: this loop breaks the roles.py abstraction by purposely assigning # users to one of each possible groupname in order to test that has_course_author_access # and remove_user work user = users.pop() group.add_users(user) user_by_role[role].append(user) self.assertTrue( auth.has_course_author_access(user, self.course_key), "{} does not have access".format(user) ) course_team_url = reverse_course_url("course_team_handler", self.course_key) response = self.client.get_html(course_team_url) for role in [CourseInstructorRole, CourseStaffRole]: # Global and org-based roles don't appear on this page for user in user_by_role[role]: self.assertContains(response, user.email) # test copying course permissions copy_course_key = self.store.make_course_key("copyu", "copydept.mycourse", "myrun") for role in [CourseInstructorRole, CourseStaffRole, OrgStaffRole, OrgInstructorRole]: if (role is OrgStaffRole) or (role is OrgInstructorRole): auth.add_users(self.user, role(copy_course_key.org), *role(self.course_key.org).users_with_role()) else: auth.add_users(self.user, role(copy_course_key), *role(self.course_key).users_with_role()) # verify access in copy course and verify that removal from source course w/ the various # groupnames works for role in [CourseInstructorRole, CourseStaffRole, OrgStaffRole, OrgInstructorRole]: for user in user_by_role[role]: # forcefully decache the groups: premise is that any real request will not have # multiple objects repr the same user but this test somehow uses different instance # in above add_users call if hasattr(user, "_roles"): del user._roles self.assertTrue(auth.has_course_author_access(user, copy_course_key), "{} no copy access".format(user)) if (role is OrgStaffRole) or (role is OrgInstructorRole): auth.remove_users(self.user, role(self.course_key.org), user) else: auth.remove_users(self.user, role(self.course_key), user) self.assertFalse( auth.has_course_author_access(user, self.course_key), "{} remove didn't work".format(user) )
def test_remove_user_from_group_requires_authenticated(self): with self.assertRaises(PermissionDenied): with mock.patch( 'django.contrib.auth.models.User.is_authenticated', new_callable=mock.PropertyMock ) as mock_is_auth: mock_is_auth.return_value = False remove_users(self.admin, CourseCreatorRole(), self.user)
def test_remove_user_from_group_requires_authenticated(self): with self.assertRaises(PermissionDenied): with mock.patch( 'django.contrib.auth.models.User.is_authenticated', new_callable=mock.PropertyMock ) as mock_is_auth: mock_is_auth.return_value = False remove_users(self.admin, CourseCreatorRole(), self.user)
def test_remove_user_from_course_group_permission_denied(self): """ Verifies PermissionDenied if caller of remove_user_from_course_group is not instructor role. """ add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator) another_staff = User.objects.create_user('another', '*****@*****.**', 'foo') add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator, self.staff, another_staff) with self.assertRaises(PermissionDenied): remove_users(self.staff, CourseStaffRole(self.course_key), another_staff)
def test_remove_user_from_course_group_permission_denied(self): """ Verifies PermissionDenied if caller of remove_user_from_course_group is not instructor role. """ add_users(self.global_admin, CourseInstructorRole(self.location), self.creator) another_staff = User.objects.create_user('another', '*****@*****.**', 'foo') add_users(self.global_admin, CourseStaffRole(self.location), self.creator, self.staff, another_staff) with self.assertRaises(PermissionDenied): remove_users(self.staff, CourseStaffRole(self.location), another_staff)
def try_remove_instructor(request, locator, user): # remove all roles in this course from this user: but fail if the user # is the last instructor in the course team instructors = CourseInstructorRole(locator) if instructors.has_user(user): if instructors.users_with_role().count() == 1: msg = {"error":_("You may not remove the last instructor from a course")} raise CannotOrphanCourse(msg) else: auth.remove_users(request.user, instructors, user)
def try_remove_instructor(request, locator, user): # remove all roles in this course from this user: but fail if the user # is the last instructor in the course team instructors = CourseInstructorRole(locator) if instructors.has_user(user): if instructors.users_with_role().count() == 1: msg = {"error":_("You may not remove the last instructor from a course")} raise CannotOrphanCourse(msg) else: auth.remove_users(request.user, instructors, user)
def update_course_creator_group(caller, user, add): """ Method for adding and removing users from the creator group. Caller must have staff permissions. """ if add: auth.add_users(caller, CourseCreatorRole(), user) else: auth.remove_users(caller, CourseCreatorRole(), user)
def test_get_all_users(self): """ Test getting all authors for a course where their permissions run the gamut of allowed group types. """ # first check the course creator.has explicit access (don't use has_access as is_staff # will trump the actual test) self.assertTrue( CourseInstructorRole(self.course_key).has_user(self.user), "Didn't add creator as instructor.") users = copy.copy(self.users) # doesn't use role.users_with_role b/c it's verifying the roles.py behavior user_by_role = {} # add the misc users to the course in different groups for role in [CourseInstructorRole, CourseStaffRole]: user_by_role[role] = [] # pylint: disable=protected-access group = role(self.course_key) # NOTE: this loop breaks the roles.py abstraction by purposely assigning # users to one of each possible groupname in order to test that has_course_access # and remove_user work user = users.pop() group.add_users(user) user_by_role[role].append(user) self.assertTrue(has_course_access(user, self.course_key), "{} does not have access".format(user)) course_team_url = reverse_course_url('course_team_handler', self.course_key) response = self.client.get_html(course_team_url) for role in [CourseInstructorRole, CourseStaffRole]: for user in user_by_role[role]: self.assertContains(response, user.email) # test copying course permissions copy_course_key = SlashSeparatedCourseKey('copyu', 'copydept.mycourse', 'myrun') for role in [CourseInstructorRole, CourseStaffRole]: auth.add_users(self.user, role(copy_course_key), *role(self.course_key).users_with_role()) # verify access in copy course and verify that removal from source course w/ the various # groupnames works for role in [CourseInstructorRole, CourseStaffRole]: for user in user_by_role[role]: # forcefully decache the groups: premise is that any real request will not have # multiple objects repr the same user but this test somehow uses different instance # in above add_users call if hasattr(user, '_roles'): del user._roles self.assertTrue(has_course_access(user, copy_course_key), "{} no copy access".format(user)) auth.remove_users(self.user, role(self.course_key), user) self.assertFalse(has_course_access(user, self.course_key), "{} remove didn't work".format(user))
def test_creator_group_enabled_nonempty(self): """ Tests creator group feature on, user added. """ with mock.patch.dict('django.conf.settings.FEATURES', {"ENABLE_CREATOR_GROUP": True}): add_users(self.admin, CourseCreatorRole(), self.user) self.assertTrue(has_access(self.user, CourseCreatorRole())) # check that a user who has not been added to the group still returns false user_not_added = User.objects.create_user('testuser2', '*****@*****.**', 'foo2') self.assertFalse(has_access(user_not_added, CourseCreatorRole())) # remove first user from the group and verify that CourseCreatorRole().has_user now returns false remove_users(self.admin, CourseCreatorRole(), self.user) self.assertFalse(has_access(self.user, CourseCreatorRole()))
def test_creator_group_enabled_nonempty(self): """ Tests creator group feature on, user added. """ with mock.patch.dict('django.conf.settings.FEATURES', {"ENABLE_CREATOR_GROUP": True}): add_users(self.admin, CourseCreatorRole(), self.user) self.assertTrue(user_has_role(self.user, CourseCreatorRole())) # check that a user who has not been added to the group still returns false user_not_added = User.objects.create_user('testuser2', '*****@*****.**', 'foo2') self.assertFalse(user_has_role(user_not_added, CourseCreatorRole())) # remove first user from the group and verify that CourseCreatorRole().has_user now returns false remove_users(self.admin, CourseCreatorRole(), self.user) self.assertFalse(user_has_role(self.user, CourseCreatorRole()))
def test_remove_user_from_course_group(self): """ Tests removing user from course group (happy path). """ add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator) add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator) add_users(self.creator, CourseStaffRole(self.course_key), self.staff) self.assertTrue(has_access(self.staff, CourseStaffRole(self.course_key))) remove_users(self.creator, CourseStaffRole(self.course_key), self.staff) self.assertFalse(has_access(self.staff, CourseStaffRole(self.course_key))) remove_users(self.creator, CourseInstructorRole(self.course_key), self.creator) self.assertFalse(has_access(self.creator, CourseInstructorRole(self.course_key)))
def test_remove_user_from_course_group(self): """ Tests removing user from course group (happy path). """ add_users(self.global_admin, CourseInstructorRole(self.location), self.creator) add_users(self.global_admin, CourseStaffRole(self.location), self.creator) add_users(self.creator, CourseStaffRole(self.location), self.staff) self.assertTrue(has_access(self.staff, CourseStaffRole(self.location))) remove_users(self.creator, CourseStaffRole(self.location), self.staff) self.assertFalse(has_access(self.staff, CourseStaffRole(self.location))) remove_users(self.creator, CourseInstructorRole(self.location), self.creator) self.assertFalse(has_access(self.creator, CourseInstructorRole(self.location)))
def test_course_creation_disabled(self): """ Tests that the COURSE_CREATION_DISABLED flag overrides course creator group settings. """ with mock.patch.dict('django.conf.settings.FEATURES', {'DISABLE_COURSE_CREATION': True, "ENABLE_CREATOR_GROUP": True}): # Add user to creator group. add_users(self.admin, CourseCreatorRole(), self.user) # DISABLE_COURSE_CREATION overrides (user is not marked as staff). self.assertFalse(has_access(self.user, CourseCreatorRole())) # Mark as staff. Now CourseCreatorRole().has_user returns true. self.user.is_staff = True self.assertTrue(has_access(self.user, CourseCreatorRole())) # Remove user from creator group. CourseCreatorRole().has_user still returns true because is_staff=True remove_users(self.admin, CourseCreatorRole(), self.user) self.assertTrue(has_access(self.user, CourseCreatorRole()))
def test_course_creation_disabled(self): """ Tests that the COURSE_CREATION_DISABLED flag overrides course creator group settings. """ with mock.patch.dict('django.conf.settings.FEATURES', {'DISABLE_COURSE_CREATION': True, "ENABLE_CREATOR_GROUP": True}): # Add user to creator group. add_users(self.admin, CourseCreatorRole(), self.user) # DISABLE_COURSE_CREATION overrides (user is not marked as staff). self.assertFalse(user_has_role(self.user, CourseCreatorRole())) # Mark as staff. Now CourseCreatorRole().has_user returns true. self.user.is_staff = True self.assertTrue(user_has_role(self.user, CourseCreatorRole())) # Remove user from creator group. CourseCreatorRole().has_user still returns true because is_staff=True remove_users(self.admin, CourseCreatorRole(), self.user) self.assertTrue(user_has_role(self.user, CourseCreatorRole()))
def test_remove_user_from_course_group(self): """ Tests removing user from course group (happy path). """ add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator) add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator) add_users(self.creator, CourseStaffRole(self.course_key), self.staff) self.assertTrue( user_has_role(self.staff, CourseStaffRole(self.course_key))) remove_users(self.creator, CourseStaffRole(self.course_key), self.staff) self.assertFalse( user_has_role(self.staff, CourseStaffRole(self.course_key))) add_users(self.creator, CourseAssistantRole(self.course_key), self.assistant) self.assertTrue( user_has_role(self.assistant, CourseAssistantRole(self.course_key))) remove_users(self.creator, CourseAssistantRole(self.course_key), self.assistant) self.assertFalse( user_has_role(self.assistant, CourseAssistantRole(self.course_key))) remove_users(self.creator, CourseInstructorRole(self.course_key), self.creator) self.assertFalse( user_has_role(self.creator, CourseInstructorRole(self.course_key)))
def _course_team_user(request, course_key, email): """ Handle the add, remove, promote, demote requests ensuring the requester has authority """ # check that logged in user has permissions to this item requester_perms = get_user_permissions(request.user, course_key) permissions_error_response = JsonResponse({"error": _("Insufficient permissions")}, 403) if (requester_perms & STUDIO_VIEW_USERS) or (email == request.user.email): # This user has permissions to at least view the list of users or is editing themself pass else: # This user is not even allowed to know who the authorized users are. return permissions_error_response try: user = User.objects.get(email=email) except Exception: msg = { "error": _("Could not find user by email address '{email}'.").format(email=email), } return JsonResponse(msg, 404) is_library = isinstance(course_key, LibraryLocator) # Ordered list of roles: can always move self to the right, but need STUDIO_EDIT_ROLES to move any user left if is_library: role_hierarchy = (CourseInstructorRole, CourseStaffRole, LibraryUserRole) else: role_hierarchy = (CourseInstructorRole, CourseStaffRole) if request.method == "GET": # just return info about the user msg = { "email": user.email, "active": user.is_active, "role": None, } # what's the highest role that this user has? (How should this report global staff?) for role in role_hierarchy: if role(course_key).has_user(user): msg["role"] = role.ROLE break return JsonResponse(msg) # All of the following code is for editing/promoting/deleting users. # Check that the user has STUDIO_EDIT_ROLES permission or is editing themselves: if not ((requester_perms & STUDIO_EDIT_ROLES) or (user.id == request.user.id)): return permissions_error_response if request.method == "DELETE": new_role = None else: # only other operation supported is to promote/demote a user by changing their role: # role may be None or "" (equivalent to a DELETE request) but must be set. # Check that the new role was specified: if "role" in request.json or "role" in request.POST: new_role = request.json.get("role", request.POST.get("role")) else: return JsonResponse({"error": _("No `role` specified.")}, 400) # can't modify an inactive user but can remove it if not (user.is_active or new_role is None): msg = { "error": _('User {email} has registered but has not yet activated his/her account.').format(email=email), } return JsonResponse(msg, 400) old_roles = set() role_added = False for role_type in role_hierarchy: role = role_type(course_key) if role_type.ROLE == new_role: if (requester_perms & STUDIO_EDIT_ROLES) or (user.id == request.user.id and old_roles): # User has STUDIO_EDIT_ROLES permission or # is currently a member of a higher role, and is thus demoting themself auth.add_users(request.user, role, user) role_added = True else: return permissions_error_response elif role.has_user(user, check_user_activation=False): # Remove the user from this old role: old_roles.add(role) if new_role and not role_added: return JsonResponse({"error": _("Invalid `role` specified.")}, 400) for role in old_roles: if isinstance(role, CourseInstructorRole) and role.users_with_role().count() == 1: msg = {"error": _("You may not remove the last Admin. Add another Admin first.")} return JsonResponse(msg, 400) auth.remove_users(request.user, role, user) if new_role and not is_library: # The user may be newly added to this course. # auto-enroll the user in the course so that "View Live" will work. CourseEnrollment.enroll(user, course_key) return JsonResponse()
def test_get_all_users(self): """ Test getting all authors for a course where their permissions run the gamut of allowed group types. """ # first check the course creator.has explicit access (don't use has_access as is_staff # will trump the actual test) self.assertTrue( CourseInstructorRole(self.course_locator).has_user(self.user), "Didn't add creator as instructor." ) users = copy.copy(self.users) # doesn't use role.users_with_role b/c it's verifying the roles.py behavior user_by_role = {} # add the misc users to the course in different groups for role in [CourseInstructorRole, CourseStaffRole]: user_by_role[role] = [] # pylint: disable=protected-access groupnames = role(self.course_locator)._group_names self.assertGreater(len(groupnames), 1, "Only 0 or 1 groupname for {}".format(role.ROLE)) # NOTE: this loop breaks the roles.py abstraction by purposely assigning # users to one of each possible groupname in order to test that has_course_access # and remove_user work for groupname in groupnames: group, _ = Group.objects.get_or_create(name=groupname) user = users.pop() user_by_role[role].append(user) user.groups.add(group) user.save() self.assertTrue(has_course_access(user, self.course_locator), "{} does not have access".format(user)) self.assertTrue(has_course_access(user, self.course_location), "{} does not have access".format(user)) response = self.client.get_html(self.course_locator.url_reverse('course_team')) for role in [CourseInstructorRole, CourseStaffRole]: for user in user_by_role[role]: self.assertContains(response, user.email) # test copying course permissions copy_course_location = Location(['i4x', 'copyu', 'copydept.mycourse', 'course', 'myrun']) copy_course_locator = loc_mapper().translate_location( copy_course_location.course_id, copy_course_location, False, True ) for role in [CourseInstructorRole, CourseStaffRole]: auth.add_users( self.user, role(copy_course_locator), *role(self.course_locator).users_with_role() ) # verify access in copy course and verify that removal from source course w/ the various # groupnames works for role in [CourseInstructorRole, CourseStaffRole]: for user in user_by_role[role]: # forcefully decache the groups: premise is that any real request will not have # multiple objects repr the same user but this test somehow uses different instance # in above add_users call if hasattr(user, '_groups'): del user._groups self.assertTrue(has_course_access(user, copy_course_locator), "{} no copy access".format(user)) self.assertTrue(has_course_access(user, copy_course_location), "{} no copy access".format(user)) auth.remove_users(self.user, role(self.course_locator), user) self.assertFalse(has_course_access(user, self.course_locator), "{} remove didn't work".format(user))
def test_remove_user_from_group_requires_authenticated(self): with self.assertRaises(PermissionDenied): self.admin.is_authenticated = mock.Mock(return_value=False) remove_users(self.admin, CourseCreatorRole(), self.user)
def test_remove_user_from_group_requires_active(self): with self.assertRaises(PermissionDenied): self.admin.is_active = False remove_users(self.admin, CourseCreatorRole(), self.user)
def test_remove_user_from_group_requires_active(self): with self.assertRaises(PermissionDenied): self.admin.is_active = False remove_users(self.admin, CourseCreatorRole(), self.user)
def _course_team_user(request, course_key, email): """ Handle the add, remove, promote, demote requests ensuring the requester has authority """ # check that logged in user has permissions to this item if has_course_access(request.user, course_key, role=CourseInstructorRole): # instructors have full permissions pass elif has_course_access( request.user, course_key, role=CourseStaffRole) and email == request.user.email: # staff can only affect themselves pass else: msg = {"error": _("Insufficient permissions")} return JsonResponse(msg, 400) try: user = User.objects.get(email=email) except Exception: msg = { "error": _("Could not find user by email address '{email}'.").format( email=email), } return JsonResponse(msg, 404) # role hierarchy: globalstaff > "instructor" > "staff" (in a course) if request.method == "GET": # just return info about the user msg = { "email": user.email, "active": user.is_active, "role": None, } # what's the highest role that this user has? (How should this report global staff?) for role in [ CourseInstructorRole(course_key), CourseStaffRole(course_key) ]: if role.has_user(user): msg["role"] = role.ROLE break return JsonResponse(msg) # can't modify an inactive user if not user.is_active: msg = { "error": _('User {email} has registered but has not yet activated his/her account.' ).format(email=email), } return JsonResponse(msg, 400) if request.method == "DELETE": try: try_remove_instructor(request, course_key, user) except CannotOrphanCourse as oops: return JsonResponse(oops.msg, 400) auth.remove_users(request.user, CourseStaffRole(course_key), user) return JsonResponse() # all other operations require the requesting user to specify a role role = request.json.get("role", request.POST.get("role")) if role is None: return JsonResponse({"error": _("`role` is required")}, 400) if role == "instructor": if not has_course_access( request.user, course_key, role=CourseInstructorRole): msg = {"error": _("Only instructors may create other instructors")} return JsonResponse(msg, 400) auth.add_users(request.user, CourseInstructorRole(course_key), user) # auto-enroll the course creator in the course so that "View Live" will work. CourseEnrollment.enroll(user, course_key) elif role == "staff": # add to staff regardless (can't do after removing from instructors as will no longer # be allowed) auth.add_users(request.user, CourseStaffRole(course_key), user) try: try_remove_instructor(request, course_key, user) except CannotOrphanCourse as oops: return JsonResponse(oops.msg, 400) # auto-enroll the course creator in the course so that "View Live" will work. CourseEnrollment.enroll(user, course_key) return JsonResponse()
def _course_team_user(request, course_key, email): """ Handle the add, remove, promote, demote requests ensuring the requester has authority """ # check that logged in user has permissions to this item requester_perms = get_user_permissions(request.user, course_key) permissions_error_response = JsonResponse({"error": _("Insufficient permissions")}, 403) if (requester_perms & STUDIO_VIEW_USERS) or (email == request.user.email): # This user has permissions to at least view the list of users or is editing themself pass else: # This user is not even allowed to know who the authorized users are. return permissions_error_response try: user = User.objects.get(email=email) except Exception: # pylint: disable=broad-except msg = { "error": _(u"Could not find user by email address '{email}'.").format(email=email), } return JsonResponse(msg, 404) is_library = isinstance(course_key, LibraryLocator) # Ordered list of roles: can always move self to the right, but need STUDIO_EDIT_ROLES to move any user left if is_library: role_hierarchy = (CourseInstructorRole, CourseStaffRole, LibraryUserRole) else: role_hierarchy = (CourseInstructorRole, CourseStaffRole) if request.method == "GET": # just return info about the user msg = { "email": user.email, "active": user.is_active, "role": None, } # what's the highest role that this user has? (How should this report global staff?) for role in role_hierarchy: if role(course_key).has_user(user): msg["role"] = role.ROLE break return JsonResponse(msg) # All of the following code is for editing/promoting/deleting users. # Check that the user has STUDIO_EDIT_ROLES permission or is editing themselves: if not ((requester_perms & STUDIO_EDIT_ROLES) or (user.id == request.user.id)): return permissions_error_response if request.method == "DELETE": new_role = None else: # only other operation supported is to promote/demote a user by changing their role: # role may be None or "" (equivalent to a DELETE request) but must be set. # Check that the new role was specified: if "role" in request.json or "role" in request.POST: new_role = request.json.get("role", request.POST.get("role")) else: return JsonResponse({"error": _("No `role` specified.")}, 400) # can't modify an inactive user but can remove it if not (user.is_active or new_role is None): msg = { "error": _(u'User {email} has registered but has not yet activated his/her account.').format(email=email), } return JsonResponse(msg, 400) old_roles = set() role_added = False for role_type in role_hierarchy: role = role_type(course_key) if role_type.ROLE == new_role: if (requester_perms & STUDIO_EDIT_ROLES) or (user.id == request.user.id and old_roles): # User has STUDIO_EDIT_ROLES permission or # is currently a member of a higher role, and is thus demoting themself auth.add_users(request.user, role, user) role_added = True else: return permissions_error_response elif role.has_user(user, check_user_activation=False): # Remove the user from this old role: old_roles.add(role) if new_role and not role_added: return JsonResponse({"error": _("Invalid `role` specified.")}, 400) for role in old_roles: if isinstance(role, CourseInstructorRole) and role.users_with_role().count() == 1: msg = {"error": _("You may not remove the last Admin. Add another Admin first.")} return JsonResponse(msg, 400) auth.remove_users(request.user, role, user) if new_role and not is_library: # The user may be newly added to this course. # auto-enroll the user in the course so that "View Live" will work. CourseEnrollment.enroll(user, course_key) return JsonResponse()
def _course_team_user(request, locator, email): """ Handle the add, remove, promote, demote requests ensuring the requester has authority """ # check that logged in user has permissions to this item if has_course_access(request.user, locator, role=CourseInstructorRole): # instructors have full permissions pass elif has_course_access(request.user, locator, role=CourseStaffRole) and email == request.user.email: # staff can only affect themselves pass else: msg = { "error": _("Insufficient permissions") } return JsonResponse(msg, 400) try: user = User.objects.get(email=email) except Exception: msg = { "error": _("Could not find user by email address '{email}'.").format(email=email), } return JsonResponse(msg, 404) # role hierarchy: globalstaff > "instructor" > "staff" (in a course) if request.method == "GET": # just return info about the user msg = { "email": user.email, "active": user.is_active, "role": None, } # what's the highest role that this user has? (How should this report global staff?) for role in [CourseInstructorRole(locator), CourseStaffRole(locator)]: if role.has_user(user): msg["role"] = role.ROLE break return JsonResponse(msg) # can't modify an inactive user if not user.is_active: msg = { "error": _('User {email} has registered but has not yet activated his/her account.').format(email=email), } return JsonResponse(msg, 400) if request.method == "DELETE": try: try_remove_instructor(request, locator, user) except CannotOrphanCourse as oops: return JsonResponse(oops.msg, 400) auth.remove_users(request.user, CourseStaffRole(locator), user) return JsonResponse() # all other operations require the requesting user to specify a role role = request.json.get("role", request.POST.get("role")) if role is None: return JsonResponse({"error": _("`role` is required")}, 400) old_location = loc_mapper().translate_locator_to_location(locator) if role == "instructor": if not has_course_access(request.user, locator, role=CourseInstructorRole): msg = { "error": _("Only instructors may create other instructors") } return JsonResponse(msg, 400) auth.add_users(request.user, CourseInstructorRole(locator), user) # auto-enroll the course creator in the course so that "View Live" will work. CourseEnrollment.enroll(user, old_location.course_id) elif role == "staff": # add to staff regardless (can't do after removing from instructors as will no longer # be allowed) auth.add_users(request.user, CourseStaffRole(locator), user) try: try_remove_instructor(request, locator, user) except CannotOrphanCourse as oops: return JsonResponse(oops.msg, 400) # auto-enroll the course creator in the course so that "View Live" will work. CourseEnrollment.enroll(user, old_location.course_id) return JsonResponse()
def test_remove_user_from_group_requires_authenticated(self): with self.assertRaises(PermissionDenied): self.admin.is_authenticated = mock.Mock(return_value=False) remove_users(self.admin, CourseCreatorRole(), self.user)