API Key Wildcard: Technische Details
Technik von API Key Wildcard: Ablauf einer Anfrage und des Plugin-Lebenszyklus als Diagramm, Klassen und Rückgabewerte, SQL-Prüfung, Auto-Update, Signal api und Dateistruktur.
API Key Wildcard: Technische Details
Ablauf einer Anfrage
graph TD
A["POST /api/wildcard/tickets.json"] --> B["api/.htaccess: Regel wildcard/ nach wildcard.php"]
B --> C["api/wildcard.php mit PATH_INFO /tickets.json"]
C --> D{"Route POST /tickets.json, .xml oder .email?"}
D -->|"Nein"| E["Keine Route der Wildcard-Prüfung"]
D -->|"Ja"| F["WildcardTicketApiController.create"]
F --> G["WildcardApiController.requireApiKey"]
G -->|"Key fehlt, unbekannt, inaktiv oder IP passt nicht"| H["401"]
G -->|"Key gültig"| I{"Key-IP ist 0.0.0.0 und Logging aktiv?"}
I -->|"Ja"| J["Debug-Eintrag im System-Log"]
I -->|"Nein"| K["Ticket wird erstellt"]
J --> K
wildcard.php bootstrapt osTicket über ../main.inc.php, lädt include/plugins/api-key-wildcard/api.wildcard.inc.php und api.tickets.php. Es definiert WildcardTicketApiController als Unterklasse von TicketApiController, deren requireApiKey() an WildcardApiController delegiert. Anschließend wird der Dispatcher aufgebaut, das Signal api gesendet und der Pfad aufgelöst.
Prüfung des API-Keys
WildcardApiController.requireApiKey() arbeitet in dieser Reihenfolge:
- Kein Key im Request:
401 Valid API key required. - Suche mit
wildcard_getIdByKey(): ohne Treffer401 API key not found or IP not authorized. - Key laden: nicht vorhanden oder nicht aktiv ergibt
401 API key not active. - Key-IP ist weder
0.0.0.0noch die Absender-IP:401 Source IP not authorized. - Key-IP ist
0.0.0.0undlog_wildcard_accessaktiv: Debug-Eintrag, danach wird der Key zurückgegeben.
Die SQL-Bedingung der Suche lautet:
SELECT id FROM API_KEY_TABLE WHERE apikey = ? AND (ipaddr = ? OR ipaddr = "0.0.0.0")
Die Standard-API prüft dagegen nur auf die exakte IP. Schritt 4 ist nach der SQL-Suche eine zusätzliche Absicherung.
Lebenszyklus des Plugins
graph TD
A["bootstrap()"] --> B{"installed_version leer oder niedriger?"}
B -->|"Ja"| C["performUpdate()"]
B -->|"Nein"| D["Nichts zu tun"]
C --> E["PluginInstaller.update()"]
E --> F["HtaccessManager.applyAll(), falls api/.htaccess existiert"]
F --> G["installed_version speichern, Eintrag im PHP-Error-Log"]
H["enable()"] --> I["Singleton-Instanz anlegen, falls keine existiert"]
I --> J["PluginInstaller.install()"]
J --> K["HtaccessManager.applyAll()"]
K --> L["installed_version speichern"]
M["disable()"] --> N["PluginInstaller.uninstall()"]
N --> O["removeWildcardRule() und removeMultiViews()"]
Klassen und Rückgabewerte
| Klasse | Aufgabe | Wichtige Methoden |
|---|---|---|
ApiKeyWildcardPlugin |
Plugin-Klasse, Singleton | bootstrap(), enable(), disable(), performUpdate() (public) |
ApiKeyWildcardConfig |
Konfigurationsfelder | getOptions() |
PluginInstaller |
Endpoint-Datei kopieren, löschen | install() und update() geben ein Array mit Fehlern zurück, uninstall() gibt bool zurück |
HtaccessManager |
Änderungen an api/.htaccess |
applyAll() gibt ein Array mit Fehlern zurück, addMultiViews(), addWildcardRule(), removeWildcardRule(), removeMultiViews() geben bool zurück |
PluginConstants |
Konstanten (Slug, Dateiname, 0.0.0.0, Kommentare, Dateimodus 0755) |
|
WildcardApiController |
API-Key-Prüfung mit Wildcard | requireApiKey() |
WildcardTicketApiController |
Ticket-Controller mit dieser Prüfung (in wildcard.php) |
requireApiKey() |
enable() gibt true oder ein Array mit Fehlern zurück. disable() gibt immer true zurück, die Ergebnisse der einzelnen Schritte werden nicht ausgewertet. performUpdate() gibt ein Array mit allen Fehlern zurück, sonst true.
Auto-Update
Bei jedem bootstrap() liest das Plugin installed_version aus der Konfiguration und vergleicht sie per version_compare mit der Version aus plugin.php. Ist der Wert leer oder niedriger, läuft performUpdate(): Die Endpoint-Datei wird neu kopiert, api/.htaccess (falls vorhanden) ergänzt und die neue Version gespeichert. Bei Erfolg schreibt performUpdate() eine Zeile ins PHP-Error-Log (Installation oder Update). Eine gleiche oder höhere installierte Version löst kein Update aus.
enable() schreibt kein Installations- oder Update-Log. Es schreibt nur dann ins PHP-Error-Log, wenn es die Singleton-Instanz automatisch anlegt: [API Key Wildcard] Auto-created singleton instance bei Erfolg, [API Key Wildcard] Failed to auto-create instance: ... bei einem Fehler.
Signal api
| Signal | Gesendet von | Zweck |
|---|---|---|
api |
wildcard.php |
Gibt anderen Plugins die Möglichkeit, Routen am Dispatcher des Wildcard-Endpoints zu registrieren. Diese Routen nutzen ihre eigene Key-Prüfung. |
Die Plugin-Klasse selbst verbindet sich mit keinem Signal.
Dateistruktur
Auszug aus dem Repository. Das ist nicht der Inhalt des Release-ZIP.
osticket-api-key-wildcard/
├── plugin.php # Registrierung (ID, Name, Plugin-Klasse)
├── class.ApiKeyWildcard.php # Plugin-Klasse und Konfiguration
├── class.PluginConstants.php # Konstanten
├── class.PluginInstaller.php # Endpoint-Datei kopieren und löschen
├── class.HtaccessManager.php # Änderungen an api/.htaccess
├── api.wildcard.inc.php # WildcardApiController und Hilfsfunktionen
├── wildcard.php # Endpoint, wird nach api/ kopiert
├── .htaccess # Referenz, nur im Repository, vom Plugin nicht verwendet
├── README.md
├── CHANGELOG.md
├── LICENSE
├── .releaseinclude # Dateien des Release-ZIP
├── .gitignore
└── .github/ # CI-Workflow
Das Release-ZIP enthält laut .releaseinclude nur *.php, README.md, README-de.md, LICENSE und CHANGELOG.md. Die .htaccess ist daher nicht im ZIP. Die Datei README-de.md steht in .releaseinclude, existiert im Repository aber nicht.