Ejemplo n.º 1
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)
Ejemplo n.º 2
0
    def log(self, *args, **kwargs):
        from guillotina.utils import get_authenticated_user_id
        from guillotina.utils import get_current_request
        from guillotina.exceptions import RequestNotFound

        func = getattr(self._logger, name)
        request = kwargs.pop('request', None)
        eid = kwargs.pop('eid', None)
        if request is None:
            try:
                request = get_current_request()
            except RequestNotFound:
                pass
        if request is not None:
            if eid is None:
                eid = uuid.uuid4().hex
            extra = kwargs.get('extra', {})
            try:
                url = request.url.human_repr()
            except AttributeError:
                # older version of aiohttp
                url = request.path
            extra.update({
                'method': request.method,
                'url': url,
                'container': getattr(request, '_container_id', None),
                'db_id': getattr(request, '_db_id', None),
                'user': get_authenticated_user_id(request) or 'Anonymous',
                'eid': eid
            })
            kwargs['extra'] = extra
        return func(*args, **kwargs)
Ejemplo n.º 3
0
    async def begin(self, request=None):
        """Starts a new transaction.
        """

        self._db_conn = await self._storage.open()

        if request is None:
            if self.request is None:
                self.request = get_current_request()
            request = self.request

        user = get_authenticated_user_id(request)
        if self._txn is not None:
            if self._pool is None:
                self._pool = LifoQueue()
            # Save the actual transaction and start a new one
            self._pool.put(self._txn)

        self._txn = txn = Transaction(self, request=request)

        # CACHE!!

        if user is not None:
            txn.user = user
        await txn.tpc_begin(self._db_conn)

        return txn
Ejemplo n.º 4
0
    async def __call__(self):
        data = await self.request.json()
        if '@type' not in data or data['@type'] not in app_settings['container_types']:
            raise HTTPNotFound(content={
                'message': 'can not create this type %s' % data['@type']
            })

        if 'id' not in data:
            raise HTTPPreconditionFailed(content={
                'message': 'We need an id'
            })

        if not data.get('title'):
            data['title'] = data['id']

        if 'description' not in data:
            data['description'] = ''

        value = await self.context.async_contains(data['id'])

        if value:
            # Already exist
            raise HTTPConflict(content={
                'message': 'Container with id already exists'
            })

        install_addons = data.pop('@addons', None) or []
        for addon in install_addons:
            # validate addon list
            if addon not in app_settings['available_addons']:
                return ErrorResponse(
                    'RequiredParam',
                    "Property '@addons' must refer to a valid addon",
                    status=412, reason=error_reasons.INVALID_ID)

        owner_id = get_authenticated_user_id(self.request)

        container = await create_container(
            self.context, data.pop('id'),
            container_type=data.pop('@type'),
            owner_id=owner_id, **data)
        self.request._container_id = container.__name__
        self.request.container = container

        annotations_container = get_adapter(container, IAnnotations)
        self.request.container_settings = await annotations_container.async_get(REGISTRY_DATA_KEY)

        for addon in install_addons:
            await addons.install(container, addon)

        resp = {
            '@type': container.type_name,
            'id': container.id,
            'title': data['title']
        }
        headers = {
            'Location': posixpath.join(self.request.path, container.id)
        }

        return Response(content=resp, headers=headers)
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
    async def __call__(self):
        data = await self.request.json()
        if '@type' not in data or data['@type'] not in app_settings[
                'container_types']:
            raise HTTPNotFound(
                content={
                    'message': 'can not create this type %s' % data['@type']
                })

        if 'id' not in data:
            raise HTTPPreconditionFailed(content={'message': 'We need an id'})

        if not data.get('title'):
            data['title'] = data['id']

        if 'description' not in data:
            data['description'] = ''

        value = await self.context.async_contains(data['id'])

        if value:
            # Already exist
            raise HTTPConflict(
                content={'message': 'Container with id already exists'})

        install_addons = data.pop('@addons', None) or []
        for addon in install_addons:
            # validate addon list
            if addon not in app_settings['available_addons']:
                return ErrorResponse(
                    'RequiredParam',
                    "Property '@addons' must refer to a valid addon",
                    status=412,
                    reason=error_reasons.INVALID_ID)

        owner_id = get_authenticated_user_id(self.request)

        container = await create_container(self.context,
                                           data.pop('id'),
                                           container_type=data.pop('@type'),
                                           owner_id=owner_id,
                                           **data)
        self.request._container_id = container.__name__
        self.request.container = container

        annotations_container = get_adapter(container, IAnnotations)
        self.request.container_settings = await annotations_container.async_get(
            REGISTRY_DATA_KEY)

        for addon in install_addons:
            await addons.install(container, addon)

        resp = {
            '@type': container.type_name,
            'id': container.id,
            'title': data['title']
        }
        headers = {'Location': posixpath.join(self.request.path, container.id)}

        return Response(content=resp, headers=headers)
