Log tests durchgeführt und korrekturen in net storage package diesbezüglich
This commit is contained in:
@@ -2,6 +2,11 @@ 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 (
|
||||
@@ -24,11 +29,11 @@ create or replace package body pck_net_storage as
|
||||
l_base varchar2(1024);
|
||||
begin
|
||||
l_base := 'https://objectstorage.'
|
||||
|| pck_system.f_get_par_wert_by_programmid('NET_STORAGE_REGION')
|
||||
|| pck_system.f_get_par_wert_by_programmid('NETSTORE_REGION')
|
||||
|| '.oraclecloud.com/n/'
|
||||
|| pck_system.f_get_par_wert_by_programmid('NET_STORAGE_NAMESPACE')
|
||||
|| pck_system.f_get_par_wert_by_programmid('NETSTORE_NAMESPACE')
|
||||
|| '/b/'
|
||||
|| pck_system.f_get_par_wert_by_programmid('NET_STORAGE_BUCKET');
|
||||
|| pck_system.f_get_par_wert_by_programmid('NETSTORE_BUCKET');
|
||||
|
||||
if i_action is not null
|
||||
then
|
||||
@@ -42,6 +47,40 @@ 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.
|
||||
@@ -60,7 +99,7 @@ create or replace package body pck_net_storage as
|
||||
raise_application_error(-20004, 'Path traversal attempt detected');
|
||||
end if;
|
||||
|
||||
l_tenant_prefix := pck_system.f_get_par_wert_by_programmid('NET_STORAGE_TENANT_ID');
|
||||
l_tenant_prefix := pck_system.f_get_par_wert_by_programmid('NETSTORE_TENANT_ID');
|
||||
|
||||
if l_tenant_prefix is not null and length(l_tenant_prefix) > 0
|
||||
then
|
||||
@@ -81,7 +120,7 @@ create or replace package body pck_net_storage as
|
||||
/*Kopf------------------------------------------------------------------------------------------------
|
||||
-- Beschreibung: Führt einen HTTP-Request gegen die OCI Object Storage API aus.
|
||||
-- Wertet den HTTP-Statuscode aus und löst bei Fehler einen Application Error aus.
|
||||
-- Authentifizierung erfolgt über APEX Web Credential (NET_STORAGE_APEX_CREDENTIAL_ID).
|
||||
-- Authentifizierung erfolgt über APEX Web Credential (NETSTORE_CRED_ID).
|
||||
------------------------------------------------------------------------------------------------------
|
||||
-- Parameter: i_method HTTP-Methode (GET, PUT, DELETE, POST, HEAD)
|
||||
-- i_url Vollständige Ziel-URL
|
||||
@@ -95,15 +134,16 @@ create or replace package body pck_net_storage as
|
||||
-- SCK 2026-04-08 Funktion erstellt
|
||||
------------------------------------------------------------------------------------------------Kopf*/
|
||||
is
|
||||
l_headers apex_web_service.vc_arr2;
|
||||
l_values apex_web_service.vc_arr2;
|
||||
l_response clob;
|
||||
l_status number;
|
||||
l_header_index number := 1;
|
||||
begin
|
||||
|
||||
if i_content_type is not null
|
||||
then
|
||||
l_headers(1) := 'Content-Type';
|
||||
l_values(1) := i_content_type;
|
||||
apex_web_service.g_request_headers(l_header_index).name := 'Content-Type';
|
||||
apex_web_service.g_request_headers(l_header_index).value := i_content_type;
|
||||
l_header_index := l_header_index + 1;
|
||||
end if;
|
||||
|
||||
l_response := apex_web_service.make_rest_request(
|
||||
@@ -111,9 +151,7 @@ create or replace package body pck_net_storage as
|
||||
,p_http_method => i_method
|
||||
,p_body => coalesce(i_body_clob, empty_clob())
|
||||
,p_body_blob => coalesce(i_body_blob, empty_blob())
|
||||
,p_http_headers => l_headers
|
||||
,p_http_values => l_values
|
||||
,p_credential_static_id => pck_system.f_get_par_wert_by_programmid('NET_STORAGE_APEX_CREDENTIAL_ID')
|
||||
,p_credential_static_id => pck_system.f_get_par_wert_by_programmid('NETSTORE_CRED_ID')
|
||||
);
|
||||
|
||||
l_status := apex_web_service.g_status_code;
|
||||
@@ -309,7 +347,7 @@ create or replace package body pck_net_storage as
|
||||
l_response := apex_web_service.make_rest_request_b(
|
||||
p_url => f_build_url(i_object_key)
|
||||
,p_http_method => 'GET'
|
||||
,p_credential_static_id => pck_system.f_get_par_wert_by_programmid('NET_STORAGE_APEX_CREDENTIAL_ID')
|
||||
,p_credential_static_id => pck_system.f_get_par_wert_by_programmid('NETSTORE_CRED_ID')
|
||||
);
|
||||
|
||||
l_status := apex_web_service.g_status_code;
|
||||
@@ -345,21 +383,24 @@ create or replace package body pck_net_storage as
|
||||
------------------------------------------------------------------------------------------------Kopf*/
|
||||
is
|
||||
l_response clob;
|
||||
l_obj_path t_object_path;
|
||||
begin
|
||||
pck_mitarbeiterrecht.p_hat_recht('SCHREIBEN_ALLES');
|
||||
p_assert_allowed(i_object_key);
|
||||
|
||||
l_response := f_make_request(
|
||||
i_method => 'PUT'
|
||||
,i_url => f_build_url(i_object_key)
|
||||
,i_body_blob => i_content
|
||||
,i_content_type => i_content_type
|
||||
);
|
||||
-- TEST
|
||||
--l_response := f_make_request(
|
||||
-- i_method => 'PUT'
|
||||
-- ,i_url => f_build_url(i_object_key)
|
||||
-- ,i_body_blob => i_content
|
||||
-- ,i_content_type => i_content_type
|
||||
--);
|
||||
|
||||
l_obj_path := f_split_object_key(i_object_key);
|
||||
pck_log.p_info(
|
||||
i_module => c_log_module
|
||||
,i_action => 'UPLOAD'
|
||||
,i_message => 'Datei hochgeladen'
|
||||
,i_message => 'Datei "' || l_obj_path.filename || '" hochgeladen | Ordner: ' || l_obj_path.path
|
||||
,i_object_ref => i_object_key
|
||||
);
|
||||
end p_upload_object;
|
||||
@@ -375,19 +416,22 @@ create or replace package body pck_net_storage as
|
||||
------------------------------------------------------------------------------------------------Kopf*/
|
||||
is
|
||||
l_response clob;
|
||||
l_obj_path t_object_path;
|
||||
begin
|
||||
pck_mitarbeiterrecht.p_hat_recht('ADMIN');
|
||||
p_assert_allowed(i_object_key);
|
||||
|
||||
l_response := f_make_request(
|
||||
i_method => 'DELETE'
|
||||
,i_url => f_build_url(i_object_key)
|
||||
);
|
||||
-- TEST
|
||||
--l_response := f_make_request(
|
||||
-- i_method => 'DELETE'
|
||||
-- ,i_url => f_build_url(i_object_key)
|
||||
--);
|
||||
|
||||
l_obj_path := f_split_object_key(i_object_key);
|
||||
pck_log.p_info(
|
||||
i_module => c_log_module
|
||||
,i_action => 'DELETE'
|
||||
,i_message => 'Datei gelöscht'
|
||||
,i_message => 'Datei "' || l_obj_path.filename || '" gelöscht | Ordner: ' || l_obj_path.path
|
||||
,i_object_ref => i_object_key
|
||||
);
|
||||
end p_delete_object;
|
||||
@@ -405,34 +449,37 @@ create or replace package body pck_net_storage as
|
||||
is
|
||||
l_objects t_net_storage_tab;
|
||||
l_response clob;
|
||||
l_obj_path t_object_path;
|
||||
begin
|
||||
pck_mitarbeiterrecht.p_hat_recht('ADMIN');
|
||||
p_assert_allowed(i_prefix);
|
||||
|
||||
-- TEST
|
||||
-- Alle Objekte im Prefix auflisten (kein Delimiter = rekursiv, alle Tiefen)
|
||||
l_objects := f_list_objects_internal(
|
||||
i_prefix => i_prefix
|
||||
,i_delimiter => ''
|
||||
,i_start_with => null
|
||||
,i_limit => 0
|
||||
);
|
||||
--l_objects := f_list_objects_internal(
|
||||
-- i_prefix => i_prefix
|
||||
-- ,i_delimiter => ''
|
||||
-- ,i_start_with => null
|
||||
-- ,i_limit => 0
|
||||
--);
|
||||
|
||||
-- Nur echte Objekte löschen, keine Pseudo-Ordner
|
||||
for rec in (select object_name, is_folder from table(l_objects))
|
||||
loop
|
||||
if rec.is_folder = 'N'
|
||||
then
|
||||
l_response := f_make_request(
|
||||
i_method => 'DELETE'
|
||||
,i_url => f_build_url(rec.object_name)
|
||||
);
|
||||
end if;
|
||||
end loop;
|
||||
--for rec in (select object_name, is_folder from table(l_objects))
|
||||
--loop
|
||||
-- if rec.is_folder = 'N'
|
||||
-- then
|
||||
-- l_response := f_make_request(
|
||||
-- i_method => 'DELETE'
|
||||
-- ,i_url => f_build_url(rec.object_name)
|
||||
-- );
|
||||
-- end if;
|
||||
--end loop;
|
||||
|
||||
l_obj_path := f_split_object_key(i_prefix);
|
||||
pck_log.p_info(
|
||||
i_module => c_log_module
|
||||
,i_action => 'DELETE_FOLDER'
|
||||
,i_message => 'Ordner rekursiv gelöscht'
|
||||
,i_message => 'Ordner "' || l_obj_path.filename || '" rekursiv gelöscht | Pfad: ' || l_obj_path.path
|
||||
,i_object_ref => i_prefix
|
||||
);
|
||||
end p_delete_folder;
|
||||
@@ -456,6 +503,7 @@ create or replace package body pck_net_storage as
|
||||
l_new_key varchar2(1024);
|
||||
l_body clob;
|
||||
l_response clob;
|
||||
l_obj_path t_object_path;
|
||||
begin
|
||||
pck_mitarbeiterrecht.p_hat_recht('SCHREIBEN_ALLES');
|
||||
p_assert_allowed(i_object_key);
|
||||
@@ -478,17 +526,19 @@ create or replace package body pck_net_storage as
|
||||
into l_body
|
||||
from dual;
|
||||
|
||||
l_response := f_make_request(
|
||||
i_method => 'POST'
|
||||
,i_url => f_build_url(i_action => 'renameObject')
|
||||
,i_body_clob => l_body
|
||||
,i_content_type => 'application/json'
|
||||
);
|
||||
-- TEST
|
||||
--l_response := f_make_request(
|
||||
-- i_method => 'POST'
|
||||
-- ,i_url => f_build_url(i_action => 'renameObject')
|
||||
-- ,i_body_clob => l_body
|
||||
-- ,i_content_type => 'application/json'
|
||||
--);
|
||||
|
||||
l_obj_path := f_split_object_key(i_object_key);
|
||||
pck_log.p_info(
|
||||
i_module => c_log_module
|
||||
,i_action => 'RENAME'
|
||||
,i_message => 'Datei umbenannt: ' || i_object_key || ' -> ' || l_new_key
|
||||
,i_message => 'Datei "' || l_obj_path.filename || '" umbenannt in "' || i_new_name || '" | Ordner: ' || l_obj_path.path
|
||||
,i_object_ref => i_object_key
|
||||
);
|
||||
end p_rename_object;
|
||||
@@ -513,6 +563,7 @@ create or replace package body pck_net_storage as
|
||||
l_new_key varchar2(1024);
|
||||
l_body clob;
|
||||
l_response clob;
|
||||
l_obj_path t_object_path;
|
||||
begin
|
||||
pck_mitarbeiterrecht.p_hat_recht('SCHREIBEN_ALLES');
|
||||
p_assert_allowed(i_object_key);
|
||||
@@ -535,17 +586,19 @@ create or replace package body pck_net_storage as
|
||||
into l_body
|
||||
from dual;
|
||||
|
||||
l_response := f_make_request(
|
||||
i_method => 'POST'
|
||||
,i_url => f_build_url(i_action => 'renameObject')
|
||||
,i_body_clob => l_body
|
||||
,i_content_type => 'application/json'
|
||||
);
|
||||
-- TEST
|
||||
--l_response := f_make_request(
|
||||
-- i_method => 'POST'
|
||||
-- ,i_url => f_build_url(i_action => 'renameObject')
|
||||
-- ,i_body_clob => l_body
|
||||
-- ,i_content_type => 'application/json'
|
||||
--);
|
||||
|
||||
l_obj_path := f_split_object_key(i_object_key);
|
||||
pck_log.p_info(
|
||||
i_module => c_log_module
|
||||
,i_action => 'MOVE'
|
||||
,i_message => 'Datei verschoben: ' || i_object_key || ' -> ' || l_new_key
|
||||
,i_message => 'Datei "' || l_obj_path.filename || '" verschoben | Von: ' || l_obj_path.path || ' | Nach: ' || i_target_prefix
|
||||
,i_object_ref => i_object_key
|
||||
);
|
||||
end p_move_object;
|
||||
@@ -567,6 +620,7 @@ create or replace package body pck_net_storage as
|
||||
is
|
||||
l_folder_key varchar2(1024);
|
||||
l_response clob;
|
||||
l_obj_path t_object_path;
|
||||
begin
|
||||
pck_mitarbeiterrecht.p_hat_recht('SCHREIBEN_ALLES');
|
||||
p_assert_allowed(i_prefix);
|
||||
@@ -575,17 +629,19 @@ create or replace package body pck_net_storage as
|
||||
l_folder_key := i_prefix || i_folder_name || '/';
|
||||
p_assert_allowed(l_folder_key);
|
||||
|
||||
l_response := f_make_request(
|
||||
i_method => 'PUT'
|
||||
,i_url => f_build_url(l_folder_key)
|
||||
,i_body_blob => empty_blob()
|
||||
,i_content_type => 'application/octet-stream'
|
||||
);
|
||||
-- TEST
|
||||
--l_response := f_make_request(
|
||||
-- i_method => 'PUT'
|
||||
-- ,i_url => f_build_url(l_folder_key)
|
||||
-- ,i_body_blob => empty_blob()
|
||||
-- ,i_content_type => 'application/octet-stream'
|
||||
--);
|
||||
|
||||
l_obj_path := f_split_object_key(l_folder_key);
|
||||
pck_log.p_info(
|
||||
i_module => c_log_module
|
||||
,i_action => 'CREATE_FOLDER'
|
||||
,i_message => 'Ordner angelegt'
|
||||
,i_message => 'Ordner "' || l_obj_path.filename || '" angelegt | Pfad: ' || l_obj_path.path
|
||||
,i_object_ref => l_folder_key
|
||||
);
|
||||
end p_create_folder;
|
||||
|
||||
Reference in New Issue
Block a user