Client Provisioning¶
Übersicht¶
Das Client-Provisioning-System ermöglicht die automatische Konfiguration von xynap Desktop- und Mobil-Clients über Einmal-Links. Ein Admin generiert einen Token, der Nutzer öffnet den Link, und der Client richtet sich automatisch ein (WebDAV, SIP/WebRTC, Mail, Platform-Login).
Enterprise-tauglich
Alle Dienste laufen über Port 443 (HTTPS/WSS). Kein extra Port nötig — funktioniert in jedem Firmennetz.
Architektur¶
Admin UI → POST /api/v1/provisioning/client-tokens
→ Token generiert (xprov_{prefix}_{secret}, SHA256 gespeichert)
→ Provisioning-Link: https://{domain}/provision/{token}
Client öffnet Link:
→ GET /provision/{token}?lang=de (öffentlich, kein Auth)
→ Einmaliger Abruf → Token verbraucht
→ JSON mit Services, Credentials, URLs
→ Client konfiguriert sich automatisch
Dynamischer Dienst-Katalog¶
Alle verfügbaren Dienste werden in der Datenbank verwaltet (provisioning_services). Jeder Dienst hat:
- slug — Eindeutiger Bezeichner (z.B.
cloud-storage,telephony) - name_i18n / description_i18n — Mehrsprachige Texte (JSON:
{"de": "...", "en": "..."}) - icon — Lucide-Icon-Name für die Client-UI
- config_template — JSON-Template mit Platzhaltern
- feature_slug — Verknüpfung zu Features/Modulen
- is_base — Basis-Dienst (immer aktiv, unabhängig von Buchung)
Platzhalter in config_template¶
| Platzhalter | Beschreibung | Beispiel |
|---|---|---|
{base_url} |
Domain des Tenants | xynap.cloud |
{user_slug} |
User-Slug (E-Mail mit _at_) |
max_at_firma.de |
{email} |
E-Mail-Adresse des Users | max@firma.de |
{domain} |
E-Mail-Domain | firma.de |
{display_name} |
Anzeigename | Max Mustermann |
Standard-Dienste¶
| Dienst | Slug | Protokoll | URL-Pattern |
|---|---|---|---|
| Platform-Zugang | platform-access |
HTTPS | https://{base_url} |
| Cloud-Speicher | cloud-storage |
WebDAV | https://{base_url}/dav/files/{user_slug}/ |
| Kontakte | contacts |
CardDAV | https://{base_url}/dav/addressbooks/{user_slug}/contacts/ |
| Kalender | calendar |
CalDAV | https://{base_url}/dav/calendars/{user_slug}/default/ |
email |
IMAP+SMTP | mail.{base_url}:993/587 |
|
| Telefonie | telephony |
SIP-WSS | wss://{base_url}/sip |
Feature-Freischaltung¶
Die Zuordnung erfolgt über provisioning_service_mappings:
User → Customer → Subscriptions (Package + Addons) + TenantModules
→ Mapping via module_slug, package_type, package_id
→ Dienst booked=true/false
- Basis-Dienste (
is_base=true): Immer aktiv - Modul-basiert: TenantModule-Slug matcht
module_slugim Mapping - Paket-basiert: Subscription Package-Type matcht
package_type - Fallback: Keine Buchungen vorhanden → alles freigeschaltet
API-Endpoints¶
Token-Verwaltung (Auth erforderlich)¶
| Methode | Pfad | Permission | Beschreibung |
|---|---|---|---|
| POST | /api/v1/provisioning/client-tokens |
provisioning.client_tokens.create |
Token erstellen |
| GET | /api/v1/provisioning/client-tokens |
provisioning.client_tokens.read |
Tokens auflisten |
| DELETE | /api/v1/provisioning/client-tokens/{id} |
provisioning.client_tokens.create |
Token widerrufen |
| GET | /api/v1/provisioning/my-services?lang=de |
Authentifiziert | Aktuelle Services (Feature-Refresh) |
Öffentlicher Endpoint (kein Auth)¶
| Methode | Pfad | Beschreibung |
|---|---|---|
| GET | /provision/{token}?lang=de\|en |
Konfiguration abrufen (einmalig) |
Token-Format¶
prefix: 8 Hex-Zeichen (für Anzeige)secret: 48 Byte URL-safe Base64- Gespeichert: SHA256-Hash
- Gültigkeit: 7 Tage (konfigurierbar)
Provisioning-Response¶
{
"server_url": "https://xynap.cloud",
"plan": "business",
"features": ["platform", "webdav", "carddav", "caldav", "mail", "sip"],
"user": {
"id": 42,
"email": "max@firma.de",
"display_name": "Max Mustermann",
"locale": "de"
},
"services": [
{
"slug": "platform-access",
"feature": "platform",
"name": "Platform-Zugang",
"description": "Login und Zugang zur xynap Platform",
"icon": "layout-dashboard",
"booked": true,
"is_base": true,
"config": {
"protocol": "https",
"url_template": "https://xynap.cloud",
"provides_login_token": true,
"login_token": "eyJ...",
"token_ttl_minutes": 15
}
},
{
"slug": "telephony",
"feature": "sip",
"name": "Telefonie",
"description": "SIP/WebRTC Softphone",
"icon": "phone",
"booked": true,
"is_base": false,
"config": {
"protocol": "sip-wss",
"wss_url": "wss://xynap.cloud/sip",
"realm": "xynap.cloud",
"extension": "1001",
"password": "..."
}
}
],
"booked": {
"modules": [{"slug": "cloud", "tier": "business", "status": "active"}],
"subscriptions": [{"id": 1, "status": "active", "package": {"slug": "cloud-business"}}],
"addons": []
}
}
Nicht gebuchte Dienste
Dienste mit booked: false haben keine config. Der Client zeigt diese grau an mit Upgrade-Hinweis.
SIP-WebSocket (Enterprise)¶
SIP/WebRTC läuft über Traefik auf Port 443 — kein separater Port nötig:
Client (WSS) → Traefik :443 (TLS-Terminierung)
→ sip-ws-proxy (SIP-Header WSS↔WS Rewriting)
→ FreeSwitch :5066 (WS)
Unterstützte Domains:
wss://platform.xynap.tech/sipwss://xynap.cloud/sipwss://*.xynap.cloud/sip
Events & Notifications¶
Bei erfolgreicher Provisioning wird automatisch ausgelöst:
- Notification an den User: "Gerät erfolgreich eingerichtet" (Kategorie:
provisioning, Icon:monitor-check) - Event
provisioning.completedmit Payload (user_id, features, client_ip, etc.)
Feature-Refresh¶
Clients können beim Start ihre aktuellen Features prüfen ohne Token zu verbrauchen:
Liefert die gleiche Struktur wie die Provisioning-Response, aber ohne Credentials.
Dateipfade¶
| Pfad | Inhalt |
|---|---|
app/core_models/client_provisioning_token.py |
Token-Modell |
app/core_models/provisioning_service.py |
Dienst-Katalog + Mappings |
app/core/provisioning/client_tokens.py |
Token CRUD + my-services |
app/core/provisioning/public.py |
Öffentlicher Provisioning-Endpoint |
alembic/versions/c3f1a2b4d5e6_provisioning_services.py |
Migration + Seed |
/usr/local/xynap/sip-ws-proxy/ |
SIP-WebSocket Proxy (Docker) |
/usr/local/xynap/bin/test-provisioning.py |
Wiederverwendbares Test-Script |