Tenant — Invitations

Le système d’invitations permet d’inviter des utilisateurs à rejoindre un tenant par email avec un token d’acceptation.

Module : src.module.tenant.domain.invitation_service

send_invitation

src.module.tenant.domain.invitation_service.send_invitation(tenant, email, roles, invited_by, membership_queryset) Invitation

Crée une invitation et envoie un email.

  1. Vérifie qu’aucune invitation en attente n’existe pour cet email/tenant

  2. Crée l’invitation avec un token UUID unique

  3. Calcule la date d’expiration (INVITATION_EXPIRATION_HOURS)

  4. Envoie l’email (différent selon que l’utilisateur est déjà inscrit ou non)

  5. Émet InvitationSent

Parameters:
  • tenant – Tenant émetteur

  • email – Email du destinataire

  • roles – Liste de rôles pré-assignés

  • invited_by – Utilisateur émetteur

  • membership_queryset – QuerySet pour vérifier les doublons

Returns:

Instance Invitation créée

from src.module.tenant.domain.invitation_service import send_invitation

invitation = send_invitation(
    tenant=acme_tenant,
    email="new.user@example.com",
    roles=["member", "billing"],
    invited_by=admin_user,
    membership_queryset=TenantMembership.objects.all(),
)

accept_invitation_by_token

src.module.tenant.domain.invitation_service.accept_invitation_by_token(token, user) TenantMembership

Accepte une invitation par son token.

  1. Recherche l’invitation par token

  2. Vérifie que l’invitation est en attente et non expirée

  3. Vérifie que l’email correspond à l’utilisateur

  4. Crée la membership avec les rôles pré-assignés

  5. Émet InvitationAccepted

Parameters:
  • token – UUID du token d’invitation

  • user – Utilisateur acceptant l’invitation

Returns:

Instance TenantMembership créée

Raises:

ValueError si le token est invalide, expiré, ou l’email ne correspond pas

Flux d’invitation

Admin                         Système                        Invité
  │                              │                              │
  ├── POST /invitations/ ──────►│                              │
  │   {email, roles}            │                              │
  │                              ├── Crée Invitation ──────────│
  │                              ├── Envoie email ─────────────►│
  │                              │   (lien avec token)          │
  │                              │                              │
  │                              │◄── GET /invitations/accept/ ─┤
  │                              │    {token}                   │
  │                              │                              │
  │                              ├── Valide token               │
  │                              ├── Crée TenantMembership      │
  │                              ├── Émet InvitationAccepted    │
  │                              │                              │
  │                              │── 200 OK ───────────────────►│
  │                              │                              │

Configuration

MULTITENANT = {
    'INVITATION_ENABLED': True,
    'INVITATION_EXPIRATION_HOURS': 168,  # 7 jours
    'INVITATION_FROM_EMAIL': 'noreply@example.com',
}