Beispiel #1
0
def create_service_resource_view(request):
    """
    Register a new resource directly under a service or under one of its children resources.
    """
    service = ar.get_service_matchdict_checked(request)
    resource_name = ar.get_multiformat_body(request, "resource_name")
    resource_display_name = ar.get_multiformat_body(request, "resource_display_name", default=resource_name)
    resource_type = ar.get_multiformat_body(request, "resource_type")
    parent_id = ar.get_multiformat_body(request, "parent_id")  # no check because None/empty is allowed
    db_session = request.db
    if parent_id is None:
        parent_id = service.resource_id
    else:
        parent_id = ax.evaluate_call(lambda: int(parent_id),
                                     http_error=HTTPUnprocessableEntity,
                                     msg_on_fail=s.ServiceResources_POST_UnprocessableEntityResponseSchema.description)
        # validate target service is actually the root service of the provided parent resource ID
        root_service = ru.get_resource_root_service_by_id(parent_id, db_session=db_session)
        ax.verify_param(root_service, not_none=True, param_name="parent_id",
                        msg_on_fail=s.ServiceResources_POST_NotFoundResponseSchema.description,
                        http_error=HTTPNotFound)
        ax.verify_param(root_service.resource_id, is_equal=True,
                        param_compare=service.resource_id, param_name="parent_id",
                        msg_on_fail=s.ServiceResources_POST_ForbiddenResponseSchema.description,
                        http_error=HTTPForbidden)
    return ru.create_resource(resource_name, resource_display_name, resource_type,
                              parent_id=parent_id, db_session=db_session)
Beispiel #2
0
def create_group_view(request):
    """
    Create a group.
    """
    group_name = ar.get_value_multiformat_body_checked(request, "group_name")
    group_desc = ar.get_multiformat_body(request, "description", default="")
    group_disc = asbool(
        ar.get_multiformat_body(request, "discoverable", default=False))
    return gu.create_group(group_name, group_desc, group_disc, request.db)
Beispiel #3
0
def register_service_view(request):
    """
    Registers a new service.
    """
    # accomplish basic validations here, create_service will do more field-specific checks
    service_name = ar.get_value_multiformat_body_checked(request, "service_name")
    service_url = ar.get_value_multiformat_body_checked(request, "service_url", pattern=ax.URL_REGEX)
    service_type = ar.get_value_multiformat_body_checked(request, "service_type")
    service_push = asbool(ar.get_multiformat_body(request, "service_push", default=False))
    service_cfg = ar.get_multiformat_body(request, "configuration")
    return su.create_service(service_name, service_type, service_url, service_push, service_cfg, db_session=request.db)