Ejemplo n.º 7
0
async def cms_object_added(obj, event):
    cms = query_adapter(obj, ICMSBehavior)
    if cms is not None:
        request = get_current_request()
        user_id = get_authenticated_user_id(request)

        workflow = IWorkflow(obj)
        await cms.load(create=True)
        state = cms.review_state

        if 'set_permission' in workflow.states[state]:
            await apply_sharing(obj, workflow.states[state]['set_permission'])

        setattr(cms, 'history', [])
        cms.history.append({
            'actor': user_id,
            'comments': '',
            'time': datetime.datetime.now(),
            'title': 'Created',
            'type': 'workflow',
            'data': {
                'action': None,
                'review_state': state,
            }
        })
        cms._p_register()

    if hasattr(obj, 'title') and obj.title is None:
        obj.title = obj.id
Ejemplo n.º 8
0
    async def __call__(self):
        data = await self.request.json()
        if "@type" not in data or data["@type"] not in app_settings[
                "container_types"]:
            raise HTTPNotFound(
                content={
                    "message": "can not create this type %s" % data["@type"]
                })

        if "id" not in data:
            raise HTTPPreconditionFailed(content={"message": "We need an id"})

        if not data.get("title"):
            data["title"] = data["id"]

        if "description" not in data:
            data["description"] = ""

        value = await self.context.async_contains(data["id"])

        if value:
            # Already exist
            raise HTTPConflict(
                content={"message": "Container with id already exists"})

        install_addons = data.pop("@addons", None) or []
        for addon in install_addons:
            # validate addon list
            if addon not in app_settings["available_addons"]:
                return ErrorResponse(
                    "RequiredParam",
                    "Property '@addons' must refer to a valid addon",
                    status=412,
                    reason=error_reasons.INVALID_ID,
                )

        owner_id = get_authenticated_user_id()

        container = await create_container(self.context,
                                           data.pop("id"),
                                           container_type=data.pop("@type"),
                                           owner_id=owner_id,
                                           **data)
        task_vars.container.set(container)

        annotations_container = get_adapter(container, IAnnotations)
        task_vars.registry.set(
            await annotations_container.async_get(REGISTRY_DATA_KEY))

        for addon in install_addons:
            await addons.install(container, addon)

        resp = {
            "@type": container.type_name,
            "id": container.id,
            "title": data["title"]
        }
        headers = {"Location": posixpath.join(self.request.path, container.id)}

        return Response(content=resp, headers=headers)
Ejemplo n.º 9
0
    async def begin(self, read_only: bool = False) -> ITransaction:
        """Starts a new transaction.
        """
        # already has txn registered, as long as connection is closed, it
        # is safe
        txn: typing.Optional[ITransaction] = task_vars.txn.get()
        if (txn is not None and txn.manager == self and txn.status
                in (Status.ABORTED, Status.COMMITTED, Status.CONFLICT)):
            # re-use txn if possible
            txn.status = Status.ACTIVE
            if (txn._db_conn is not None
                    and getattr(txn._db_conn, '_in_use', None) is None):
                try:
                    await self._close_txn(txn)
                except Exception:
                    logger.warn('Unable to close spurious connection',
                                exc_info=True)
        else:
            txn = Transaction(self, read_only=read_only)

        try:
            txn.user = get_authenticated_user_id()
        except RequestNotFound:
            pass

        await txn.tpc_begin()

        # make sure to explicitly set!
        task_vars.txn.set(txn)

        return txn
