Ejemplo n.º 1
0
async def create_container(parent: IDatabase, container_id: str,
                           container_type: str='Container',
                           owner_id: Optional[str]=None,
                           emit_events: bool=True, **data):
    container = await create_content(
        container_type, id=container_id,
        **data)

    # Special case we don't want the parent pointer
    container.__name__ = container_id

    await parent.async_set(container_id, container)
    await container.install()

    # Local Roles assign owner as the creator user
    if owner_id is not None:
        roleperm = IPrincipalRoleManager(container)
        roleperm.assign_role_to_principal('guillotina.Owner', owner_id)

    if emit_events:
        await notify(ObjectAddedEvent(
            container, parent, container.__name__, payload={
                'id': container.id,
                **data
            }))
    return container
Ejemplo n.º 2
0
    async def generate_test_data(self, db):
        # don't slow us down with transactions
        db._db._storage._transaction_strategy = 'none'

        tm = db.get_transaction_manager()
        tm.request = self.request
        await tm.begin(self.request)
        container = await db.async_get('testdata')
        if container is None:
            container = await create_content(
                'Container', id='testdata', title='Test Data')
            container.__name__ = 'testdata'
            await db.async_set('testdata', container)
            await container.install()
            self.request._container_id = container.__name__
            # Local Roles assign owner as the creator user
            roleperm = IPrincipalRoleManager(container)
            roleperm.assign_role_to_principal('guillotina.Owner', 'root')

            await notify(ObjectAddedEvent(container, db, container.__name__))
            await tm.commit()
            await tm.begin(self.request)

        api = WikipediaAPI()
        folder_count = 0
        async for page_data in api.iter_pages():
            await self.import_folder(api, tm, container, page_data)
            folder_count += 1
            if folder_count >= self.arguments.per_node:
                break
Ejemplo n.º 3
0
async def create_container(
    parent: IDatabase,
    container_id: str,
    container_type: str = "Container",
    owner_id: Optional[str] = None,
    emit_events: bool = True,
    **data,
):
    container = await create_content(container_type, id=container_id, **data)

    # Special case we don't want the parent pointer
    container.__name__ = container_id

    task_vars.container.set(container)
    await parent.async_set(container_id, container)
    await container.install()

    # Local Roles assign owner as the creator user
    if owner_id is not None:
        roleperm = IPrincipalRoleManager(container)
        roleperm.assign_role_to_principal("guillotina.Owner", owner_id)

    if emit_events:
        await notify(
            ObjectAddedEvent(container,
                             parent,
                             container.__name__,
                             payload={
                                 "id": container.id,
                                 **data
                             }))
    task_vars.container.set(container)
    return container
Ejemplo n.º 4
0
def test_get_owners(dummy_guillotina):
    content = create_content()
    roleperm = IPrincipalRoleManager(content)
    roleperm.assign_role_to_principal('guillotina.Owner', 'foobar')
    assert utils.get_owners(content) == ['foobar']
    roleperm.assign_role_to_principal('guillotina.Owner', 'foobar2')
    assert utils.get_owners(content) == ['foobar', 'foobar2']
Ejemplo n.º 5
0
    async def generate_test_data(self, db):
        tm = self.request._tm = db.get_transaction_manager()
        self.request._db_id = db.id
        tm = db.get_transaction_manager()
        self.request._txn = txn = await tm.begin(self.request)

        container = await db.async_get(self.arguments.container)
        if container is None:
            container = await create_content(
                'Container', id=self.arguments.container, title='Test Data')
            container.__name__ = self.arguments.container
            await db.async_set(self.arguments.container, container)
            await container.install()
            self.request._container_id = container.__name__
            # Local Roles assign owner as the creator user
            roleperm = IPrincipalRoleManager(container)
            roleperm.assign_role_to_principal('guillotina.Owner', 'root')

            await notify(ObjectAddedEvent(container, db, container.__name__))
            await tm.commit(txn=txn)
            txn = await tm.begin(self.request)

        self.request.container = container
        self.request._container_id = container.id

        api = WikipediaAPI()
        folder_count = 0
        async for page_data in api.iter_pages():
            await self.import_folder(api, tm, txn, container, page_data)
            folder_count += 1
            if folder_count >= self.arguments.per_node:
                break

        await tm.commit(txn=txn)
        api.close()
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'})

        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.º 7