Beispiel #4
0
def update_service_view(request):
    """
    Update service information.
    """
    service = ar.get_service_matchdict_checked(request)
    service_push = asbool(ar.get_multiformat_body(request, "service_push", default=False))

    def select_update(new_value, old_value):
        return new_value if new_value is not None and not new_value == "" else old_value

    # None/Empty values are accepted in case of unspecified
    svc_name = select_update(ar.get_multiformat_body(request, "service_name"), service.resource_name)
    svc_url = select_update(ar.get_multiformat_body(request, "service_url"), service.url)
    ax.verify_param(svc_name, param_compare="types", not_equal=True,
                    param_name="service_name", http_error=HTTPForbidden,
                    msg_on_fail=s.Service_PATCH_ForbiddenResponseSchema_ReservedKeyword.description)
    ax.verify_param(svc_name == service.resource_name and svc_url == service.url, not_equal=True,
                    param_compare=True, param_name="service_name/service_url",
                    http_error=HTTPBadRequest, msg_on_fail=s.Service_PATCH_BadRequestResponseSchema.description)

    # config explicitly provided as None (null) means override (erase)
    # to leave it as is, just don't specific the field
    old_svc_config = service.configuration
    new_svc_config = ar.get_multiformat_body(request, "configuration")
    if old_svc_config != new_svc_config:
        if new_svc_config is not None:
            ax.verify_param(new_svc_config, param_compare=dict, is_type=True, http_error=HTTPUnprocessableEntity,
                            msg_on_fail=s.Service_CheckConfig_UnprocessableEntityResponseSchema.description)
        service.configuration = new_svc_config

    if svc_name != service.resource_name:
        all_services = request.db.query(models.Service)
        all_svc_names = [svc.resource_name for svc in all_services]
        ax.verify_param(svc_name, not_in=True, param_compare=all_svc_names, with_param=False,
                        http_error=HTTPConflict, content={"service_name": str(svc_name)},
                        msg_on_fail=s.Service_PATCH_ConflictResponseSchema.description)

    def update_service_magpie_and_phoenix(_svc, new_name, new_url, svc_push, db_session):
        _svc.resource_name = new_name
        _svc.url = new_url
        has_getcap = Permission.GET_CAPABILITIES in SERVICE_TYPE_DICT[_svc.type].permissions
        if svc_push and _svc.type in SERVICES_PHOENIX_ALLOWED and has_getcap:
            # (re)apply getcapabilities to updated service to ensure updated push
            su.add_service_getcapabilities_perms(_svc, db_session)
            sync_services_phoenix(db_session.query(models.Service))  # push all services

    old_svc_content = sf.format_service(service, show_private_url=True)
    err_svc_content = {"service": old_svc_content, "new_service_name": svc_name, "new_service_url": svc_url}
    ax.evaluate_call(lambda: update_service_magpie_and_phoenix(service, svc_name, svc_url, service_push, request.db),
                     fallback=lambda: request.db.rollback(),
                     http_error=HTTPForbidden, msg_on_fail=s.Service_PATCH_ForbiddenResponseSchema.description,
                     content=err_svc_content)
    return ax.valid_http(http_success=HTTPOk, detail=s.Service_PATCH_OkResponseSchema.description,
                         content={"service": sf.format_service(service, show_private_url=True)})
Beispiel #5
0
def create_user_view(request):
    """
    Create a new user.
    """
    user_name = ar.get_multiformat_body(request, "user_name")
    email = ar.get_multiformat_body(request, "email")
    password = ar.get_multiformat_body(request, "password")
    group_name = ar.get_multiformat_body(request, "group_name")
    return uu.create_user(user_name,
                          password,
                          email,
                          group_name,
                          db_session=request.db)
Beispiel #6
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 #7
0
def create_resource_view(request):
    """
    Register a new resource.
    """
    resource_name = ar.get_value_multiformat_body_checked(
        request, "resource_name")
    resource_display_name = ar.get_multiformat_body(request,
                                                    "resource_display_name",
                                                    default=resource_name)
    resource_type = ar.get_value_multiformat_body_checked(
        request, "resource_type")
    parent_id = ar.get_value_multiformat_body_checked(request,
                                                      "parent_id",
                                                      check_type=int)
    return ru.create_resource(resource_name, resource_display_name,
                              resource_type, parent_id, request.db)
Beispiel #8
0
def unregister_service_view(request):
    """
    Unregister a service.
    """
    service = ar.get_service_matchdict_checked(request)
    service_push = asbool(ar.get_multiformat_body(request, "service_push", default=False))
    svc_content = sf.format_service(service, show_private_url=True)
    svc_res_id = service.resource_id
    ax.evaluate_call(lambda: models.RESOURCE_TREE_SERVICE.delete_branch(resource_id=svc_res_id, db_session=request.db),
                     fallback=lambda: request.db.rollback(), http_error=HTTPForbidden,
                     msg_on_fail="Delete service from resource tree failed.", content=svc_content)

    def remove_service_magpie_and_phoenix(svc, svc_push, db_session):
        db_session.delete(svc)
        if svc_push and svc.type in SERVICES_PHOENIX_ALLOWED:
            sync_services_phoenix(db_session.query(models.Service))

    ax.evaluate_call(lambda: remove_service_magpie_and_phoenix(service, service_push, request.db),
                     fallback=lambda: request.db.rollback(), http_error=HTTPForbidden,
                     msg_on_fail=s.Service_DELETE_ForbiddenResponseSchema.description, content=svc_content)
    return ax.valid_http(http_success=HTTPOk, detail=s.Service_DELETE_OkResponseSchema.description)
