rustango 0.30.19

Django-shaped batteries-included web framework for Rust: ORM + migrations + auto-admin + multi-tenancy + audit log + auth (sessions, JWT, OAuth2/OIDC, HMAC) + APIs (ViewSet, OpenAPI auto-derive, JSON:API) + jobs (in-mem + Postgres) + email + media (S3 / R2 / B2 / MinIO + presigned uploads + collections + tags) + production middleware (CSRF, CSP, rate-limiting, compression, idempotency, etc.).
Documentation
{% extends "op_layout.html" %}
{% block title %}Edit {{ slug }} — {{ brand_name | default(value='Rustango Operator Console') }}{% endblock %}
{% block content %}

<nav class="breadcrumb" aria-label="breadcrumb">
  <a href="/orgs">Organizations</a>
  <span class="sep"></span>
  <code>{{ slug }}</code>
  <span class="sep"></span>
  edit
</nav>

<h1>Edit <code>{{ slug }}</code></h1>
<p class="lead">
  Adjust the live config for this tenant. Locked fields stay where they
  are — re-provisioning needs <code>cargo run -- create-tenant</code> /
  <code>drop-tenant</code>. Inputs are generated from
  <code>Org::SCHEMA</code> via
  <code>rustango::admin::render::render_input</code>, so new columns
  added to <code>Org</code> show up here without template edits.
</p>

{% if error %}<div class="alert alert-error">{{ error }}</div>{% endif %}
{% if notice %}<div class="alert alert-notice">{{ notice }}</div>{% endif %}

<form method="post" action="/orgs/{{ slug }}/edit" class="edit-form">

  <fieldset class="section locked">
    <legend>Locked</legend>
    <table>
      {% for row in locked_rows %}
      <tr>
        <th>{{ row.name }}</th>
        <td>{% if row.value %}<code>{{ row.value }}</code>{% else %}<span class="empty">None</span>{% endif %}</td>
      </tr>
      {% endfor %}
    </table>
  </fieldset>

  <fieldset class="section">
    <legend>Editable</legend>
    <table>
      {% for row in editable_rows %}
      <tr>
        <th><label for="{{ row.name }}">{{ row.name }}</label></th>
        <td>
          {{ row.input | safe }}
          {% if row.helper %}<div class="field-helper">{{ row.helper }}</div>{% endif %}
        </td>
      </tr>
      {% endfor %}
    </table>
  </fieldset>

  <div class="form-actions">
    <button type="submit" class="btn btn-primary">Save</button>
    <a href="/orgs" class="btn-link">Cancel</a>
  </div>
</form>

<form method="post" action="/orgs/{{ slug }}/edit/branding" enctype="multipart/form-data" class="edit-form">
  <fieldset class="section">
    <legend>Branding assets</legend>
    <table>
      <tr>
        <th><label for="logo">Logo</label></th>
        <td>
          {% if logo_url %}<img class="brand-asset-preview" src="{{ logo_url }}" alt="">{% endif %}
          <input type="file" id="logo" name="logo" accept="image/png,image/jpeg,image/webp">
          <div class="field-helper">PNG, JPEG, or WebP. Max 1 MB. Leave empty to keep the current logo.</div>
        </td>
      </tr>
      <tr>
        <th><label for="favicon">Favicon</label></th>
        <td>
          {% if favicon_url %}<img class="brand-asset-preview" src="{{ favicon_url }}" alt="">{% endif %}
          <input type="file" id="favicon" name="favicon" accept="image/png,image/x-icon">
          <div class="field-helper">PNG or ICO. Max 1 MB. Leave empty to keep the current favicon.</div>
        </td>
      </tr>
    </table>
  </fieldset>
  <div class="form-actions">
    <button type="submit" class="btn btn-primary">Save branding assets</button>
  </div>
</form>

{# v0.27.8 (#78) — Open admin as superuser. Posts to
   /orgs/{slug}/impersonate which mints a short-lived tenant
   session cookie (1h default), pinned to this slug, and 302s
   to the tenant admin's /__admin/. Banner + audit entries make
   the session visible + traceable. Hidden if impersonation
   wasn't enabled at boot (the operator console route only
   mounts when the tenant session secret is shared). #}
{% if impersonate_enabled %}
<form method="post" action="/orgs/{{ slug }}/impersonate" class="edit-form">
  <fieldset class="section">
    <legend>Impersonate (sign in as superuser)</legend>
    <p style="margin: 0 0 var(--space-3) 0; color: var(--color-fg-muted); font-size: 13px">
      Open this tenant's admin as a synthetic operator-superuser.
      You'll see an unmissable banner during the session; every
      write is recorded as
      <code>operator:&lt;your-id&gt;:impersonating</code> in the
      tenant's audit log. Session expires after the configured
      TTL (default 1&nbsp;hour).
    </p>
  </fieldset>
  <div class="form-actions">
    <button type="submit" class="btn btn-primary">Open admin as superuser →</button>
  </div>
</form>
{% endif %}

{% endblock %}