def revoke_permission(self, permission, group, forum): """Revoke a permission from a group in the specified forum.""" if self.apply_updates: remove_perm(permission, group, forum) self.stdout.write( f"REMOVED {permission} for group {group.name} in forum {forum.pk} ({forum.slug})" )
def post(self, request, *args, **kwargs): """ We lock all forums of this course. Default group shouldn't have writing permissions anymore. The LTIContex will then be marked as blocked. """ lti_context = self.get_object().lti_contexts.get( id=self.request.forum_permission_handler.current_lti_context_id) default_group = lti_context.get_base_group() # remove all permissions for each forum of this LTIContext for forum in self.get_forums_list(): # pylint: disable=not-an-iterable for perm in DEFAULT_FORUM_BASE_WRITE_PERMISSIONS: remove_perm(perm, default_group, forum) # mark this course as locked lti_context.is_marked_locked = True lti_context.save() return HttpResponseRedirect(self.get_success_url())
def test_knows_precedence_of_permissions_is_user_group_allusers(self): # Setup machina_settings.DEFAULT_AUTHENTICATED_USER_FORUM_PERMISSIONS = [] user = UserFactory.create() group = GroupFactory.create() user.groups.add(group) # 'res' in the following dict means 'expected result' test_list = [ # Differing user settings, all_auth and group to True { 'level': 'global', 'all_auth': True, 'group': True, 'user': True, 'res': True }, { 'level': 'global', 'all_auth': True, 'group': True, 'user': '******', 'res': True }, { 'level': 'global', 'all_auth': True, 'group': True, 'user': False, 'res': False }, # Differing user settings, all_auto True, group permission False { 'level': 'global', 'all_auth': True, 'group': False, 'user': True, 'res': True }, { 'level': 'global', 'all_auth': True, 'group': False, 'user': '******', 'res': False }, { 'level': 'global', 'all_auth': True, 'group': False, 'user': False, 'res': False }, # Differing user settings, all_auth and group on False { 'level': 'global', 'all_auth': False, 'group': False, 'user': True, 'res': True }, { 'level': 'global', 'all_auth': False, 'group': False, 'user': '******', 'res': False }, { 'level': 'global', 'all_auth': False, 'group': False, 'user': False, 'res': False }, # Differing user settings, all_auth False, group permission True { 'level': 'global', 'all_auth': False, 'group': True, 'user': True, 'res': True }, { 'level': 'global', 'all_auth': False, 'group': True, 'user': '******', 'res': True }, { 'level': 'global', 'all_auth': False, 'group': True, 'user': False, 'res': False }, # Now on forum level instead of global # Differing user settings, all_auth and group to True { 'level': 'forum', 'all_auth': True, 'group': True, 'user': True, 'res': True }, { 'level': 'forum', 'all_auth': True, 'group': True, 'user': '******', 'res': True }, { 'level': 'forum', 'all_auth': True, 'group': True, 'user': False, 'res': False }, # Differing user settings, all_auto True, group permission False { 'level': 'forum', 'all_auth': True, 'group': False, 'user': True, 'res': True }, { 'level': 'forum', 'all_auth': True, 'group': False, 'user': '******', 'res': False }, { 'level': 'forum', 'all_auth': True, 'group': False, 'user': False, 'res': False }, # Differing user settings, all_auth and group on False { 'level': 'forum', 'all_auth': False, 'group': False, 'user': True, 'res': True }, { 'level': 'forum', 'all_auth': False, 'group': False, 'user': '******', 'res': False }, { 'level': 'forum', 'all_auth': False, 'group': False, 'user': False, 'res': False }, # Differing user settings, all_auth False, group permission True { 'level': 'forum', 'all_auth': False, 'group': True, 'user': True, 'res': True }, { 'level': 'forum', 'all_auth': False, 'group': True, 'user': '******', 'res': True }, { 'level': 'forum', 'all_auth': False, 'group': True, 'user': False, 'res': False }, ] # loop over test dict: for dct in test_list: # set each permission as instructed in the dict if dct['level'] == 'global': forum_val = None else: forum_val = self.forum assign_perm('can_read_forum', ALL_AUTHENTICATED_USERS, forum_val, has_perm=dct['all_auth']) assign_perm('can_read_forum', group, forum_val, has_perm=dct['group']) if dct['user'] != 'unset': assign_perm('can_read_forum', user, forum_val, has_perm=dct['user']) checker = ForumPermissionChecker(user) # test if value is as the expected value assert checker.has_perm('can_read_forum', forum_val) == dct['res'] # unset the set permissions so the next iteration goes in blankly remove_perm('can_read_forum', ALL_AUTHENTICATED_USERS, forum_val) remove_perm('can_read_forum', group, forum_val) if dct['user'] != 'unset': remove_perm('can_read_forum', user, forum_val)
def _do_on_login(self, lti_request: LTI) -> HttpResponse: """Process the request when the user is logged in via LTI""" # Get or create the LTIContext model associated with the current LTI launch request context_id = lti_request.get_param("context_id") if not context_id: return HttpResponseBadRequest( "LTI parameter context_id is mandatory") context, _context_created = LTIContext.objects.get_or_create( lti_id=context_id, lti_consumer=lti_request.get_consumer()) # Synchronize the user groups related to the current LTI context context.sync_user_groups(self.request.user, lti_request.roles) # Store the current user LTI context in session self.request.session[SESSION_LTI_CONTEXT_ID] = context.id # Get or create the requested forum forum_uuid = self.kwargs["uuid"] # The requested forum must exist in this context or needs to be created try: forum = Forum.objects.get( lti_id=forum_uuid, type=Forum.FORUM_POST, lti_contexts__id=context.id, ) # If course is locked, security to remove forum permission on default group # only needed if the course has been marked outside web navigation if context.is_marked_locked and any( item in DEFAULT_FORUM_BASE_READ_PERMISSIONS for item in GroupForumPermission.objects.filter( forum=forum, group=context.get_base_group(), has_perm=True).values_list("permission__codename", flat=True)): for perm in DEFAULT_FORUM_BASE_WRITE_PERMISSIONS: remove_perm(perm, context.get_base_group(), forum) except Forum.DoesNotExist: # Check if this uuid exists for another context.id to reuse its name as a # default value (enables copy and paste) forum_same_uuid = (Forum.objects.only("name").filter( lti_id=forum_uuid, type=Forum.FORUM_POST).order_by("-created").first()) forum = Forum.objects.create( lti_id=forum_uuid, type=Forum.FORUM_POST, name=forum_same_uuid.name if forum_same_uuid else lti_request.context_title, ) logger.debug("Forum %s created", forum_uuid) self._init_forum(forum, context) if not getattr(self.request.user, "public_username", ""): redirect_url = reverse("forum.username.change") else: redirect_url = reverse("forum:forum", kwargs={ "slug": forum.slug, "pk": forum.id }) response = HttpResponseRedirect(redirect_url) locale = lti_request.get_param("launch_presentation_locale") if locale: logger.debug("Course locale detected %s", locale) translation.activate(locale) response.set_cookie(settings.LANGUAGE_COOKIE_NAME, locale) return response