Beispiel #9
0
def update_user_view(request):
    """
    Update user information by user name.
    """
    user = ar.get_user_matchdict_checked_or_logged(request)
    new_user_name = ar.get_multiformat_body(request,
                                            "user_name",
                                            default=user.user_name)
    new_email = ar.get_multiformat_body(request, "email", default=user.email)
    new_password = ar.get_multiformat_body(request,
                                           "password",
                                           default=user.user_password)

    update_username = user.user_name != new_user_name and new_user_name is not None
    update_password = user.user_password != new_password and new_password is not None
    update_email = user.email != new_email and new_email is not None
    ax.verify_param(
        any([update_username, update_password, update_email]),
        is_true=True,
        with_param=False,  # params are not useful in response for this case
        content={"user_name": user.user_name},
        http_error=HTTPBadRequest,
        msg_on_fail=s.User_PATCH_BadRequestResponseSchema.description)
    # user name change is admin-only operation
    if update_username:
        ax.verify_param(
            get_constant("MAGPIE_ADMIN_GROUP"),
            is_in=True,
            param_compare=uu.get_user_groups_checked(request.user, request.db),
            with_param=False,
            http_error=HTTPForbidden,
            msg_on_fail=s.User_PATCH_ForbiddenResponseSchema.description)

    # logged user updating itself is forbidden if it corresponds to special users
    # cannot edit reserved keywords nor apply them to another user
    forbidden_user_names = [
        get_constant("MAGPIE_ADMIN_USER", request),
        get_constant("MAGPIE_ANONYMOUS_USER", request),
        get_constant("MAGPIE_LOGGED_USER", request),
    ]
    check_user_name_cases = [user.user_name, new_user_name
                             ] if update_username else [user.user_name]
    for check_user_name in check_user_name_cases:
        ax.verify_param(
            check_user_name,
            not_in=True,
            param_compare=forbidden_user_names,
            param_name="user_name",
            http_error=HTTPForbidden,
            content={"user_name": str(check_user_name)},
            msg_on_fail=s.User_PATCH_ForbiddenResponseSchema.description)
    if update_username:
        uu.check_user_info(user_name=new_user_name,
                           check_email=False,
                           check_password=False,
                           check_group=False)
        existing_user = ax.evaluate_call(
            lambda: UserService.by_user_name(new_user_name,
                                             db_session=request.db),
            fallback=lambda: request.db.rollback(),
            http_error=HTTPForbidden,
            msg_on_fail=s.User_PATCH_ForbiddenResponseSchema.description)
        ax.verify_param(
            existing_user,
            is_none=True,
            with_param=False,
            http_error=HTTPConflict,
            msg_on_fail=s.User_PATCH_ConflictResponseSchema.description)
        user.user_name = new_user_name
    if update_email:
        uu.check_user_info(email=new_email,
                           check_name=False,
                           check_password=False,
                           check_group=False)
        user.email = new_email
    if update_password:
        uu.check_user_info(password=new_password,
                           check_name=False,
                           check_email=False,
                           check_group=False)
        UserService.set_password(user, new_password)
        UserService.regenerate_security_code(user)

    return ax.valid_http(http_success=HTTPOk,
                         detail=s.Users_PATCH_OkResponseSchema.description)
