Ejemplo n.º 1
0
    def __init__(self, request):
        self.__acl__ = []
        self.used_uuid = False
        # used_uuid is set to true if user who is normally not authorized to
        # view the resource gains access to it because owner set it to public
        # and user knows the uuid of object

        alert_id = request.matchdict.get("alert_id",
                                         request.GET.get("alert_id"))
        self.alert = AlertChannelActionService.by_pkey(alert_id)
        if not self.alert:
            raise HTTPNotFound()

        self.chart = DashboardChartService.by_uuid(self.alert.other_id)

        if not self.chart:
            raise HTTPNotFound()

        self.resource = ResourceService.by_resource_id(self.chart.resource_id)
        if self.resource and request.user:
            self.__acl__ = self.resource.__acl__
            permissions = ResourceService.perms_for_user(
                self.resource, request.user)
            for perm_user, perm_name in permission_to_04_acls(permissions):
                self.__acl__.append(rewrite_root_perm(perm_user, perm_name))

        if self.resource and self.resource.public:
            if not request.has_permission("view", self):
                self.used_uuid = True
            self.__acl__.append((Allow, Everyone, "view"))

        add_root_superperm(request, self)
Ejemplo n.º 2
0
    def __init__(self, request):
        Resource = appenlight.models.resource.Resource

        self.__acl__ = []
        group_id = request.matchdict.get("group_id", request.params.get("group_id"))
        group_id = to_integer_safe(group_id)
        self.report_group = ReportGroupService.by_id(group_id) if group_id else None
        if not self.report_group:
            raise HTTPNotFound()

        self.public = self.report_group.public
        self.resource = (
            ResourceService.by_resource_id(self.report_group.resource_id)
            if self.report_group
            else None
        )

        if self.resource:
            self.__acl__ = self.resource.__acl__
        if request.user:
            permissions = ResourceService.perms_for_user(self.resource, request.user)
            for perm_user, perm_name in permission_to_04_acls(permissions):
                self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
        if self.public:
            self.__acl__.append((Allow, Everyone, "view"))
        if not request.user:
            # unauthed users need to visit using both group and report pair
            report_id = request.params.get(
                "reportId", request.params.get("report_id", -1)
            )
            report = self.report_group.get_report(report_id, public=True)
            if not report:
                raise HTTPNotFound()
        add_root_superperm(request, self)
Ejemplo n.º 3
0
def user_resource_permission_create(request):
    """
    Set new permissions for user for a resource
    """
    resource = request.context.resource
    user_name = request.unsafe_json_body.get("user_name")
    user = UserService.by_user_name(user_name)
    if not user:
        user = UserService.by_email(user_name)
    if not user:
        return False

    for perm_name in request.unsafe_json_body.get("permissions", []):
        permission = UserResourcePermissionService.by_resource_user_and_perm(
            user.id, perm_name, resource.resource_id
        )
        if not permission:
            permission = UserResourcePermission(perm_name=perm_name, user_id=user.id)
            resource.user_permissions.append(permission)
    DBSession.flush()
    perms = [
        p.perm_name
        for p in ResourceService.perms_for_user(resource, user)
        if p.type == "user"
    ]
    result = {"user_name": user.user_name, "permissions": list(set(perms))}
    return result
Ejemplo n.º 4
0
    def __init__(self, request):
        self.__acl__ = []
        self.used_uuid = False
        # used_uuid is set to true if user who is normally not authorized to
        # view the resource gains access to it because owner set it to public
        # and user knows the uuid of object

        org_resource_id = request.matchdict.get("resource_id",
                                                request.GET.get("resource_id"))
        resource_id = to_integer_safe(org_resource_id)
        self.resource = (ResourceService.by_resource_id(resource_id)
                         if resource_id else None)
        if self.resource is None:
            self.resource = DashboardService.by_uuid(org_resource_id)

        if self.resource and request.user:
            self.__acl__ = self.resource.__acl__
            permissions = ResourceService.perms_for_user(
                self.resource, request.user)
            for perm_user, perm_name in permission_to_04_acls(permissions):
                self.__acl__.append(rewrite_root_perm(perm_user, perm_name))

        if self.resource and self.resource.public:
            if not request.has_permission("view", self):
                self.used_uuid = True
            self.__acl__.append((Allow, Everyone, "view"))

        add_root_superperm(request, self)
