Example #1
0
 def effective_permissions(self, resource, user):
     # type: (models.Resource, models.User) -> List[ResourcePermissionType]
     """
     Recursively rewind the resource tree from the specified resource up to the topmost parent service resource and
     retrieve permissions along the way that should be applied to children when using resource inheritance.
     """
     resource_effective_perms = list()
     while resource is not None:
         current_resource_perms = ResourceService.perms_for_user(resource, user, db_session=self.request.db)
         resource_effective_perms.extend(current_resource_perms)
         if resource.parent_id:
             resource = ResourceService.by_resource_id(resource.parent_id, db_session=self.request.db)
         else:
             resource = None
     return resource_effective_perms
Example #2
0
 def build_json_user_resource_tree(usr):
     json_res = {}
     services = ResourceService.all(models.Service, db_session=db)
     for svc in services:
         svc_perms = uu.get_user_service_permissions(
             user=usr,
             service=svc,
             request=request,
             inherit_groups_permissions=inherit_groups_perms)
         if svc.type not in json_res:
             json_res[svc.type] = {}
         res_perms_dict = uu.get_user_service_resources_permissions_dict(
             user=usr,
             service=svc,
             request=request,
             inherit_groups_permissions=inherit_groups_perms)
         json_res[svc.type][svc.resource_name] = format_service_resources(
             svc,
             db_session=db,
             service_perms=svc_perms,
             resources_perms_dict=res_perms_dict,
             show_all_children=False,
             show_private_url=False,
         )
     return json_res
Example #3
0
    def _apply_session(_usr_name=None, _grp_name=None):
        """
        Apply operation using db session.
        """
        from magpie.api.management.user import user_utils as ut
        from magpie.api.management.group import group_utils as gt

        res = ResourceService.by_resource_id(resource_id,
                                             db_session=cookies_or_session)
        if _usr_name:
            usr = UserService.by_user_name(_usr_name,
                                           db_session=cookies_or_session)
            if create_perm:
                return ut.create_user_resource_permission_response(
                    usr, res, perm, db_session=cookies_or_session)
            else:
                return ut.delete_user_resource_permission_response(
                    usr, res, perm, db_session=cookies_or_session)
        if _grp_name:
            grp = GroupService.by_group_name(_grp_name,
                                             db_session=cookies_or_session)
            if create_perm:
                return gt.create_group_resource_permission_response(
                    grp, res, perm, db_session=cookies_or_session)
            else:
                return gt.delete_group_resource_permission_response(
                    grp, res, perm, db_session=cookies_or_session)
Example #4
0
    def expand_acl(self, resource, user):
        # type: (models.Resource, models.User) -> None
        if resource:
            for ace in resource.__acl__:
                self.acl.append(ace)

            if user:
                permissions = ResourceService.perms_for_user(resource, user, db_session=self.request.db)
                for outcome, perm_user, perm_name in permission_to_pyramid_acls(permissions):
                    self.acl.append((outcome, perm_user, perm_name,))
            else:
                user = UserService.by_user_name(get_constant("MAGPIE_ANONYMOUS_USER"), db_session=self.request.db)
                if user is None:
                    raise Exception("No Anonymous user in the database")
                else:
                    permissions = ResourceService.perms_for_user(resource, user, db_session=self.request.db)
                    for outcome, perm_user, perm_name in permission_to_pyramid_acls(permissions):
                        self.acl.append((outcome, EVERYONE, perm_name,))