0
async def on_user_created(user: User, event: ObjectAddedEvent) -> None:
    # Store only the hash of the password
    user.password = hash_password(user.password)

    # Give user ownership to his own folder object by default
    roleperm = IPrincipalRoleManager(user)
    roleperm.assign_role_to_principal("guillotina.Owner", user.id)

    await notify(NewUserAdded(user))
Ejemplo n.º 8
0
async def user_created(user, event):
    user.password = hash_password(user.password)

    # user has access to his own object by default
    container = get_current_container()
    roleperm = IPrincipalRoleManager(container)
    roleperm.assign_role_to_principal('guillotina.Owner', user.id)

    await notify(NewUserAdded(user))
Ejemplo n.º 9
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.º 10
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.º 11
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.º 12
0
async def sharing_post(context, request):
    """Change permissions"""
    lroles = local_roles()
    data = await request.json()
    if 'prinrole' not in data and \
            'roleperm' not in data and \
            'prinperm' not in data:
        raise AttributeError('prinrole or roleperm or prinperm missing')

    if 'type' not in data:
        raise AttributeError('type missing')

    setting = data['type']

    # we need to check if we are changing any info
    changed = False

    if 'prinrole' in data:
        if setting not in PermissionMap['prinrole']:
            raise AttributeError('Invalid Type')
        manager = IPrincipalRoleManager(context)
        operation = PermissionMap['prinrole'][setting]
        func = getattr(manager, operation)
        for user, roles in data['prinrole'].items():
            for role in roles:
                if role in lroles:
                    changed = True
                    func(role, user)
                else:
                    raise KeyError('No valid local role')

    if 'prinperm' in data:
        if setting not in PermissionMap['prinperm']:
            raise AttributeError('Invalid Type')
        manager = IPrincipalPermissionManager(context)
        operation = PermissionMap['prinperm'][setting]
        func = getattr(manager, operation)
        for user, permissions in data['prinperm'].items():
            for permision in permissions:
                changed = True
                func(permision, user)

    if 'roleperm' in data:
        if setting not in PermissionMap['roleperm']:
            raise AttributeError('Invalid Type')
        manager = IRolePermissionManager(context)
        operation = PermissionMap['roleperm'][setting]
        func = getattr(manager, operation)
        for role, permissions in data['roleperm'].items():
            for permission in permissions:
                changed = True
                func(permission, role)

    if changed:
        context._p_register()  # make sure data is saved
        await notify(ObjectPermissionsModifiedEvent(context, data))
Ejemplo n.º 13
0
    async def generate_test_data(self, db):
        tm = db.get_transaction_manager()
        task_vars.db.set(db)
        tm = db.get_transaction_manager()
        txn = await tm.begin()

        container = await db.async_get(self.arguments.container)
        if container is None:
            container = await create_content("Container",
                                             id=self.arguments.container,
                                             title="Test Data")
            container.__name__ = self.arguments.container
            await db.async_set(self.arguments.container, container)
            await container.install()
            # Local Roles assign owner as the creator user
            roleperm = IPrincipalRoleManager(container)
            roleperm.assign_role_to_principal("guillotina.Owner", "root")

            await notify(ObjectAddedEvent(container, db, container.__name__))
            try:
                await tm.commit(txn=txn)
            except ConflictIdOnContainer:
                # ignore id conflicts
                await tm.abort(txn=txn)
            txn = await tm.begin()

        task_vars.registry.set(None)
        task_vars.container.set(container)

        api = WikipediaAPI()
        folder_count = 0
        async for page_data in api.iter_pages():
            await self.import_folder(api, tm, txn, container, page_data)
            folder_count += 1
            if folder_count >= self.arguments.per_node:
                break

        try:
            await tm.commit(txn=txn)
        except ConflictIdOnContainer:
            # ignore id conflicts
            await tm.abort(txn=txn)
        api.close()
