654 lines
19 KiB
PHP
654 lines
19 KiB
PHP
<?php
|
|
/**
|
|
* Copyright seit 2024 Webshop System
|
|
*
|
|
* Admin Controller für Module-API-Verwaltung
|
|
*
|
|
* @author Webshop System
|
|
* @license GPL v3
|
|
*/
|
|
|
|
namespace App\Controllers\Admin;
|
|
|
|
use App\Core\ModuleAPI;
|
|
use App\Core\Plugin;
|
|
use App\Core\Extension;
|
|
use App\Core\Logger;
|
|
use Doctrine\DBAL\DriverManager;
|
|
use Doctrine\DBAL\Exception;
|
|
|
|
class ModuleAPIController extends BaseAdminController
|
|
{
|
|
private $moduleAPI;
|
|
private $plugin;
|
|
private $extension;
|
|
private $logger;
|
|
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
|
|
$this->moduleAPI = ModuleAPI::getInstance();
|
|
$this->plugin = Plugin::getInstance();
|
|
$this->extension = Extension::getInstance();
|
|
$this->logger = Logger::getInstance();
|
|
}
|
|
|
|
/**
|
|
* API-Übersicht anzeigen
|
|
*/
|
|
public function index()
|
|
{
|
|
$this->checkPermission('api_management');
|
|
|
|
$apiStatus = $this->moduleAPI->getApiStatus();
|
|
$pluginStats = $this->plugin->getPluginStatistics();
|
|
$extensionStats = $this->extension->getExtensionStatistics();
|
|
|
|
$this->render('admin/module_api/index', [
|
|
'api_status' => $apiStatus['data'],
|
|
'plugin_stats' => $pluginStats,
|
|
'extension_stats' => $extensionStats,
|
|
'page_title' => 'Module-API Verwaltung'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* API-Keys verwalten
|
|
*/
|
|
public function apiKeys()
|
|
{
|
|
$this->checkPermission('api_management');
|
|
|
|
$action = $_GET['action'] ?? 'list';
|
|
|
|
switch ($action) {
|
|
case 'create':
|
|
$this->createApiKey();
|
|
break;
|
|
case 'delete':
|
|
$this->deleteApiKey();
|
|
break;
|
|
default:
|
|
$this->listApiKeys();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* API-Keys auflisten
|
|
*/
|
|
private function listApiKeys()
|
|
{
|
|
try {
|
|
$conn = DriverManager::getConnection([
|
|
'url' => getenv('DATABASE_URL') ?: 'mysql://root:password@localhost/webshop'
|
|
]);
|
|
|
|
$stmt = $conn->prepare('
|
|
SELECT id, api_key, name, permissions, active, created_at, updated_at
|
|
FROM ws_api_keys
|
|
ORDER BY created_at DESC
|
|
');
|
|
$stmt->execute();
|
|
|
|
$apiKeys = $stmt->fetchAllAssociative();
|
|
|
|
$this->render('admin/module_api/api_keys', [
|
|
'api_keys' => $apiKeys,
|
|
'page_title' => 'API-Keys verwalten'
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
$this->addError('Fehler beim Laden der API-Keys: ' . $e->getMessage());
|
|
$this->redirect('/admin/module-api/keys');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* API-Key erstellen
|
|
*/
|
|
private function createApiKey()
|
|
{
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$name = $_POST['name'] ?? '';
|
|
$permissions = $_POST['permissions'] ?? [];
|
|
|
|
if (empty($name)) {
|
|
$this->addError('Name ist erforderlich');
|
|
$this->redirect('/admin/module-api/keys');
|
|
return;
|
|
}
|
|
|
|
$apiKey = $this->moduleAPI->createApiKey($name, $permissions);
|
|
|
|
if ($apiKey) {
|
|
$this->addSuccess('API-Key erfolgreich erstellt: ' . $apiKey);
|
|
$this->logger->info('API-Key erstellt via Admin', [
|
|
'name' => $name,
|
|
'permissions' => $permissions
|
|
]);
|
|
} else {
|
|
$this->addError('Fehler beim Erstellen des API-Keys');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/keys');
|
|
} else {
|
|
$this->render('admin/module_api/create_api_key', [
|
|
'page_title' => 'API-Key erstellen'
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* API-Key löschen
|
|
*/
|
|
private function deleteApiKey()
|
|
{
|
|
$apiKey = $_GET['key'] ?? '';
|
|
|
|
if (empty($apiKey)) {
|
|
$this->addError('API-Key ist erforderlich');
|
|
$this->redirect('/admin/module-api/keys');
|
|
return;
|
|
}
|
|
|
|
$result = $this->moduleAPI->deleteApiKey($apiKey);
|
|
|
|
if ($result) {
|
|
$this->addSuccess('API-Key erfolgreich gelöscht');
|
|
$this->logger->info('API-Key gelöscht via Admin', [
|
|
'api_key' => $this->moduleAPI->maskApiKey($apiKey)
|
|
]);
|
|
} else {
|
|
$this->addError('Fehler beim Löschen des API-Keys');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/keys');
|
|
}
|
|
|
|
/**
|
|
* Plugins verwalten
|
|
*/
|
|
public function plugins()
|
|
{
|
|
$this->checkPermission('plugin_management');
|
|
|
|
$action = $_GET['action'] ?? 'list';
|
|
|
|
switch ($action) {
|
|
case 'activate':
|
|
$this->activatePlugin();
|
|
break;
|
|
case 'deactivate':
|
|
$this->deactivatePlugin();
|
|
break;
|
|
case 'delete':
|
|
$this->deletePlugin();
|
|
break;
|
|
case 'upload':
|
|
$this->uploadPlugin();
|
|
break;
|
|
default:
|
|
$this->listPlugins();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Plugins auflisten
|
|
*/
|
|
private function listPlugins()
|
|
{
|
|
$plugins = $this->plugin->getAllPlugins();
|
|
|
|
$this->render('admin/module_api/plugins', [
|
|
'plugins' => $plugins,
|
|
'page_title' => 'Plugins verwalten'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Plugin aktivieren
|
|
*/
|
|
private function activatePlugin()
|
|
{
|
|
$pluginName = $_GET['name'] ?? '';
|
|
|
|
if (empty($pluginName)) {
|
|
$this->addError('Plugin-Name ist erforderlich');
|
|
$this->redirect('/admin/module-api/plugins');
|
|
return;
|
|
}
|
|
|
|
$result = $this->plugin->activatePlugin($pluginName);
|
|
|
|
if ($result) {
|
|
$this->addSuccess('Plugin erfolgreich aktiviert');
|
|
} else {
|
|
$this->addError('Fehler beim Aktivieren des Plugins');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/plugins');
|
|
}
|
|
|
|
/**
|
|
* Plugin deaktivieren
|
|
*/
|
|
private function deactivatePlugin()
|
|
{
|
|
$pluginName = $_GET['name'] ?? '';
|
|
|
|
if (empty($pluginName)) {
|
|
$this->addError('Plugin-Name ist erforderlich');
|
|
$this->redirect('/admin/module-api/plugins');
|
|
return;
|
|
}
|
|
|
|
$result = $this->plugin->deactivatePlugin($pluginName);
|
|
|
|
if ($result) {
|
|
$this->addSuccess('Plugin erfolgreich deaktiviert');
|
|
} else {
|
|
$this->addError('Fehler beim Deaktivieren des Plugins');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/plugins');
|
|
}
|
|
|
|
/**
|
|
* Plugin löschen
|
|
*/
|
|
private function deletePlugin()
|
|
{
|
|
$pluginName = $_GET['name'] ?? '';
|
|
|
|
if (empty($pluginName)) {
|
|
$this->addError('Plugin-Name ist erforderlich');
|
|
$this->redirect('/admin/module-api/plugins');
|
|
return;
|
|
}
|
|
|
|
$result = $this->plugin->deletePlugin($pluginName);
|
|
|
|
if ($result) {
|
|
$this->addSuccess('Plugin erfolgreich gelöscht');
|
|
} else {
|
|
$this->addError('Fehler beim Löschen des Plugins');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/plugins');
|
|
}
|
|
|
|
/**
|
|
* Plugin hochladen
|
|
*/
|
|
private function uploadPlugin()
|
|
{
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
if (!isset($_FILES['plugin_file']) || $_FILES['plugin_file']['error'] !== UPLOAD_ERR_OK) {
|
|
$this->addError('Fehler beim Hochladen der Plugin-Datei');
|
|
$this->redirect('/admin/module-api/plugins');
|
|
return;
|
|
}
|
|
|
|
$uploadedFile = $_FILES['plugin_file'];
|
|
$fileName = $uploadedFile['name'];
|
|
$filePath = $uploadedFile['tmp_name'];
|
|
|
|
// Datei-Validierung
|
|
if (pathinfo($fileName, PATHINFO_EXTENSION) !== 'zip') {
|
|
$this->addError('Nur ZIP-Dateien sind erlaubt');
|
|
$this->redirect('/admin/module-api/plugins');
|
|
return;
|
|
}
|
|
|
|
// Plugin installieren
|
|
$result = $this->installPluginFromZip($filePath);
|
|
|
|
if ($result) {
|
|
$this->addSuccess('Plugin erfolgreich installiert');
|
|
} else {
|
|
$this->addError('Fehler beim Installieren des Plugins');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/plugins');
|
|
} else {
|
|
$this->render('admin/module_api/upload_plugin', [
|
|
'page_title' => 'Plugin hochladen'
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Plugin aus ZIP installieren
|
|
*/
|
|
private function installPluginFromZip($zipPath)
|
|
{
|
|
$pluginsDir = __DIR__ . '/../../../../plugins/';
|
|
|
|
if (!is_dir($pluginsDir)) {
|
|
mkdir($pluginsDir, 0755, true);
|
|
}
|
|
|
|
$zip = new \ZipArchive();
|
|
|
|
if ($zip->open($zipPath) !== true) {
|
|
return false;
|
|
}
|
|
|
|
// Plugin-Name aus ZIP extrahieren
|
|
$pluginName = null;
|
|
$configContent = $zip->getFromName('plugin.json');
|
|
|
|
if ($configContent) {
|
|
$config = json_decode($configContent, true);
|
|
$pluginName = $config['name'] ?? null;
|
|
}
|
|
|
|
if (!$pluginName) {
|
|
$zip->close();
|
|
return false;
|
|
}
|
|
|
|
// Plugin-Verzeichnis erstellen
|
|
$pluginDir = $pluginsDir . $pluginName;
|
|
|
|
if (is_dir($pluginDir)) {
|
|
// Bestehendes Plugin sichern
|
|
$backupDir = $pluginDir . '_backup_' . date('Y-m-d_H-i-s');
|
|
rename($pluginDir, $backupDir);
|
|
}
|
|
|
|
// ZIP entpacken
|
|
$zip->extractTo($pluginDir);
|
|
$zip->close();
|
|
|
|
// Plugin registrieren
|
|
if (file_exists($pluginDir . '/plugin.json')) {
|
|
$config = json_decode(file_get_contents($pluginDir . '/plugin.json'), true);
|
|
$this->plugin->registerPlugin($pluginName, $config);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Extensions verwalten
|
|
*/
|
|
public function extensions()
|
|
{
|
|
$this->checkPermission('extension_management');
|
|
|
|
$action = $_GET['action'] ?? 'list';
|
|
|
|
switch ($action) {
|
|
case 'activate':
|
|
$this->activateExtension();
|
|
break;
|
|
case 'deactivate':
|
|
$this->deactivateExtension();
|
|
break;
|
|
case 'delete':
|
|
$this->deleteExtension();
|
|
break;
|
|
case 'upload':
|
|
$this->uploadExtension();
|
|
break;
|
|
default:
|
|
$this->listExtensions();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extensions auflisten
|
|
*/
|
|
private function listExtensions()
|
|
{
|
|
$extensions = $this->extension->getAllExtensions();
|
|
|
|
$this->render('admin/module_api/extensions', [
|
|
'extensions' => $extensions,
|
|
'page_title' => 'Extensions verwalten'
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Extension aktivieren
|
|
*/
|
|
private function activateExtension()
|
|
{
|
|
$extensionName = $_GET['name'] ?? '';
|
|
|
|
if (empty($extensionName)) {
|
|
$this->addError('Extension-Name ist erforderlich');
|
|
$this->redirect('/admin/module-api/extensions');
|
|
return;
|
|
}
|
|
|
|
$result = $this->extension->activateExtension($extensionName);
|
|
|
|
if ($result) {
|
|
$this->addSuccess('Extension erfolgreich aktiviert');
|
|
} else {
|
|
$this->addError('Fehler beim Aktivieren der Extension');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/extensions');
|
|
}
|
|
|
|
/**
|
|
* Extension deaktivieren
|
|
*/
|
|
private function deactivateExtension()
|
|
{
|
|
$extensionName = $_GET['name'] ?? '';
|
|
|
|
if (empty($extensionName)) {
|
|
$this->addError('Extension-Name ist erforderlich');
|
|
$this->redirect('/admin/module-api/extensions');
|
|
return;
|
|
}
|
|
|
|
$result = $this->extension->deactivateExtension($extensionName);
|
|
|
|
if ($result) {
|
|
$this->addSuccess('Extension erfolgreich deaktiviert');
|
|
} else {
|
|
$this->addError('Fehler beim Deaktivieren der Extension');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/extensions');
|
|
}
|
|
|
|
/**
|
|
* Extension löschen
|
|
*/
|
|
private function deleteExtension()
|
|
{
|
|
$extensionName = $_GET['name'] ?? '';
|
|
|
|
if (empty($extensionName)) {
|
|
$this->addError('Extension-Name ist erforderlich');
|
|
$this->redirect('/admin/module-api/extensions');
|
|
return;
|
|
}
|
|
|
|
$result = $this->extension->deleteExtension($extensionName);
|
|
|
|
if ($result) {
|
|
$this->addSuccess('Extension erfolgreich gelöscht');
|
|
} else {
|
|
$this->addError('Fehler beim Löschen der Extension');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/extensions');
|
|
}
|
|
|
|
/**
|
|
* Extension hochladen
|
|
*/
|
|
private function uploadExtension()
|
|
{
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
if (!isset($_FILES['extension_file']) || $_FILES['extension_file']['error'] !== UPLOAD_ERR_OK) {
|
|
$this->addError('Fehler beim Hochladen der Extension-Datei');
|
|
$this->redirect('/admin/module-api/extensions');
|
|
return;
|
|
}
|
|
|
|
$uploadedFile = $_FILES['extension_file'];
|
|
$fileName = $uploadedFile['name'];
|
|
$filePath = $uploadedFile['tmp_name'];
|
|
|
|
// Datei-Validierung
|
|
if (pathinfo($fileName, PATHINFO_EXTENSION) !== 'zip') {
|
|
$this->addError('Nur ZIP-Dateien sind erlaubt');
|
|
$this->redirect('/admin/module-api/extensions');
|
|
return;
|
|
}
|
|
|
|
// Extension installieren
|
|
$result = $this->installExtensionFromZip($filePath);
|
|
|
|
if ($result) {
|
|
$this->addSuccess('Extension erfolgreich installiert');
|
|
} else {
|
|
$this->addError('Fehler beim Installieren der Extension');
|
|
}
|
|
|
|
$this->redirect('/admin/module-api/extensions');
|
|
} else {
|
|
$this->render('admin/module_api/upload_extension', [
|
|
'page_title' => 'Extension hochladen'
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extension aus ZIP installieren
|
|
*/
|
|
private function installExtensionFromZip($zipPath)
|
|
{
|
|
$extensionsDir = __DIR__ . '/../../../../extensions/';
|
|
|
|
if (!is_dir($extensionsDir)) {
|
|
mkdir($extensionsDir, 0755, true);
|
|
}
|
|
|
|
$zip = new \ZipArchive();
|
|
|
|
if ($zip->open($zipPath) !== true) {
|
|
return false;
|
|
}
|
|
|
|
// Extension-Name aus ZIP extrahieren
|
|
$extensionName = null;
|
|
$configContent = $zip->getFromName('extension.json');
|
|
|
|
if ($configContent) {
|
|
$config = json_decode($configContent, true);
|
|
$extensionName = $config['name'] ?? null;
|
|
}
|
|
|
|
if (!$extensionName) {
|
|
$zip->close();
|
|
return false;
|
|
}
|
|
|
|
// Extension-Verzeichnis erstellen
|
|
$extensionDir = $extensionsDir . $extensionName;
|
|
|
|
if (is_dir($extensionDir)) {
|
|
// Bestehende Extension sichern
|
|
$backupDir = $extensionDir . '_backup_' . date('Y-m-d_H-i-s');
|
|
rename($extensionDir, $backupDir);
|
|
}
|
|
|
|
// ZIP entpacken
|
|
$zip->extractTo($extensionDir);
|
|
$zip->close();
|
|
|
|
// Extension registrieren
|
|
if (file_exists($extensionDir . '/extension.json')) {
|
|
$config = json_decode(file_get_contents($extensionDir . '/extension.json'), true);
|
|
$this->extension->registerExtension($extensionName, $config);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* API-Logs anzeigen
|
|
*/
|
|
public function apiLogs()
|
|
{
|
|
$this->checkPermission('api_management');
|
|
|
|
try {
|
|
$conn = DriverManager::getConnection([
|
|
'url' => getenv('DATABASE_URL') ?: 'mysql://root:password@localhost/webshop'
|
|
]);
|
|
|
|
$page = max(1, $_GET['page'] ?? 1);
|
|
$limit = 50;
|
|
$offset = ($page - 1) * $limit;
|
|
|
|
// Logs abrufen
|
|
$stmt = $conn->prepare('
|
|
SELECT * FROM ws_api_requests
|
|
ORDER BY created_at DESC
|
|
LIMIT ? OFFSET ?
|
|
');
|
|
$stmt->execute([$limit, $offset]);
|
|
|
|
$logs = $stmt->fetchAllAssociative();
|
|
|
|
// Gesamtanzahl
|
|
$stmt = $conn->prepare('SELECT COUNT(*) as total FROM ws_api_requests');
|
|
$stmt->execute();
|
|
$total = $stmt->fetchAssociative()['total'];
|
|
|
|
$this->render('admin/module_api/api_logs', [
|
|
'logs' => $logs,
|
|
'page' => $page,
|
|
'limit' => $limit,
|
|
'total' => $total,
|
|
'pages' => ceil($total / $limit),
|
|
'page_title' => 'API-Logs'
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
$this->addError('Fehler beim Laden der API-Logs: ' . $e->getMessage());
|
|
$this->redirect('/admin/module-api');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* API-Einstellungen
|
|
*/
|
|
public function settings()
|
|
{
|
|
$this->checkPermission('api_management');
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$enabled = isset($_POST['api_enabled']);
|
|
$rateLimit = (int)($_POST['rate_limit'] ?? 1000);
|
|
$rateLimitWindow = (int)($_POST['rate_limit_window'] ?? 3600);
|
|
|
|
// Einstellungen speichern
|
|
$this->moduleAPI->setEnabled($enabled);
|
|
$this->moduleAPI->setRateLimit($rateLimit, $rateLimitWindow);
|
|
|
|
$this->addSuccess('API-Einstellungen erfolgreich gespeichert');
|
|
$this->redirect('/admin/module-api/settings');
|
|
} else {
|
|
$apiStatus = $this->moduleAPI->getApiStatus();
|
|
|
|
$this->render('admin/module_api/settings', [
|
|
'api_status' => $apiStatus['data'],
|
|
'page_title' => 'API-Einstellungen'
|
|
]);
|
|
}
|
|
}
|
|
}
|