Skip to content

QGIS viewer user context (expression variables)

The map viewer loads authenticated user metadata before the form and expression runtimes initialize. This enables QGIS-style expressions that reference the signed-in user.

API

GET /api/auth/context (session cookie, credentials: include)

Authenticated:

{
  "authenticated": true,
  "user": {
    "id": "42",
    "username": "alice",
    "email": "alice@example.com",
    "roles": ["editor", "viewer"],
    "groups": ["Editors", "field-team"],
    "attributes": {
      "district_id": 3,
      "tenant_id": "abc"
    }
  }
}

Anonymous (no session or central auth disabled):

{
  "authenticated": false,
  "user": null
}

User attributes (optional)

To expose custom keys such as district_id in expressions, add a JSONB column on the central auth database:

ALTER TABLE dashboard_users
  ADD COLUMN IF NOT EXISTS attributes JSONB NOT NULL DEFAULT '{}'::jsonb;

UPDATE dashboard_users
SET attributes = '{"district_id": 3, "tenant_id": "abc"}'::jsonb
WHERE username = 'alice';

If the column does not exist, attributes is always {}.

Viewer bootstrap

js/qgis-user-context.js runs on DOMContentLoaded before fetchProject(). It sets:

  • window.__qgisCurrentUser — user object or null

Debug logging:

window.__qgisDebugUserContext = true;
// reload viewer → console: [qgis-user-context] loaded

Expression debug snapshot (updated when auth context loads):

window.__qgisExprDebug.user; // same as __qgisCurrentUser

Standalone variables return values, not booleans:

evaluateQgisExpression('@user');        // { ok: true, value: "admin" }
evaluateQgisExpression('@district_id'); // { ok: true, value: null }
evaluateQgisExpression('current_user()'); // { ok: true, value: "admin" }

Comparisons still evaluate to boolean (owner = @usertrue / false).

Expression variables

Evaluated in js/qgis-expr-runtime.js (visibility, editable, required, defaults, constraints):

Token Resolves to
current_user() Signed-in username (empty when anonymous)
@user, @username Username
@roles Array of role slugs (e.g. ["admin","editor","viewer"])
@groups Array of group names
@district_id, @tenant_id, … Matching key from user.attributes

Example expressions

Use in QGIS field visibility, editable, or constraint expressions (published via forms manifest):

owner = @user
district_id = @district_id
district_id = @district_id AND status = 'open'
current_user() = 'alice'
"tenant_id" = @tenant_id

Manual acceptance check

  1. Sign in to Central / dashboard so the session cookie is present.
  2. Open viewer.html?id=<project> for a layer with:
  3. Visibility: owner = @user on a field users should only see for their rows.
  4. Editable: district_id = @district_id on a field that should lock when district differs.
  5. Set window.__qgisDebugUserContext = true and reload — confirm [qgis-user-context] loaded and username in the debug payload.
  6. In the browser console:
resolveQgisVariable('user');
resolveQgisVariable('district_id');
evaluateQgisExpression('owner = @user', function (n) { return n === 'owner' ? 'alice' : undefined; });
  1. Edit a feature and confirm visibility/editable rules react when attribute values change.