From 01f935b76958ba7b57a9da2222a01b810c3247c5 Mon Sep 17 00:00:00 2001 From: Terranom674 Date: Thu, 20 Aug 2026 10:43:46 +0200 Subject: [PATCH] Keep only WebDAV connection-scoped Piwigo auth helpers --- include/nc_connector_piwigo_api.inc.php | 203 ++++-------------------- 1 file changed, 35 insertions(+), 168 deletions(-) diff --git a/include/nc_connector_piwigo_api.inc.php b/include/nc_connector_piwigo_api.inc.php index 26f411e..87fdb55 100644 --- a/include/nc_connector_piwigo_api.inc.php +++ b/include/nc_connector_piwigo_api.inc.php @@ -7,10 +7,7 @@ if (!defined('PHPWG_ROOT_PATH')) function bratonien_tools_nc_connector_xml_value(SimpleXMLElement $node) { $children = $node->children(); - if (count($children) === 0) - { - return (string)$node; - } + if (count($children) === 0) return (string)$node; $result = array(); foreach ($children as $name => $child) @@ -18,16 +15,10 @@ function bratonien_tools_nc_connector_xml_value(SimpleXMLElement $node) $value = bratonien_tools_nc_connector_xml_value($child); if (array_key_exists($name, $result)) { - if (!is_array($result[$name]) || !array_is_list($result[$name])) - { - $result[$name] = array($result[$name]); - } + if (!is_array($result[$name]) || !array_is_list($result[$name])) $result[$name] = array($result[$name]); $result[$name][] = $value; } - else - { - $result[$name] = $value; - } + else $result[$name] = $value; } return $result; } @@ -35,15 +26,9 @@ function bratonien_tools_nc_connector_xml_value(SimpleXMLElement $node) function bratonien_tools_nc_connector_decode_api_response($body, $content_type = '') { $decoded = json_decode((string)$body, true); - if (is_array($decoded)) - { - return $decoded; - } + if (is_array($decoded)) return $decoded; - if (!function_exists('simplexml_load_string')) - { - throw new RuntimeException('Piwigo-API lieferte XML, aber SimpleXML ist in PHP nicht verfuegbar.'); - } + if (!function_exists('simplexml_load_string')) throw new RuntimeException('Piwigo-API lieferte XML, aber SimpleXML ist in PHP nicht verfügbar.'); $previous = libxml_use_internal_errors(true); $xml = simplexml_load_string((string)$body); @@ -52,7 +37,7 @@ function bratonien_tools_nc_connector_decode_api_response($body, $content_type = if ($xml === false || $xml->getName() !== 'rsp') { $detail = $content_type !== '' ? ' Antworttyp: '.$content_type.'.' : ''; - throw new RuntimeException('Piwigo-API lieferte weder gueltiges JSON noch eine gueltige XML-Webservice-Antwort.'.$detail); + throw new RuntimeException('Piwigo-API lieferte weder gültiges JSON noch eine gültige XML-Webservice-Antwort.'.$detail); } $response = array('stat'=>(string)$xml['stat']); @@ -61,27 +46,17 @@ function bratonien_tools_nc_connector_decode_api_response($body, $content_type = $value = bratonien_tools_nc_connector_xml_value($child); if (array_key_exists($name, $response)) { - if (!is_array($response[$name]) || !array_is_list($response[$name])) - { - $response[$name] = array($response[$name]); - } + if (!is_array($response[$name]) || !array_is_list($response[$name])) $response[$name] = array($response[$name]); $response[$name][] = $value; } - else - { - $response[$name] = $value; - } + else $response[$name] = $value; } return $response; } function bratonien_tools_nc_connector_api_payload(array $decoded) { - if (array_key_exists('result', $decoded)) - { - return $decoded['result']; - } - + if (array_key_exists('result', $decoded)) return $decoded['result']; unset($decoded['stat']); return $decoded; } @@ -91,66 +66,42 @@ function bratonien_tools_nc_connector_collect_method_names($value, array &$metho if (is_string($value)) { $value = trim($value); - if ($value !== '' && preg_match('/^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)+$/', $value)) - { - $methods[$value] = true; - } - return; - } - - if (!is_array($value)) - { + if ($value !== '' && preg_match('/^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)+$/', $value)) $methods[$value] = true; return; } + if (!is_array($value)) return; if (isset($value['name']) && is_string($value['name'])) { $name = trim($value['name']); - if ($name !== '') - { - $methods[$name] = true; - } - } - - foreach ($value as $entry) - { - bratonien_tools_nc_connector_collect_method_names($entry, $methods); + if ($name !== '') $methods[$name] = true; } + foreach ($value as $entry) bratonien_tools_nc_connector_collect_method_names($entry, $methods); } function bratonien_tools_nc_connector_piwigo_api_request($api_key_id, $api_key_secret, $method) { - if (!function_exists('curl_init')) - { - throw new RuntimeException('cURL ist in PHP nicht verfuegbar. Der API-Key-Test kann nicht ausgefuehrt werden.'); - } + if (!function_exists('curl_init')) throw new RuntimeException('cURL ist in PHP nicht verfügbar. Der API-Key-Test kann nicht ausgeführt werden.'); $api_key_id = trim((string)$api_key_id); $api_key_secret = trim((string)$api_key_secret); - if ($api_key_id === '' || $api_key_secret === '') - { - throw new RuntimeException('API-Schluessel-ID und Geheimnis muessen angegeben werden.'); - } + if ($api_key_id === '' || $api_key_secret === '') throw new RuntimeException('API-Schlüssel-ID und Geheimnis müssen angegeben werden.'); - $api_key = $api_key_id.':'.$api_key_secret; $url = rtrim(get_absolute_root_url(true), '/').'/ws.php'; $ch = curl_init($url); curl_setopt_array($ch, array( - CURLOPT_RETURNTRANSFER => true, - CURLOPT_POST => true, - CURLOPT_POSTFIELDS => http_build_query(array( - 'method' => (string)$method, - 'format' => 'json', - )), - CURLOPT_HTTPHEADER => array( - 'X-PIWIGO-API: '.$api_key, + CURLOPT_RETURNTRANSFER=>true, + CURLOPT_POST=>true, + CURLOPT_POSTFIELDS=>http_build_query(array('method'=>(string)$method,'format'=>'json')), + CURLOPT_HTTPHEADER=>array( + 'X-PIWIGO-API: '.$api_key_id.':'.$api_key_secret, 'Accept: application/json, text/xml;q=0.9', 'Content-Type: application/x-www-form-urlencoded', ), - CURLOPT_CONNECTTIMEOUT => 10, - CURLOPT_TIMEOUT => 20, - CURLOPT_FOLLOWLOCATION => false, - CURLOPT_USERAGENT => 'Bratonien-Tools-NC-Connector/'.(function_exists('bratonien_tools_current_version') ? bratonien_tools_current_version() : 'dev'), + CURLOPT_CONNECTTIMEOUT=>10, + CURLOPT_TIMEOUT=>20, + CURLOPT_FOLLOWLOCATION=>false, + CURLOPT_USERAGENT=>'Bratonien-Tools-NC-WebDAV/'.(function_exists('bratonien_tools_current_version') ? bratonien_tools_current_version() : 'dev'), )); $body = curl_exec($ch); @@ -160,14 +111,8 @@ function bratonien_tools_nc_connector_piwigo_api_request($api_key_id, $api_key_s $content_type = (string)curl_getinfo($ch, CURLINFO_CONTENT_TYPE); curl_close($ch); - if ($body === false || $errno !== 0) - { - throw new RuntimeException('Piwigo-API konnte nicht erreicht werden: '.$error); - } - if ($http_code < 200 || $http_code >= 300) - { - throw new RuntimeException('Piwigo-API antwortete mit HTTP '.$http_code.'.'); - } + if ($body === false || $errno !== 0) throw new RuntimeException('Piwigo-API konnte nicht erreicht werden: '.$error); + if ($http_code < 200 || $http_code >= 300) throw new RuntimeException('Piwigo-API antwortete mit HTTP '.$http_code.'.'); $decoded = bratonien_tools_nc_connector_decode_api_response((string)$body, $content_type); if (($decoded['stat'] ?? '') !== 'ok') @@ -175,29 +120,19 @@ function bratonien_tools_nc_connector_piwigo_api_request($api_key_id, $api_key_s $message = (string)($decoded['message'] ?? $decoded['err'] ?? 'API-Aufruf wurde abgelehnt.'); throw new RuntimeException($message); } - return bratonien_tools_nc_connector_api_payload($decoded); } function bratonien_tools_nc_connector_validate_fallback_credentials($username, $password) { - if (!function_exists('curl_init')) - { - throw new RuntimeException('cURL ist in PHP nicht verfuegbar. Der Piwigo-Fallback kann nicht geprueft werden.'); - } + if (!function_exists('curl_init')) throw new RuntimeException('cURL ist in PHP nicht verfügbar. Der Piwigo-Fallback kann nicht geprüft werden.'); $username = trim((string)$username); $password = (string)$password; - if ($username === '' || $password === '') - { - throw new RuntimeException('Piwigo-Benutzername und Passwort muessen angegeben werden.'); - } + if ($username === '' || $password === '') throw new RuntimeException('Piwigo-Benutzername und Passwort müssen angegeben werden.'); $cookie_file = tempnam(sys_get_temp_dir(), 'br-pwg-auth-'); - if ($cookie_file === false) - { - throw new RuntimeException('Temporare Piwigo-Sitzung konnte nicht angelegt werden.'); - } + if ($cookie_file === false) throw new RuntimeException('Temporäre Piwigo-Sitzung konnte nicht angelegt werden.'); try { @@ -214,7 +149,7 @@ function bratonien_tools_nc_connector_validate_fallback_credentials($username, $ CURLOPT_CONNECTTIMEOUT=>10, CURLOPT_TIMEOUT=>20, CURLOPT_FOLLOWLOCATION=>false, - CURLOPT_USERAGENT=>'Bratonien-Tools-NC-Connector/'.(function_exists('bratonien_tools_current_version') ? bratonien_tools_current_version() : 'dev'), + CURLOPT_USERAGENT=>'Bratonien-Tools-NC-WebDAV/'.(function_exists('bratonien_tools_current_version') ? bratonien_tools_current_version() : 'dev'), )); $body = curl_exec($ch); $errno = curl_errno($ch); @@ -222,8 +157,8 @@ function bratonien_tools_nc_connector_validate_fallback_credentials($username, $ $http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); $type = (string)curl_getinfo($ch, CURLINFO_CONTENT_TYPE); curl_close($ch); - if ($body === false || $errno !== 0) throw new RuntimeException('Piwigo-Fallback konnte nicht geprueft werden: '.$error); - if ($http < 200 || $http >= 300) throw new RuntimeException('Piwigo-Fallback-Pruefung antwortete mit HTTP '.$http.'.'); + if ($body === false || $errno !== 0) throw new RuntimeException('Piwigo-Fallback konnte nicht geprüft werden: '.$error); + if ($http < 200 || $http >= 300) throw new RuntimeException('Piwigo-Fallback-Prüfung antwortete mit HTTP '.$http.'.'); $decoded = bratonien_tools_nc_connector_decode_api_response((string)$body, $type); if (($decoded['stat'] ?? '') !== 'ok') { @@ -233,83 +168,15 @@ function bratonien_tools_nc_connector_validate_fallback_credentials($username, $ return bratonien_tools_nc_connector_api_payload($decoded); }; - $request(array('method'=>'pwg.session.login', 'username'=>$username, 'password'=>$password)); + $request(array('method'=>'pwg.session.login','username'=>$username,'password'=>$password)); $status = $request(array('method'=>'pwg.session.getStatus')); if (!is_array($status)) throw new RuntimeException('Piwigo hat keinen auswertbaren Benutzerstatus geliefert.'); $role = strtolower(trim((string)($status['status'] ?? ''))); - if (!in_array($role, array('admin','webmaster'), true)) - { - throw new RuntimeException('Der Piwigo-Fallback funktioniert, gehoert aber keinem Administrator/Webmaster.'); - } - return array('username'=>(string)($status['username'] ?? $username), 'status'=>$role); + if (!in_array($role, array('admin','webmaster'), true)) throw new RuntimeException('Der Piwigo-Fallback funktioniert, gehört aber keinem Administrator/Webmaster.'); + return array('username'=>(string)($status['username'] ?? $username),'status'=>$role); } finally { @unlink($cookie_file); } } - -function bratonien_tools_nc_connector_piwigo_api_test() -{ - $api_key_id = trim((string)($_POST['nc_piwigo_api_key_id'] ?? '')); - $api_key_secret = trim((string)($_POST['nc_piwigo_api_key_secret'] ?? '')); - if ($api_key_id === '') - { - throw new RuntimeException('Piwigo-API-Schluessel-ID fehlt.'); - } - if ($api_key_secret === '') - { - throw new RuntimeException('Piwigo-API-Geheimnis fehlt.'); - } - - $status = bratonien_tools_nc_connector_piwigo_api_request($api_key_id, $api_key_secret, 'pwg.session.getStatus'); - if (!is_array($status)) - { - throw new RuntimeException('Piwigo hat keinen auswertbaren Benutzerstatus geliefert.'); - } - - $username = (string)($status['username'] ?? $status['user'] ?? ''); - $user_status = strtolower((string)($status['status'] ?? '')); - $is_admin = in_array($user_status, array('admin', 'webmaster'), true); - if (!$is_admin) - { - throw new RuntimeException('Der API-Key funktioniert, gehoert aber keinem Piwigo-Administrator/Webmaster. Er wurde nicht gespeichert.'); - } - - $method_result = bratonien_tools_nc_connector_piwigo_api_request($api_key_id, $api_key_secret, 'reflection.getMethodList'); - $method_map = array(); - bratonien_tools_nc_connector_collect_method_names($method_result, $method_map); - $methods = array_keys($method_map); - sort($methods, SORT_STRING); - - $required_methods = array('bratonien.nc.syncProductive', 'bratonien.nc.syncOrphans'); - $missing = array_values(array_diff($required_methods, $methods)); - if ($missing) - { - throw new RuntimeException('Der API-Key ist gueltig, aber die benoetigten Bratonien-Sync-Methoden fehlen: '.implode(', ', $missing).'.'); - } - - bratonien_tools_nc_api_credentials_store($api_key_id, $api_key_secret); - - $sync_candidates = array_values(array_filter($methods, function($method) - { - return preg_match('/sync|synchron|site/i', (string)$method) === 1; - })); - - $result = array( - 'ok' => true, - 'username' => $username !== '' ? $username : 'nicht gemeldet', - 'status' => $user_status !== '' ? $user_status : 'nicht gemeldet', - 'admin' => true, - 'method_count' => count($methods), - 'sync_candidates' => $sync_candidates, - 'sync_api_detected' => true, - 'stored' => true, - 'conclusion' => 'Der API-Key ist als bevorzugter Connector-Zugang gespeichert. Produktive API-Synchronisierung bleibt auf die im Plugin freigegebene Piwigo-Version begrenzt; bei einer nicht freigegebenen Version greift nur der konfigurierte Benutzername/Passwort-Fallback.', - ); - - return array( - 'message' => 'Piwigo-API-Key wurde geprueft und verschluesselt als bevorzugter Connector-Zugang gespeichert.', - 'nc_piwigo_api_test' => $result, - ); -}