def condition(context): AccessControlList = apps.get_model(app_label='acls', model_name='AccessControlList') Model = apps.get_model(app_label=app_label, model_name=model_name) try: request = context.request except AttributeError: # Simple request extraction failed. Might not be a view context. # Try alternate method. try: request = Variable('request').resolve(context) except VariableDoesNotExist: # There is no request variable, most probable a 500 in a test # view. Don't return any resolved links then. logger.warning( 'No request variable, aborting cascade resolution') return () if view_permission: try: Permission.check_user_permissions( permissions=(view_permission, ), user=request.user) except PermissionDenied: pass else: return True queryset = AccessControlList.objects.restrict_queryset( permission=object_permission, user=request.user, queryset=Model.objects.all()) return queryset.count() > 0
def restrict_queryset(self, permission, queryset, user): if not user.is_authenticated: return queryset.none() # Check directly granted permission via a role try: Permission.check_user_permissions(permissions=(permission, ), user=user) except PermissionDenied: acl_filters = self._get_acl_filters( queryset=queryset, stored_permission=permission.stored_permission, user=user) final_query = None for acl_filter in acl_filters: if final_query is None: final_query = acl_filter else: final_query = final_query | acl_filter return queryset.filter(final_query) else: # User has direct permission assignment via a role, is superuser or # is staff. Return the entire queryset. return queryset
def dispatch(self, request, *args, **kwargs): view_permission = self.get_view_permission() if view_permission: Permission.check_user_permissions(permissions=(view_permission, ), user=self.request.user) return super(ViewPermissionCheckMixin, self).dispatch(request, *args, **kwargs)
def has_permission(self, request, view): required_permissions = getattr(view, 'mayan_view_permissions', {}).get(request.method, None) if required_permissions: try: Permission.check_user_permissions( permissions=required_permissions, user=request.user) except PermissionDenied: return False else: return True else: return True
def validate(self, attrs): attrs['content_type'] = ContentType.objects.get_for_model( model=self.context['content_object']) attrs['object_id'] = self.context['content_object'].pk try: attrs['role'] = Role.objects.get(pk=attrs.pop('role_pk')) except Role.DoesNotExist as exception: raise ValidationError(force_text(exception)) permissions_pk_list = attrs.pop('permissions_pk_list', None) permissions_result = [] if permissions_pk_list: for pk in permissions_pk_list.split(','): try: permission = Permission.get(pk=pk) except KeyError: raise ValidationError(_('No such permission: %s') % pk) else: # Accumulate valid stored permission pks permissions_result.append(permission.pk) instance = AccessControlList(**attrs) try: instance.full_clean() except DjangoValidationError as exception: raise ValidationError(exception) # Add a queryset of valid stored permissions so that they get added # after the ACL gets created. attrs['permissions'] = StoredPermission.objects.filter( pk__in=permissions_result) return attrs
def setUp(self): super(MenuClassTestCase, self).setUp() self.test_object = self._test_case_group self.add_test_view(test_object=self.test_object) self.namespace = PermissionNamespace(TEST_PERMISSION_NAMESPACE_NAME, TEST_PERMISSION_NAMESPACE_TEXT) self.test_permission = self.namespace.add_permission( name=TEST_PERMISSION_NAME, label=TEST_PERMISSION_LABEL) self.menu = Menu(name=TEST_MENU_NAME) self.sub_menu = Menu(name=TEST_SUBMENU_NAME) self.link = Link(text=TEST_LINK_TEXT, view=TEST_VIEW_NAME) Permission.invalidate_cache()
def restrict_queryset(self, permission, queryset, user): # /opt/mayan-edms/lib/python3.7/site-packages/mayan/apps/acls/managers.py if queryset: try: queryset[0] except Exception as ex: print("---------------------------") print("queryset = ", queryset) print("queryset[0] = ", ex) print("required permission = ", permission) print("User got permission? ", permission.stored_permission.user_has_this(user=user)) print("user.is_authenticated = ", user.is_authenticated) print("---------------------------") if not user.is_authenticated: return queryset.none() if str(queryset) == "documents.DocumentPage.valid": return queryset # Check directly granted permission via a role try: Permission.check_user_permissions(permissions=(permission, ), user=user) except PermissionDenied: acl_filters = self._get_acl_filters( queryset=queryset, stored_permission=permission.stored_permission, user=user) final_query = None for acl_filter in acl_filters: if final_query is None: final_query = acl_filter else: final_query = final_query | acl_filter return queryset.filter(final_query) else: # User has direct permission assignment via a role, is superuser or # is staff. Return the entire queryset. return queryset
def setUp(self): super(LinkClassTestCase, self).setUp() self.test_object = self._test_case_group self.add_test_view(test_object=self.test_object) self.namespace = PermissionNamespace( label=TEST_PERMISSION_NAMESPACE_TEXT, name=TEST_PERMISSION_NAMESPACE_NAME) self.test_permission = self.namespace.add_permission( name=TEST_PERMISSION_NAME, label=TEST_PERMISSION_LABEL) ModelPermission.register(model=self.test_object._meta.model, permissions=(self.test_permission, )) self.link = Link(text=TEST_LINK_TEXT, view=TEST_VIEW_NAME) Permission.invalidate_cache()
def validate(self, attrs): permissions_pk_list = attrs.pop('permission_pk', None) permissions_result = [] if permissions_pk_list: for pk in permissions_pk_list.split(','): try: permission = Permission.get(pk=pk) except KeyError: raise ValidationError(_('No such permission: %s') % pk) else: # Accumulate valid stored permission pks permissions_result.append(permission.pk) attrs['permissions'] = StoredPermission.objects.filter( pk__in=permissions_result) return attrs
def resolve(self, context=None, request=None, resolved_object=None): if not context and not request: raise ImproperlyConfigured( 'Must provide a context or a request in order to resolve the ' 'link.') AccessControlList = apps.get_model(app_label='acls', model_name='AccessControlList') if not context: context = RequestContext(request=request) if not request: # Try to get the request object the faster way and fallback to the # slower method. try: request = context.request except AttributeError: request = Variable('request').resolve(context=context) current_path = request.META['PATH_INFO'] current_view_name = resolve(current_path).view_name # ACL is tested agains the resolved_object or just {{ object }} if not if not resolved_object: try: resolved_object = Variable('object').resolve(context=context) except VariableDoesNotExist: pass # If this link has a required permission check that the user has it # too if self.permissions: if resolved_object: try: AccessControlList.objects.check_access( obj=resolved_object, permissions=self.permissions, user=request.user) except PermissionDenied: return None else: try: Permission.check_user_permissions( permissions=self.permissions, user=request.user) except PermissionDenied: return None # Check to see if link has conditional display function and only # display it if the result of the conditional display function is # True if self.condition: if not self.condition(context=context): return None resolved_link = ResolvedLink(current_view_name=current_view_name, link=self) if self.view: view_name = Variable('"{}"'.format(self.view)) if isinstance(self.args, list) or isinstance(self.args, tuple): # TODO: Don't check for instance check for iterable in try/except # block. This update required changing all 'args' argument in # links.py files to be iterables and not just strings. args = [Variable(var=arg) for arg in self.args] else: args = [Variable(var=self.args)] # If we were passed an instance of the view context object we are # resolving, inject it into the context. This help resolve links for # object lists. if resolved_object: context['resolved_object'] = resolved_object try: kwargs = self.kwargs(context) except TypeError: # Is not a callable kwargs = self.kwargs kwargs = {key: Variable(value) for key, value in kwargs.items()} # Use Django's exact {% url %} code to resolve the link node = URLNode(view_name=view_name, args=args, kwargs=kwargs, asvar=None) try: resolved_link.url = node.render(context=context) except VariableDoesNotExist as exception: """Not critical, ignore""" logger.debug( 'VariableDoesNotExist when resolving link "%s" URL; %s', self.text, exception) except Exception as exception: logger.error('Error resolving link "%s" URL; %s', self.text, exception) elif self.url: resolved_link.url = self.url # This is for links that should be displayed but that are not clickable if self.conditional_disable: resolved_link.disabled = self.conditional_disable(context=context) else: resolved_link.disabled = False # Lets a new link keep the same URL query string of the current URL if self.keep_query: # Sometimes we are required to remove a key from the URL QS parsed_url = furl( force_str(request.get_full_path() or request.META.get( 'HTTP_REFERER', reverse(setting_home_view.value)))) for key in self.remove_from_query: try: parsed_url.query.remove(key) except KeyError: pass # Use the link's URL but with the previous URL querystring new_url = furl(url=resolved_link.url) new_url.args = parsed_url.querystr resolved_link.url = new_url.url resolved_link.context = context return resolved_link