Ejemplo n.º 10
0
async def workflow_object_added(obj, event):
    workflow = query_adapter(obj, IWorkflowBehavior)
    wkf = query_adapter(obj, IWorkflow)
    if workflow is not None and wkf is not None:
        user_id = get_authenticated_user_id()

        await workflow.load(create=True)
        state = workflow.review_state

        if "set_permission" in wkf.states[state]:
            await apply_sharing(obj, wkf.states[state]["set_permission"])

        setattr(workflow, "history", [])
        workflow.history.append({
            "actor": user_id,
            "comments": "",
            "time": datetime.datetime.now(),
            "title": "Created",
            "type": "workflow",
            "data": {
                "action": None,
                "review_state": state
            },
        })
        workflow.register()
Ejemplo n.º 11
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)
Ejemplo n.º 12
0
    async def __call__(self):
        data = await self.request.json()
        if '@type' not in data or data['@type'] not in app_settings[
                'container_types']:
            raise HTTPNotFound(
                content={
                    'message': 'can not create this type %s' % data['@type']
                })

        if 'id' not in data:
            raise HTTPPreconditionFailed(content={'message': 'We need an id'})

        if not data.get('title'):
            data['title'] = data['id']

        if 'description' not in data:
            data['description'] = ''

        value = await self.context.async_contains(data['id'])

        if value:
            # Already exist
            raise HTTPConflict(
                content={'message': 'Container with id already exists'})

        container = await create_content(data['@type'],
                                         id=data['id'],
                                         title=data['title'],
                                         description=data['description'])

        # Special case we don't want the parent pointer
        container.__name__ = data['id']

        await self.context.async_set(data['id'], container)
        await container.install()

        self.request._container_id = container.__name__
        self.request.container = container

        user = get_authenticated_user_id(self.request)

        # Local Roles assign owner as the creator user
        roleperm = IPrincipalRoleManager(container)
        roleperm.assign_role_to_principal('guillotina.Owner', user)

        await notify(
            ObjectAddedEvent(container,
                             self.context,
                             container.__name__,
                             payload=data))

        resp = {
            '@type': data['@type'],
            'id': data['id'],
            'title': data['title']
        }
        headers = {'Location': posixpath.join(self.request.path, data['id'])}

        return Response(content=resp, headers=headers)
Ejemplo n.º 13
0
def generate_unauthorized_response(e, request):
    # We may need to check the roles of the users to show the real error
    eid = uuid.uuid4().hex
    message = _('Not authorized to render operation') + ' ' + eid
    user = get_authenticated_user_id(request)
    extra = {'r': _url(request), 'u': user}
    logger.error(message, exc_info=e, extra=extra)
    return UnauthorizedResponse(message)
Ejemplo n.º 14
0
def generate_error_response(e, request, error, status=400):
    # We may need to check the roles of the users to show the real error
    eid = uuid.uuid4().hex
    message = _('Error on execution of view') + ' ' + eid
    user = get_authenticated_user_id(request)
    extra = {'r': _url(request), 'u': user}
    logger.error(message, exc_info=e, extra=extra)

    return ErrorResponse(error, message, status)
Ejemplo n.º 15
0
async def container_added(conversation, event):
    user_id = get_authenticated_user_id()
    if user_id not in conversation.users:
        conversation.users.append(user_id)

    manager = IPrincipalRoleManager(conversation)
    for user in conversation.users or []:
        manager.assign_role_to_principal(
            'guillotina_chat.ConversationParticipant', user)