Beispiel #10
0
def edit_group_view(request):
    """
    Update a group by name.
    """
    group = ar.get_group_matchdict_checked(request,
                                           group_name_key="group_name")
    special_groups = [
        get_constant("MAGPIE_ANONYMOUS_GROUP", settings_container=request),
        get_constant("MAGPIE_ADMIN_GROUP", settings_container=request),
    ]
    ax.verify_param(
        group.group_name,
        not_in=True,
        param_compare=special_groups,
        param_name="group_name",
        http_error=HTTPForbidden,
        msg_on_fail=s.Group_PATCH_ReservedKeyword_ForbiddenResponseSchema.
        description)

    new_group_name = ar.get_multiformat_body(request, "group_name")
    new_description = ar.get_multiformat_body(request, "description")
    new_discoverability = ar.get_multiformat_body(request, "discoverable")
    if new_discoverability is not None:
        new_discoverability = asbool(new_discoverability)
    update_name = group.group_name != new_group_name and new_group_name is not None
    update_desc = group.description != new_description and new_description is not None
    update_disc = group.discoverable != new_discoverability and new_discoverability is not None
    ax.verify_param(
        any([update_name, update_desc, update_disc]),
        is_true=True,
        with_param=False,  # params are not useful in response for this case
        http_error=HTTPBadRequest,
        content={"group_name": group.group_name},
        msg_on_fail=s.Group_PATCH_None_BadRequestResponseSchema.description)
    if update_name:
        ax.verify_param(new_group_name,
                        not_none=True,
                        not_empty=True,
                        http_error=HTTPBadRequest,
                        msg_on_fail=s.
                        Group_PATCH_Name_BadRequestResponseSchema.description)
        group_name_size_range = range(
            1, 1 + get_constant("MAGPIE_GROUP_NAME_MAX_LENGTH",
                                settings_container=request))
        ax.verify_param(len(new_group_name),
                        is_in=True,
                        param_compare=group_name_size_range,
                        http_error=HTTPBadRequest,
                        msg_on_fail=s.
                        Group_PATCH_Size_BadRequestResponseSchema.description)
        ax.verify_param(
            GroupService.by_group_name(new_group_name, db_session=request.db),
            is_none=True,
            http_error=HTTPConflict,
            with_param=False,  # don't return group as value
            msg_on_fail=s.Group_PATCH_ConflictResponseSchema.description)
        group.group_name = new_group_name
    if update_desc:
        group.description = new_description
    if update_disc:
        group.discoverable = new_discoverability
    return ax.valid_http(http_success=HTTPOk,
                         detail=s.Group_PATCH_OkResponseSchema.description)
Beispiel #11
0
 def _get_param_value(self, param):
     return get_multiformat_body(self.request, param, None)
Beispiel #12
0
def update_resource(request):
    """
    Update a resource information.
    """
    resource = ar.get_resource_matchdict_checked(request, "resource_id")
    service_push = asbool(
        ar.get_multiformat_body(request, "service_push", default=False))
    res_old_name = resource.resource_name
    res_new_name = ar.get_value_multiformat_body_checked(
        request, "resource_name")
    ax.verify_param(
        res_new_name,
        not_equal=True,
        param_compare=res_old_name,
        param_name="resource_name",
        http_error=HTTPBadRequest,
        msg_on_fail=s.Resource_PATCH_BadRequestResponseSchema.description)
    db_session = request.db

    # check for conflicting name, either with services or children resources
    err_msg = s.Resource_PATCH_ConflictResponseSchema.description
    is_res_svc = resource.resource_type == models.Service.resource_type_name
    if is_res_svc:
        all_services = db_session.query(models.Service)
        all_svc_names = [svc.resource_name for svc in all_services]
        ax.verify_param(res_new_name,
                        not_in=True,
                        param_compare=all_svc_names,
                        with_param=False,
                        http_error=HTTPConflict,
                        content={"resource_name": str(res_new_name)},
                        msg_on_fail=err_msg)
    else:
        ru.check_unique_child_resource_name(res_new_name,
                                            resource.parent_id,
                                            err_msg,
                                            db_session=db_session)

    def rename_service_magpie_and_phoenix():
        resource.resource_name = res_new_name
        if is_res_svc and service_push:
            sync_services_phoenix(all_services)

    ax.evaluate_call(
        lambda: rename_service_magpie_and_phoenix(),
        fallback=lambda: db_session.rollback(),
        http_error=HTTPForbidden,
        msg_on_fail=s.Resource_PATCH_ForbiddenResponseSchema.description,
        content={
            "resource_id": resource.resource_id,
            "resource_name": resource.resource_name,
            "old_resource_name": res_old_name,
            "new_resource_name": res_new_name
        })
    return ax.valid_http(http_success=HTTPOk,
                         detail=s.Resource_PATCH_OkResponseSchema.description,
                         content={
                             "resource_id": resource.resource_id,
                             "resource_name": resource.resource_name,
                             "old_resource_name": res_old_name,
                             "new_resource_name": res_new_name
                         })