rustango 0.27.9

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
<!doctype html>
<html lang="en" data-theme="{{ theme_mode | default(value='auto') }}">
<head>
  <meta charset="utf-8">
  <title>Sign in — {{ brand_name | default(value='rustango operator console') }}</title>
  {% include "_theme_tokens.html" %}
  {% if brand_css %}<style>:root { {{ brand_css | safe }} }</style>{% endif %}
  <style>
    body {
      margin: 0;
      font-family: var(--font-family-base);
      font-size: var(--font-size-base);
      line-height: var(--line-height-base);
      background: var(--color-bg);
      color: var(--color-fg);
      display: flex;
      min-height: 100vh;
      align-items: center;
      justify-content: center;
    }
    .card {
      width: 320px;
      padding: var(--space-6);
      border: 1px solid var(--color-border);
      border-radius: var(--radius-lg);
      background: var(--color-bg-surface);
      box-shadow: var(--shadow-sm);
    }
    .card .brand-logo {
      display: block;
      max-height: 56px;
      max-width: 100%;
      margin: 0 auto var(--space-3) auto;
    }
    h1 {
      color: var(--color-accent);
      font-size: 1.4rem;
      margin: 0 0 var(--space-2) 0;
    }
    p.sub {
      color: var(--color-fg-muted);
      margin: 0 0 var(--space-5) 0;
    }
    label {
      display: block;
      font-size: var(--font-size-sm);
      color: var(--color-fg-muted);
      margin-top: var(--space-3);
      text-transform: uppercase;
      letter-spacing: 0.05em;
    }
    input[type=text], input[type=password] {
      width: 100%;
      padding: var(--space-2) 0.6rem;
      border: 1px solid var(--color-border);
      border-radius: var(--radius-md);
      font: inherit;
      background: var(--color-bg-input);
      color: var(--color-fg);
      margin-top: var(--space-1);
    }
    input:focus { outline: 2px solid var(--color-accent); outline-offset: 1px; }
    button {
      margin-top: var(--space-5);
      width: 100%;
      padding: 0.6rem;
      background: var(--color-accent);
      color: var(--color-fg-on-accent);
      border: 0;
      border-radius: var(--radius-md);
      font: inherit;
      font-weight: var(--font-weight-bold);
      cursor: pointer;
    }
    button:hover { filter: brightness(1.1); }
    .error {
      color: var(--color-error-fg);
      background: var(--color-error-bg);
      padding: var(--space-2) var(--space-3);
      border-radius: var(--radius-md);
      margin: var(--space-4) 0 0 0;
      font-size: 13px;
    }
  </style>
</head>
<body>
  <form class="card" method="post" action="/login">
    {% if brand_logo_url %}<img class="brand-logo" src="{{ brand_logo_url | safe }}" alt="">{% endif %}
    <h1>{{ brand_name | default(value='rustango') }}</h1>
    <p class="sub">{{ brand_tagline | default(value='Operator console') }}</p>
    {% if error %}<div class="error">{{ error }}</div>{% endif %}
    <label for="username">Username</label>
    <input type="text" id="username" name="username" autocomplete="username" autofocus required>
    <label for="password">Password</label>
    <input type="password" id="password" name="password" autocomplete="current-password" required>
    <input type="hidden" name="next" value="{{ next }}">
    <button type="submit">Sign in</button>
  </form>
</body>
</html>