Beispiel #1
0
def create_group_resource_permission_response(group, resource, permission, db_session):
    # type: (models.Group, ServiceOrResourceType, Permission, Session) -> HTTPException
    """
    Creates a permission on a group/resource combination if it is permitted and not conflicting.

    :returns: valid HTTP response on successful operations.
    :raises HTTPException: error HTTP response of corresponding situation.
    """
    resource_id = resource.resource_id
    check_valid_service_or_resource_permission(permission.value, resource, db_session)
    perm_content = {u"permission_name": str(permission.value),
                    u"resource": format_resource(resource, basic_info=True),
                    u"group": format_group(group, basic_info=True)}
    existing_perm = ax.evaluate_call(
        lambda: GroupResourcePermissionService.get(group.id, resource_id, permission.value, db_session=db_session),
        fallback=lambda: db_session.rollback(), httpError=HTTPForbidden,
        msgOnFail=s.GroupResourcePermissions_POST_ForbiddenGetResponseSchema.description, content=perm_content
    )
    ax.verify_param(existing_perm, isNone=True, httpError=HTTPConflict,
                    msgOnFail=s.GroupResourcePermissions_POST_ConflictResponseSchema.description, content=perm_content)
    # noinspection PyArgumentList
    new_perm = ax.evaluate_call(
        lambda: models.GroupResourcePermission(resource_id=resource_id, group_id=group.id, perm_name=permission.value),
        fallback=lambda: db_session.rollback(), httpError=HTTPForbidden, content=perm_content,
        msgOnFail=s.GroupResourcePermissions_POST_ForbiddenCreateResponseSchema.description)
    ax.evaluate_call(lambda: db_session.add(new_perm), fallback=lambda: db_session.rollback(),
                     httpError=HTTPForbidden, content=perm_content,
                     msgOnFail=s.GroupResourcePermissions_POST_ForbiddenAddResponseSchema.description)
    return ax.valid_http(httpSuccess=HTTPCreated, content=perm_content,
                         detail=s.GroupResourcePermissions_POST_CreatedResponseSchema.description)
Beispiel #2
0
def delete_resource(request):
    resource = ar.get_resource_matchdict_checked(request)
    service_push = asbool(
        ar.get_multiformat_body(request, "service_push", default=False))
    res_content = {"resource": format_resource(resource, basic_info=True)}
    ax.evaluate_call(
        lambda: models.RESOURCE_TREE_SERVICE.delete_branch(
            resource_id=resource.resource_id, db_session=request.db),
        fallback=lambda: request.db.rollback(),
        http_error=HTTPForbidden,
        msg_on_fail="Delete resource branch from tree service failed.",
        content=res_content)

    def remove_service_magpie_and_phoenix(res, svc_push, db):
        if res.resource_type != "service":
            svc_push = False
        db.delete(res)
        if svc_push:
            sync_services_phoenix(db.query(models.Service))

    ax.evaluate_call(
        lambda: remove_service_magpie_and_phoenix(resource, service_push,
                                                  request.db),
        fallback=lambda: request.db.rollback(),
        http_error=HTTPForbidden,
        msg_on_fail=s.Resource_DELETE_ForbiddenResponseSchema.description,
        content=res_content)
    return ax.valid_http(http_success=HTTPOk,
                         detail=s.Resource_DELETE_OkResponseSchema.description)
Beispiel #3
0
def get_resource_view(request):
    """
    Get resource information.
    """
    resource = ar.get_resource_matchdict_checked(request)
    res_json = ax.evaluate_call(lambda: rf.format_resource_with_children(resource, db_session=request.db),
                                fallback=lambda: request.db.rollback(), httpError=HTTPInternalServerError,
                                msgOnFail=s.Resource_GET_InternalServerErrorResponseSchema.description,
                                content={u"resource": rf.format_resource(resource, basic_info=True)})
    return ax.valid_http(httpSuccess=HTTPOk, content={"resource": res_json},
                         detail=s.Resource_GET_OkResponseSchema.description)
Beispiel #4
0
def get_resource_permissions_view(request):
    """
    List all applicable permissions for a resource.
    """
    resource = ar.get_resource_matchdict_checked(request, "resource_id")
    res_perm = ax.evaluate_call(lambda: ru.get_resource_permissions(resource, db_session=request.db),
                                fallback=lambda: request.db.rollback(), httpError=HTTPBadRequest,
                                msgOnFail=s.ResourcePermissions_GET_BadRequestResponseSchema.description,
                                content={u"resource": rf.format_resource(resource, basic_info=True)})
    return ax.valid_http(httpSuccess=HTTPOk, detail=s.ResourcePermissions_GET_OkResponseSchema.description,
                         content={u"permission_names": format_permissions(res_perm)})