Ejemplo n.º 5
0
    def perms_for_user(self, user, db_session=None):
        """

        .. deprecated:: 0.8

        :param user:
        :param db_session:
        :return:
        """
        db_session = get_db_session(db_session, self)
        return ResourceService.perms_for_user(
            self, user=user, db_session=db_session)
Ejemplo n.º 6
0
    def __init__(self, request):
        Resource = appenlight.models.resource.Resource

        self.__acl__ = []
        resource_id = request.unsafe_json_body().get("resource_id")
        resource_id = to_integer_safe(resource_id)
        self.resource = ResourceService.by_resource_id(resource_id)
        if self.resource and request.user:
            self.__acl__ = self.resource.__acl__
            permissions = ResourceService.perms_for_user(self.resource, request.user)
            for perm_user, perm_name in permission_to_04_acls(permissions):
                self.__acl__.append(rewrite_root_perm(perm_user, perm_name))
        add_root_superperm(request, self)
Ejemplo n.º 7
0
def get_user_service_permissions(user, service, request,
                                 inherit_groups_permissions=True, resolve_groups_permissions=False):
    # type: (models.User, models.Service, Request, bool, bool) -> List[PermissionSet]
    if service.owner_user_id == user.id:
        perm_type = PermissionType.OWNED
        usr_svc_perms = service_factory(service, request).permissions
    else:
        if inherit_groups_permissions or resolve_groups_permissions:
            perm_type = PermissionType.INHERITED
            usr_svc_perms = ResourceService.perms_for_user(service, user, db_session=request.db)
        else:
            perm_type = PermissionType.DIRECT
            usr_svc_perms = ResourceService.direct_perms_for_user(service, user, db_session=request.db)
    return [PermissionSet(p, typ=perm_type) for p in usr_svc_perms]
Ejemplo n.º 8
0
    def test_resources_with_user_perms(self, db_session):
        self.maxDiff = 9999
        self.set_up_user_group_and_perms(db_session)
        perms = ResourceService.perms_for_user(self.resource,
                                               self.user,
                                               db_session=db_session)
        second = [
            PermissionTuple(self.user, "foo_perm", "user", None, self.resource,
                            False, True),
            PermissionTuple(self.user, "group_perm", "group", self.group,
                            self.resource, False, True),
            PermissionTuple(self.user, "test_perm2", "user", None,
                            self.resource, False, True),
        ]

        check_one_in_other(perms, second)
Ejemplo n.º 9
0
    def __init__(self, request):
        Resource = appenlight.models.resource.Resource
        self.__acl__ = []
        self.resource = None
        plugin_id = to_integer_safe(request.matchdict.get("id"))
        self.plugin = PluginConfigService.by_id(plugin_id)
        if not self.plugin:
            raise HTTPNotFound()
        if self.plugin.resource_id:
            self.resource = ResourceService.by_resource_id(self.plugin.resource_id)
        if self.resource:
            self.__acl__ = self.resource.__acl__
        if request.user and self.resource:
            permissions = ResourceService.perms_for_user(self.resource, request.user)
            for perm_user, perm_name in permission_to_04_acls(permissions):
                self.__acl__.append(rewrite_root_perm(perm_user, perm_name))

        add_root_superperm(request, self)
Ejemplo n.º 10
0
    def test_resources_with_user_perms(self, db_session):
        self.maxDiff = 9999
        self.set_up_user_group_and_perms(db_session)
        perms = ResourceService.perms_for_user(
            self.resource, self.user, db_session=db_session
        )
        second = [
            PermissionTuple(
                self.user, "foo_perm", "user", None, self.resource, False, True
            ),
            PermissionTuple(
                self.user, "group_perm", "group", self.group, self.resource, False, True
            ),
            PermissionTuple(
                self.user, "test_perm2", "user", None, self.resource, False, True
            ),
        ]

        check_one_in_other(perms, second)
