def has_permission(self, request: Request, view) -> bool: from rest_framework.viewsets import ViewSetMixin if bypass_permissions(request): return True scopes_required = get_required_scopes(view) component = self.get_component(view) if not self.permission_fields: return request.jwt_auth.has_auth(scopes_required, component) main_resource = self.get_main_resource() if view.action == "create": if view.__class__ is main_resource: main_object_data = request.data else: main_object_url = request.data[view.permission_main_object] main_object_path = urlparse(main_object_url).path main_object = get_resource_for_path(main_object_path) main_object_data = self.format_data(main_object, request) fields = self.get_fields(main_object_data) return request.jwt_auth.has_auth(scopes_required, component, **fields) # detect if this is an unsupported method - if it's a viewset and the # action was not mapped, it's not supported and DRF will catch it if view.action is None and isinstance(view, ViewSetMixin): return True # by default - check if the action is allowed at all return request.jwt_auth.has_auth(scopes_required, component)
def has_permission(self, request: Request, view) -> bool: # permission checks run before the handler is determined. if there is no handler, # a "method is not allowed" must be raised, not an HTTP 403 (see #385) # this implementation works for both APIView and viewsets has_handler = hasattr(view, request.method.lower()) if not has_handler: view.http_method_not_allowed(request) # JWTs are only valid for a short amount of time self.check_jwt_expiry(request.jwt_auth.payload) from rest_framework.viewsets import ViewSetMixin if bypass_permissions(request): return True scopes_required = get_required_scopes(view) component = self.get_component(view) if not self.permission_fields: return request.jwt_auth.has_auth(scopes_required, component) main_resource = self.get_main_resource() if view.action == "create": if view.__class__ is main_resource: main_object_data = request.data else: main_object_url = request.data[view.permission_main_object] main_object_path = urlparse(main_object_url).path try: main_object = get_resource_for_path(main_object_path) except ObjectDoesNotExist: raise ValidationError({ view.permission_main_object: ValidationError( _("The object does not exist in the database"), code="object-does-not-exist", ).detail }) except DjangoValidationError as exc: err_dict = as_serializer_error( ValidationError({view.permission_main_object: exc})) raise ValidationError(err_dict) main_object_data = self.format_data(main_object, request) fields = self.get_fields(main_object_data) return request.jwt_auth.has_auth(scopes_required, component, **fields) # detect if this is an unsupported method - if it's a viewset and the # action was not mapped, it's not supported and DRF will catch it if view.action is None and isinstance(view, ViewSetMixin): return True # by default - check if the action is allowed at all return request.jwt_auth.has_auth(scopes_required, component)
def has_permission(self, request: Request, view) -> bool: if bypass_permissions(request): return True scopes_required = get_required_scopes(view) component = self.get_component(view) main_object = view._get_zaak() main_object_data = self.format_data(main_object, request) fields = self.get_fields(main_object_data) return request.jwt_auth.has_auth(scopes_required, component, **fields)
def has_object_permission(self, request: Request, view, obj) -> bool: if bypass_permissions(request): return True scopes_required = get_required_scopes(view) component = self.get_component(view) if not self.permission_fields: return request.jwt_auth.has_auth(scopes_required, component) main_resource = self.get_main_resource() if view.__class__ is main_resource: main_object = obj else: main_object = self.get_main_object(obj, view.permission_main_object) main_object_data = self.format_data(main_object, request) fields = self.get_fields(main_object_data) return request.jwt_auth.has_auth(scopes_required, component, **fields)
def get_security(self): """Return a list of security requirements for this operation. Returning an empty list marks the endpoint as unauthenticated (i.e. removes all accepted authentication schemes). Returning ``None`` will inherit the top-level secuirty requirements. :return: security requirements :rtype: list[dict[str,list[str]]]""" permissions = self.view.get_permissions() scope_permissions = [ perm for perm in permissions if isinstance(perm, AuthRequired) ] if not scope_permissions: return super().get_security() if len(permissions) != len(scope_permissions): logger.warning( "Can't represent all permissions in OAS for path %s and method %s", self.path, self.method, ) required_scopes = [] for perm in scope_permissions: scopes = get_required_scopes(self.view) if scopes is None: continue required_scopes.append(scopes) if not required_scopes: return None # use global security scopes = [str(scope) for scope in sorted(required_scopes)] # operation level security return [{settings.SECURITY_DEFINITION_NAME: scopes}]