Beispiel #5
0
def delete_group_resource_permission_response(group,
                                              resource,
                                              permission,
                                              db_session,
                                              similar=True):
    # type: (models.Group, ServiceOrResourceType, PermissionSet, Session, bool) -> HTTPException
    """
    Get validated response on deleted group resource permission.

    :param group: group for which to delete the permission.
    :param resource: service or resource for which to delete the permission.
    :param permission: permission with modifiers to be deleted.
    :param db_session: database connection.
    :param similar:
        Allow matching provided permission against any similar database permission. Otherwise, must match exactly.
    :returns: valid HTTP response on successful operations.
    :raises HTTPException: error HTTP response of corresponding situation.
    """
    check_valid_service_or_resource_permission(permission.name, resource,
                                               db_session)
    res_id = resource.resource_id
    if similar:
        found_perm = get_similar_group_resource_permission(
            group, resource, permission, db_session=db_session)
    else:
        found_perm = permission
    del_perm = GroupResourcePermissionService.get(group.id,
                                                  res_id,
                                                  str(found_perm),
                                                  db_session=db_session)
    permission.type = PermissionType.APPLIED
    perm_content = {
        "permission_name": str(permission),
        "permission": permission.json(),
        "resource": format_resource(resource, basic_info=True),
        "group": format_group(group, basic_info=True)
    }
    ax.verify_param(
        del_perm,
        not_none=True,
        http_error=HTTPNotFound,
        content=perm_content,
        msg_on_fail=s.GroupServicePermission_DELETE_NotFoundResponseSchema.
        description)
    ax.evaluate_call(
        lambda: db_session.delete(del_perm),
        fallback=lambda: db_session.rollback(),
        http_error=HTTPForbidden,
        content=perm_content,
        msg_on_fail=s.GroupServicePermission_DELETE_ForbiddenResponseSchema.
        description)
    return ax.valid_http(
        http_success=HTTPOk,
        detail=s.GroupServicePermission_DELETE_OkResponseSchema.description)
Beispiel #6
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)})
Beispiel #7
0
def delete_group_resource_permission_response(group, resource, permission, db_session):
    # type: (models.Group, ServiceOrResourceType, Permission, Session) -> HTTPException
    """
    Get validated response on deleted group resource permission.

    :returns: valid HTTP response on successful operations.
    :raises HTTPException: error HTTP response of corresponding situation.
    """
    resource_id = resource.resource_id
    check_valid_service_or_resource_permission(permission.value, resource, db_session)
    perm_content = {u"permission_name": permission.value,
                    u"resource": format_resource(resource, basic_info=True),
                    u"group": format_group(group, basic_info=True)}
    del_perm = ax.evaluate_call(
        lambda: GroupResourcePermissionService.get(group.id, resource_id, permission.value, db_session=db_session),
        fallback=lambda: db_session.rollback(), httpError=HTTPForbidden,
        msgOnFail=s.GroupServicePermission_DELETE_ForbiddenGetResponseSchema.description, content=perm_content
    )
    ax.verify_param(del_perm, notNone=True, httpError=HTTPNotFound, content=perm_content,
                    msgOnFail=s.GroupServicePermission_DELETE_NotFoundResponseSchema.description)
    ax.evaluate_call(lambda: db_session.delete(del_perm), fallback=lambda: db_session.rollback(),
                     httpError=HTTPForbidden, content=perm_content,
                     msgOnFail=s.GroupServicePermission_DELETE_ForbiddenResponseSchema.description)
    return ax.valid_http(httpSuccess=HTTPOk, detail=s.GroupServicePermission_DELETE_OkResponseSchema.description)
Beispiel #8
0
def get_similar_group_resource_permission(group, resource, permission,
                                          db_session):
    # type: (models.Group, ServiceOrResourceType, PermissionSet, Session) -> Optional[PermissionSet]
    """
    Obtains the group service/resource permission that corresponds to the provided one.

    Lookup considers only *similar* applied permission such that other permission modifiers don't affect comparison.
    """
    permission.type = PermissionType.APPLIED
    res_id = resource.resource_id
    err_content = {
        "group": format_group(group, basic_info=True),
        "resource": format_resource(resource, basic_info=True),
        "permission_name": str(permission),
        "permission": permission.json()
    }

    def is_similar_permission():
        perms_dict = get_group_resources_permissions_dict(
            group, resource_ids=[res_id], db_session=db_session)
        perms_list = perms_dict.get(res_id, [])
        return [
            PermissionSet(perm) for perm in perms_list if perm.like(permission)
        ]

    similar_perms = ax.evaluate_call(
        lambda: is_similar_permission(),
        http_error=HTTPForbidden,
        content=err_content,
        msg_on_fail=s.GroupResourcePermissions_Check_ErrorResponseSchema.
        description)
    if not similar_perms:
        return None
    found_perm = similar_perms[0]
    found_perm.type = PermissionType.APPLIED
    return found_perm