Ejemplo n.º 11
0
    def __init__(self, request):
        self.__acl__ = []
        resource_id = safe_integer(request.matchdict.get("object_id"))
        self.resource = ResourceService.by_resource_id(
            resource_id, db_session=request.dbsession)
        if not self.resource:
            raise HTTPNotFound()

        if self.resource:
            self.__acl__ = self.resource.__acl__

        if self.resource and request.user:
            # add perms that this user has for this resource
            # this is a big performance optimization - we fetch only data
            # needed to check one specific user
            permissions = ResourceService.perms_for_user(
                self.resource, request.user)
            for outcome, perm_user, perm_name in permission_to_pyramid_acls(
                    permissions):
                self.__acl__.append(
                    rewrite_root_perm(outcome, perm_user, perm_name))

        allow_root_access(request, context=self)
Ejemplo n.º 12
0
def user_resource_permission_delete(request):
    """
    Removes user permission from specific resource
    """
    resource = request.context.resource

    user = UserService.by_user_name(request.GET.get("user_name"))
    if not user:
        return False

    for perm_name in request.GET.getall("permissions"):
        permission = UserResourcePermissionService.by_resource_user_and_perm(
            user.id, perm_name, resource.resource_id
        )
        resource.user_permissions.remove(permission)
    DBSession.flush()
    perms = [
        p.perm_name
        for p in ResourceService.perms_for_user(resource, user)
        if p.type == "user"
    ]
    result = {"user_name": user.user_name, "permissions": list(set(perms))}
    return result
Ejemplo n.º 13
0
def index(request):
    if not request.user:
        return {"owned_dashboards": [], "viewable_dashboards": []}

    dashboards = UserService.resources_with_perms(request.user, ["delete"],
                                                  resource_types=["dashboard"])
    owned_dashboard_list = []
    owned_dashboard_ids = []
    viewable_dashboards_list = []
    for d in dashboards:
        ddict = d.get_dict(
            exclude_keys=None,
            include_keys=["resource_id", "resource_name", "uuid", "public"],
        )
        owned_dashboard_list.append(ddict)
        owned_dashboard_ids.append(ddict["resource_id"])

    viewable_dashboards = UserService.resources_with_perms(
        request.user, ["view"], resource_types=["dashboard"])

    for d in viewable_dashboards:
        if d.resource_id in owned_dashboard_ids:
            continue
        ddict = d.get_dict(
            exclude_keys=None,
            include_keys=["resource_id", "resource_name", "uuid", "public"],
        )
        ddict["permissions"] = [
            perm.perm_name
            for perm in ResourceService.perms_for_user(d, request.user)
        ]
        viewable_dashboards_list.append(ddict)

    return {
        "owned_dashboards": owned_dashboard_list,
        "viewable_dashboards": viewable_dashboards_list,
    }
Ejemplo n.º 14
0
 def get_usr_res_perms():
     perm_type = None
     perm_unique = True
     res_perm_list = []
     if resource.owner_user_id == user.id:
         # FIXME: no 'magpie.models.Resource.permissions' - ok for now because no owner handling...
         perm_type = PermissionType.OWNED
         res_perm_list = models.RESOURCE_TYPE_DICT[resource.type].permissions
     else:
         if effective_permissions:
             svc = ru.get_resource_root_service_impl(resource, request)
             res_perm_list = svc.effective_permissions(user, resource)
             perm_type = PermissionType.EFFECTIVE
         else:
             if inherit_groups_permissions or resolve_groups_permissions:
                 perm_unique = resolve_groups_permissions  # allow duplicates from distinct groups if not resolved
                 res_perm_list = ResourceService.perms_for_user(resource, user, db_session=db_session)
                 res_perm_list = regroup_permissions_by_resource(res_perm_list, resolve=resolve_groups_permissions)
                 res_perm_list = res_perm_list.get(resource.resource_id, [])
                 perm_type = PermissionType.INHERITED
             else:
                 res_perm_list = ResourceService.direct_perms_for_user(resource, user, db_session=db_session)
                 perm_type = PermissionType.DIRECT
     return format_permissions(res_perm_list, perm_type, force_unique=perm_unique)
