{% extends "base.html" %} {% block title %}{{ t('access.title') }} — painfree{% endblock %} {% block body %}

{{ t('access.heading') }}

{{ t('access.lede') }}

{# Who may do what is people by connections by level, so it is drawn as that. A list of people each carrying a list of their connections answers "what does Olive hold" and makes "who can move money at this bank" a read of every row and every sub-list. #}

{{ t('access.totals', people=subjects | length, connections=connections | length, movers=movers) }}

{% if stranded %} {# A grant is inert without a way to use it. Under `basic` this is the ordinary consequence of granting before the account exists, and the console could not show it at all until `basic_account` was joined in. #}
{{ t('access.stranded_heading', count=stranded | length) }}

{{ t('access.stranded_why') }}

{% for subject in stranded %}{{ subject }} {% endfor %}

{% endif %}
{% if subjects %} {% for row in connections %} {% endfor %} {% for row in subjects %} {# The subject is the identity provider's `sub` claim, verbatim: an identifier, never translated and never reformatted. #} {% if row.oversight %} {# Oversight names no connection, so it is a band rather than a cell: drawing it inside one column would be drawing something the model does not have. #} {% else %} {% for connection in connections %} {# `first` on an empty sequence raises under `StrictUndefined`, and most cells are empty: a matrix is mostly the absence of a grant. #} {% set held = row.grants | selectattr('connection_id', 'equalto', connection.connection_id) | list %} {% endfor %} {% endif %} {% endfor %}
{{ t('access.person') }}{{ t('access.signs_in_with') }}{{ row.connection_id }}{{ t('access.last_seen') }}
{{ row.display_name or row.subject }} {% if row.display_name %}
{{ row.subject }}{% endif %}
{# `cannot sign in` is only true under `basic`, where a password is the only credential. Development mode accepts a header from anybody and `oidc` accounts live at the provider, so neither can be answered from what this deployment stores. #} {%- if row.subject in password_holders %}{{ t('access.signs_in_password') }} {%- elif auth_mode == 'oidc' %}{{ t('access.signs_in_provider') }} {%- elif auth_mode == 'basic' and (row.grants or row.oversight) %}{{ t('access.cannot_sign_in') }} {%- else %}{% endif %} oversight {{ t('access.every_connection_readonly') }}{% if held %}{{ held[0].level.value }} {% else %}·{% endif %}{{ row.last_seen_at | moment }}

{{ t('access.narrowing_note') }}

{% else %}

{{ t('access.nobody') }}

{% endif %}
{% if ungranted %}
{{ t('access.ungranted_heading') }}

{{ t('access.ungranted_why') }}

{% for row in ungranted %}{{ row.subject }} {% endfor %}

{% endif %}

{{ t('access.lede_no_user_list') }}

{{ t('access.lede_oversight') }}

{% endblock %}