Ejemplo n.º 14
0
def test_get_owners(dummy_guillotina, mock_txn):
    content = create_content()
    roleperm = IPrincipalRoleManager(content)
    roleperm.assign_role_to_principal("guillotina.Owner", "foobar")
    assert utils.get_owners(content) == ["foobar"]
    roleperm.assign_role_to_principal("guillotina.Owner", "foobar2")
    assert utils.get_owners(content) == ["foobar", "foobar2"]
Ejemplo n.º 15
0
def test_get_owners(dummy_guillotina):
    content = create_content()
    roleperm = IPrincipalRoleManager(content)
    roleperm.assign_role_to_principal('guillotina.Owner', 'foobar')
    assert utils.get_owners(content) == ['foobar']
    roleperm.assign_role_to_principal('guillotina.Owner', 'foobar2')
    assert utils.get_owners(content) == ['foobar', 'foobar2']
Ejemplo n.º 16
0
async def grantinfo(context, request):
    payload = await request.json()
    inherit = payload.get("inherit", None)

    inheritManager = IInheritPermissionManager(context)
    if inherit is True:
        for permission in PERMISSIONS_TO_FORBIT_ONINHERIT:
            inheritManager.allow_inheritance(permission)
    elif inherit is False:
        for permission in PERMISSIONS_TO_FORBIT_ONINHERIT:
            inheritManager.deny_inheritance(permission)

    entries = payload.get("entries", [])
    try:
        container = get_current_container()
        users = await container.async_get("users")
        groups = await container.async_get("groups")
    except (AttributeError, KeyError, ContainerNotFound):
        return None

    prinrole = IPrincipalRoleManager(context)
    for entry in entries:
        valid = False
        if entry["type"] == "group" and await groups.async_contains(entry["id"]
                                                                    ):
            valid = True
        if entry["type"] == "user" and await users.async_contains(entry["id"]):
            valid = True

        if valid:
            for role, permission in entry["roles"].items():
                if permission == "Allow":
                    prinrole.assign_role_to_principal(entry["id"], role)
                elif permission == "Deny":
                    prinrole.remove_role_from_principal(entry["id"], role)
                elif permission is None:
                    prinrole.unset_role_for_principal(entry["id"], role)
                elif permission == "AllowSingle":
                    prinrole.assign_role_to_principal_no_inherit(
                        entry["id"], role)
Ejemplo n.º 17
0
async def addPerms(obj, perms, changed=False):
    """apply some permissions. Copied almost verbatim from sharingPOST service
    """
    lroles = local_roles()
    groles = global_roles()
    if ("prinrole" not in perms and "roleperm" not in perms
            and "prinperm" not in perms):
        raise PreconditionFailed(obj,
                                 "prinrole or roleperm or prinperm missing")

    for prinrole in perms.get("prinrole") or []:
        setting = prinrole.get("setting")
        if setting not in PermissionMap["prinrole"]:
            raise PreconditionFailed(obj, "Invalid Type {}".format(setting))
        manager = IPrincipalRoleManager(obj)
        operation = PermissionMap["prinrole"][setting]
        func = getattr(manager, operation)

        if (obj.type_name == "Container"
                and prinrole["role"] not in groles + lroles):
            raise PreconditionFailed(
                obj, "Not a valid role: {}".format(prinrole["role"]))
        if obj.type_name != "Container" and prinrole["role"] not in lroles:
            raise PreconditionFailed(
                obj, "Not a valid local role: {}".format(prinrole["role"]))

        changed = True
        func(prinrole["role"], prinrole["principal"])

    for prinperm in perms.get("prinperm") or []:
        setting = prinperm["setting"]
        if setting not in PermissionMap["prinperm"]:
            raise PreconditionFailed(obj, "Invalid Type")
        manager = IPrincipalPermissionManager(obj)
        operation = PermissionMap["prinperm"][setting]
        func = getattr(manager, operation)
        changed = True
        func(prinperm["permission"], prinperm["principal"])

    for roleperm in perms.get("roleperm") or []:
        setting = roleperm["setting"]
        if setting not in PermissionMap["roleperm"]:
            raise PreconditionFailed(obj, "Invalid Type")
        manager = IRolePermissionManager(obj)
        operation = PermissionMap["roleperm"][setting]
        func = getattr(manager, operation)
        changed = True
        func(roleperm["permission"], roleperm["role"])

    if changed:
        obj._p_register()  # make sure data is saved
