async def move(context, request): try: data = await request.json() except Exception: data = {} destination = data.get('destination') if destination is None: destination_ob = context.__parent__ else: try: destination_ob = await navigate_to(request.container, destination) except KeyError: destination_ob = None if destination_ob is None: raise PreconditionFailed(context, 'Could not find destination object') old_id = context.id if 'new_id' in data: new_id = data['new_id'] context.id = context.__name__ = new_id else: new_id = context.id security = IInteraction(request) if not security.check_permission('guillotina.AddContent', destination_ob): raise PreconditionFailed( context, 'You do not have permission to add content to the ' 'destination object') if await destination_ob.async_contains(new_id): raise PreconditionFailed( context, f'Destination already has object with the id {new_id}') original_parent = context.__parent__ txn = get_transaction(request) cache_keys = txn._cache.get_cache_keys(context, 'deleted') data['id'] = new_id await notify( BeforeObjectMovedEvent(context, original_parent, old_id, destination_ob, new_id, payload=data)) context.__parent__ = destination_ob context._p_register() await notify( ObjectMovedEvent(context, original_parent, old_id, destination_ob, new_id, payload=data)) cache_keys += txn._cache.get_cache_keys(context, 'added') await txn._cache.delete_all(cache_keys) absolute_url = query_multi_adapter((context, request), IAbsoluteURL) return { '@url': absolute_url() }
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))
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))
async def __call__(self, changed=False): """Change permissions""" context = self.context request = self.request data = await request.json() if ("prinrole" not in data and "roleperm" not in data and "prinperm" not in data and "perminhe" not in data): raise PreconditionFailed( self.context, "prinrole or roleperm or prinperm missing") return await apply_sharing(context, data)
async def can_i_do(context, request): if 'permission' not in request.query and 'permissions' not in request.query: raise PreconditionFailed(context, 'No permission param') policy = get_security_policy() if 'permissions' in request.query: results = {} for perm in request.query['permissions'].split(','): results[perm] = policy.check_permission(perm, context) return results else: return policy.check_permission(request.query['permission'], context)
async def can_i_do(context, request): if "permission" not in request.query and "permissions" not in request.query: raise PreconditionFailed(context, "No permission param") policy = get_security_policy() if "permissions" in request.query: results = {} for perm in request.query["permissions"].split(","): results[perm] = policy.check_permission(perm, context) return results else: return policy.check_permission(request.query["permission"], context)
async def can_i_do(context, request): if 'permission' not in request.query and 'permissions' not in request.query: raise PreconditionFailed(context, 'No permission param') interaction = IInteraction(request) if 'permissions' in request.GET: results = {} for perm in request.GET['permissions'].split(','): results[perm] = interaction.check_permission(perm, context) return results else: return interaction.check_permission(request.GET['permission'], context)
async def __call__(self, changed=False): """Change permissions""" context = self.context request = self.request 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') return await apply_sharing(context, data)
async def update_groups(group, event): container = get_current_container() users = group.users for user in users: try: context = await navigate_to(container, f"users/{user}") except KeyError: raise PreconditionFailed(container, "inexistent user") if group.id not in context.user_groups: context.user_groups.append(user) context.register()
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
async def duplicate(context, request): try: data = await request.json() except Exception: data = {} destination = data.get('destination') if destination is not None: destination_ob = await navigate_to(request.container, destination) if destination_ob is None: raise PreconditionFailed( context, 'Could not find destination object', ) else: destination_ob = context.__parent__ security = IInteraction(request) if not security.check_permission('guillotina.AddContent', destination_ob): raise PreconditionFailed( context, 'You do not have permission to add content to ' 'the destination object', ) if 'new_id' in data: new_id = data['new_id'] 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}' new_obj = await create_content_in_container( destination_ob, context.type_name, new_id, id=new_id, creators=context.creators, contributors=context.contributors) for key in context.__dict__.keys(): if key.startswith('__') or key.startswith('_BaseObject'): continue if key in ('id', ): continue new_obj.__dict__[key] = context.__dict__[key] 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) data['id'] = new_id await notify( ObjectDuplicatedEvent(new_obj, context, destination_ob, new_id, payload=data)) get = DefaultGET(new_obj, request) return await get()
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 move( context: IResource, destination: Optional[Union[IResource, str]] = None, new_id: Optional[str] = None, check_permission: bool = True, ) -> None: if destination is None: destination_ob = context.__parent__ else: if isinstance(destination, str): destination_ob = None if destination.startswith("/"): container = task_vars.container.get() if container is not None: 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") if destination_ob.__uuid__ == context.__uuid__: raise PreconditionFailed(context, "You can not move object to itself") if destination_ob.__uuid__ == context.__parent__.__uuid__ and new_id == context.id: raise PreconditionFailed(context, "Object already belongs to this parent with same id") txn = get_transaction() if txn is not None: cache_keys = txn._cache.get_cache_keys(context, "deleted") old_id = context.id if new_id is None: new_id = context.id else: id_checker = get_adapter(context, IIDChecker) if not isinstance(new_id, str) or not await id_checker(new_id, context.type_name): raise PreconditionFailed(new_id, "Invalid id") 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 await destination_ob.async_contains(new_id): raise HTTPConflict(content={"reason": f'Destination already has object with the id "{new_id}"'}) original_parent = context.__parent__ await notify( BeforeObjectMovedEvent( context, original_parent, old_id, destination_ob, new_id, payload={"id": new_id, "destination": destination}, ) ) if new_id != old_id: context.id = context.__name__ = new_id context.__parent__ = destination_ob context.register() await notify( ObjectMovedEvent( context, original_parent, old_id, destination_ob, new_id, payload={"id": new_id, "destination": destination}, ) ) if txn is not None: cache_keys += txn._cache.get_cache_keys(context, "added") await txn._cache.delete_all(cache_keys)
async def duplicate( context: IResource, destination: Union[IResource, str] = None, new_id: str = None, check_permission: bool = True, ) -> IResource: if destination is not None: if isinstance(destination, str): container = task_vars.container.get() if container: destination_ob = await navigate_to(container, destination) else: raise PreconditionFailed(context, "Could not find destination object") 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 new_obj = await create_content_in_container( destination_ob, context.type_name, new_id, id=new_id, creators=context.creators, contributors=context.contributors, ) for key in context.__dict__.keys(): if key.startswith("__") or key.startswith("_BaseObject"): continue if key in ("id",): continue new_obj.__dict__[key] = context.__dict__[key] 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 duplicate(context: IResource, destination: Union[IResource, str] = None, new_id: str = None, check_permission: bool = True) -> IResource: if destination is not None: if isinstance(destination, str): request = get_current_request() destination_ob = await navigate_to(request.container, destination) 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: request = get_current_request() security = IInteraction(request) if not security.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 new_obj = await create_content_in_container( destination_ob, context.type_name, new_id, id=new_id, creators=context.creators, contributors=context.contributors) for key in context.__dict__.keys(): if key.startswith('__') or key.startswith('_BaseObject'): continue if key in ('id', ): continue new_obj.__dict__[key] = context.__dict__[key] 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 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))
async def move(context: IResource, destination: Union[IResource, str] = None, new_id: str = None, check_permission: bool = True) -> None: if destination is None: destination_ob = context.__parent__ else: if isinstance(destination, str): request = get_current_request() try: destination_ob = await navigate_to(request.container, destination) except KeyError: destination_ob = None else: destination_ob = destination if destination_ob is None: raise PreconditionFailed(context, 'Could not find destination object') old_id = context.id if new_id is not None: context.id = context.__name__ = new_id else: new_id = context.id if check_permission: request = get_current_request() security = IInteraction(request) if not security.check_permission('guillotina.AddContent', destination_ob): raise PreconditionFailed( context, 'You do not have permission to add content to the ' 'destination object') if await destination_ob.async_contains(new_id): raise PreconditionFailed( context, f'Destination already has object with the id {new_id}') original_parent = context.__parent__ txn = get_transaction(request) cache_keys = txn._cache.get_cache_keys(context, 'deleted') await notify( BeforeObjectMovedEvent(context, original_parent, old_id, destination_ob, new_id, payload={ 'id': new_id, 'destination': destination })) context.__parent__ = destination_ob context._p_register() await notify( ObjectMovedEvent(context, original_parent, old_id, destination_ob, new_id, payload={ 'id': new_id, 'destination': destination })) cache_keys += txn._cache.get_cache_keys(context, 'added') await txn._cache.delete_all(cache_keys)
async def move(context: IResource, destination: Union[IResource, str] = None, new_id: str = None, check_permission: bool = True) -> None: if destination is None: destination_ob = context.__parent__ else: if isinstance(destination, str): container = task_vars.container.get() if container is not None: try: destination_ob = await navigate_to(container, destination) except KeyError: destination_ob = None else: raise PreconditionFailed(context, 'Could not find destination object') else: destination_ob = destination if destination_ob is None: raise PreconditionFailed(context, 'Could not find destination object') if destination_ob.__uuid__ == context.__uuid__: raise PreconditionFailed(context, 'You can not move object to itself') if destination_ob.__uuid__ == context.__parent__.__uuid__ and new_id == context.id: raise PreconditionFailed( context, 'Object already belongs to this parent with same id') txn = get_transaction() if txn is not None: cache_keys = txn._cache.get_cache_keys(context, 'deleted') old_id = context.id if new_id is not None: context.id = context.__name__ = new_id else: new_id = context.id 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 await destination_ob.async_contains(new_id): raise PreconditionFailed( context, f'Destination already has object with the id {new_id}') original_parent = context.__parent__ await notify( BeforeObjectMovedEvent(context, original_parent, old_id, destination_ob, new_id, payload={ 'id': new_id, 'destination': destination })) context.__parent__ = destination_ob context.register() await notify( ObjectMovedEvent(context, original_parent, old_id, destination_ob, new_id, payload={ 'id': new_id, 'destination': destination })) if txn is not None: cache_keys += txn._cache.get_cache_keys(context, 'added') await txn._cache.delete_all(cache_keys)