[Developer] #424 separate ORDS auth context from object queries
This commit is contained in:
@@ -8,10 +8,13 @@
|
|||||||
-- * ADMIN ORDS schema enablement
|
-- * ADMIN ORDS schema enablement
|
||||||
--
|
--
|
||||||
-- Purpose:
|
-- Purpose:
|
||||||
-- * VPD path: Authorization header -> Bearer key -> SYS_CONTEXT -> VPD.
|
-- * Common package: Authorization header -> Bearer key -> SYS_CONTEXT.
|
||||||
|
-- * Object query handlers: call the common package, then query their
|
||||||
|
-- own protected table/view.
|
||||||
|
-- * VPD demo path: a fixed demo handler for ADMIN.CB_V_SEARCH_DOCUMENTS.
|
||||||
-- * DDS probe: Authorization header -> local mapping only. This does not
|
-- * DDS probe: Authorization header -> local mapping only. This does not
|
||||||
-- attach a DDS EndUserSecurityContext, so DDS cannot treat the request
|
-- attach a DDS EndUserSecurityContext, so DDS cannot treat the request
|
||||||
-- as the mapped END USER.
|
-- as the mapped END USER. It is not a protected object query handler.
|
||||||
-- ============================================================
|
-- ============================================================
|
||||||
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
WHENEVER SQLERROR EXIT SQL.SQLCODE
|
||||||
SET ECHO OFF
|
SET ECHO OFF
|
||||||
@@ -19,6 +22,8 @@ SET FEEDBACK ON
|
|||||||
|
|
||||||
PROMPT === Creating CB_ORDS handler package ===
|
PROMPT === Creating CB_ORDS handler package ===
|
||||||
CREATE OR REPLACE PACKAGE cb_ords_handler_pkg AUTHID DEFINER AS
|
CREATE OR REPLACE PACKAGE cb_ords_handler_pkg AUTHID DEFINER AS
|
||||||
|
PROCEDURE set_vpd_context(p_authorization IN VARCHAR2);
|
||||||
|
PROCEDURE clear_vpd_context;
|
||||||
FUNCTION vpd_search_json(p_authorization IN VARCHAR2) RETURN CLOB;
|
FUNCTION vpd_search_json(p_authorization IN VARCHAR2) RETURN CLOB;
|
||||||
FUNCTION dds_bearer_probe_json(p_authorization IN VARCHAR2) RETURN CLOB;
|
FUNCTION dds_bearer_probe_json(p_authorization IN VARCHAR2) RETURN CLOB;
|
||||||
END;
|
END;
|
||||||
@@ -47,15 +52,25 @@ CREATE OR REPLACE PACKAGE BODY cb_ords_handler_pkg AS
|
|||||||
END CASE;
|
END CASE;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
FUNCTION vpd_search_json(p_authorization IN VARCHAR2) RETURN CLOB AS
|
PROCEDURE set_vpd_context(p_authorization IN VARCHAR2) AS
|
||||||
v_bearer_key VARCHAR2(4000);
|
v_bearer_key VARCHAR2(4000);
|
||||||
v_rows_json CLOB;
|
|
||||||
v_response CLOB;
|
|
||||||
v_context_read_contents VARCHAR2(1);
|
|
||||||
BEGIN
|
BEGIN
|
||||||
admin.cb_agent_ctx_pkg.clear_user;
|
admin.cb_agent_ctx_pkg.clear_user;
|
||||||
v_bearer_key := extract_bearer_key(p_authorization);
|
v_bearer_key := extract_bearer_key(p_authorization);
|
||||||
admin.cb_agent_ctx_pkg.set_user_by_bearer(v_bearer_key);
|
admin.cb_agent_ctx_pkg.set_user_by_bearer(v_bearer_key);
|
||||||
|
END;
|
||||||
|
|
||||||
|
PROCEDURE clear_vpd_context AS
|
||||||
|
BEGIN
|
||||||
|
admin.cb_agent_ctx_pkg.clear_user;
|
||||||
|
END;
|
||||||
|
|
||||||
|
FUNCTION vpd_search_json(p_authorization IN VARCHAR2) RETURN CLOB AS
|
||||||
|
v_rows_json CLOB;
|
||||||
|
v_response CLOB;
|
||||||
|
v_context_read_contents VARCHAR2(1);
|
||||||
|
BEGIN
|
||||||
|
set_vpd_context(p_authorization);
|
||||||
|
|
||||||
SELECT JSON_ARRAYAGG(
|
SELECT JSON_ARRAYAGG(
|
||||||
JSON_OBJECT(
|
JSON_OBJECT(
|
||||||
@@ -91,11 +106,11 @@ CREATE OR REPLACE PACKAGE BODY cb_ords_handler_pkg AS
|
|||||||
INTO v_response
|
INTO v_response
|
||||||
FROM dual;
|
FROM dual;
|
||||||
|
|
||||||
admin.cb_agent_ctx_pkg.clear_user;
|
clear_vpd_context;
|
||||||
RETURN v_response;
|
RETURN v_response;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
admin.cb_agent_ctx_pkg.clear_user;
|
clear_vpd_context;
|
||||||
RAISE;
|
RAISE;
|
||||||
END;
|
END;
|
||||||
|
|
||||||
@@ -182,14 +197,36 @@ BEGIN
|
|||||||
p_source_type => ORDS.source_type_plsql,
|
p_source_type => ORDS.source_type_plsql,
|
||||||
p_source => q'[
|
p_source => q'[
|
||||||
DECLARE
|
DECLARE
|
||||||
v_response CLOB;
|
v_rows_json CLOB;
|
||||||
BEGIN
|
BEGIN
|
||||||
v_response := cb_ords_handler_pkg.vpd_search_json(:auth_header);
|
cb_ords_handler_pkg.set_vpd_context(:auth_header);
|
||||||
|
|
||||||
|
SELECT JSON_ARRAYAGG(
|
||||||
|
JSON_OBJECT(
|
||||||
|
'doc_id' VALUE doc_id,
|
||||||
|
'title' VALUE title,
|
||||||
|
'owner_emp_no' VALUE owner_emp_no,
|
||||||
|
'dept_code' VALUE dept_code,
|
||||||
|
'contents' VALUE contents
|
||||||
|
RETURNING CLOB
|
||||||
|
)
|
||||||
|
ORDER BY doc_id
|
||||||
|
RETURNING CLOB
|
||||||
|
)
|
||||||
|
INTO v_rows_json
|
||||||
|
FROM admin.cb_v_search_documents;
|
||||||
|
|
||||||
|
IF v_rows_json IS NULL THEN
|
||||||
|
v_rows_json := '[]';
|
||||||
|
END IF;
|
||||||
|
|
||||||
:status_code := 200;
|
:status_code := 200;
|
||||||
OWA_UTIL.MIME_HEADER('application/json', TRUE);
|
OWA_UTIL.MIME_HEADER('application/json', TRUE);
|
||||||
HTP.P(v_response);
|
HTP.P(JSON_OBJECT('rows' VALUE v_rows_json FORMAT JSON RETURNING CLOB));
|
||||||
|
cb_ords_handler_pkg.clear_vpd_context;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
|
cb_ords_handler_pkg.clear_vpd_context;
|
||||||
:status_code := 403;
|
:status_code := 403;
|
||||||
OWA_UTIL.MIME_HEADER('application/json', TRUE);
|
OWA_UTIL.MIME_HEADER('application/json', TRUE);
|
||||||
HTP.P('{"error":"' || REPLACE(SQLERRM, '"', '\"') || '"}');
|
HTP.P('{"error":"' || REPLACE(SQLERRM, '"', '\"') || '"}');
|
||||||
|
|||||||
@@ -166,19 +166,10 @@ public class OrdsMetadataService {
|
|||||||
String selectColumns = String.join(", ", columns);
|
String selectColumns = String.join(", ", columns);
|
||||||
return """
|
return """
|
||||||
DECLARE
|
DECLARE
|
||||||
v_auth VARCHAR2(4000);
|
|
||||||
v_bearer_key VARCHAR2(4000);
|
|
||||||
v_limit NUMBER := LEAST(GREATEST(NVL(:row_limit, 50), 1), 500);
|
v_limit NUMBER := LEAST(GREATEST(NVL(:row_limit, 50), 1), 500);
|
||||||
v_rows_json CLOB;
|
v_rows_json CLOB;
|
||||||
BEGIN
|
BEGIN
|
||||||
v_auth := TRIM(:auth_header);
|
cb_ords_handler_pkg.set_vpd_context(:auth_header);
|
||||||
IF v_auth IS NULL OR LOWER(SUBSTR(v_auth, 1, 7)) != 'bearer ' THEN
|
|
||||||
RAISE_APPLICATION_ERROR(-20101, 'Authorization header must be Bearer <key>');
|
|
||||||
END IF;
|
|
||||||
v_bearer_key := TRIM(SUBSTR(v_auth, 8));
|
|
||||||
|
|
||||||
admin.cb_agent_ctx_pkg.clear_user;
|
|
||||||
admin.cb_agent_ctx_pkg.set_user_by_bearer(v_bearer_key);
|
|
||||||
|
|
||||||
SELECT JSON_ARRAYAGG(
|
SELECT JSON_ARRAYAGG(
|
||||||
JSON_OBJECT(
|
JSON_OBJECT(
|
||||||
@@ -201,10 +192,10 @@ public class OrdsMetadataService {
|
|||||||
:status_code := 200;
|
:status_code := 200;
|
||||||
OWA_UTIL.MIME_HEADER('application/json', TRUE);
|
OWA_UTIL.MIME_HEADER('application/json', TRUE);
|
||||||
HTP.P(JSON_OBJECT('rows' VALUE v_rows_json FORMAT JSON RETURNING CLOB));
|
HTP.P(JSON_OBJECT('rows' VALUE v_rows_json FORMAT JSON RETURNING CLOB));
|
||||||
admin.cb_agent_ctx_pkg.clear_user;
|
cb_ords_handler_pkg.clear_vpd_context;
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN OTHERS THEN
|
WHEN OTHERS THEN
|
||||||
admin.cb_agent_ctx_pkg.clear_user;
|
cb_ords_handler_pkg.clear_vpd_context;
|
||||||
:status_code := 403;
|
:status_code := 403;
|
||||||
OWA_UTIL.MIME_HEADER('application/json', TRUE);
|
OWA_UTIL.MIME_HEADER('application/json', TRUE);
|
||||||
HTP.P(JSON_OBJECT('error' VALUE SQLERRM RETURNING CLOB));
|
HTP.P(JSON_OBJECT('error' VALUE SQLERRM RETURNING CLOB));
|
||||||
|
|||||||
Reference in New Issue
Block a user