Ejemplo n.º 18
0
async def apply_sharing(context, data):
    lroles = role.local_roles()
    changed = False
    for perminhe in data.get('perminhe') or []:
        setting = perminhe.get('setting')
        if setting not in PermissionMap['perminhe']:
            raise PreconditionFailed(context,
                                     'Invalid Type {}'.format(setting))
        manager = IInheritPermissionManager(context)
        operation = PermissionMap['perminhe'][setting]
        func = getattr(manager, operation)
        changed = True
        func(perminhe['permission'])

    for prinrole in data.get('prinrole') or []:
        setting = prinrole.get('setting')
        if setting not in PermissionMap['prinrole']:
            raise PreconditionFailed(context,
                                     'Invalid Type {}'.format(setting))
        manager = IPrincipalRoleManager(context)
        operation = PermissionMap['prinrole'][setting]
        func = getattr(manager, operation)
        if prinrole['role'] in lroles:
            changed = True
            func(prinrole['role'], prinrole['principal'])
        else:
            raise PreconditionFailed(context, 'No valid local role')

    for prinperm in data.get('prinperm') or []:
        setting = prinperm['setting']
        if setting not in PermissionMap['prinperm']:
            raise PreconditionFailed(context, 'Invalid Type')
        manager = IPrincipalPermissionManager(context)
        operation = PermissionMap['prinperm'][setting]
        func = getattr(manager, operation)
        changed = True
        func(prinperm['permission'], prinperm['principal'])

    for roleperm in data.get('roleperm') or []:
        setting = roleperm['setting']
        if setting not in PermissionMap['roleperm']:
            raise PreconditionFailed(context, 'Invalid Type')
        manager = IRolePermissionManager(context)
        operation = PermissionMap['roleperm'][setting]
        func = getattr(manager, operation)
        changed = True
        func(roleperm['permission'], roleperm['role'])

    if changed:
        context._p_register()  # make sure data is saved
        await notify(ObjectPermissionsModifiedEvent(context, data))
Ejemplo n.º 19
0
    async def __call__(self, changed=False):
        """Change permissions"""
        context = self.context
        request = self.request
        lroles = local_roles()
        data = await request.json()
        if 'prinrole' not in data and \
                'roleperm' not in data and \
                'prinperm' not in data:
            raise PreconditionFailed(
                self.context, 'prinrole or roleperm or prinperm missing')

        for prinrole in data.get('prinrole') or []:
            setting = prinrole.get('setting')
            if setting not in PermissionMap['prinrole']:
                raise PreconditionFailed(self.context,
                                         'Invalid Type {}'.format(setting))
            manager = IPrincipalRoleManager(context)
            operation = PermissionMap['prinrole'][setting]
            func = getattr(manager, operation)
            if prinrole['role'] in lroles:
                changed = True
                func(prinrole['role'], prinrole['principal'])
            else:
                raise PreconditionFailed(self.context, 'No valid local role')

        for prinperm in data.get('prinperm') or []:
            setting = prinperm['setting']
            if setting not in PermissionMap['prinperm']:
                raise PreconditionFailed(self.context, 'Invalid Type')
            manager = IPrincipalPermissionManager(context)
            operation = PermissionMap['prinperm'][setting]
            func = getattr(manager, operation)
            changed = True
            func(prinperm['permission'], prinperm['principal'])

        for roleperm in data.get('roleperm') or []:
            setting = roleperm['setting']
            if setting not in PermissionMap['roleperm']:
                raise PreconditionFailed(self.context, 'Invalid Type')
            manager = IRolePermissionManager(context)
            operation = PermissionMap['roleperm'][setting]
            func = getattr(manager, operation)
            changed = True
            func(roleperm['permission'], roleperm['role'])

        if changed:
            context._p_register()  # make sure data is saved
            await notify(ObjectPermissionsModifiedEvent(context, data))