Ejemplo n.º 16
0
    async def __call__(self):
        data = await self.request.json()
        if '@type' not in data or data['@type'] != 'Container':
            return ErrorResponse('NotAllowed',
                                 'can not create this type %s' % data['@type'],
                                 status=401)

        if 'id' not in data:
            return ErrorResponse('NotAllowed', 'We need an id', status=401)

        if not data.get('title'):
            data['title'] = data['id']

        if 'description' not in data:
            data['description'] = ''

        value = await self.context.async_contains(data['id'])

        if value:
            # Already exist
            return ErrorResponse('ConflictId',
                                 'Container with id already exists',
                                 status=409)

        container = await create_content('Container',
                                         id=data['id'],
                                         title=data['title'],
                                         description=data['description'])

        # Special case we don't want the parent pointer
        container.__name__ = data['id']

        await self.context.async_set(data['id'], container)
        await container.install()

        self.request._container_id = container.__name__
        self.request.container = container

        user = get_authenticated_user_id(self.request)

        # Local Roles assign owner as the creator user
        roleperm = IPrincipalRoleManager(container)
        roleperm.assign_role_to_principal('guillotina.Owner', user)

        await notify(
            ObjectAddedEvent(container,
                             self.context,
                             container.__name__,
                             payload=data))

        resp = {'@type': 'Container', 'id': data['id'], 'title': data['title']}
        headers = {'Location': self.request.path + data['id']}

        return Response(response=resp, headers=headers)
Ejemplo n.º 17
0
async def get_conversations(context, request):
    results = []
    conversations = await context.async_get('conversations')
    user_id = get_authenticated_user_id(request)
    async for conversation in conversations.async_values():
        if user_id in conversation.users:
            summary = await getMultiAdapter((conversation, request),
                                            IResourceSerializeToJsonSummary)()
            results.append(summary)
    results = sorted(results, key=lambda conv: conv['creation_date'])
    return results
Ejemplo n.º 18
0
    async def asubscribers(self, objects, provided):
        from guillotina.utils import get_current_request, get_authenticated_user_id, get_dotted_name
        from guillotina.exceptions import RequestNotFound
        from guillotina import task_vars

        if len(objects) > 1:
            event = get_dotted_name(objects[1])
            context = getattr(objects[0], "__uuid__", None)
        else:
            event = get_dotted_name(objects[0])
            context = None

        try:
            request = get_current_request()
        except RequestNotFound:
            request = None
        try:
            url = request.url.human_repr()
        except AttributeError:
            # older version of aiohttp
            url = ""
        info = {
            "url": url,
            "container": getattr(task_vars.container.get(), "id", None),
            "user": get_authenticated_user_id(),
            "db_id": getattr(task_vars.db.get(), "id", None),
            "request_uid": getattr(request, "_uid", None),
            "method": getattr(request, "method", None),
            "subscribers": [],
            "context": context,
            "event": event,
        }

        start = time.time() * 1000
        subscriptions = sorted(
            self.subscriptions(map(providedBy, objects), provided),
            key=lambda sub: getattr(sub, "priority", 100),
        )
        info["lookup_time"] = (time.time() * 1000) - start
        info["found"] = len(subscriptions)
        results = []
        for subscription in subscriptions:
            start = time.time() * 1000
            if asyncio.iscoroutinefunction(subscription):
                results.append(await subscription(*objects))
            else:
                results.append(subscription(*objects))
            info["subscribers"].append({
                "duration": (time.time() * 1000) - start,
                "name": get_dotted_name(subscription)
            })
        info["duration"] = (time.time() * 1000) - start
        profile_logger.info(info)
        return results
Ejemplo n.º 19
0
async def addfavorite(context, request):
    user = get_authenticated_user_id(request)
    behavior = IFollowing(context)
    await behavior.load(True)
    users_list = behavior.favorites
    if not users_list:
        behavior.favorites = []
        users_list = behavior.favorites
    if user not in users_list:
        users_list.append(user)
    behavior.data._p_register()
    await notify(ObjectModifiedEvent(context, payload={'favorites': ''}))