Ejemplo n.º 15
0
    def effective_permissions(self,
                              user,
                              resource,
                              permissions=None,
                              allow_match=True):
        # type: (models.User, ServiceOrResourceType, Optional[Collection[Permission]], bool) -> List[PermissionSet]
        """
        Obtains the effective permissions the user has over the specified resource.

        Recursively rewinds the resource tree from the specified resource up to the top-most parent service the resource
        resides under (or directly if the resource is the service) and retrieve permissions along the way that should be
        applied to children when using scoped-resource inheritance. Rewinding of the tree can terminate earlier when
        permissions can be immediately resolved such as when more restrictive conditions enforce denied access.

        Both user and group permission inheritance is resolved simultaneously to tree hierarchy with corresponding
        allow and deny conditions. User :term:`Direct Permissions` have priority over all its groups
        :term:`Inherited Permissions`, and denied permissions have priority over allowed access ones.

        All applicable permissions on the resource (as defined by :meth:`allowed_permissions`) will have their
        resolution (Allow/Deny) provided as output, unless a specific subset of permissions is requested using
        :paramref:`permissions`. Other permissions are ignored in this case to only resolve requested ones.
        For example, this parameter can be used to request only ACL resolution from specific permissions applicable
        for a given request, as obtained by :meth:`permission_requested`.

        Permissions scoped as `match` can be ignored using :paramref:`allow_match`, such as when the targeted resource
        does not exist.

        .. seealso::
            - :meth:`ServiceInterface.resource_requested`
        """
        if not permissions:
            permissions = self.allowed_permissions(resource)
        requested_perms = set(permissions)  # type: Set[Permission]
        effective_perms = dict()  # type: Dict[Permission, PermissionSet]

        # immediately return all permissions if user is an admin
        db_session = self.request.db
        admin_group = get_constant("MAGPIE_ADMIN_GROUP", self.request)
        admin_group = GroupService.by_group_name(admin_group,
                                                 db_session=db_session)
        if admin_group in user.groups:  # noqa
            return [
                PermissionSet(perm,
                              access=Access.ALLOW,
                              scope=Scope.MATCH,
                              typ=PermissionType.EFFECTIVE,
                              reason=PERMISSION_REASON_ADMIN)
                for perm in permissions
            ]

        # level at which last permission was found, -1 if not found
        # employed to resolve with *closest* scope and for applicable 'reason' combination on same level
        effective_level = dict()  # type: Dict[Permission, Optional[int]]
        current_level = 1  # one-based to avoid ``if level:`` check failing with zero
        full_break = False
        # current and parent resource(s) recursive-scope
        while resource is not None and not full_break:  # bottom-up until service is reached

            # include both permissions set in database as well as defined directly on resource
            cur_res_perms = ResourceService.perms_for_user(
                resource, user, db_session=db_session)
            cur_res_perms.extend(permission_to_pyramid_acls(resource.__acl__))

            for perm_name in requested_perms:
                if full_break:
                    break
                for perm_tup in cur_res_perms:
                    perm_set = PermissionSet(perm_tup)

                    # if user is owner (directly or via groups), all permissions are set,
                    # but continue processing this resource until end in case user explicit deny reverts it
                    if perm_tup.perm_name == ALL_PERMISSIONS:
                        # FIXME:
                        #   This block needs to be validated if support of ownership rules are added.
                        #   Conditions must be revised according to wanted behaviour...
                        #   General idea for now is that explict user/group deny should be prioritized over resource
                        #   ownership permissions since these can be attributed to *any user* while explicit deny are
                        #   definitely set by an admin-level user.
                        for perm in requested_perms:
                            if perm_set.access == Access.DENY:
                                all_perm = PermissionSet(
                                    perm, perm_set.access, perm.scope,
                                    PermissionType.OWNED)
                                effective_perms[perm] = all_perm
                            else:
                                all_perm = PermissionSet(
                                    perm, perm_set.access, perm.scope,
                                    PermissionType.OWNED)
                                effective_perms.setdefault(perm, all_perm)
                        full_break = True
                        break
                    # skip if the current permission must not be processed (at all or for the moment until next 'name')
                    if perm_set.name not in requested_perms or perm_set.name != perm_name:
                        continue
                    # only first resource can use match (if even enabled with found one), parents are recursive-only
                    if not allow_match and perm_set.scope == Scope.MATCH:
                        continue
                    # pick the first permission if none was found up to this point
                    prev_perm = effective_perms.get(perm_name)
                    scope_level = effective_level.get(perm_name)
                    if not prev_perm:
                        effective_perms[perm_name] = perm_set
                        effective_level[perm_name] = current_level
                        continue

                    # user direct permissions have priority over inherited ones from groups
                    # if inherited permission was found during previous iteration, override it with direct permission
                    if perm_set.type == PermissionType.DIRECT:
                        # - reset resolution scope of previous permission attributed to group as it takes precedence
                        # - since there can't be more than one user permission-name per resource on a given level,
                        #   scope resolution is done after applying this *closest* permission, ignore higher level ones
                        if prev_perm.type == PermissionType.INHERITED or not scope_level:
                            effective_perms[perm_name] = perm_set
                            effective_level[perm_name] = current_level
                        continue  # final decision for this user, skip any group permissions

                    # resolve prioritized permission according to ALLOW/DENY, scope and group priority
                    # (see 'PermissionSet.resolve' method for extensive details)
                    # skip if last permission is not on group to avoid redundant USER > GROUP check processed before
                    if prev_perm.type == PermissionType.INHERITED:
                        # - If new permission to process is done against the previous permission from *same* tree-level,
                        #   there is a possibility to combine equal priority groups. In such case, reason is 'MULTIPLE'.
                        # - If not of equal priority, the appropriate permission is selected and reason is overridden
                        #   accordingly by the new higher priority permission.
                        # - If no permission was defined at all (first occurrence), also set it using current permission
                        if scope_level in [None, current_level]:
                            resolved_perm = PermissionSet.resolve(
                                perm_set,
                                prev_perm,
                                context=PermissionType.EFFECTIVE)
                            effective_perms[perm_name] = resolved_perm
                            effective_level[perm_name] = current_level
                        # - If new permission is at *different* tree-level, it applies only if the group has higher
                        #   priority than the previous one, to respect the *closest* scope to the target resource.
                        #   Same priorities are ignored as they were already resolved by *closest* scope above.
                        # - Reset scope level with new permission such that another permission of same group priority as
                        #   that could be processed in next iteration can be compared against it, to resolve 'access'
                        #   priority between them.
                        elif perm_set.group_priority > prev_perm.group_priority:
                            effective_perms[perm_name] = perm_set
                            effective_level[perm_name] = current_level

            # don't bother moving to parent if everything is resolved already
            #   can only assume nothing left to resolve if all permissions are direct on user (highest priority)
            #   if any found permission is group inherited, higher level user permission could still override it
            if (len(effective_perms) == len(requested_perms)
                    and all(perm.type == PermissionType.DIRECT
                            for perm in effective_perms.values())):
                break
            # otherwise, move to parent if any available, since we are not done rewinding the resource tree
            allow_match = False  # reset match not applicable anymore for following parent resources
            current_level += 1
            if resource.parent_id:
                resource = ResourceService.by_resource_id(
                    resource.parent_id, db_session=db_session)
            else:
                resource = None

        # set deny for all still unresolved permissions from requested ones
        resolved_perms = set(effective_perms)
        missing_perms = set(permissions) - resolved_perms
        final_perms = set(effective_perms.values())  # type: Set[PermissionSet]
        for perm_name in missing_perms:
            perm = PermissionSet(perm_name,
                                 access=Access.DENY,
                                 scope=Scope.MATCH,
                                 typ=PermissionType.EFFECTIVE,
                                 reason=PERMISSION_REASON_DEFAULT)
            final_perms.add(perm)
        # enforce type and scope (use MATCH to make it explicit that it applies specifically for this resource)
        for perm in final_perms:
            perm.type = PermissionType.EFFECTIVE
            perm.scope = Scope.MATCH
        return list(final_perms)