Example #5
0
def get_user_services(user,
                      request,
                      cascade_resources=False,
                      inherit_groups_permissions=False,
                      format_as_list=False):
    # type: (models.User, Request, bool, bool, bool) -> UserServicesType
    """
    Returns services by type with corresponding services by name containing sub-dict information.

    :param user: user for which to find services
    :param request: request with database session connection
    :param cascade_resources:
        If `False`, return only services with *Direct* user permissions on their corresponding service-resource.
        Otherwise, return every service that has at least one sub-resource with user permissions.
    :param inherit_groups_permissions:
        If `False`, return only user-specific service/sub-resources permissions.
        Otherwise, resolve inherited permissions using all groups the user is member of.
    :param format_as_list:
        returns as list of service dict information (not grouped by type and by name)
    :return: only services which the user as *Direct* or *Inherited* permissions, according to `inherit_from_resources`
    :rtype:
        dict of services by type with corresponding services by name containing sub-dict information,
        unless `format_as_dict` is `True`
    """
    db_session = request.db
    resource_type = None if cascade_resources else [
        models.Service.resource_type
    ]
    res_perm_dict = get_user_resources_permissions_dict(
        user,
        resource_types=resource_type,
        request=request,
        inherit_groups_permissions=inherit_groups_permissions)

    services = {}
    for resource_id, perms in res_perm_dict.items():
        svc = ResourceService.by_resource_id(resource_id=resource_id,
                                             db_session=db_session)
        if svc.resource_type != models.Service.resource_type and cascade_resources:
            svc = get_resource_root_service(svc, request)
            perms = svc.permissions
        if svc.type not in services:
            services[svc.type] = {}
        if svc.resource_name not in services[svc.type]:
            services[svc.type][svc.resource_name] = format_service(
                svc, perms, show_private_url=False)

    if not format_as_list:
        return services

    services_list = list()
    for svc_type in services:
        for svc_name in services[svc_type]:
            services_list.append(services[svc_type][svc_name])
    return services_list
Example #6
0
def get_resource_root_service(resource, request):
    # type: (models.Resource, Request) -> ServiceInterface
    """
    Retrieves the service class corresponding to the specified resource's root service-resource.
    """
    if resource.resource_type == models.Service.resource_type_name:
        res_root_svc = resource
    else:
        res_root_svc = ResourceService.by_resource_id(resource.root_service_id,
                                                      db_session=request.db)
    return service_factory(res_root_svc, request)
Example #7
0
def add_service_getcapabilities_perms(service, db_session, group_name=None):
    if service.type in SERVICES_PHOENIX_ALLOWED and \
            Permission.GET_CAPABILITIES in SERVICE_TYPE_DICT[service.type].permissions:
        if group_name is None:
            group_name = get_constant('MAGPIE_ANONYMOUS_USER')
        group = GroupService.by_group_name(group_name, db_session=db_session)
        perm = ResourceService.perm_by_group_and_perm_name(
            service.resource_id, group.id, Permission.GET_CAPABILITIES.value,
            db_session)
        if perm is None:  # not set, create it
            create_group_resource_permission_response(
                group, service, Permission.GET_CAPABILITIES, db_session)
Example #8
0
def get_group_services(resources_permissions_dict, db_session):
    # type: (JSON, Session) -> JSON
    """
    Nest and regroup the resource permissions under corresponding root service types.
    """
    grp_svc_dict = {}
    for res_id, perms in resources_permissions_dict.items():
        svc = ResourceService.by_resource_id(resource_id=res_id, db_session=db_session)
        svc_type = str(svc.type)
        svc_name = str(svc.resource_name)
        if svc_type not in grp_svc_dict:
            grp_svc_dict[svc_type] = {}
        grp_svc_dict[svc_type][svc_name] = format_service(svc, perms, show_private_url=False)
    return grp_svc_dict
Example #9
0
def get_user_service_permissions(user,
                                 service,
                                 request,
                                 inherit_groups_permissions=True):
    # type: (models.User, models.Service, Request, bool) -> List[Permission]
    if service.owner_user_id == user.id:
        usr_svc_perms = service_factory(service, request).permissions
    else:
        usr_svc_perms = ResourceService.perms_for_user(service,
                                                       user,
                                                       db_session=request.db)
        if not inherit_groups_permissions:
            usr_svc_perms = filter_user_permission(usr_svc_perms, user)
    return [convert_permission(p) for p in usr_svc_perms]
Example #10
0
 def get_usr_res_perms():
     if resource.owner_user_id == user.id:
         res_perm_list = models.RESOURCE_TYPE_DICT[
             resource.type].permissions
     else:
         if effective_permissions:
             svc = get_resource_root_service(resource, request)
             res_perm_list = svc.effective_permissions(resource, user)
         else:
             res_perm_list = ResourceService.perms_for_user(
                 resource, user, db_session=db_session)
             if not inherit_groups_permissions:
                 res_perm_list = filter_user_permission(res_perm_list, user)
     return format_permissions(res_perm_list)