Ejemplo n.º 20
0
async def deletefavorite(context, request):
    user = get_authenticated_user_id()
    behavior = IFollowing(context)
    await behavior.load(True)
    users_list = behavior.favorites
    if users_list is None:
        behavior.favorites = []
        users_list = behavior.favorites
    if user in users_list:
        users_list.remove(user)
    behavior.data.register()
    await notify(ObjectModifiedEvent(context, payload={"favorites": ""}))
Ejemplo n.º 21
0
 async def install(self, site, request):
     registry = await get_registry()
     registry.for_interface(ILayers)['active_layers'] |= {USERS_LAYER}
     user = get_authenticated_user_id()
     await create_content_in_container(site,
                                       'UserManager',
                                       'users',
                                       creators=(user, ),
                                       title='Users')
     await create_content_in_container(site,
                                       'GroupManager',
                                       'groups',
                                       creators=(user, ),
                                       title='Groups')
Ejemplo n.º 22
0
 async def install(self, site, request):
     registry = await get_registry()
     registry.for_interface(ILayers)["active_layers"] |= {USERS_LAYER}
     user = get_authenticated_user_id()
     await create_content_in_container(site,
                                       "UserManager",
                                       "users",
                                       creators=(user, ),
                                       title="Users")
     await create_content_in_container(site,
                                       "GroupManager",
                                       "groups",
                                       creators=(user, ),
                                       title="Groups")
Ejemplo n.º 23
0
    async def start(self, dm):
        """Init an upload.

        _uload_file_id : temporal url to image beeing uploaded
        _resumable_uri : uri to resumable upload
        _uri : finished uploaded image
        """
        util = get_utility(IGCloudBlobStore)
        request = get_current_request()
        upload_file_id = dm.get("upload_file_id")
        if upload_file_id is not None:
            await self.delete_upload(upload_file_id)

        generator = get_multi_adapter((self.context, self.field),
                                      IFileNameGenerator)
        upload_file_id = await apply_coroutine(generator)

        init_url = "{}&name={}".format(
            UPLOAD_URL.format(bucket=await util.get_bucket_name()),
            quote_plus(upload_file_id),
        )

        creator = get_authenticated_user_id()
        metadata = json.dumps({
            "CREATOR": creator,
            "REQUEST": str(request),
            "NAME": dm.get("filename")
        })
        call_size = len(metadata)
        async with util.session.post(
                init_url,
                headers={
                    "AUTHORIZATION":
                    "Bearer {}".format(await util.get_access_token()),
                    "X-Upload-Content-Type": to_str(dm.content_type),
                    "X-Upload-Content-Length": str(dm.size),
                    "Content-Type": "application/json; charset=UTF-8",
                    "Content-Length": str(call_size),
                },
                data=metadata,
        ) as call:
            if call.status != 200:
                text = await call.text()
                raise GoogleCloudException(f"{call.status}: {text}")
            resumable_uri = call.headers["Location"]

        await dm.update(current_upload=0,
                        resumable_uri=resumable_uri,
                        upload_file_id=upload_file_id)
Ejemplo n.º 24
0
async def get_user_info(context, request):
    userid = get_authenticated_user_id(request)
    if userid == 'root':
        raise HTTPBadRequest(content={
            'reason': 'not a valid user'
        })

    user = await utils.find_user(id=userid)
    if user is None:
        raise HTTPPreconditionFailed(content={
            'reason': 'Not a valid user'
        })

    if 'password' in user:
        del user['password']
    return user
