diff --git a/database/docs/plan_pck_net_storage.md b/database/docs/plan_pck_net_storage.md index ede3d49..76236dd 100644 --- a/database/docs/plan_pck_net_storage.md +++ b/database/docs/plan_pck_net_storage.md @@ -47,15 +47,16 @@ Grund: DBMS_CLOUD ist auf dieser DB nicht installiert. APEX übernimmt OCI HTTP ## Konfigurationsparameter -Alle zur Laufzeit via `pck_system.f_get_par_wert_by_programmid`: +Alle zur Laufzeit via `pck_system.f_get_par_wert_by_programmid`: | Parameter-ID | Inhalt | |---|---| -| `NETSTORE_BUCKET` | Bucket-Name | -| `NETSTORE_NAMESPACE` | OCI Object Storage Namespace | -| `NETSTORE_REGION` | z.B. `eu-frankfurt-1` | +| `NETSTORE_BUCKET` | OCI Object Storage Bucket-Name, z.B. `INKA_NET_STORAGE` | +| `NETSTORE_NAMESPACE` | OCI Object Storage Namespace, z.B. `frhqaxi5sgcg` | +| `NETSTORE_REGION` | OCI Region unter der der Object Storage erreichbar ist, z.B. `eu-frankfurt-1`. | +| `NETSTORE_WALLET_PATH` | Der Pfad zur Wallet-Datei auf dem DB Server, die für die Zertifkatsvalidierung bei Verbindungen zum OCI Object Storage genutzt werden muss.
z.B.: `file:/u01/app/oracle/product/19.0.0.0/dbhome_1/wallets/digicert-global-root-g2-wallet` | | `NETSTORE_TENANT_ID` | Erlaubter Root-Prefix, z.B. `mandant_42/` | -| `NETSTORE_CRED_ID` | Credential Static ID für apex_web_service calls, z.B. 'OCI_OBJ_STORE_CRED' | +| `NETSTORE_CRED_ID` | Credential Static ID für apex_web_service calls, z.B. 'OCI_INKA_NET_STORE' | | `NETSTORE_MARKER_DB` | Name der Marker-Datei im Object Store, der von Automaton abgelegt wird, um zu signalisieren, dass der entsprechende Unterordner komplett hochgeladen wurde. Verhindert die Verarbeitung von unvollständig hochgeladenen Ordnern. z.B.: `_READY_FOR_DB_PROCESSING_` | | `NETSTORE_MARKER_SB` | Name der Marker-Datei im Object Store, der von DB beim Verarbeiten angelegt wird, wenn eine oder mehrere Dateien eines ZIPs nicht automatisiert importiert werden konnten. Das soll signalisieren, dass ein Sachbearbeiter die Dateien in diesem Unterordner manuell prüfen und importieren muss. z.B.: `_BITTE_PRÜFEN_` | | `NETSTORE_BA_PREFIX` | Pfad in Object Storage, wo BA-Daten liegen. Muss mit einem `/` enden, z.B. `BA/Eingang/` | diff --git a/database/packages/pck_net_storage.pkb b/database/packages/pck_net_storage.pkb index 0f1422f..7337e39 100644 --- a/database/packages/pck_net_storage.pkb +++ b/database/packages/pck_net_storage.pkb @@ -2,11 +2,6 @@ create or replace package body pck_net_storage as c_log_module constant lg_app_log.log_module%type := 'NETZLAUFWERK'; - type t_object_path is record ( - path varchar2(1024) - ,filename varchar2(256) - ); - -- ==================== Private Helpers ==================== function f_build_url ( @@ -47,40 +42,6 @@ create or replace package body pck_net_storage as end if; end f_build_url; - function f_split_object_key (i_object_key in varchar2) return t_object_path - /*Kopf------------------------------------------------------------------------------------------------ - -- Beschreibung: Extrahiert Pfad und Dateiname aus einem OCI-Objektschlüssel. - -- Bei Ordner-Keys (trailing Slash) wird der Ordnername als Dateiname zurückgegeben. - ------------------------------------------------------------------------------------------------------ - -- Parameter: i_object_key Vollständiger Objektschlüssel (z.B. mandant/Eingang/Import/datei.pdf) - ------------------------------------------------------------------------------------------------------ - -- Rückgabe: t_object_path Record mit path (inkl. trailing Slash) und filename - ------------------------------------------------------------------------------------------------------ - -- MA Datum Änderung - -- SCK 2026-04-09 Funktion erstellt - ------------------------------------------------------------------------------------------------Kopf*/ - is - l_key varchar2(1024); - l_pos number; - l_result t_object_path; - begin - -- Trailing Slash entfernen damit Ordner-Keys genauso behandelt werden wie Datei-Keys - l_key := rtrim(i_object_key, '/'); - - l_pos := instr(l_key, '/', -1); - - if l_pos > 0 - then - l_result.path := substr(l_key, 1, l_pos); - l_result.filename := substr(l_key, l_pos + 1); - else - l_result.path := null; - l_result.filename := l_key; - end if; - - return l_result; - end f_split_object_key; - procedure p_assert_allowed (i_object_key in varchar2) /*Kopf------------------------------------------------------------------------------------------------ -- Beschreibung: Prüft den Objektschlüssel auf Path-Traversal-Angriffe und Tenant-Scope. @@ -152,6 +113,7 @@ create or replace package body pck_net_storage as ,p_body => coalesce(i_body_clob, empty_clob()) ,p_body_blob => coalesce(i_body_blob, empty_blob()) ,p_credential_static_id => pck_system.f_get_par_wert_by_programmid('NETSTORE_CRED_ID') + ,p_wallet_path => pck_system.f_get_par_wert_by_programmid('NETSTORE_WALLET_PATH') ); l_status := apex_web_service.g_status_code; @@ -209,9 +171,9 @@ create or replace package body pck_net_storage as while not l_done loop l_url := f_build_url() - || '?prefix=' || utl_url.escape(i_prefix, false) - || '&delimiter=' || utl_url.escape(i_delimiter, false) - || '&limit=' || c_page_size; + || '?limit=' || c_page_size + || (case when i_prefix is not null then '&prefix=' || utl_url.escape(i_prefix, false) else '' end) + || (case when i_delimiter is not null then '&delimiter=' || utl_url.escape(i_delimiter, false) else '' end); if l_cur_start is not null then @@ -300,9 +262,43 @@ create or replace package body pck_net_storage as -- ==================== Öffentliche Funktionen ==================== + function f_split_object_key (i_object_key in varchar2) return t_object_path + /*Kopf------------------------------------------------------------------------------------------------ + -- Beschreibung: Extrahiert Pfad und Dateiname aus einem OCI-Objektschlüssel. + -- Bei Ordner-Keys (trailing Slash) wird der Ordnername als Dateiname zurückgegeben. + ------------------------------------------------------------------------------------------------------ + -- Parameter: i_object_key Vollständiger Objektschlüssel (z.B. mandant/Eingang/Import/datei.pdf) + ------------------------------------------------------------------------------------------------------ + -- Rückgabe: t_object_path Record mit path (inkl. trailing Slash) und filename + ------------------------------------------------------------------------------------------------------ + -- MA Datum Änderung + -- SCK 2026-04-09 Funktion erstellt + ------------------------------------------------------------------------------------------------Kopf*/ + is + l_key varchar2(1024); + l_pos number; + l_result t_object_path; + begin + -- Trailing Slash entfernen damit Ordner-Keys genauso behandelt werden wie Datei-Keys + l_key := rtrim(i_object_key, '/'); + + l_pos := instr(l_key, '/', -1); + + if l_pos > 0 + then + l_result.path := substr(l_key, 1, l_pos); + l_result.filename := substr(l_key, l_pos + 1); + else + l_result.path := null; + l_result.filename := l_key; + end if; + + return l_result; + end f_split_object_key; + function f_list_objects ( i_prefix in varchar2 - ,i_delimiter in varchar2 default '/' + ,i_delimiter in varchar2 default null ,i_start_with in varchar2 default null ,i_limit in number default 0 ) return t_net_storage_tab @@ -310,7 +306,7 @@ create or replace package body pck_net_storage as -- Beschreibung: Listet Objekte und Unterordner im Bucket mit Rechteprüfung und Scope-Validierung. ------------------------------------------------------------------------------------------------------ -- Parameter: i_prefix Präfix / Pfad im Bucket (z.B. eingang/) - -- i_delimiter Trennzeichen für Hierarchie-Simulation (Standard: /) + -- i_delimiter Trennzeichen für Hierarchie-Simulation (Standard: null = alle Dateien inkl. Unterordner anzeigen. Nutze '/' um nur die Dateien im Ordner i_prefix zu sehen) -- i_start_with Optionaler Startpunkt für Paginierung -- i_limit Maximale Anzahl Ergebnisse (0 = unbegrenzt) ------------------------------------------------------------------------------------------------------ diff --git a/database/packages/pck_net_storage.pkh b/database/packages/pck_net_storage.pkh index 8623f87..b6e71c8 100644 --- a/database/packages/pck_net_storage.pkh +++ b/database/packages/pck_net_storage.pkh @@ -1,5 +1,11 @@ create or replace package pck_net_storage as + -- Object Key aufgeteilt in Pfad (ohne Dateiname) und Dateiname (ohne Ordner Pfad) + type t_object_path is record ( + path varchar2(4000) + ,filename varchar2(256) + ); + -- Metadaten eines einzelnen OCI-Objekts (HEAD-Anfrage) type t_object_meta is record ( object_name varchar2(1024) @@ -9,9 +15,13 @@ create or replace package pck_net_storage as ,etag varchar2(256) ); + function f_split_object_key ( + i_object_key in varchar2 + ) return t_object_path; + function f_list_objects ( i_prefix in varchar2 - ,i_delimiter in varchar2 default '/' + ,i_delimiter in varchar2 default null ,i_start_with in varchar2 default null ,i_limit in number default 0 ) return t_net_storage_tab;