Ejemplo n.º 20
0
    async def generate_test_data(self, db):
        tm = self.request._tm = db.get_transaction_manager()
        self.request._db_id = db.id
        tm = db.get_transaction_manager()
        self.request._txn = txn = await tm.begin(self.request)

        container = await db.async_get(self.arguments.container)
        if container is None:
            container = await create_content('Container',
                                             id=self.arguments.container,
                                             title='Test Data')
            container.__name__ = self.arguments.container
            await db.async_set(self.arguments.container, container)
            await container.install()
            self.request._container_id = container.__name__
            # Local Roles assign owner as the creator user
            roleperm = IPrincipalRoleManager(container)
            roleperm.assign_role_to_principal('guillotina.Owner', 'root')

            await notify(ObjectAddedEvent(container, db, container.__name__))
            await tm.commit(txn=txn)
            txn = await tm.begin(self.request)

        self.request.container = container
        self.request._container_id = container.id

        api = WikipediaAPI()
        folder_count = 0
        async for page_data in api.iter_pages():
            await self.import_folder(api, tm, txn, container, page_data)
            folder_count += 1
            if folder_count >= self.arguments.per_node:
                break

        await tm.commit(txn=txn)
        api.close()
Ejemplo n.º 21
0
    async def install(self):
        # Creating and registering a local registry
        from guillotina.registry import Registry
        annotations_container = IAnnotations(self)
        registry = Registry()
        await annotations_container.async_set(REGISTRY_DATA_KEY, registry)

        # Set default plugins
        registry.register_interface(ILayers)
        registry.register_interface(IAddons)
        layers = registry.for_interface(ILayers)
        layers['active_layers'] = frozenset()

        roles = IPrincipalRoleManager(self)
        roles.assign_role_to_principal('guillotina.ContainerAdmin',
                                       ROOT_USER_ID)

        roles.assign_role_to_principal('guillotina.Owner', ROOT_USER_ID)
Ejemplo n.º 22
0
    async def __call__(self):
        """To create a content."""
        data = await self.get_data()
        type_ = data.get('@type', None)
        id_ = data.get('id', None)
        behaviors = data.get('@behaviors', None)

        if '__acl__' in data:
            # we don't allow to change the permisions on this patch
            del data['__acl__']

        if not type_:
            return ErrorResponse('RequiredParam',
                                 _("Property '@type' is required"))

        # Generate a temporary id if the id is not given
        if not id_:
            new_id = None
        else:
            if not valid_id(id_):
                return ErrorResponse('PreconditionFailed',
                                     str('Invalid id'),
                                     status=412)
            new_id = id_

        user = get_authenticated_user_id(self.request)

        # Create object
        try:
            obj = await create_content_in_container(self.context,
                                                    type_,
                                                    new_id,
                                                    id=new_id,
                                                    creators=(user, ),
                                                    contributors=(user, ))
        except (PreconditionFailed, NotAllowedContentType) as e:
            return ErrorResponse('PreconditionFailed', str(e), status=412)
        except ConflictIdOnContainer as e:
            return ErrorResponse('ConflictId', str(e), status=409)
        except ValueError as e:
            return ErrorResponse('CreatingObject', str(e), status=400)

        for behavior in behaviors or ():
            obj.add_behavior(behavior)

        # Update fields
        deserializer = queryMultiAdapter((obj, self.request),
                                         IResourceDeserializeFromJson)
        if deserializer is None:
            return ErrorResponse('DeserializationError',
                                 'Cannot deserialize type {}'.format(
                                     obj.type_name),
                                 status=501)

        try:
            await deserializer(data, validate_all=True)
        except DeserializationError as e:
            return ErrorResponse('DeserializationError',
                                 str(e),
                                 exc=e,
                                 status=400)

        # Local Roles assign owner as the creator user
        get_owner = getUtility(IGetOwner)
        roleperm = IPrincipalRoleManager(obj)
        roleperm.assign_role_to_principal('guillotina.Owner', await
                                          get_owner(obj, user))

        await notify(ObjectAddedEvent(obj, self.context, obj.id, payload=data))

        absolute_url = queryMultiAdapter((obj, self.request), IAbsoluteURL)

        headers = {
            'Access-Control-Expose-Headers': 'Location',
            'Location': absolute_url()
        }

        serializer = queryMultiAdapter((obj, self.request),
                                       IResourceSerializeToJson)
        response = await serializer()
        return Response(response=response, headers=headers, status=201)
