示例#1
0
    def get_records(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)

        # 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='',
                                              collection_id='bucket')
            for bucket in every_bucket:
                bucket_uri = '/buckets/{id}'.format(**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,
                                                          collection_id=res)
                    for subobject in every_subobjects:
                        subobj_uri = bucket_uri + '/{0}s/{1}'.format(
                            res, 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, prefix id with resource name
            matchdict[resource_name + '_id'] = matchdict.get('id')

            # 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_record_set(entries,
                                  filters=filters,
                                  sorting=sorting,
                                  pagination_rules=pagination_rules,
                                  limit=limit)
示例#2
0
    def get_records(
        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="", collection_id="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, collection_id=res)
                    for subobject in every_subobjects:
                        subobj_uri = bucket_uri + "/{0}s/{1}".format(res, 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_record_set(
            entries,
            filters=filters,
            sorting=sorting,
            id_field="uri",
            pagination_rules=pagination_rules,
            limit=limit,
        )
示例#3
0
    def get_records(
        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="",
                                              collection_id="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,
                                                          collection_id=res)
                    for subobject in every_subobjects:
                        subobj_uri = bucket_uri + "/{0}s/{1}".format(
                            res, 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_record_set(
            entries,
            filters=filters,
            sorting=sorting,
            id_field="uri",
            pagination_rules=pagination_rules,
            limit=limit,
        )
示例#4
0
    def get_records(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.effective_principals
        if Authenticated in principals:
            # Since this view does not require any permission (can be used to
            # obtain public users permissions), we have to add the prefixed
            # userid among the principals
            # (see :mod:`kinto.core.authentication`)
            userid = self.request.prefixed_userid
            principals.append(userid)

        # Query every possible permission of the current user from backend.
        backend = self.request.registry.permission
        perms_by_object_uri = backend.get_accessible_objects(principals)

        entries = []
        for object_uri, perms in perms_by_object_uri.items():
            try:
                # Obtain associated resource 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, prefix id with resource name
            matchdict[resource_name + '_id'] = matchdict.get('id')

            # 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_record_set(entries,
                                  filters=filters,
                                  sorting=sorting,
                                  pagination_rules=pagination_rules,
                                  limit=limit)
示例#5
0
 def get_records(self, filters=None, sorting=None, pagination_rules=None,
                 limit=None, include_deleted=False, parent_id=None):
     return extract_record_set(self._entries(), filters=filters, sorting=sorting,
                               pagination_rules=pagination_rules,
                               limit=limit)