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()
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
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
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']
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"]
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']
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
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)
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))
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))
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)
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)
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)
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)
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()
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)
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()
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)
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
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)
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)
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)