Skip to content

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 calling bfabric_rest_proxy.feeder_operations.is_employee(user_client, feeder_client) in-process. The user SOAP 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 the QG_ALLOW_UNAUTHENTICATED=1 dev path, the call is skipped and is_employee is True.
  • container_id (non-employees only) — supplied by the request (entity_id). Because B-Fabric addresses Container / Order / Project by the same containerid key, 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 leaving BfabricHelper.
  • 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_UNAUTHENTICATED opt-in; remove silent unauthenticated fallback.
  • Call the bfabric_rest_proxy.feeder_operations.is_employee helper (with both user and feeder clients) during the auth cell to obtain is_employee.
  • Read container_id (from entity_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.