Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bfabric_rest_proxy/docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
### Changed

- `feeder_operations.create_workunit` is now a thin authorization + audit-stamping wrapper around `bfabric.operations.workunit.create_workunit`. The workunit creation now flips the workunit to status `failed` on any error after initial creation (was: orphaned in `processing` status).
- `POST /create/workunit/v1` request body now accepts an optional `created_using` field (e.g. calling-app identifier). It is recorded as the `Created Using` custom attribute alongside the server-stamped `Created For` attribute. The wrapper signature changed accordingly: it now takes a single `CreateWorkunitRequest` (subclass of `CreateWorkunitParams`) instead of separate `params` + `created_using` arguments.
- Renamed the workunit custom attribute that records the initiating web-app user from `WebApp User` to `Created For`.

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,36 @@

from bfabric import Bfabric
from bfabric.entities import Workunit
from bfabric.operations.workunit import CreateWorkunitParams, create_workunit as _create_workunit
from bfabric.operations.workunit import CreateWorkunitParams
from bfabric.operations.workunit import create_workunit as _create_workunit

__all__ = ["CreateWorkunitParams", "create_workunit"]
__all__ = ["CreateWorkunitParams", "CreateWorkunitRequest", "create_workunit"]


class CreateWorkunitRequest(CreateWorkunitParams):
"""Proxy-level request: core workunit params plus client-supplied audit metadata."""

created_using: str | None = None


def create_workunit(
user_client: Bfabric,
feeder_client: Bfabric,
params: CreateWorkunitParams,
request: CreateWorkunitRequest,
) -> Workunit:
"""Create a workunit with the given parameters, using the feeder client on behalf of the user client.

Before proceeding, it will be checked if the user has permission to read the target container.
"""Create a workunit using the feeder client on behalf of the user client.

:param user_client: the web application user, which initiates the operation
:param feeder_client: the feeder user, which will actually perform the operation
:param params: the workunit parameters
:return: the created workunit
:raise: BfabricException if any API operation fails
:raise: RuntimeError if authorization fails
`Created For` is set server-side from the authenticated user.
`Created Using` is set from the (optional) client-supplied field.
"""
_check_container_access(user_client=user_client, container_id=params.container_id)
_check_container_access(user_client=user_client, container_id=request.container_id)
audit_attributes = {"Created For": user_client.auth.login}
if request.created_using is not None:
audit_attributes["Created Using"] = request.created_using
return _create_workunit(
client=feeder_client,
params=params,
audit_attributes={"WebApp User": user_client.auth.login},
params=request,
audit_attributes=audit_attributes,
)


Expand Down
6 changes: 3 additions & 3 deletions bfabric_rest_proxy/src/bfabric_rest_proxy/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from pydantic import BaseModel, Field, SecretStr, model_validator

from bfabric import Bfabric, BfabricAuth, BfabricClientConfig
from bfabric_rest_proxy.feeder_operations.create_workunit import CreateWorkunitParams, create_workunit
from bfabric_rest_proxy.feeder_operations.create_workunit import CreateWorkunitRequest, create_workunit
from bfabric_rest_proxy.settings import ServerSettings
from bfabric_rest_proxy.feeder_operations.is_employee import is_employee

Expand Down Expand Up @@ -108,9 +108,9 @@ def read(user_client: BfabricUserClientDep, params: ReadParams):
def post_create_workunit(
user_client: BfabricUserClientDep,
feeder_client: BfabricFeederClientDep,
params: CreateWorkunitParams,
params: CreateWorkunitRequest,
):
workunit = create_workunit(user_client=user_client, feeder_client=feeder_client, params=params)
workunit = create_workunit(user_client=user_client, feeder_client=feeder_client, request=params)
return [{**workunit.data_dict, "uri": workunit.uri}]


Expand Down
Loading