Ejemplo n.º 25
0
    async def __call__(self):
        data = await self.request.json()
        if '@type' not in data and data['@type'] != 'Site':
            return ErrorResponse('NotAllowed',
                                 'can not create this type %s' % data['@type'],
                                 status=401)

        if 'title' not in data and not data['title']:
            return ErrorResponse('NotAllowed', 'We need a title', status=401)

        if 'id' not in data:
            return ErrorResponse('NotAllowed', 'We need an id', status=401)

        if 'description' not in data:
            data['description'] = ''

        value = await self.context.async_contains(data['id'])

        if value:
            # Already exist
            return ErrorResponse('NotAllowed', 'Duplicate id', status=401)

        site = await create_content('Site',
                                    id=data['id'],
                                    title=data['title'],
                                    description=data['description'])

        # Special case we don't want the parent pointer
        site.__name__ = data['id']

        await self.context.async_set(data['id'], site)
        await site.install()

        self.request._site_id = site.__name__

        user = get_authenticated_user_id(self.request)

        # Local Roles assign owner as the creator user
        roleperm = IPrincipalRoleManager(site)
        roleperm.assign_role_to_principal('guillotina.Owner', user)

        await notify(ObjectAddedEvent(site, self.context, site.__name__))

        resp = {'@type': 'Site', 'id': data['id'], 'title': data['title']}
        headers = {'Location': self.request.path + data['id']}

        return Response(response=resp, headers=headers)
Ejemplo n.º 26
0
    async def begin(self, request=None):
        """Starts a new transaction.
        """

        if request is None:
            try:
                request = get_current_request()
            except RequestNotFound:
                pass

        user = None

        txn = None

        # already has txn registered, as long as connection is closed, it
        # is safe
        if (getattr(request, '_txn', None) is not None and request._txn.status
                in (Status.ABORTED, Status.COMMITTED, Status.CONFLICT)):
            # re-use txn if possible
            txn = request._txn
            txn.status = Status.ACTIVE
            if txn._db_conn is not None:
                try:
                    await self._close_txn(txn)
                except Exception:
                    logger.warn('Unable to close spurious connection',
                                exc_info=True)
        else:
            txn = Transaction(self, request=request)

        self._last_txn = txn

        if request is not None:
            # register tm and txn with request
            request._tm = self
            request._txn = txn
            user = get_authenticated_user_id(request)

        if user is not None:
            txn.user = user

        db_conn = self._last_db_conn = await self._storage.open()
        txn._query_count_start = _get_conn_query_count(db_conn)
        await txn.tpc_begin(db_conn)

        return txn
Ejemplo n.º 27
0
    async def begin(self, request=None):
        """Starts a new transaction.
        """

        if request is None:
            try:
                request = get_current_request()
            except RequestNotFound:
                pass

        user = None

        txn = None

        # already has txn registered, as long as connection is closed, it
        # is safe
        if (getattr(request, '_txn', None) is not None and
                request._txn.status in (Status.ABORTED, Status.COMMITTED, Status.CONFLICT)):
            # re-use txn if possible
            txn = request._txn
            txn.status = Status.ACTIVE
            if (txn._db_conn is not None and
                    getattr(txn._db_conn, '_in_use', None) is None):
                try:
                    await self._close_txn(txn)
                except Exception:
                    logger.warn('Unable to close spurious connection', exc_info=True)
        else:
            txn = Transaction(self, request=request)

        self._last_txn = txn

        if request is not None:
            # register tm and txn with request
            request._tm = self
            request._txn = txn
            user = get_authenticated_user_id(request)

        if user is not None:
            txn.user = user

        await txn.tpc_begin()

        return txn
Ejemplo n.º 28
0
    async def begin(self, request=None):
        """Starts a new transaction.
        """

        db_conn = self._last_db_conn = await self._storage.open()

        if request is None:
            try:
                request = get_current_request()
            except RequestNotFound:
                pass

        user = None

        txn = None
        # already has txn registered, as long as connection is closed, it
        # is safe
        if (getattr(request, '_txn', None) is not None
                and request._txn._db_conn is None
                and request._txn.status in (Status.ABORTED, Status.COMMITTED)):
            # re-use txn if possible
            txn = request._txn
            txn.status = Status.ACTIVE
        # XXX do we want to auto clean up here? Or throw an error?
        # This will break tests that are starting multiple transactions
        # else:
        #     await self._close_txn(request._txn)
        else:
            txn = Transaction(self, request=request)

        self._last_txn = txn

        if request is not None:
            # register tm and txn with request
            request._tm = self
            request._txn = txn
            user = get_authenticated_user_id(request)

        if user is not None:
            txn.user = user

        await txn.tpc_begin(db_conn)

        return txn
