async def __call__(self): allowed = app_settings.get("allow_register", False) if allowed is False: raise HTTPUnauthorized(content={"text": "Not allowed registration"}) validator = RecaptchaValidator() status = await validator.validate() if status is False: raise HTTPUnauthorized(content={"text": "Invalid validation"}) payload = await self.request.json() user_id = payload.get("id", None) user = await find_user({"id": user_id}) if user is not None: raise HTTPUnauthorized(content={"text": "Invalid login"}) validation_utility = get_utility(IAuthValidationUtility) if validation_utility is not None: redirect_url = self.request.query.get("redirect_url", None) username = payload.get("fullname", payload.get("id", "")) task_description = f"Registering user {username}" actual_user = get_authenticated_user() await validation_utility.start( as_user=payload.get("id"), from_user=actual_user.id, task_description=task_description, task_id="register_user", email=payload.get("email"), context_description=self.context.title, redirect_url=redirect_url, data=payload, ) else: raise HTTPNotAcceptable()
async def modify_comment(context, request): payload = await request.json() comment_id = request.matchdict["comment_id"] bhr = ICMSBehavior(context) if not bhr.allow_discussion: raise HTTPUnauthorized(content={"text": "Not available option"}) await bhr.load() if comment_id not in bhr.comments: raise ErrorResponse("InvalidComment", "This comment does not exist", status=412) user_id = get_authenticated_user_id() comment = bhr.comments[comment_id] # TODO: We need ? if user_id != comment["author_username"]: raise HTTPUnauthorized(content={"text": "Not the author"}) comment["text"]["data"] = payload.get("text", "") comment["modification_date"] = datetime.now().isoformat() bhr.register() url = getMultiAdapter((context, request), IAbsoluteURL)() headers = {"Location": url + "/@comments/" + comment_id} return Response(status=204, headers=headers)
async def delete_comment(context, request): comment_id = request.matchdict["comment_id"] bhr = ICMSBehavior(context) if not bhr.allow_discussion: raise HTTPUnauthorized(content={"text": "Not available option"}) await bhr.load() if comment_id not in bhr.comments: raise ErrorResponse("InvalidComment", "This comment does not exist", status=412) user_id = get_authenticated_user_id() comment = bhr.comments[comment_id] # TODO: We need ? policy = get_security_policy() if user_id != comment["author_username"] or not policy.check_permission( "guillotina.DeleteAllComments", context): raise HTTPUnauthorized( content={"text": "Not the author or permission"}) list_to_delete = [comment_id] delete_from_list(bhr.comments, list_to_delete) for comment in list_to_delete: del bhr.comments[comment] bhr.register() return Response(status=204)
async def post_login(context, request): ''' After challenge initiated, use this to actually login! ''' if 'admin_url' not in app_settings['hydra']: raise HTTPBadRequest(content={ 'reason': 'hydra admin_url not configured' }) data = await request.json() pw = data['password'] username = data.get('username', data.get('login', '')) email = data.get('email') challenge = data['challenge'] remember = data.get('remember') or False if email is None and '@' in username: # username entered as email email = username if email is not None: user = await utils.find_user(email=email.lower()) else: user = await utils.find_user(username=username) if user is None: raise HTTPUnauthorized(content={ 'text': 'login failed' }) if check_password(user['password'], pw): csrf_cookie = await utils.get_csrf_cookie_str(request) accept_request = await hydra_admin_request( 'put', os.path.join('login', challenge, 'accept'), json={ 'subject': user['id'], 'remember': remember, 'remember_for': 3600, # acr is a value to represent level of authentication. # this can be used with 2-factor auth schemes 'acr': "0" }, headers={ 'Set-Cookie': csrf_cookie } ) if not data.get('auto_grant', False): return { 'url': accept_request['redirect_to'], 'user': user } else: return await _login_user( request, accept_request, user) else: raise HTTPUnauthorized(content={ 'text': 'login failed' })
async def __call__(self): user_id: str = self.request.matchdict["user"] actual_user = get_authenticated_user() if actual_user.id == user_id: # Self setting password # Payload : { # 'old_password': '******', # 'new_password': '******', # } data = await self.request.json() try: await actual_user.set_password( data.get("new_password", None), old_password=data.get("old_password", None) ) except AttributeError: raise HTTPNotAcceptable() else: # We validate with recaptcha validator = RecaptchaValidator() status = await validator.validate() if status is False: raise HTTPUnauthorized(content={"text": "Invalid validation"}) # We need to validate is a valid user user = await find_user({"id": user_id}) if user is None: raise HTTPUnauthorized(content={"text": "Invalid operation"}) # We need to validate is a valid user try: email = user.properties.get("email", user.email) except AttributeError: email = None if email is None and "@" in user_id: email = user_id if email is None: raise HTTPPreconditionFailed(content={"reason": "User without mail configured"}) # We need to generate a token and send to user email validation_utility = get_utility(IAuthValidationUtility) if validation_utility is not None: redirect_url = self.request.query.get("redirect_url", None) await validation_utility.start( as_user=user_id, from_user=actual_user.id, email=email, task_description="Reset password", task_id="reset_password", context_description=self.context.title, redirect_url=redirect_url, ) else: raise HTTPNotAcceptable()
async def __call__(self): data = await self.request.json() creds = {"type": "basic", "token": data["password"], "id": data.get("username", data.get("login"))} for validator in app_settings["auth_token_validators"]: if validator.for_validators is not None and "basic" not in validator.for_validators: continue user = await validator().validate(creds) if user is not None: break if user is None: raise HTTPUnauthorized(content={"text": "login failed"}) session_manager = query_utility(ISessionManagerUtility) if session_manager is not None: data = json.dumps(dict(self.request.headers)) session = await session_manager.new_session(user.id, data=data) data = {"session": session} else: data = {} jwt_token, data = authenticate_user( user.id, timeout=app_settings["jwt"]["token_expiration"], data=data ) await notify(UserLogin(user, jwt_token)) return {"exp": data["exp"], "token": jwt_token}
async def add_comment(context, request): payload = await request.json() bhr = ICMSBehavior(context) if not bhr.allow_discussion: raise HTTPUnauthorized(content={"text": "Not available option"}) await bhr.load() if bhr.comments is None: bhr.comments = {} user_id = get_authenticated_user_id() comment_uuid = uuid.uuid4().hex bhr.comments[comment_uuid] = { "@parent": None, "author_name": None, "author_username": user_id, "creation_date": datetime.now().isoformat(), "in_reply_to": None, "is_deletable": True, "is_editable": True, "modification_date": datetime.now().isoformat(), "text": { "data": payload.get("text", ""), "mime-type": "text/plain" }, "user_notification": None, } bhr.register() url = getMultiAdapter((context, request), IAbsoluteURL)() headers = {"Location": url + "/@comments/" + comment_uuid} return Response(status=204, headers=headers)
async def __call__(self): data = await self.request.json() creds = { 'type': 'basic', 'token': data['password'], 'id': data.get('username', data.get('login')) } for validator in app_settings['auth_token_validators']: if (validator.for_validators is not None and 'basic' not in validator.for_validators): continue user = await validator(self.request).validate(creds) if user is not None: break if user is None: raise HTTPUnauthorized(content={ 'text': 'login failed' }) jwt_token, data = authenticate_user(user.id) await notify(UserLogin(user, jwt_token)) return { 'exp': data['exp'], 'token': jwt_token }
async def finish(self, token: str, payload=None): data = await extract_validation_token(token) if data is None: raise HTTPUnauthorized() action = data.get("v_task") if action in app_settings["auth_validation_tasks"]: if "schema" in app_settings["auth_validation_tasks"][action]: schema = app_settings["auth_validation_tasks"][action][ "schema"] try: jsonvalidate(instance=payload, schema=schema) except ValidationError as e: raise HTTPPreconditionFailed( content={ "reason": "json schema validation error", "message": e.message, "validator": e.validator, "validator_value": e.validator_value, "path": [i for i in e.path], "schema_path": [i for i in e.schema_path], "schema": schema, }) task = resolve_dotted_name( app_settings["auth_validation_tasks"][action]["executor"]) result = await task.run(data, payload) else: logger.error(f"Invalid task {action}") raise HTTPNotImplemented() await notify(ValidationEvent(data)) return result
async def set_password(self, new_password, old_password=None): if old_password is not None: valid = check_password(self.password, old_password) if not valid: raise HTTPUnauthorized() self.password = hash_password(new_password) self.register()
async def traverse( request: IRequest, parent: IBaseObject, path: Tuple[str, ...]) -> Tuple[IBaseObject, Tuple[str, ...]]: """Do not use outside the main router function.""" if IApplication.providedBy(parent): request.application = parent if len(path) == 0: return parent, path assert request is not None # could be used for permissions, etc if not ITraversable.providedBy(parent): # not a traversable context return parent, path try: if path[0][0] == "_" or path[0] in (".", ".."): raise HTTPUnauthorized() if path[0][0] == "@": # shortcut return parent, path if IAsyncContainer.providedBy(parent): context = await parent.async_get(path[0], suppress_events=True) if context is None: return parent, path else: context = parent[path[0]] except (TypeError, KeyError, AttributeError): return parent, path if IDatabase.providedBy(context): task_vars.db.set(context) # Add a transaction Manager to request tm = context.get_transaction_manager() task_vars.tm.set(tm) # Start a transaction txn = await tm.begin( read_only=not app_settings["check_writable_request"](request)) # Get the root of the tree context = await tm.get_root(txn=txn) if IContainer.providedBy(context): task_vars.container.set(context) # make sure to unset before we attempt to load in case # there is an existing registry object set on task_vars task_vars.registry.set(None) registry = await get_registry(context) layers = registry.get(ACTIVE_LAYERS_KEY, []) for layer in layers: try: alsoProvides(request, import_class(layer)) except ModuleNotFoundError: logger.error("Can not apply layer " + layer, request=request) return await traverse(request, context, path[1:])
async def preflight(self): """We need to check if there is cors enabled and is valid.""" headers = {} renderer = app_settings['cors_renderer'](self.request) settings = await renderer.get_settings() if not settings: return {} origin = self.request.headers.get('Origin', None) if not origin: raise HTTPNotFound(content={ 'message': 'Origin this header is mandatory' }) requested_method = self.getRequestMethod() if not requested_method: raise HTTPNotFound(content={ 'text': 'Access-Control-Request-Method this header is mandatory' }) requested_headers = ( self.request.headers.get('Access-Control-Request-Headers', ())) if requested_headers: requested_headers = map(str.strip, requested_headers.split(', ')) requested_method = requested_method.upper() allowed_methods = settings['allow_methods'] if requested_method not in allowed_methods: raise HTTPMethodNotAllowed( requested_method, allowed_methods, content={ 'message': 'Access-Control-Request-Method Method not allowed' }) supported_headers = settings['allow_headers'] if '*' not in supported_headers and requested_headers: supported_headers = [s.lower() for s in supported_headers] for h in requested_headers: if not h.lower() in supported_headers: raise HTTPUnauthorized(content={ 'text': 'Access-Control-Request-Headers Header %s not allowed' % h }) supported_headers = [] if supported_headers is None else supported_headers requested_headers = [] if requested_headers is None else requested_headers supported_headers = set(supported_headers) | set(requested_headers) headers['Access-Control-Allow-Headers'] = ','.join(supported_headers) headers['Access-Control-Allow-Methods'] = ','.join(settings['allow_methods']) headers['Access-Control-Max-Age'] = str(settings['max_age']) return headers
async def __call__(self): user = get_authenticated_user() user_id: str = self.request.matchdict["user"] if user.id != user_id: raise HTTPUnauthorized() session_manager = query_utility(ISessionManagerUtility) if session_manager is not None: return await session_manager.list_sessions(user.id) else: raise HTTPNotAcceptable()
async def traverse(request, parent, path): """Do not use outside the main router function.""" if IApplication.providedBy(parent): request.application = parent if not path: return parent, path assert request is not None # could be used for permissions, etc if not ITraversable.providedBy(parent): # not a traversable context return parent, path try: if path[0][0] == '_' or path[0] in ('.', '..'): raise HTTPUnauthorized() if path[0][0] == '@': # shortcut return parent, path if IAsyncContainer.providedBy(parent): context = await parent.async_get(path[0], suppress_events=True) if context is None: return parent, path else: context = parent[path[0]] except (TypeError, KeyError, AttributeError): return parent, path if IDatabase.providedBy(context): request._db_write_enabled = app_settings['check_writable_request']( request) request._db_id = context.id # Add a transaction Manager to request tm = request._tm = context.get_transaction_manager() # Start a transaction txn = await tm.begin(request=request) # Get the root of the tree context = await tm.get_root(txn=txn) if IContainer.providedBy(context): request._container_id = context.id request.container = context annotations_container = IAnnotations(request.container) request.container_settings = await annotations_container.async_get( REGISTRY_DATA_KEY) layers = request.container_settings.get(ACTIVE_LAYERS_KEY, []) for layer in layers: try: alsoProvides(request, import_class(layer)) except ModuleNotFoundError: logger.error('Can not apply layer ' + layer, request=request) return await traverse(request, context, path[1:])
async def get_field_value(context, request): field_name = request.matchdict["dotted_name"] if "." in field_name: # behavior field lookup iface_dotted = ".".join(field_name.split(".")[:-1]) field_name = field_name.split(".")[-1] try: schema = resolve_dotted_name(iface_dotted) except ModuleNotFoundError: return HTTPNotFound( content={"reason": f"Could resolve: {iface_dotted}"}) try: field = schema[field_name] except KeyError: return HTTPNotFound(content={"reason": f"No field: {field_name}"}) try: behavior = await get_behavior(context, schema) except AttributeError: return HTTPNotFound( content={"reason": f"Could not load behavior: {iface_dotted}"}) if behavior is None: return HTTPNotFound( content={"reason": f"Not valid behavior: {iface_dotted}"}) field = field.bind(behavior) field_context = behavior else: # main object field factory = get_cached_factory(context.type_name) schema = factory.schema try: field = schema[field_name] except KeyError: return HTTPNotFound(content={"reason": f"No field: {field_name}"}) field = field.bind(context) field_context = context # check permission read_permissions = merged_tagged_value_dict(schema, read_permission.key) serializer = get_multi_adapter((context, request), IResourceSerializeToJson) if not serializer.check_permission(read_permissions.get(field_name)): return HTTPUnauthorized( content={"reason": "You are not authorized to render this field"}) field_renderer = query_multi_adapter((context, request, field), IFieldValueRenderer) if field_renderer is None: return await serializer.serialize_field(field_context, field) else: return await field_renderer()
async def __call__(self): user = get_authenticated_user(self.request) if user is None: return HTTPUnauthorized(content={'reason': 'user not authorized'}) data = { 'exp': datetime.utcnow() + timedelta(seconds=self.token_timeout), 'id': user.id } jwt_token = jwt.encode(data, app_settings['jwt']['secret']).decode('utf-8') return {'exp': data['exp'], 'token': jwt_token}
async def __call__(self): user = get_authenticated_user() user_id: str = self.request.matchdict["user"] session_id: str = self.request.matchdict["session"] if user.id != user_id: raise HTTPUnauthorized() session_manager = query_utility(ISessionManagerUtility) if session_manager is not None: value = await session_manager.get_session(user.id, session_id) return json.loads(value) else: raise HTTPNotAcceptable()
async def preflight(self): """We need to check if there is cors enabled and is valid.""" headers = {} renderer = app_settings["cors_renderer"](self.request) settings = await renderer.get_settings() if not settings: return {} origin = self.request.headers.get("Origin", None) if not origin: raise HTTPNotFound(content={"message": "Origin this header is mandatory"}) requested_method = self.getRequestMethod() if not requested_method: raise HTTPNotFound(content={"text": "Access-Control-Request-Method this header is mandatory"}) requested_headers = self.request.headers.get("Access-Control-Request-Headers", ()) if requested_headers: requested_headers = map(str.strip, requested_headers.split(", ")) requested_method = requested_method.upper() allowed_methods = settings["allow_methods"] if requested_method not in allowed_methods: raise HTTPMethodNotAllowed( requested_method, allowed_methods, content={"message": "Access-Control-Request-Method Method not allowed"}, ) supported_headers = settings["allow_headers"] if "*" not in supported_headers and requested_headers: supported_headers = [s.lower() for s in supported_headers] for h in requested_headers: if not h.lower() in supported_headers: raise HTTPUnauthorized( content={"text": "Access-Control-Request-Headers Header %s not allowed" % h} ) supported_headers = [] if supported_headers is None else supported_headers requested_headers = [] if requested_headers is None else requested_headers supported_headers = set(supported_headers) | set(requested_headers) headers["Access-Control-Allow-Headers"] = ",".join(supported_headers) headers["Access-Control-Allow-Methods"] = ",".join(settings["allow_methods"]) headers["Access-Control-Max-Age"] = str(settings["max_age"]) return headers
async def post_consent(context, request): if 'admin_url' not in app_settings['hydra']: raise HTTPBadRequest(content={ 'reason': 'hydra admin_url not configured' }) data = await request.json() remember = data.get('remember') or False user = await utils.find_user(id=data['subject']) if user is None: raise HTTPUnauthorized(content={ 'text': 'login failed' }) # XXX check valid scopes accept_request = await hydra_admin_request( 'put', os.path.join('consent', data['challenge'], 'accept'), json={ 'grant_scope': data['requested_scope'], # The session allows us to set session data for id # and access tokens 'session': { 'access_token': { 'username': user['username'], }, 'id_token': { 'username': user['username'], 'email': user['email'], 'phone': user['phone'], 'data': user['data'], 'allowed_scopes': user['allowed_scopes'], } }, 'remember': remember, 'remember_for': 3600 }, headers={ 'Set-Cookie': await utils.get_csrf_cookie_str(request) } ) return { 'url': accept_request['redirect_to'], 'user': user }
async def __call__(self): data = await self.request.json() creds = {"type": "basic", "token": data["password"], "id": data.get("username", data.get("login"))} for validator in app_settings["auth_token_validators"]: if validator.for_validators is not None and "basic" not in validator.for_validators: continue user = await validator().validate(creds) if user is not None: break if user is None: raise HTTPUnauthorized(content={"text": "login failed"}) jwt_token, data = authenticate_user(user.id) await notify(UserLogin(user, jwt_token)) return {"exp": data["exp"], "token": jwt_token}
async def __call__(self): data = await self.request.json() creds = { 'token': data['password'], 'id': data.get('username', data.get('login')) } validator = SaltedHashPasswordValidator(self.request) user = await validator.validate(creds) if user is None: return HTTPUnauthorized(content={'reason': 'login failed'}) data = { 'exp': datetime.utcnow() + timedelta(seconds=self.token_timeout), 'id': user.id } jwt_token = jwt.encode(data, app_settings['jwt']['secret']).decode('utf-8') return {'exp': data['exp'], 'token': jwt_token}
async def do_action(self, request, action, comments): available_actions = self.actions if action not in available_actions: raise KeyError('Unavailable action') action_def = available_actions[action] policy = get_security_policy() if 'check_permission' in action_def and not policy.check_permission( action_def['check_permission'], self.context): raise HTTPUnauthorized() # Change permission new_state = action_def['to'] if 'set_permission' in self.states[new_state]: await apply_sharing(self.context, self.states[new_state]['set_permission']) # Write history user = get_authenticated_user_id() history = { 'actor': user, 'comments': comments, 'time': datetime.datetime.now(), 'title': action_def['title'], 'type': 'workflow', 'data': { 'action': action, 'review_state': new_state, } } cms_behavior = ICMSBehavior(self.context) await cms_behavior.load() cms_behavior.review_state = new_state cms_behavior.history.append(history) cms_behavior.register() await notify( WorkflowChangedEvent(self.context, self, action, comments)) return history
async def do_action(self, action, comments): available_actions = self.actions if action not in available_actions: raise HTTPPreconditionFailed( content={"reason": "Unavailable action"}) action_def = available_actions[action] policy = get_security_policy() if "check_permission" in action_def and not policy.check_permission( action_def["check_permission"], self.context): raise HTTPUnauthorized() # Change permission new_state = action_def["to"] if "set_permission" in self.states[new_state]: await apply_sharing(self.context, self.states[new_state]["set_permission"]) # Write history user = get_authenticated_user_id() history = { "actor": user, "comments": comments, "time": datetime.datetime.now(), "title": action_def["title"], "type": "workflow", "data": { "action": action, "review_state": new_state }, } workflow_behavior = IWorkflowBehavior(self.context) workflow_behavior.review_state = new_state workflow_behavior.history.append(history) workflow_behavior.register() await notify( WorkflowChangedEvent(self.context, self, action, comments)) return history
async def __call__(self): validator = RecaptchaValidator() status = await validator.validate() if status is False: raise HTTPUnauthorized(content={"text": "Invalid validation"}) auth_providers = app_settings.get("auth_providers", {}) providers = [] if "twitter" in auth_providers: providers.append("twitter") if "facebook" in auth_providers: providers.append("facebook") if "google" in auth_providers: providers.append("google") return { "register": app_settings.get("allow_register", False), "social": providers, "title": self.context.title, }
async def list_comments(context, request): bhr = ICMSBehavior(context) if not bhr.allow_discussion: raise HTTPUnauthorized(content={"text": "Not available option"}) await bhr.load() url = getMultiAdapter((context, request), IAbsoluteURL)() result = [] response = {"@id": url + "/@comments", "items": result} if bhr.comments is None: return response for key, value in bhr.comments.items(): new_comment = deepcopy(value) new_comment["@type"] = "Discussion Item" if new_comment.get("@parent", False): new_comment["@parent"] = url + new_comment.get("@parent") new_comment["@id"] = url + "/@comments/" + key new_comment["comment_id"] = key result.append(new_comment) return response
async def get_headers(self): settings = await self.get_settings() headers = {} origin = self.request.headers.get('Origin', None) if origin: if '*' in settings['allow_origin']: headers['Access-Control-Allow-Origin'] = '*' elif any([fnmatch.fnmatchcase(origin, o) for o in settings['allow_origin']]): headers['Access-Control-Allow-Origin'] = origin else: logger.error('Origin %s not allowed' % origin, request=self.request) raise HTTPUnauthorized() if self.request.headers.get( 'Access-Control-Request-Method', None) != 'OPTIONS': if settings['allow_credentials']: headers['Access-Control-Allow-Credentials'] = 'True' if len(settings['allow_headers']): headers['Access-Control-Expose-Headers'] = ', '.join( settings['allow_headers']) return headers
async def get_headers(self): settings = await self.get_settings() headers = {} origin = self.request.headers.get("Origin", None) if origin: if "*" in settings["allow_origin"]: headers["Access-Control-Allow-Origin"] = "*" elif any([ fnmatch.fnmatchcase(origin, o) for o in settings["allow_origin"] ]): headers["Access-Control-Allow-Origin"] = origin else: logger.error("Origin %s not allowed" % origin, request=self.request) raise HTTPUnauthorized() if self.request.headers.get("Access-Control-Request-Method", None) != "OPTIONS": if settings["allow_credentials"]: headers["Access-Control-Allow-Credentials"] = "true" if len(settings["allow_headers"]): headers["Access-Control-Expose-Headers"] = ", ".join( settings["allow_headers"]) return headers
async def real_resolve(self, request: IRequest) -> Optional[MatchInfo]: """Main function to resolve a request.""" if request.method not in app_settings['http_methods']: raise HTTPMethodNotAllowed( method=request.method, allowed_methods=[ k for k in app_settings['http_methods'].keys() ]) method = app_settings['http_methods'][request.method] try: resource, tail = await self.traverse(request) except ConflictError: # can also happen from connection errors so we bubble this... raise except Exception as _exc: logger.error('Unhandled exception occurred', exc_info=True) request.resource = request.tail = None request.exc = _exc data = { 'success': False, 'exception_message': str(_exc), 'exception_type': getattr(type(_exc), '__name__', str(type(_exc))), # noqa } if app_settings.get('debug'): data['traceback'] = traceback.format_exc() raise HTTPBadRequest(content={'reason': data}) request.record('traversed') await notify(ObjectLoadedEvent(resource)) request.resource = resource request.tail = tail if request.resource is None: await notify(TraversalResourceMissEvent(request, tail)) raise HTTPNotFound(content={"reason": 'Resource not found'}) if tail and len(tail) > 0: # convert match lookups view_name = routes.path_to_view_name(tail) elif not tail: view_name = '' request.record('beforeauthentication') authenticated = await authenticate_request(request) # Add anonymous participation if authenticated is None: authenticated = AnonymousUser() set_authenticated_user(authenticated) request.record('authentication') policy = get_security_policy(authenticated) for language in get_acceptable_languages(request): translator = query_adapter((resource, request), ILanguage, name=language) if translator is not None: resource = translator.translate() break # container registry lookup try: view = query_multi_adapter((resource, request), method, name=view_name) except AttributeError: view = None if view is None and method == IOPTIONS: view = DefaultOPTIONS(resource, request) # Check security on context to AccessContent unless # is view allows explicit or its OPTIONS permission = get_utility(IPermission, name='guillotina.AccessContent') if not policy.check_permission(permission.id, resource): # Check if its a CORS call: if IOPTIONS != method: # Check if the view has permissions explicit if view is None or not view.__allow_access__: logger.info( "No access content {content} with {auth}".format( content=resource, auth=authenticated.id), request=request) raise HTTPUnauthorized( content={ "reason": "You are not authorized to access content", "content": str(resource), "auth": authenticated.id }) if not view and len(tail) > 0: # we should have a view in this case because we are matching routes await notify(TraversalViewMissEvent(request, tail)) return None request.found_view = view request.view_name = view_name request.record('viewfound') ViewClass = view.__class__ view_permission = get_view_permission(ViewClass) if view_permission is None: # use default view permission view_permission = app_settings['default_permission'] if not policy.check_permission(view_permission, view): if IOPTIONS != method: raise HTTPUnauthorized( content={ "reason": "You are not authorized to view", "content": str(resource), "auth": authenticated.id }) try: view.__route__.matches(request, tail or []) except (KeyError, IndexError): await notify(TraversalRouteMissEvent(request, tail)) return None except AttributeError: pass if hasattr(view, 'prepare'): view = (await view.prepare()) or view request.record('authorization') return MatchInfo(resource, request, view)