rustango 0.61.13

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
<!doctype html>
<html lang="en" data-theme="{{ theme_mode | default(value='auto') }}">
<head>
  <meta charset="utf-8">
  {#- Scripts read the CSRF token here (autoescaped), never inline. -#}
  <meta name="csrf-token" content="{{ csrf_token | default(value='') }}">
  <meta name="console-prefix" content="{{ console_prefix | default(value='') }}">
  <script nonce="{{ csp_nonce }}">
    function csrfToken() {
      return document.querySelector('meta[name="csrf-token"]').content;
    }
    // A console path under the console's mount prefix (#2007).
    function consoleUrl(path) {
      return document.querySelector('meta[name="console-prefix"]').content + path;
    }
    // Shows a connection probe's JSON as text nodes, never as HTML (#2144).
    async function showProbe(out, res) {
      const p = await res.json().catch(() => null);
      const el = document.createElement("div");
      el.className = "probe " + (p && p.status === "ok" ? "probe-ok" : "probe-bad");
      if (!p) {
        el.textContent = "unexpected response: HTTP " + res.status;
      } else {
        if (p.endpoint) {
          const code = document.createElement("code");
          code.textContent = p.endpoint;
          el.append("Reached ", code, ". ");
        }
        const msg = document.createElement("span");
        msg.textContent = String(p.message || "");
        el.append(msg);
        // A rights report: each right, then how to fix what is missing.
        if (Array.isArray(p.rights) && p.rights.length) {
          const ul = document.createElement("ul");
          ul.className = "rights";
          for (const r of p.rights) {
            const li = document.createElement("li");
            li.className = "right-" + String(r.has);
            li.textContent = String(r.label) + ": " + String(r.has);
            ul.append(li);
          }
          el.append(ul);
        }
        for (const key of ["note", "fix"]) {
          if (p[key]) {
            const d = document.createElement("div");
            d.textContent = String(p[key]);
            el.append(d);
          }
        }
        if (Array.isArray(p.fix_sql) && p.fix_sql.length) {
          const pre = document.createElement("pre");
          pre.className = "fix-sql";
          pre.textContent = p.fix_sql.map(String).join("\n");
          el.append(pre);
        }
        if (p.alternative) {
          const d = document.createElement("div");
          d.textContent = String(p.alternative);
          el.append(d);
        }
      }
      out.replaceChildren(el);
    }
// Delegated handlers: a strict CSP blocks inline on* attributes (#1703).
document.addEventListener('submit',function(e){var m=e.target.getAttribute('data-confirm');if(m&&!confirm(m))e.preventDefault();});
document.addEventListener('click',function(e){var b=e.target.closest&&e.target.closest('button[data-confirm]');if(b&&!confirm(b.getAttribute('data-confirm')))e.preventDefault();});
document.addEventListener('change',function(e){var s=e.target;if(s.matches&&s.matches('select[data-nav]')){location.href=s.options[s.selectedIndex].dataset.href;}});
  </script>
  {% if brand_logo_url %}<link rel="icon" href="{{ brand_logo_url }}">{% endif %}
  <title>{% block title %}{{ brand_name | default(value='Rustango Operator Console') }}{% endblock %}</title>
  <script nonce="{{ csp_nonce }}">
  // No-flash theme application — see _theme_toggle.html for the cycle UI.
  (function(){try{var t=localStorage.getItem('rustango-theme');if(t==='light'||t==='dark'||t==='auto'){document.documentElement.dataset.theme=t;}}catch(e){}})();
  </script>
  {% include "_theme_tokens.html" %}
  {% include "_op_styles.html" %}
  {% if brand_css %}<style nonce="{{ csp_nonce }}">:root { {{ brand_css | safe }} }</style>{% endif %}
</head>
<body>
  <div class="shell">
    {#- The column stretches to the page; the sidebar inside it sticks. -#}
    <div class="sidebar-col">
    <aside class="sidebar">
      <div class="brand">
        {% if brand_logo_url %}<img class="brand-logo" src="{{ brand_logo_url }}" alt="">{% endif %}
        <span class="brand-text">
          <span class="brand-name">{{ brand_name | default(value='Rustango') }}</span>
          {% if brand_tagline %}<span class="brand-tagline">{{ brand_tagline }}</span>{% endif %}
        </span>
      </div>
      <nav>
        <a href="{{ console_home | default(value='/') }}" class="{% if section == 'home' %}active{% endif %}">Home</a>
        <a href="{{ console_prefix | default(value='') }}/operators" class="{% if section == 'operators' %}active{% endif %}">Operators</a>
        <a href="{{ console_prefix | default(value='') }}/orgs" class="{% if section == 'orgs' %}active{% endif %}">Organizations</a>
        {% if nav_db_servers %}<a href="{{ console_prefix | default(value='') }}/db-servers" class="{% if section == 'db_servers' %}active{% endif %}">Database servers</a>{% endif %}
        {% if sso_console %}<a href="{{ console_prefix | default(value='') }}/sso-shared" class="{% if section == 'sso' %}active{% endif %}">Shared SSO</a>{% endif %}
        <a href="{{ console_prefix | default(value='') }}/audit" class="{% if section == 'audit' %}active{% endif %}">Audit log</a>
        <a href="{{ console_prefix | default(value='') }}/change-password" class="{% if section == 'change_password' %}active{% endif %}">Change password</a>
        {% if totp_console %}<a href="{{ console_prefix | default(value='') }}/account/totp" class="{% if section == 'totp' %}active{% endif %}">Two-factor sign-in</a>{% endif %}
      </nav>
      <div class="who">Signed in as <strong>{{ operator_username }}</strong></div>
      <form class="logout" method="post" action="{{ console_prefix | default(value='') }}/logout">
        {{ csrf_input | default(value='') | safe }}
        <button type="submit">Sign out</button>
      </form>
    </aside>
    </div>
    <main>
      {% block content %}{% endblock %}
    </main>
  </div>
  {% include "_theme_toggle.html" %}
</body>
</html>