Ejemplo n.º 29
0
    def log(self, *args, **kwargs):
        from guillotina.utils import get_authenticated_user_id
        from guillotina.utils import get_current_request
        from guillotina.exceptions import RequestNotFound

        func = getattr(self._logger, name)
        request = kwargs.pop("request", None)
        eid = kwargs.pop("eid", None)
        if request is None:
            try:
                request = get_current_request()
            except RequestNotFound:
                pass
        if request is not None:
            if eid is None:
                eid = uuid.uuid4().hex
            extra = kwargs.get("extra", {})
            try:
                url = request.url.human_repr()
            except AttributeError:
                # older version of aiohttp
                url = request.path
            try:
                agent = request.headers["User-Agent"]
            except (AttributeError, KeyError):
                agent = "Unknown"
            container = task_vars.container.get()
            db = task_vars.db.get()
            extra.update({
                "method": request.method,
                "url": url,
                "container": getattr(container, "id", None),
                "account": getattr(container, "id", None),
                "db_id": getattr(db, "id", None),
                "user": get_authenticated_user_id() or "Anonymous",
                "eid": eid,
                "agent": agent,
                # in case a fake req object doesn't use the guillotina Request object
                "request_uid": getattr(request, "uid", None),
            })
            kwargs["extra"] = extra
        return func(*args, **kwargs)
Ejemplo n.º 30
0
    def log(self, *args, **kwargs):
        from guillotina.utils import get_authenticated_user_id
        from guillotina.utils import get_current_request
        from guillotina.exceptions import RequestNotFound

        func = getattr(self._logger, name)
        request = kwargs.pop('request', None)
        eid = kwargs.pop('eid', None)
        if request is None:
            try:
                request = get_current_request()
            except RequestNotFound:
                pass
        if request is not None:
            if eid is None:
                eid = uuid.uuid4().hex
            extra = kwargs.get('extra', {})
            try:
                url = request.url.human_repr()
            except AttributeError:
                # older version of aiohttp
                url = request.path
            try:
                agent = request.headers['User-Agent']
            except (AttributeError, KeyError):
                agent = 'Unknown'
            container = task_vars.container.get()
            db = task_vars.db.get()
            extra.update({
                'method': request.method,
                'url': url,
                'container': getattr(container, 'id', None),
                'account': getattr(container, 'id', None),
                'db_id': getattr(db, 'id', None),
                'user': get_authenticated_user_id() or 'Anonymous',
                'eid': eid,
                'agent': agent,
                # in case a fake req object doesn't use the guillotina Request object
                'request_uid': getattr(request, 'uid', None)
            })
            kwargs['extra'] = extra
        return func(*args, **kwargs)
Ejemplo n.º 31
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
Ejemplo n.º 32
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
Ejemplo n.º 33
0
    def log(self, *args, **kwargs):
        from guillotina.utils import get_authenticated_user_id
        from guillotina.utils import get_current_request
        from guillotina.exceptions import RequestNotFound

        func = getattr(self._logger, name)
        request = kwargs.pop('request', None)
        eid = kwargs.pop('eid', None)
        if request is None:
            try:
                request = get_current_request()
            except RequestNotFound:
                pass
        if request is not None:
            if eid is None:
                eid = uuid.uuid4().hex
            extra = kwargs.get('extra', {})
            try:
                url = request.url.human_repr()
            except AttributeError:
                # older version of aiohttp
                url = request.path
            try:
                agent = request.headers['User-Agent']
            except (AttributeError, KeyError):
                agent = 'Unknown'
            extra.update({
                'method': request.method,
                'url': url,
                'container': getattr(request, '_container_id', None),
                'account': getattr(request, '_container_id', None),
                'db_id': getattr(request, '_db_id', None),
                'user': get_authenticated_user_id(request) or 'Anonymous',
                'eid': eid,
                'agent': agent,
                # in case a fake req object doesn't use the guillotina Request object
                'request_uid': getattr(request, 'uid', None)
            })
            kwargs['extra'] = extra
        return func(*args, **kwargs)