Beispiel #9
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,
        param_name="resource_name",
        not_none=True,
        not_empty=True,
        http_error=HTTPUnprocessableEntity,
        msg_on_fail=
        "Invalid 'resource_name' specified for child resource creation.")
    ax.verify_param(
        resource_type,
        param_name="resource_type",
        not_none=True,
        not_empty=True,
        http_error=HTTPUnprocessableEntity,
        msg_on_fail=
        "Invalid 'resource_type' specified for child resource creation.")
    ax.verify_param(
        parent_id,
        param_name="parent_id",
        not_none=True,
        is_type=True,
        param_compare=int,
        http_error=HTTPUnprocessableEntity,
        msg_on_fail="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(),
        http_error=HTTPNotFound,
        msg_on_fail=s.Resources_POST_NotFoundResponseSchema.description,
        content={
            "parent_id": parent_id,
            "resource_name": str(resource_name),
            "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
    err_msg = s.Resources_POST_ConflictResponseSchema.description
    check_unique_child_resource_name(resource_name,
                                     parent_id,
                                     err_msg,
                                     db_session=db_session)

    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(),
        http_error=HTTPForbidden,
        msg_on_fail=s.Resources_POST_ForbiddenResponseSchema.description)
    return ax.valid_http(
        http_success=HTTPCreated,
        detail=s.Resources_POST_CreatedResponseSchema.description,
        content={"resource": format_resource(new_resource, basic_info=True)})
Beispiel #10
0
def create_group_resource_permission_response(group,
                                              resource,
                                              permission,
                                              db_session,
                                              overwrite=False):
    # type: (models.Group, ServiceOrResourceType, PermissionSet, Session, bool) -> HTTPException
    """
    Creates a permission on a group/resource combination if it is permitted and not conflicting.

    :param group: group for which to create/update the permission.
    :param resource: service or resource for which to create the permission.
    :param permission: permission with modifiers to be applied.
    :param db_session: database connection.
    :param overwrite:
        If the corresponding `(group, resource, permission[name])` exists, there is a conflict.
        Conflict is considered only by permission-name regardless of other modifiers.
        If overwrite is ``False``, the conflict will be raised and not be applied.
        If overwrite is ``True``, the permission modifiers will be replaced by the new ones, or created if missing.
    :returns: valid HTTP response on successful operations.
    :raises HTTPException: error HTTP response of corresponding situation.
    """
    resource_id = resource.resource_id
    check_valid_service_or_resource_permission(permission.name, resource,
                                               db_session)
    exist_perm = get_similar_group_resource_permission(group,
                                                       resource,
                                                       permission,
                                                       db_session=db_session)
    perm_content = {
        "permission_name": str(permission),
        "permission": permission.json(),
        "resource": format_resource(resource, basic_info=True),
        "group": format_group(group, basic_info=True)
    }
    http_success = HTTPCreated
    http_detail = s.GroupResourcePermissions_POST_CreatedResponseSchema.description
    if overwrite and exist_perm:
        # skip similar permission lookup since we already did it
        http_success = HTTPOk
        http_detail = s.GroupResourcePermissions_PUT_OkResponseSchema.description
        delete_group_resource_permission_response(group,
                                                  resource,
                                                  exist_perm,
                                                  db_session=db_session,
                                                  similar=False)
    else:
        ax.verify_param(
            exist_perm,
            is_none=True,
            http_error=HTTPConflict,
            content=perm_content,
            msg_on_fail=s.GroupResourcePermissions_POST_ConflictResponseSchema.
            description)

    new_perm = ax.evaluate_call(
        lambda: models.GroupResourcePermission(resource_id=resource_id,
                                               group_id=group.id,
                                               perm_name=str(permission)),
        fallback=lambda: db_session.rollback(),
        http_error=HTTPForbidden,
        content=perm_content,
        msg_on_fail=s.
        GroupResourcePermissions_POST_ForbiddenCreateResponseSchema.description
    )
    ax.evaluate_call(
        lambda: db_session.add(new_perm),
        fallback=lambda: db_session.rollback(),
        http_error=HTTPForbidden,
        content=perm_content,
        msg_on_fail=s.GroupResourcePermissions_POST_ForbiddenAddResponseSchema.
        description)
    return ax.valid_http(http_success=http_success,
                         content=perm_content,
                         detail=http_detail)