def get_objects( self, filters=None, sorting=None, pagination_rules=None, limit=None, include_deleted=False, parent_id=None, ): objs, _ = extract_object_set( objects=self._entries(), filters=filters, sorting=sorting, pagination_rules=pagination_rules, limit=limit, ) return objs
def get_objects( self, filters=None, sorting=None, pagination_rules=None, limit=None, include_deleted=False, parent_id=None, ): # Invert the permissions inheritance tree. perms_descending_tree = {} for on_resource, tree in PERMISSIONS_INHERITANCE_TREE.items(): for obtained_perm, obtained_from in tree.items(): for from_resource, perms in obtained_from.items(): for perm in perms: perms_descending_tree.setdefault( from_resource, {}).setdefault(perm, {}).setdefault( on_resource, set()).add(obtained_perm) # Obtain current principals. principals = self.request.prefixed_principals # Query every possible permission of the current user from backend. backend = self.request.registry.permission perms_by_object_uri = backend.get_accessible_objects(principals) # Check settings for every allowed resources. from_settings = allowed_from_settings(self.request.registry.settings, principals) # Add additional resources and permissions defined in settings/plugins for root_perm in from_settings.get("root", []): resource_name, _ = root_perm.split(":") perms_by_object_uri.setdefault("/", set()).add(root_perm) perms_descending_tree.setdefault("root", {}).update( {root_perm: { "root": {root_perm} }}) # Expand permissions obtained from backend with the object URIs that # correspond to permissions allowed from settings. allowed_resources = {"bucket", "collection", "group"} & set( from_settings.keys()) if allowed_resources: storage = self.request.registry.storage every_bucket, _ = storage.get_all(parent_id="", resource_name="bucket") for bucket in every_bucket: bucket_uri = "/buckets/{id}".format_map(bucket) for res in allowed_resources: resource_perms = from_settings[res] # Bucket is always fetched. if res == "bucket": perms_by_object_uri.setdefault( bucket_uri, set()).update(resource_perms) continue # Fetch bucket collections and groups. # XXX: wrong approach: query in a loop! every_subobjects, _ = storage.get_all(parent_id=bucket_uri, resource_name=res) for subobject in every_subobjects: subobj_uri = bucket_uri + f"/{res}s/{subobject['id']}" perms_by_object_uri.setdefault( subobj_uri, set()).update(resource_perms) entries = [] for object_uri, perms in perms_by_object_uri.items(): try: # Obtain associated res from object URI resource_name, matchdict = core_utils.view_lookup( self.request, object_uri) except ValueError: # Skip permissions entries that are not linked to an object URI continue # For consistency with event payloads, if resource has an id, # prefix it with its resource name if "id" in matchdict: matchdict[resource_name + "_id"] = matchdict["id"] # The imaginary "root" resource gets mapped to the hello # view. Handle it explicitly. if resource_name == "hello": resource_name = "root" # Expand implicit permissions using descending tree. permissions = set(perms) for perm in perms: obtained = perms_descending_tree[resource_name][perm] # Related to same resource only and not every sub-objects. # (e.g "bucket:write" gives "bucket:read" but not "group:read") permissions |= obtained[resource_name] entry = dict( uri=object_uri, resource_name=resource_name, permissions=list(permissions), **matchdict, ) entries.append(entry) return extract_object_set( entries, filters=filters, sorting=sorting, id_field="uri", pagination_rules=pagination_rules, limit=limit, )