Ejemplo n.º 23
0
async def apply_sharing(context, data):
    lroles = role.local_roles()
    changed = False
    for perminhe in data.get("perminhe") or []:
        if not isinstance(perminhe, dict):
            raise PreconditionFailed(
                context, "Invalid Type, must be list {}".format(perminhe))
        setting = perminhe.get("setting")
        if setting not in PermissionMap["perminhe"]:
            raise PreconditionFailed(context,
                                     "Invalid Type {}".format(setting))
        manager = IInheritPermissionManager(context)
        operation = PermissionMap["perminhe"][setting]
        func = getattr(manager, operation)
        changed = True
        func(perminhe["permission"])

    for prinrole in data.get("prinrole") or []:
        if not isinstance(prinrole, dict):
            raise PreconditionFailed(
                context, "Invalid Type, must be list {}".format(prinrole))
        setting = prinrole.get("setting")
        if setting not in PermissionMap["prinrole"]:
            raise PreconditionFailed(context,
                                     "Invalid Type {}".format(setting))
        manager = IPrincipalRoleManager(context)
        operation = PermissionMap["prinrole"][setting]
        func = getattr(manager, operation)
        if prinrole["role"] in lroles:
            changed = True
            func(prinrole["role"], prinrole["principal"])
        else:
            raise PreconditionFailed(context, "No valid local role")

    for prinperm in data.get("prinperm") or []:
        if not isinstance(prinperm, dict):
            raise PreconditionFailed(
                context, "Invalid Type, must be list {}".format(prinperm))
        setting = prinperm["setting"]
        if setting not in PermissionMap["prinperm"]:
            raise PreconditionFailed(context, "Invalid Type")
        manager = IPrincipalPermissionManager(context)
        operation = PermissionMap["prinperm"][setting]
        func = getattr(manager, operation)
        changed = True
        func(prinperm["permission"], prinperm["principal"])

    for roleperm in data.get("roleperm") or []:
        if not isinstance(roleperm, dict):
            raise PreconditionFailed(
                context, "Invalid Type, must be list {}".format(roleperm))
        setting = roleperm["setting"]
        if setting not in PermissionMap["roleperm"]:
            raise PreconditionFailed(context, "Invalid Type")
        manager = IRolePermissionManager(context)
        operation = PermissionMap["roleperm"][setting]
        func = getattr(manager, operation)
        changed = True
        func(roleperm["permission"], roleperm["role"])

    if changed:
        context.register()  # make sure data is saved
        await notify(ObjectPermissionsModifiedEvent(context, data))
