User Modes — Requirements¶
Please do not change this document without discussion since it involves security implications of the system.
Status: implemented
Scope: src/qg/apps/queue_app.py
This document covers the B-Fabric portal app (
queue_app.py). The standalone local app (queue_app_local.py, see Local app) has no authentication and no B-Fabric dependency — nothing in this document applies to it. (Scope note only; the security model below is unchanged.)
Authentication¶
The app requires an authenticated user in the request. An unauthenticated session is permitted only when QG_ALLOW_UNAUTHENTICATED=1 is set in the environment; otherwise the app refuses to render. Production deployments do not set this variable.
Inputs¶
is_employee: bool— obtained by callingbfabric_rest_proxy.feeder_operations.is_employee(user_client, feeder_client)in-process. TheuserSOAP endpoint is admin-restricted, so the feeder client performs the privileged lookup on behalf of the authenticated user. Fail-closed cases: no feeder credentials configured for the user's instance, or the lookup itself errors. In theQG_ALLOW_UNAUTHENTICATED=1dev path, the call is skipped andis_employeeisTrue.container_id(non-employees only) — supplied by the request (entity_id). Because B-Fabric addresses Container / Order / Project by the samecontaineridkey, this one input covers all three entity classes. Auth, existence and permission are guaranteed upstream; the app does not re-check.
Non-employee preconditions¶
Before any B-Fabric query runs: entity_class ∈ {Container, Order, Project} and entity_id is not None. If either fails, the app halts with no queries issued and no data loaded.
Non-employee experience¶
- The container from the request is fixed and shown read-only. There is no order table, no refresh button, and no access to other containers' metadata.
- B-Fabric reads use the feeder client; the user client is not used for data reads.
- Samples on shared plates are filtered to
entity_id; samples belonging to other containers are dropped before leavingBfabricHelper. - The container cache (
projects_df) is never loaded. - All other queue-building controls and the upload button behave the same as for employees.
- If the container has no samples, the app halts — no partial data is loaded. UX of the halted state is left to implementation.
- Tech area is freely selectable. It may optionally be restricted to options matching the container's Area, if the existing Area→tech_area mapping can be reused without adding new config.
Employee experience¶
Full order table with multi-select, refresh button, and all controls freely selectable. No preselection from the request.
Summary of changes (tentative)¶
- Add
QG_ALLOW_UNAUTHENTICATEDopt-in; remove silent unauthenticated fallback. - Call the
bfabric_rest_proxy.feeder_operations.is_employeehelper (with both user and feeder clients) during the auth cell to obtainis_employee. - Read
container_id(fromentity_id) for non-employees. - Enforce non-employee preconditions (
entity_class,entity_id) at entry; halt otherwise. - Replace the order table with a read-only banner in non-employee mode; suppress the refresh button.
- Stop loading the container cache for non-employees.
- Halt the app when a non-employee's container has no samples.