Skip to content

webserver refactoring: Retire using get_services_for_user_in_product #7838

@pcrespov

Description

@pcrespov

Follows up from #7836 where we added a cache to get_services_for_user_in_product

Example of how can be replace get_project

@routes.get(f"/{VTAG}/projects/{{project_id}}", name="get_project")
@login_required
@permission_required("project.read")
@handle_plugin_requests_exceptions
async def get_project(request: web.Request):
    """

    Raises:
        web.HTTPUnprocessableEntity: (422) if validation of request parameters fail
        web.HTTPNotFound: User has no access to at least one service in project
        web.HTTPForbidden: User has no access rights to get this project
        web.HTTPNotFound: This project was not found
    """

    req_ctx = RequestContext.model_validate(request)
    path_params = parse_request_path_parameters_as(ProjectPathParams, request)

    # 1. Get project if user has access
    project = await _projects_service.get_project_for_user(
        request.app,
        project_uuid=f"{path_params.project_id}",
        user_id=req_ctx.user_id,
        include_state=True,
        include_trashed_by_primary_gid=True,
    )

    # 2. Check if user has access to all services within the project
    services_in_project = {
        (srv["key"], srv["version"]) for _, srv in project.get("workbench", {}).items()
    }

    my_services: list[MyServiceGet] = await catalog_service.batch_get_my_services(
        request.app,
        product_name=req_ctx.product_name,
        user_id=req_ctx.user_id,
        services_ids=list(services_in_project),
    )

    not_my_services = services_in_project.difference(
        {(srv.key, srv.release.version) for srv in my_services}
    )

    if not_my_services:
        formatted_services = ", ".join(
            f"{service}:{version}" for service, version in not_my_services
        )
        # TODO: lack of permissions should be notified with https://httpstatuses.com/403 web.HTTPForbidden
        raise web.HTTPNotFound(
            reason=(
                f"Project '{path_params.project_id}' uses unavailable services. Please ask "
                f"for permission for the following services {formatted_services}"
            )
        )

    # 3. Adds permalink
    await update_or_pop_permalink_in_project(request, project)

    data = ProjectGet.from_domain_model(project).data(exclude_unset=True)
    return envelope_json_response(data)

Metadata

Metadata

Assignees

Labels

a:webserverwebserver's codebase. Assigning the area is particularly useful for bugst:enhancementImprovement or request on an existing feature

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions