def test_on_auth_complete(self): """ Verify the function receives the auth_complete_signal signal, and updates course permissions. """ # No initial permissions permissions.set_user_course_permissions(self.user, []) self.assertFalse( permissions.user_can_view_course(self.user, self.course_id)) # Permissions can be granted id_token = { claim: [self.course_id] for claim in settings.COURSE_PERMISSIONS_CLAIMS } EdXOpenIdConnect.auth_complete_signal.send(None, user=self.user, id_token=id_token) self.assertTrue( permissions.user_can_view_course(self.user, self.course_id)) # Permissions can be revoked revoked_access_id_token = { claim: list() for claim in settings.COURSE_PERMISSIONS_CLAIMS } EdXOpenIdConnect.auth_complete_signal.send( None, user=self.user, id_token=revoked_access_id_token) self.assertFalse( permissions.user_can_view_course(self.user, self.course_id))
def test_user_can_view_course_refresh(self, mock_refresh): """ Verify user_can_view_course refreshes permissions if they are not present in the cache. """ # If permissions have not been set, or have expired, they should be refreshed self.assertFalse(permissions.user_can_view_course(self.user, self.course_id)) mock_refresh.assert_called_with(self.user) self.assertFalse(permissions.user_can_view_course(self.user, self.course_id))
def test_user_can_view_course(self): """ Verify basic functionality of user_can_view_course. """ # A user with no permissions should not be able to view the course. permissions.set_user_course_permissions(self.user, []) self.assertFalse(permissions.user_can_view_course(self.user, self.course_id)) # The user should be able to view the course after the permissions have been set. permissions.set_user_course_permissions(self.user, [self.course_id]) self.assertTrue(permissions.user_can_view_course(self.user, self.course_id))
def test_superuser_can_view_course(self): """ Verify that superusers can view everything. """ user = self.user user.is_superuser = True user.save() # With no permissions set, a superuser should still be able to view a course. permissions.set_user_course_permissions(user, []) self.assertTrue(permissions.user_can_view_course(user, self.course_id)) # With permissions set, a superuser should be able to view a course # (although the individual permissions don't matter). permissions.set_user_course_permissions(user, [self.course_id]) self.assertTrue(permissions.user_can_view_course(user, self.course_id))
def test_on_auth_complete(self): """ Verify the function receives the auth_complete_signal signal, and updates course permissions. """ # No initial permissions permissions.set_user_course_permissions(self.user, []) self.assertFalse(permissions.user_can_view_course(self.user, self.course_id)) # Permissions can be granted id_token = {claim: [self.course_id] for claim in settings.COURSE_PERMISSIONS_CLAIMS} EdXOpenIdConnect.auth_complete_signal.send(None, user=self.user, id_token=id_token) self.assertTrue(permissions.user_can_view_course(self.user, self.course_id)) # Permissions can be revoked revoked_access_id_token = {claim: list() for claim in settings.COURSE_PERMISSIONS_CLAIMS} EdXOpenIdConnect.auth_complete_signal.send(None, user=self.user, id_token=revoked_access_id_token) self.assertFalse(permissions.user_can_view_course(self.user, self.course_id))
def user_can_view_learners_in_course(user, course_id): """ Returns whether or not a user can access a particular course within the learner API. """ try: user_has_permission = user_can_view_course(user, course_id) except UserNotAssociatedWithBackendError: user_has_permission = False return user_has_permission
def user_can_view_learners_in_course(user, course_id): """ Returns whether or not a user can access a particular course within the learner API. """ try: user_has_permission = user_can_view_course(user, course_id) except PermissionsRetrievalFailedError: logger.exception( "Unable to retrieve course permissions for username=%s in v0", user.username, ) user_has_permission = False return user_has_permission
def test_revoke_user_permissions(self): courses = [self.course_id] permissions_key = 'course_permissions_{}'.format(self.user.pk) update_key = 'course_permissions_updated_at_{}'.format(self.user.pk) # Set permissions and verify cache is updated permissions.set_user_course_permissions(self.user, courses) self.assertListEqual(cache.get(permissions_key), courses) self.assertIsNotNone(cache.get(update_key)) self.assertTrue(permissions.user_can_view_course(self.user, self.course_id)) # Revoke permissions and verify cache cleared permissions.revoke_user_course_permissions(self.user) self.assertIsNone(cache.get(permissions_key)) self.assertIsNone(cache.get(update_key))
def test_set_user_course_permissions(self): courses = [] permissions.set_user_course_permissions(self.user, courses) permissions_key = 'course_permissions_{}'.format(self.user.pk) self.assertListEqual(cache.get(permissions_key), courses) update_key = 'course_permissions_updated_at_{}'.format(self.user.pk) last_updated = cache.get(update_key) self.assertIsNotNone(last_updated) courses = [self.course_id] permissions.set_user_course_permissions(self.user, courses) self.assertListEqual(cache.get(permissions_key), courses) self.assertGreater(cache.get(update_key), last_updated) self.assertTrue(permissions.user_can_view_course(self.user, self.course_id))
def test_refresh_user_course_permissions(self): """ Verify course permissions are refreshed from the auth server. """ courses = [self.course_id] # Make sure the cache is completely empty cache.clear() # If user is not associated with the edX OIDC backend, an exception should be raised. self.assertRaises(UserNotAssociatedWithBackendError, permissions.refresh_user_course_permissions, self.user) # Add backend association usa = G(UserSocialAuth, user=self.user, provider='edx-oidc', extra_data={}) # An empty access token should raise an error self.assertRaises(InvalidAccessTokenError, permissions.refresh_user_course_permissions, self.user) # Set the access token usa.extra_data = {'access_token': '1234'} usa.save() # Refreshing the permissions should populate the cache and return the updated permissions actual = permissions.refresh_user_course_permissions(self.user) self.assertListEqual(list(actual), courses) # Verify the courses are stored in the cache permissions_key = 'course_permissions_{}'.format(self.user.pk) self.assertListEqual(cache.get(permissions_key), courses) # Verify the updated time is stored in the cache update_key = 'course_permissions_updated_at_{}'.format(self.user.pk) self.assertIsNotNone(cache.get(update_key)) # Sanity check: verify the user can view the course self.assertTrue( permissions.user_can_view_course(self.user, self.course_id))
def assertViewClearsPermissions(self, view_name): self.login() user = self.user course_id = 'edX/DemoX/Demo_Course' courses = [course_id] permissions_key = 'course_permissions_{}'.format(user.pk) update_key = 'course_permissions_updated_at_{}'.format(user.pk) # Set permissions and verify cache is updated set_user_course_permissions(user, courses) self.assertListEqual(cache.get(permissions_key), courses) self.assertIsNotNone(cache.get(update_key)) self.assertTrue(user_can_view_course(user, course_id)) # Logout by GETing the URL. self.client.logout() doesn't actually call this view. response = self.client.get(reverse(view_name)) # Verify cache cleared self.assertIsNone(cache.get(permissions_key)) self.assertIsNone(cache.get(update_key)) return response
def test_refresh_user_course_permissions(self): """ Verify course permissions are refreshed from the auth server. """ courses = [self.course_id] # Make sure the cache is completely empty cache.clear() # If user is not associated with the edX OIDC backend, an exception should be raised. self.assertRaises(UserNotAssociatedWithBackendError, permissions.refresh_user_course_permissions, self.user) # Add backend association usa = G(UserSocialAuth, user=self.user, provider='edx-oidc', extra_data={}) # An empty access token should raise an error self.assertRaises(InvalidAccessTokenError, permissions.refresh_user_course_permissions, self.user) # Set the access token usa.extra_data = {'access_token': '1234'} usa.save() # Refreshing the permissions should populate the cache and return the updated permissions actual = permissions.refresh_user_course_permissions(self.user) self.assertListEqual(list(actual), courses) # Verify the courses are stored in the cache permissions_key = 'course_permissions_{}'.format(self.user.pk) self.assertListEqual(cache.get(permissions_key), courses) # Verify the updated time is stored in the cache update_key = 'course_permissions_updated_at_{}'.format(self.user.pk) self.assertIsNotNone(cache.get(update_key)) # Sanity check: verify the user can view the course self.assertTrue(permissions.user_can_view_course(self.user, self.course_id))
def can_view(self): return permissions.user_can_view_course(self.user, self.course_id)