Exemplo n.º 1
0
    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()
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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'
        })
Exemplo n.º 5
0
    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()
Exemplo n.º 6
0
    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}
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
    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
        }
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
    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()
Exemplo n.º 11
0
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:])
Exemplo n.º 12
0
    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
Exemplo n.º 13
0
    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()
Exemplo n.º 14
0
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:])
Exemplo n.º 15
0
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()
Exemplo n.º 16
0
    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}
Exemplo n.º 17
0
    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()
Exemplo n.º 18
0
    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
Exemplo n.º 19
0
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
    }
Exemplo n.º 20
0
    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}
Exemplo n.º 21
0
    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}
Exemplo n.º 22
0
        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
Exemplo n.º 23
0
        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
Exemplo n.º 24
0
    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,
        }
Exemplo n.º 25
0
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
Exemplo n.º 26
0
 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
Exemplo n.º 27
0
 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
Exemplo n.º 28
0
    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)