Ejemplo n.º 24
0
async def duplicate(
    context: IResource,
    destination: Optional[Union[IResource, str]] = None,
    new_id: Optional[str] = None,
    check_permission: bool = True,
    reset_acl: bool = False,
) -> IResource:
    if destination is not None:
        if isinstance(destination, str):
            destination_ob = None
            if destination.startswith("/"):
                container = task_vars.container.get()
                if container:
                    try:
                        destination_ob = await navigate_to(container, destination)
                    except KeyError:
                        pass
            else:
                try:
                    destination_ob = await get_object_by_uid(destination)
                except KeyError:
                    pass
        else:
            destination_ob = destination

        if destination_ob is None:
            raise PreconditionFailed(context, "Could not find destination object")
    else:
        destination_ob = context.__parent__

    if check_permission:
        policy = get_security_policy()
        if not policy.check_permission("guillotina.AddContent", destination_ob):
            raise PreconditionFailed(
                context, "You do not have permission to add content to " "the destination object"
            )

    if new_id is not None:
        if await destination_ob.async_contains(new_id):
            raise PreconditionFailed(context, f"Destination already has object with the id {new_id}")
    else:
        count = 1
        new_id = f"{context.id}-duplicate-{count}"
        while await destination_ob.async_contains(new_id):
            count += 1
            new_id = f"{context.id}-duplicate-{count}"

    from guillotina.content import create_content_in_container

    creators = context.creators
    contributors = context.contributors
    user_id = get_authenticated_user_id()
    if reset_acl:
        creators = [user_id]
        contributors = [user_id]
    new_obj = await create_content_in_container(
        destination_ob,
        context.type_name,
        new_id,
        id=new_id,
        creators=creators,
        contributors=contributors,
        check_security=check_permission,
        check_constraints=True,
    )
    for key in context.__dict__.keys():
        if key.startswith("__") or key.startswith("_BaseObject"):
            continue
        if key in ("id", "creators", "contributors"):
            continue
        new_obj.__dict__[key] = context.__dict__[key]

    if reset_acl:
        new_obj.__acl__ = None
        get_owner = get_utility(IGetOwner)
        roleperm = IPrincipalRoleManager(new_obj)
        owner = await get_owner(new_obj, user_id)
        if owner is not None:
            roleperm.assign_role_to_principal("guillotina.Owner", owner)
    else:
        new_obj.__acl__ = context.__acl__

    for behavior in context.__behaviors__:
        new_obj.add_behavior(behavior)
    # need to copy annotation data as well...
    # load all annotations for context
    [b for b in await get_all_behaviors(context, load=True)]
    annotations_container = IAnnotations(new_obj)
    for anno_id, anno_data in context.__gannotations__.items():
        new_anno_data = AnnotationData()
        for key, value in anno_data.items():
            new_anno_data[key] = value
        await annotations_container.async_set(anno_id, new_anno_data)

    await notify(
        ObjectDuplicatedEvent(
            new_obj, context, destination_ob, new_id, payload={"id": new_id, "destination": destination}
        )
    )
    return new_obj
Ejemplo n.º 25
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)

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

        for addon in data.get('@addons') or []:
            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)
            await addons.install(container, addon)

        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.º 26