Example #11
0
def format_resource_tree(children, db_session, resources_perms_dict=None, internal_svc_res_perm_dict=None):
    """
    Generates the formatted service/resource tree with all its children resources by calling :function:`format_resource`
    recursively.

    Filters resource permissions with ``resources_perms_dict`` if provided.

    :param children: service or resource for which to generate the formatted resource tree
    :param db_session: connection to db
    :param resources_perms_dict: any pre-established user- or group-specific permissions. Only those are shown if given.
    :param internal_svc_res_perm_dict: *for this function's use only*,
        avoid re-fetch of already obtained permissions for corresponding resources
    :return: formatted resource tree
    """
    internal_svc_res_perm_dict = dict() if internal_svc_res_perm_dict is None else internal_svc_res_perm_dict

    fmt_res_tree = {}
    for child_id, child_dict in children.items():
        resource = child_dict[u'node']
        new_children = child_dict[u'children']
        perms = []

        # case of pre-specified user/group-specific permissions
        if resources_perms_dict is not None:
            if resource.resource_id in resources_perms_dict.keys():
                perms = resources_perms_dict[resource.resource_id]

        # case of full fetch (permitted resource permissions)
        else:
            # directly access the resource if it is a service
            if resource.root_service_id is None:
                service = resource
                service_id = resource.resource_id
                # add to dict only if not already added
                if service_id not in internal_svc_res_perm_dict:
                    internal_svc_res_perm_dict[service_id] = SERVICE_TYPE_DICT[service.type].resource_types_permissions
            # obtain corresponding top-level service resource if not already available
            else:
                service_id = resource.root_service_id
                if service_id not in internal_svc_res_perm_dict:
                    service = ResourceService.by_resource_id(service_id, db_session=db_session)
                    internal_svc_res_perm_dict[service_id] = SERVICE_TYPE_DICT[service.type].resource_types_permissions

            perms = internal_svc_res_perm_dict[service_id][resource.resource_type]

        fmt_res_tree[child_id] = format_resource(resource, perms)
        fmt_res_tree[child_id][u'children'] = format_resource_tree(new_children, db_session,
                                                                   resources_perms_dict, internal_svc_res_perm_dict)

    return fmt_res_tree
Example #12
0
def get_resource_root_service(resource, db_session):
    # type: (models.Resource, Session) -> Optional[models.Resource]
    """
    Recursively rewinds back through the top of the resource tree up to the top-level service-resource.

    :param resource: initial resource where to start searching upwards the tree
    :param db_session:
    :return: resource-tree root service as a resource object
    """
    if resource is not None:
        if resource.parent_id is None:
            return resource
        parent_resource = ResourceService.by_resource_id(resource.parent_id, db_session=db_session)
        return get_resource_root_service(parent_resource, db_session=db_session)
    return None
Example #13
0
def get_resource_permissions(resource, db_session):
    # type: (models.Resource, Session) -> List[Permission]
    ax.verify_param(resource, notNone=True, httpError=HTTPBadRequest, paramName=u"resource",
                    msgOnFail=s.UserResourcePermissions_GET_BadRequestResourceResponseSchema.description)
    # directly access the service resource
    if resource.root_service_id is None:
        service = resource
        return SERVICE_TYPE_DICT[service.type].permissions

    # otherwise obtain root level service to infer sub-resource permissions
    service = ResourceService.by_resource_id(resource.root_service_id, db_session=db_session)
    ax.verify_param(service.resource_type, isEqual=True, httpError=HTTPBadRequest,
                    paramName=u"resource_type", paramCompare=models.Service.resource_type_name,
                    msgOnFail=s.UserResourcePermissions_GET_BadRequestRootServiceResponseSchema.description)
    service_class = SERVICE_TYPE_DICT[service.type]
    ax.verify_param(resource.resource_type_name, isIn=True, httpError=HTTPBadRequest,
                    paramName=u"resource_type", paramCompare=service_class.resource_type_names,
                    msgOnFail=s.UserResourcePermissions_GET_BadRequestResourceTypeResponseSchema.description)
    return service_class.get_resource_permissions(resource.resource_type_name)
