-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New course creator group. #266
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
318372f
Introduce course creator group.
2c60a7d
pep8 cleanup
190c07d
Add smoke coverage for add and remove of course group permissions.
4a697a8
Verify that caller of add or remove from creator group is staff.
e487521
Update for change in add_user_to_creator_group API.
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| """ | ||
| Tests authz.py | ||
| """ | ||
| import mock | ||
|
|
||
| from django.test import TestCase | ||
| from django.contrib.auth.models import User | ||
| from django.core.exceptions import PermissionDenied | ||
|
|
||
| from auth.authz import add_user_to_creator_group, remove_user_from_creator_group, is_user_in_creator_group,\ | ||
| create_all_course_groups, add_user_to_course_group, STAFF_ROLE_NAME, INSTRUCTOR_ROLE_NAME,\ | ||
| is_user_in_course_group_role, remove_user_from_course_group | ||
|
|
||
|
|
||
| class CreatorGroupTest(TestCase): | ||
| """ | ||
| Tests for the course creator group. | ||
| """ | ||
|
|
||
| def setUp(self): | ||
| """ Test case setup """ | ||
| self.user = User.objects.create_user('testuser', 'test+courses@edx.org', 'foo') | ||
| self.admin = User.objects.create_user('Mark', 'admin+courses@edx.org', 'foo') | ||
| self.admin.is_staff = True | ||
|
|
||
| def test_creator_group_not_enabled(self): | ||
| """ | ||
| Tests that is_user_in_creator_group always returns True if ENABLE_CREATOR_GROUP | ||
| and DISABLE_COURSE_CREATION are both not turned on. | ||
| """ | ||
| self.assertTrue(is_user_in_creator_group(self.user)) | ||
|
|
||
| def test_creator_group_enabled_but_empty(self): | ||
| """ Tests creator group feature on, but group empty. """ | ||
| with mock.patch.dict('django.conf.settings.MITX_FEATURES', {"ENABLE_CREATOR_GROUP": True}): | ||
| self.assertFalse(is_user_in_creator_group(self.user)) | ||
|
|
||
| # Make user staff. This will cause is_user_in_creator_group to return True. | ||
| self.user.is_staff = True | ||
| self.assertTrue(is_user_in_creator_group(self.user)) | ||
|
|
||
| def test_creator_group_enabled_nonempty(self): | ||
| """ Tests creator group feature on, user added. """ | ||
| with mock.patch.dict('django.conf.settings.MITX_FEATURES', {"ENABLE_CREATOR_GROUP": True}): | ||
| self.assertTrue(add_user_to_creator_group(self.admin, self.user)) | ||
| self.assertTrue(is_user_in_creator_group(self.user)) | ||
|
|
||
| # check that a user who has not been added to the group still returns false | ||
| user_not_added = User.objects.create_user('testuser2', 'test+courses2@edx.org', 'foo2') | ||
| self.assertFalse(is_user_in_creator_group(user_not_added)) | ||
|
|
||
| # remove first user from the group and verify that is_user_in_creator_group now returns false | ||
| remove_user_from_creator_group(self.admin, self.user) | ||
| self.assertFalse(is_user_in_creator_group(self.user)) | ||
|
|
||
| def test_add_user_not_authenticated(self): | ||
| """ | ||
| Tests that adding to creator group fails if user is not authenticated | ||
| """ | ||
| self.user.is_authenticated = False | ||
| self.assertFalse(add_user_to_creator_group(self.admin, self.user)) | ||
|
|
||
| def test_add_user_not_active(self): | ||
| """ | ||
| Tests that adding to creator group fails if user is not active | ||
| """ | ||
| self.user.is_active = False | ||
| self.assertFalse(add_user_to_creator_group(self.admin, self.user)) | ||
|
|
||
| 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.MITX_FEATURES', | ||
| {'DISABLE_COURSE_CREATION': True, "ENABLE_CREATOR_GROUP": True}): | ||
| # Add user to creator group. | ||
| self.assertTrue(add_user_to_creator_group(self.admin, self.user)) | ||
|
|
||
| # DISABLE_COURSE_CREATION overrides (user is not marked as staff). | ||
| self.assertFalse(is_user_in_creator_group(self.user)) | ||
|
|
||
| # Mark as staff. Now is_user_in_creator_group returns true. | ||
| self.user.is_staff = True | ||
| self.assertTrue(is_user_in_creator_group(self.user)) | ||
|
|
||
| # Remove user from creator group. is_user_in_creator_group still returns true because is_staff=True | ||
| remove_user_from_creator_group(self.admin, self.user) | ||
| self.assertTrue(is_user_in_creator_group(self.user)) | ||
|
|
||
| def test_add_user_to_group_requires_staff_access(self): | ||
| with self.assertRaises(PermissionDenied): | ||
| self.admin.is_staff = False | ||
| add_user_to_creator_group(self.admin, self.user) | ||
|
|
||
| with self.assertRaises(PermissionDenied): | ||
| add_user_to_creator_group(self.user, self.user) | ||
|
|
||
| def test_add_user_to_group_requires_active(self): | ||
| with self.assertRaises(PermissionDenied): | ||
| self.admin.is_active = False | ||
| add_user_to_creator_group(self.admin, self.user) | ||
|
|
||
| def test_add_user_to_group_requires_authenticated(self): | ||
| with self.assertRaises(PermissionDenied): | ||
| self.admin.is_authenticated = False | ||
| add_user_to_creator_group(self.admin, self.user) | ||
|
|
||
| def test_remove_user_from_group_requires_staff_access(self): | ||
| with self.assertRaises(PermissionDenied): | ||
| self.admin.is_staff = False | ||
| remove_user_from_creator_group(self.admin, self.user) | ||
|
|
||
| def test_remove_user_from_group_requires_active(self): | ||
| with self.assertRaises(PermissionDenied): | ||
| self.admin.is_active = False | ||
| remove_user_from_creator_group(self.admin, self.user) | ||
|
|
||
| def test_remove_user_from_group_requires_authenticated(self): | ||
| with self.assertRaises(PermissionDenied): | ||
| self.admin.is_authenticated = False | ||
| remove_user_from_creator_group(self.admin, self.user) | ||
|
|
||
|
|
||
| class CourseGroupTest(TestCase): | ||
| """ | ||
| Tests for instructor and staff groups for a particular course. | ||
| """ | ||
|
|
||
| def setUp(self): | ||
| """ Test case setup """ | ||
| self.creator = User.objects.create_user('testcreator', 'testcreator+courses@edx.org', 'foo') | ||
| self.staff = User.objects.create_user('teststaff', 'teststaff+courses@edx.org', 'foo') | ||
| self.location = 'i4x', 'mitX', '101', 'course', 'test' | ||
|
|
||
| def test_add_user_to_course_group(self): | ||
| """ | ||
| Tests adding user to course group (happy path). | ||
| """ | ||
| # Create groups for a new course (and assign instructor role to the creator). | ||
| self.assertFalse(is_user_in_course_group_role(self.creator, self.location, INSTRUCTOR_ROLE_NAME)) | ||
| create_all_course_groups(self.creator, self.location) | ||
| self.assertTrue(is_user_in_course_group_role(self.creator, self.location, INSTRUCTOR_ROLE_NAME)) | ||
|
|
||
| # Add another user to the staff role. | ||
| self.assertFalse(is_user_in_course_group_role(self.staff, self.location, STAFF_ROLE_NAME)) | ||
| self.assertTrue(add_user_to_course_group(self.creator, self.staff, self.location, STAFF_ROLE_NAME)) | ||
| self.assertTrue(is_user_in_course_group_role(self.staff, self.location, STAFF_ROLE_NAME)) | ||
|
|
||
| def test_add_user_to_course_group_permission_denied(self): | ||
| """ | ||
| Verifies PermissionDenied if caller of add_user_to_course_group is not instructor role. | ||
| """ | ||
| create_all_course_groups(self.creator, self.location) | ||
| with self.assertRaises(PermissionDenied): | ||
| add_user_to_course_group(self.staff, self.staff, self.location, STAFF_ROLE_NAME) | ||
|
|
||
| def test_remove_user_from_course_group(self): | ||
| """ | ||
| Tests removing user from course group (happy path). | ||
| """ | ||
| create_all_course_groups(self.creator, self.location) | ||
|
|
||
| self.assertTrue(add_user_to_course_group(self.creator, self.staff, self.location, STAFF_ROLE_NAME)) | ||
| self.assertTrue(is_user_in_course_group_role(self.staff, self.location, STAFF_ROLE_NAME)) | ||
|
|
||
| remove_user_from_course_group(self.creator, self.staff, self.location, STAFF_ROLE_NAME) | ||
| self.assertFalse(is_user_in_course_group_role(self.staff, self.location, STAFF_ROLE_NAME)) | ||
|
|
||
| remove_user_from_course_group(self.creator, self.creator, self.location, INSTRUCTOR_ROLE_NAME) | ||
| self.assertFalse(is_user_in_course_group_role(self.creator, self.location, INSTRUCTOR_ROLE_NAME)) | ||
|
|
||
| def test_remove_user_from_course_group_permission_denied(self): | ||
| """ | ||
| Verifies PermissionDenied if caller of remove_user_from_course_group is not instructor role. | ||
| """ | ||
| create_all_course_groups(self.creator, self.location) | ||
| with self.assertRaises(PermissionDenied): | ||
| remove_user_from_course_group(self.staff, self.staff, self.location, STAFF_ROLE_NAME) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. I think we are missing some permission assertions. If this function can be called from a webapp, the interactive user (aka Mark) needs to be authenticated and authorized to add/remove people from the COURSE_CREATOR_GROUP_NAME.
I wonder if we need to assert that caller.is_staff = True here (as well as on the corresponding 'add' method)