0
    async def __call__(self):
        """To create a content."""
        data = await self.get_data()
        type_ = data.get("@type", None)
        id_ = data.get("id", None)
        behaviors = data.get("@behaviors", None)

        if not type_:
            raise ErrorResponse(
                "RequiredParam",
                _("Property '@type' is required"),
                reason=error_reasons.REQUIRED_PARAM_MISSING,
                status=412,
            )

        id_checker = get_adapter(self.context, IIDChecker)
        # Generate a temporary id if the id is not given
        new_id = None
        if not id_:
            generator = query_adapter(self.request, IIDGenerator)
            if generator is not None:
                new_id = await apply_coroutine(generator, data)
                if isinstance(new_id, str) and not await id_checker(new_id, type_):
                    raise ErrorResponse(
                        "PreconditionFailed",
                        "Invalid id: {}".format(new_id),
                        status=412,
                        reason=error_reasons.INVALID_ID,
                    )
        else:
            if not isinstance(id_, str) or not await id_checker(id_, type_):
                raise ErrorResponse(
                    "PreconditionFailed",
                    "Invalid id: {}".format(id_),
                    status=412,
                    reason=error_reasons.INVALID_ID,
                )
            new_id = id_

        user = get_authenticated_user_id()

        options = {"creators": (user,), "contributors": (user,)}
        if "uid" in data:
            options["__uuid__"] = data.pop("uid")

        # Create object
        try:
            obj = await create_content_in_container(
                self.context, type_, new_id, check_constraints=True, **options
            )
        except ValueError as e:
            return ErrorResponse("CreatingObject", str(e), status=412)

        for behavior in behaviors or ():
            obj.add_behavior(behavior)

        # Update fields
        deserializer = query_multi_adapter((obj, self.request), IResourceDeserializeFromJson)
        if deserializer is None:
            return ErrorResponse(
                "DeserializationError",
                "Cannot deserialize type {}".format(obj.type_name),
                status=412,
                reason=error_reasons.DESERIALIZATION_FAILED,
            )

        await deserializer(data, validate_all=True, create=True)

        # Local Roles assign owner as the creator user
        get_owner = IGetOwner(obj)
        roleperm = IPrincipalRoleManager(obj)
        owner = await get_owner(user)
        if owner is not None:
            roleperm.assign_role_to_principal("guillotina.Owner", owner)

        data["id"] = obj.id
        await notify(ObjectAddedEvent(obj, self.context, obj.id, payload=data))

        headers = {"Access-Control-Expose-Headers": "Location", "Location": get_object_url(obj, self.request)}

        serializer = query_multi_adapter((obj, self.request), IResourceSerializeToJsonSummary)
        response = await serializer()
        return Response(content=response, status=201, headers=headers)
Ejemplo n.º 27
0
    async def __call__(self):
        """To create a content."""
        data = await self.get_data()
        type_ = data.get('@type', None)
        id_ = data.get('id', None)
        behaviors = data.get('@behaviors', None)

        if not type_:
            raise ErrorResponse('RequiredParam',
                                _("Property '@type' is required"),
                                reason=error_reasons.REQUIRED_PARAM_MISSING,
                                status=412)

        # Generate a temporary id if the id is not given
        new_id = None
        if not id_:
            generator = query_adapter(self.request, IIDGenerator)
            if generator is not None:
                new_id = generator(data)
        else:
            if not isinstance(id_, str) or not valid_id(id_):
                raise ErrorResponse('PreconditionFailed',
                                    str('Invalid id'),
                                    status=412,
                                    reason=error_reasons.INVALID_ID)
            new_id = id_

        user = get_authenticated_user_id(self.request)

        options = {'creators': (user, ), 'contributors': (user, )}
        if 'uid' in data:
            options['_p_oid'] = data.pop('uid')

        # Create object
        try:
            obj = await create_content_in_container(self.context, type_,
                                                    new_id, **options)
        except ValueError as e:
            return ErrorResponse('CreatingObject', str(e), status=412)

        for behavior in behaviors or ():
            obj.add_behavior(behavior)

        # Update fields
        deserializer = query_multi_adapter((obj, self.request),
                                           IResourceDeserializeFromJson)
        if deserializer is None:
            return ErrorResponse('DeserializationError',
                                 'Cannot deserialize type {}'.format(
                                     obj.type_name),
                                 status=412,
                                 reason=error_reasons.DESERIALIZATION_FAILED)

        await deserializer(data, validate_all=True, create=True)

        # Local Roles assign owner as the creator user
        get_owner = get_utility(IGetOwner)
        roleperm = IPrincipalRoleManager(obj)
        owner = await get_owner(obj, user)
        if owner is not None:
            roleperm.assign_role_to_principal('guillotina.Owner', owner)

        data['id'] = obj.id
        await notify(ObjectAddedEvent(obj, self.context, obj.id, payload=data))

        absolute_url = query_multi_adapter((obj, self.request), IAbsoluteURL)

        headers = {
            'Access-Control-Expose-Headers': 'Location',
            'Location': absolute_url()
        }

        serializer = query_multi_adapter((obj, self.request),
                                         IResourceSerializeToJsonSummary)
        response = await serializer()
        return Response(content=response, status=201, headers=headers)