12 KiB
Gitea-basiertes Lizenzierungs-System
Übersicht
Das Gitea-basierte Lizenzierungs-System nutzt Gitea Repository-Zugriff als Lizenzierung für myCRM-Module. Anstatt einen separaten Lizenzserver zu betreiben, prüft das System, ob ein Benutzer Zugriff auf das private Gitea-Repository eines Moduls hat.
Konzept
Gitea Access Token → Repository-Zugriff → Gültige Lizenz
Vorteile
✅ Keine separate Lizenzserver-API nötig - Nutzt bestehende Gitea-Infrastruktur ✅ Einfache Verwaltung - Access Control über Gitea UI ✅ Flexibel - Granulare Berechtigungen pro Repository ✅ Sicher - Nutzt Gitea's bewährte Authentifizierung ✅ Offline-Support - 24h Cache + 7 Tage Grace Period ✅ Composer-Integration - Gleiche Tokens für Composer und Lizenzierung
Funktionsweise
- Modul-Repositories in Gitea erstellen (z.B.
mycrm/mycrm-billing-module) - Private Repositories - Nur lizenzierte Benutzer haben Zugriff
- Gitea Access Token als Lizenzschlüssel verwenden
- myCRM prüft Repository-Zugriff über Gitea API
- Zugriff = Lizenz gültig
Installation & Konfiguration
1. Gitea-Backend aktivieren
# .env.local
LICENSE_BACKEND=GiteaLicenseValidator
GITEA_BASE_URL=https://git.mycrm.local
GITEA_ORGANIZATION=mycrm
INSTANCE_ID=deine-unique-instance-id
2. Modul-Repository in Gitea erstellen
Namenskonvention: mycrm-{module-identifier}-module
Beispiele:
- Billing-Modul:
mycrm-billing-module - Invoicing-Modul:
mycrm-invoicing-module - Inventory-Modul:
mycrm-inventory-module
Repository-Settings:
- Visibility: Private
- Owner: Deine Organisation oder dein User (z.B.
mycrm)
3. Gitea Access Token generieren
- Gehe zu Gitea → Settings → Applications
- Klicke auf "Generate New Token"
- Name:
myCRM License - {Modul-Name} - Scopes auswählen:
- ✅
repo(Read access to repositories)
- ✅
- Token kopieren (wird nur einmal angezeigt!)
4. Lizenz in myCRM registrieren
Option A: CLI (empfohlen)
php bin/console app:module:license billing YOUR_GITEA_TOKEN_HERE
Option B: Manuell in .env.local
# .env.local
GITEA_TOKEN_BILLING=abc123def456...
GITEA_TOKEN_INVOICING=xyz789ghi012...
5. Verifizieren
php bin/console app:module:list
Ausgabe sollte zeigen:
billing ✓ Aktiv Gitea Repository-Zugriff bestätigt (mycrm/mycrm-billing-module)
Repository-Metadaten für Lizenzinformationen
Das System kann Lizenzinformationen aus Repository-Metadaten extrahieren:
Features über Topics
Füge Topics zum Repository hinzu, um Features zu definieren:
Topics: feature-invoices, feature-payments, feature-reports
Diese werden als features im Lizenz-Array zurückgegeben:
[
'valid' => true,
'features' => ['invoices', 'payments', 'reports'],
// ...
]
Ablaufdatum in Description
Füge das Ablaufdatum in die Repository-Description ein:
Premium Billing Module for myCRM
License expires: 2025-12-31
Unterstützte Formate:
expires: YYYY-MM-DDvalid until: YYYY-MM-DDLicense expires: YYYY-MM-DD
Das System parsed automatisch das Datum:
[
'valid' => true,
'expiresAt' => DateTimeImmutable('2025-12-31'),
// ...
]
Access Control: Wer darf welches Modul nutzen?
Variante 1: Team-Zugriff per Gitea Teams
-
Team in Gitea erstellen
- Gehe zu Organisation → Teams → "Create Team"
- Name:
Premium Customers
-
Team-Mitglieder hinzufügen
- Team → Members → "Add Member"
-
Repository dem Team zuweisen
- Repository → Settings → Collaboration
- Add Team:
Premium Customersmit Read Permission
-
Jedes Team-Mitglied erhält Zugriff
- Alle Mitglieder können nun Tokens mit Repo-Zugriff generieren
Variante 2: Individuelle Collaborators
- Repository → Settings → Collaboration
- "Add Collaborator"
- User auswählen + Read Permission
- User kann jetzt Token mit Zugriff generieren
Variante 3: Organisation-weiter Zugriff
- Organisation → Settings → Members
- Mitglieder mit Read-Rechten auf alle Private Repos
- Alle Mitglieder haben automatisch Zugriff auf alle Module
Composer Integration
Da Gitea-Tokens sowohl für Lizenzierung als auch für Composer-Installation genutzt werden können, ist die Integration nahtlos:
composer.json konfigurieren
composer config repositories.mycrm-billing vcs https://git.mycrm.local/mycrm/mycrm-billing-module
auth.json konfigurieren
{
"http-basic": {
"git.mycrm.local": {
"username": "dein-gitea-username",
"password": "DEIN_GITEA_TOKEN"
}
}
}
Modul installieren
composer require mycrm/billing-module
Ein Token für beides:
- ✅ Composer Installation
- ✅ Lizenz-Validierung
CLI-Befehle
Lizenz registrieren
php bin/console app:module:license <module-identifier> <gitea-token>
# Beispiel
php bin/console app:module:license billing abc123def456ghi789
Alle Module auflisten
php bin/console app:module:list
# Ausgabe:
# ┌───────────┬────────┬─────────────────────────────────────────────┐
# │ Modul │ Status │ Lizenz-Info │
# ├───────────┼────────┼─────────────────────────────────────────────┤
# │ billing │ ✓ Aktiv│ Gitea Repository-Zugriff (mycrm/mycrm-...) │
# │ invoicing │ ✗ Inakt│ Kein Gitea Access Token vorhanden │
# └───────────┴────────┴─────────────────────────────────────────────┘
Lizenz widerrufen
php bin/console app:module:revoke billing
Caching & Offline-Betrieb
Cache-Strategie
Online-Validierung → 24h Cache → 7 Tage Grace Period → Offline-Fallback
- Erste Validierung: Gitea API-Call
- 24 Stunden: Gecacht, keine API-Calls
- Nach 24h: Neue Online-Validierung
- Offline-Fall: Grace Period (7 Tage ab letzter erfolgreicher Validierung)
Cache-Verhalten
// Bei jedem Request wird geprüft:
if (cache_valid && within_24h) {
return cached_license;
}
// Online-Validierung
try {
$license = validate_with_gitea();
cache($license, 24h);
} catch (NetworkError $e) {
// Fallback auf Cache mit Grace Period
if (cached_license && within_7_days) {
return cached_license;
}
throw LicenseException();
}
Vorteile
- ✅ Performance: Nur 1 API-Call pro 24h
- ✅ Offline-Betrieb: 7 Tage funktionsfähig ohne Internet
- ✅ Kein Dauerbetrieb offline: Nach 7 Tagen ist Online-Validierung erforderlich
API-Endpunkte
Das System stellt REST-API-Endpunkte für Admin-UIs bereit:
GET /api/modules
Liste aller Module mit Lizenz-Status
{
"modules": [
{
"identifier": "billing",
"name": "Billing & Invoicing",
"version": "1.0.0",
"license": {
"valid": true,
"licensedTo": "Max Mustermann",
"expiresAt": "2025-12-31T23:59:59+00:00",
"message": "Gitea Repository-Zugriff bestätigt (mycrm/mycrm-billing-module)",
"features": ["invoices", "payments", "reports"]
}
}
]
}
POST /api/modules/{module}/license
Lizenz registrieren
curl -X POST https://mycrm.local/api/modules/billing/license \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"licenseKey": "abc123def456..."}'
DELETE /api/modules/{module}/license
Lizenz widerrufen
curl -X DELETE https://mycrm.local/api/modules/billing/license \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"
Security Best Practices
✅ DO's
- Tokens niemals committen - Nutze
.env.local(nicht in Git) - Token-Scopes minimal halten - Nur
repo:readerforderlich - Tokens rotieren - Regelmäßig neue Tokens generieren
- Team-basierte Zugriffssteuerung - Nutze Gitea Teams für Kunden-Gruppen
- HTTPS verwenden - Gitea nur über HTTPS erreichbar machen
- Tokens pro Modul - Separate Tokens für jedes Modul
❌ DONT's
- Keine Tokens in composer.json - Nur in
auth.json - Keine universellen Tokens - Nicht einen Token für alle Module
- Keine öffentlichen Repositories - Module müssen private sein
- Keine Shared Tokens - Jeder Kunde eigener Token
Troubleshooting
Problem: "Kein Zugriff auf Modul-Repository"
Ursachen:
- Token hat keine
repo:readBerechtigung - Repository ist nicht vorhanden
- User ist nicht Collaborator/Team-Mitglied
- Repository-Name folgt nicht Namenskonvention
Lösung:
# Token testen
curl -H "Authorization: token YOUR_TOKEN" \
https://git.mycrm.local/api/v1/repos/mycrm/mycrm-billing-module
# Sollte Status 200 zurückgeben
Problem: "Gitea nicht erreichbar"
Symptom: Modul läuft, zeigt aber "Offline-Modus (Grace Period)"
Ursache: Gitea-Server nicht erreichbar, aber gecachte Lizenz noch gültig
Aktion: Prüfe GITEA_BASE_URL in .env.local
Problem: "Grace Period abgelaufen"
Symptom: Modul wird nicht gestartet
Ursache: Letzte erfolgreiche Validierung > 7 Tage her
Lösung:
- Gitea-Server erreichbar machen
- Cache clearen:
php bin/console cache:clear - Modul neu starten
Migration: Standard-Lizenzserver → Gitea
Schritt 1: Bestehende Lizenzen notieren
php bin/console app:module:list
Schritt 2: Gitea-Repositories erstellen
Für jedes lizenzierte Modul:
- Repository anlegen:
mycrm-{modul}-module - Als Private setzen
- Kunden als Collaborators hinzufügen
Schritt 3: .env.local aktualisieren
# Alt (entfernen oder auskommentieren)
#LICENSE_BACKEND=LicenseValidator
#LICENSE_SERVER_URL=https://license.mycrm.local
#LICENSE_BILLING=eyJhbGciOi...
# Neu
LICENSE_BACKEND=GiteaLicenseValidator
GITEA_BASE_URL=https://git.mycrm.local
GITEA_ORGANIZATION=mycrm
GITEA_TOKEN_BILLING=abc123...
Schritt 4: Cache leeren & testen
php bin/console cache:clear
php bin/console app:module:list
Erweiterte Konfiguration
Modul-spezifische Repository-Namen
Standardmäßig: mycrm-{module}-module
Für custom Namen, erweitere GiteaLicenseValidator::getRepositoryName():
private function getRepositoryName(string $moduleIdentifier): string
{
// Custom Mapping
$mapping = [
'billing' => 'premium-billing-suite',
'invoicing' => 'invoice-pro',
];
return $mapping[$moduleIdentifier] ?? 'mycrm-' . $moduleIdentifier . '-module';
}
Custom Feature-Extraction
Erweitere extractFeaturesFromRepository() für eigene Logik:
private function extractFeaturesFromRepository(array $repoData): array
{
// Beispiel: Features aus Repository-README parsen
// Beispiel: Features aus Gitea Webhooks abrufen
// ...
}
Vergleich: Standard vs. Gitea
| Feature | Standard-Lizenzserver | Gitea-Lizenzserver |
|---|---|---|
| Infrastruktur | Eigene REST-API | Bestehende Gitea-Instanz |
| Setup-Aufwand | Hoch | Niedrig |
| Verwaltung | Custom UI | Gitea UI |
| Token-Typ | JWT | Gitea Access Token |
| Access Control | Custom-Logik | Gitea Permissions |
| Composer-Integration | Separat | Gleiche Tokens |
| Offline-Support | ✅ 7 Tage | ✅ 7 Tage |
| Skalierung | Custom | Gitea |
Fazit
Das Gitea-basierte Lizenzierungs-System ist ideal, wenn:
✅ Du bereits Gitea für Versionskontrolle nutzt ✅ Du keine separate Lizenzserver-API betreiben möchtest ✅ Du flexible, repository-basierte Access Control benötigst ✅ Du Composer-Installation und Lizenzierung vereinheitlichen willst
Nächste Schritte:
- Gitea-Instanz einrichten (falls noch nicht vorhanden)
- Private Modul-Repositories erstellen
.env.localkonfigurieren- Erste Lizenz registrieren
- Testen!
Fragen? Siehe auch:
PLUGIN_SYSTEM.md- Vollständige Plugin-System-DokumentationPLUGIN_QUICKSTART.md- 5-Minuten-Setup