Example #14
0
def create_resource(resource_name, resource_display_name, resource_type, parent_id, db_session):
    # type: (Str, Optional[Str], Str, int, Session) -> HTTPException
    ax.verify_param(resource_name, paramName=u"resource_name", notNone=True, notEmpty=True, httpError=HTTPBadRequest,
                    msgOnFail="Invalid 'resource_name' specified for child resource creation.")
    ax.verify_param(resource_type, paramName=u"resource_type", notNone=True, notEmpty=True, httpError=HTTPBadRequest,
                    msgOnFail="Invalid 'resource_type' specified for child resource creation.")
    ax.verify_param(parent_id, paramName=u"parent_id", notNone=True, notEmpty=True, paramCompare=int, ofType=True,
                    httpError=HTTPBadRequest, msgOnFail="Invalid 'parent_id' specified for child resource creation.")
    parent_resource = ax.evaluate_call(lambda: ResourceService.by_resource_id(parent_id, db_session=db_session),
                                       fallback=lambda: db_session.rollback(), httpError=HTTPNotFound,
                                       msgOnFail=s.Resources_POST_NotFoundResponseSchema.description,
                                       content={u"parent_id": str(parent_id), u"resource_name": str(resource_name),
                                                u"resource_type": str(resource_type)})

    # verify for valid permissions from top-level service-specific corresponding resources permissions
    root_service = check_valid_service_resource(parent_resource, resource_type, db_session)
    new_resource = models.resource_factory(resource_type=resource_type,
                                           resource_name=resource_name,
                                           resource_display_name=resource_display_name or resource_name,
                                           root_service_id=root_service.resource_id,
                                           parent_id=parent_resource.resource_id)

    # Two resources with the same parent can't have the same name !
    tree_struct = models.resource_tree_service.from_parent_deeper(parent_id, limit_depth=1, db_session=db_session)
    tree_struct_dict = models.resource_tree_service.build_subtree_strut(tree_struct)
    direct_children = tree_struct_dict[u"children"]
    ax.verify_param(resource_name, paramName=u"resource_name", notIn=True, httpError=HTTPConflict,
                    msgOnFail=s.Resources_POST_ConflictResponseSchema.description,
                    paramCompare=[child_dict[u"node"].resource_name for child_dict in direct_children.values()])

    def add_resource_in_tree(new_res, db):
        db_session.add(new_res)
        total_children = models.resource_tree_service.count_children(new_res.parent_id, db_session=db)
        models.resource_tree_service.set_position(resource_id=new_res.resource_id,
                                                  to_position=total_children, db_session=db)

    ax.evaluate_call(lambda: add_resource_in_tree(new_resource, db_session),
                     fallback=lambda: db_session.rollback(),
                     httpError=HTTPForbidden, msgOnFail=s.Resources_POST_ForbiddenResponseSchema.description)
    return ax.valid_http(httpSuccess=HTTPCreated, detail=s.Resources_POST_CreatedResponseSchema.description,
                         content={u"resource": format_resource(new_resource, basic_info=True)})
Example #15
0
def get_group_resources(group, db_session):
    # type: (models.Group, Session) -> JSON
    """
    Get formatted JSON body describing all service resources the ``group`` as permissions on.
    """
    json_response = {}
    for svc in list(ResourceService.all(models.Service, db_session=db_session)):
        svc_perms = get_group_service_permissions(group=group, service=svc, db_session=db_session)
        svc_name = str(svc.resource_name)
        svc_type = str(svc.type)
        if svc_type not in json_response:
            json_response[svc_type] = {}
        res_perm_dict = get_group_service_resources_permissions_dict(group=group, service=svc, db_session=db_session)
        json_response[svc_type][svc_name] = format_service_resources(
            svc,
            db_session=db_session,
            service_perms=svc_perms,
            resources_perms_dict=res_perm_dict,
            show_all_children=False,
            show_private_url=False,
        )
    return json_response