Skip to main content

Allows you to skip entering your email after registering via EVE SSO

Project description

AA Skip Email (aa_skip_email)

A small Alliance Auth plugin that lets you skip collecting real email addresses during EVE SSO registration by automatically generating a placeholder User.email. This is useful for integrations (e.g., OIDC clients) that expect email to be present.


Features

  • Creates a placeholder email for newly created users during SSO registration.
  • Includes a one-off Django management command to backfill missing emails.
  • Includes a Celery task suitable for periodic execution to keep data consistent.
  • Emits a placeholder_email_replaced signal when a user's placeholder is replaced with a real address — downstream plugins (OIDC providers, audit logs, welcome flows) can react without polling.
  • Exposes is_placeholder_email() and get_placeholder_users() helpers so callers can classify addresses without re-implementing the domain check.
  • Ships a PlaceholderEmailFilter for the Django admin user list.
  • Translated user-visible strings (admin filter, command output, AppConfig name) — currently en source + ru catalogue.

Requirements

  • Python >= 3.12
  • Alliance Auth

Installation

Install the plugin into the same Python environment as Alliance Auth (pip/uv/poetry-whatever you use).

pip install aa-skip-email

Add the app to INSTALLED_APPS (typically in local.py):

INSTALLED_APPS += [
    ...
    "aa_skip_email",
    ...
]

Add the authentication backend to AUTHENTICATION_BACKENDS.

[!IMPORTANT] This plugin replaces Alliance Auth’s default allianceauth.authentication.backends.StateBackend behavior. Update AUTHENTICATION_BACKENDS so that SkipEmailBackend is used instead of the original AA StateBackend.

Example:

AUTHENTICATION_BACKENDS = [
    # Replace the original AA StateBackend with this plugin backend
    "aa_skip_email.authentication.backends.SkipEmailBackend",
    # Keep the rest of your original backends
    "django.contrib.auth.backends.ModelBackend",
]

Configuration

Configure these in local.py (or your equivalent settings file).

AA_SKIP_EMAIL_DOMAIN

Domain used for placeholder addresses.

  • Type: str
  • Default: no-email.invalid
AA_SKIP_EMAIL_DOMAIN = "no-email.invalid"

Using a domain under .invalid helps avoid accidentally generating addresses at a real domain.

The plugin validates this setting at process start and raises ImproperlyConfigured if the value is empty, contains @ or whitespace, or has no . (single-label "domain"). This catches misconfigurations before the first SSO registration attempt.

AA_SKIP_EMAIL_LIMIT

Default limit for how many users are processed per run by the management command and the Celery task.

  • Type: int
  • Default: 5000
AA_SKIP_EMAIL_LIMIT = 5000

How placeholder emails are generated

A placeholder email is generated from the user’s username (sanitized to a conservative character set) and a unique suffix (typically the user id; otherwise a UUID). The local-part is kept within 64 characters.

Resulting format is similar to:

<sanitized-username>-<id-or-uuid>@<AA_SKIP_EMAIL_DOMAIN>

One-off backfill (management command)

The plugin provides a Django management command to fill missing emails.

Fill missing emails (default)

python manage.py fill_missing_emails

Limit number of users

python manage.py fill_missing_emails --limit 5000

Dry-run (no writes)

python manage.py fill_missing_emails --dry-run --limit 50

Overwrite emails for all users

[!CAUTION] This will replace existing emails.

python manage.py fill_missing_emails --overwrite

Overwrite only existing placeholders

Safer if some users have real emails and you only want to regenerate placeholders.

python manage.py fill_missing_emails --overwrite --only-placeholders

Scheduler (Celery Beat)

The plugin includes a Celery task named:

  • aa_skip_email.fill_missing_emails

To run it periodically, add a schedule entry in local.py using CELERYBEAT_SCHEDULE.

Example: run every 6 hours

from celery.schedules import crontab

CELERYBEAT_SCHEDULE["aa_skip_email_fill_missing_emails"] = {
    "task": "aa_skip_email.fill_missing_emails",
    "schedule": crontab(minute=0, hour="*/6"),
    # Optional: helps spread load across instances in some AA deployments
    "apply_offset": True,
}

Example: run daily at 04:15

from celery.schedules import crontab

CELERYBEAT_SCHEDULE["aa_skip_email_fill_missing_emails"] = {
    "task": "aa_skip_email.fill_missing_emails",
    "schedule": crontab(minute=15, hour=4),
    "apply_offset": True,
}

Public API for downstream plugins

is_placeholder_email(email)

from aa_skip_email import is_placeholder_email

if is_placeholder_email(user.email):
    ...  # treat as unverified / non-routable

Centralised classifier — returns True for any address produced by this plugin (case-insensitive domain match, anchored to the domain part). Falsy values (None, "") return False.

get_placeholder_users()

from aa_skip_email.helpers import get_placeholder_users

count = get_placeholder_users().count()

ORM-side analogue of is_placeholder_email. Returns a queryset of all users whose email is a plugin-generated placeholder. Useful for admin reports, audit dashboards, or batch follow-up.

Admin filter

Add PlaceholderEmailFilter to AA's existing UserAdmin.list_filter to surface a "Placeholder / Real / Blank" sidebar in the admin user list. The plugin does not re-register the User model so AA's custom UserAdmin remains intact:

# in your local.py
from django.contrib import admin
from django.contrib.auth import get_user_model
from aa_skip_email.admin import PlaceholderEmailFilter

User = get_user_model()
UserAdmin = admin.site._registry[User].__class__
UserAdmin.list_filter = (*UserAdmin.list_filter, PlaceholderEmailFilter)

Signal placeholder_email_replaced

Sent when User.email transitions from a plugin-generated placeholder to a real address. Useful for OIDC providers that flip email_verified=true on the ID token, audit logs, welcome emails, etc.

from django.dispatch import receiver
from aa_skip_email.signals import placeholder_email_replaced

@receiver(placeholder_email_replaced, dispatch_uid="my_app.email_verified")
def on_email_replaced(sender, user, old_email, new_email, **kwargs):
    ...

The signal does not fire on:

  • Initial fill of a blank/NULL email (placeholder is the new value).
  • Placeholder rewritten as another placeholder (--overwrite --only-placeholders).
  • Real email replaced with another real email.

See also

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aa_skip_email-0.3.2.tar.gz (15.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aa_skip_email-0.3.2-py3-none-any.whl (20.9 kB view details)

Uploaded Python 3

File details

Details for the file aa_skip_email-0.3.2.tar.gz.

File metadata

  • Download URL: aa_skip_email-0.3.2.tar.gz
  • Upload date:
  • Size: 15.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Gentoo","version":"2.18","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for aa_skip_email-0.3.2.tar.gz
Algorithm Hash digest
SHA256 55b80a97b2f214941555cd06a27468642ba7111fca2ee7b9eaa957eed36d635c
MD5 6ea19ec20b36cafac5d4a51b88d1304d
BLAKE2b-256 1d7e49c45e09466d0299ffe802ed1af0d03efb045aa0e2c48f0fc828dbab325b

See more details on using hashes here.

File details

Details for the file aa_skip_email-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: aa_skip_email-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 20.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.8 {"installer":{"name":"uv","version":"0.11.8","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Gentoo","version":"2.18","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for aa_skip_email-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e01124f188a9c142937fd0e20863b541fcb3fd9fbc4eec00743bb7d66c222d7b
MD5 665fd4cecaae4beffcdac5c0cada2bf8
BLAKE2b-256 0b0b6567ffd8ccfe9d5b74aa90c38410ea4f4a6aa2e214af16d39a7a9d81e784

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page