# Authorization Schemes Documentation This document describes the 5 authorization schemes used in the APEX application for access control. ## Overview | Scheme Name | Type | Users/Condition | Error Message | |-------------|------|-----------------|---------------| | Admin_auth_schema | NATIVE_EXISTS | Specific user list | Utente non autorizzato | | User Read/Write | NATIVE_FUNCTION_BODY | USERS_READONLY table | Utente abilitato in sola lettura | | Consuntivi | NATIVE_EXISTS | GET_CONSUNTIVI_USERS view | Autorizzazione necessaria... | | Gestori | NATIVE_EXISTS | GET_GESTORI_USERS view | Non possiedi i permessi... | | Solo Admins | NATIVE_EXISTS | admin, monia only | Non possiedi i permessi... | --- ## Admin_auth_schema **Type:** NATIVE_EXISTS **Caching:** BY_USER_BY_PAGE_VIEW **SQL Query:** ```sql select 1 from dual where lower(:APP_USER) in ('admin','monia','andrea','maria','sabrina','nicole','cucina','developer','elia.ballarani'); ``` **Authorized Users:** - admin - monia - andrea - maria - sabrina - nicole - cucina - developer - elia.ballarani **Usage:** General administrative access to most management pages. --- ## User Read/Write **Type:** NATIVE_FUNCTION_BODY **Caching:** BY_USER_BY_PAGE_VIEW **PL/SQL Function:** ```plsql declare v_readonly number; begin select 1 into v_readonly from users_readonly where username = :APP_USER and flgwrite = 0; return false; exception when no_data_found then return true; end; ``` **Logic:** - Checks `USERS_READONLY` table - If user exists with `FLGWRITE = 0` → Returns FALSE (read-only mode) - If user not found → Returns TRUE (write access) **Usage:** Controls whether user can modify data or only view. --- ## Consuntivi **Type:** NATIVE_EXISTS **Caching:** BY_USER_BY_PAGE_VIEW **SQL Query:** ```sql select 1 from dual where :APP_USER in (select users from get_consuntivi_users); ``` **Data Source:** `GET_CONSUNTIVI_USERS` view **Usage:** Access to financial summary pages and cost management. --- ## Gestori **Type:** NATIVE_EXISTS **Caching:** BY_USER_BY_PAGE_VIEW **SQL Query:** ```sql select 1 from dual where :APP_USER in (select users from get_gestori_users); ``` **Data Source:** `GET_GESTORI_USERS` view **Usage:** Manager-level access. Applied to: - Home page - Nuovo Evento (Page 22) - Liste (Page 9) - Griglia (Page 16) - Torte e Costi Extra (Page 28) - Template Eventi (Page 48) - Tipi Evento (Page 13) --- ## Solo Admins **Type:** NATIVE_EXISTS **Caching:** BY_USER_BY_PAGE_VIEW **SQL Query:** ```sql select 1 from dual where lower(:APP_USER) in ('admin', 'monia'); ``` **Authorized Users:** - admin - monia **Usage:** Highest level of access. Reserved for: - Permessi (Page 47) - Gestione Dati (Page 45) - Critical configuration pages --- ## Application-Level Processes ### SET_USER_READONLY **Process Point:** Before Header (runs on every page) **Sequence:** 1 ```plsql begin select 1 into :APP_READ_ONLY from users_readonly where username = :APP_USER and flgwrite = 0; exception when no_data_found then :APP_READ_ONLY := 0; end; ``` **Sets:** `APP_READ_ONLY` application item - Value `1` = Read-only mode - Value `0` = Full access This is checked in page processes with condition: ```plsql :APP_READ_ONLY = 0 ``` --- ### SET_ITEM_SESSION **Process Point:** On Demand **Security:** MUST_NOT_BE_PUBLIC_USER ```plsql declare v_itemList varchar2(32000); begin v_itemList := APEX_UTIL.TABLE_TO_STRING(APEX_APPLICATION.G_F01); for c in ( select (select result from table(STRING_TO_TABLE_ENUM(a.result, 1, '='))) as item, (select result from table(STRING_TO_TABLE_ENUM(a.result, 2, '='))) as val from table(STRING_TO_TABLE_ENUM(v_itemList)) a ) loop APEX_UTIL.set_session_state( p_name => c.item, p_value => c.val ); end loop; end; ``` **Usage:** Called by `setSessionState()` JavaScript function to update APEX session state for multiple items. --- ## Application Items ### APP_READ_ONLY **Protection Level:** Internal **Escape on HTTP Output:** No Stores the read-only flag for the current user session. ### APP_VERSION Application version identifier. --- ## Authorization Hierarchy ``` ┌─────────────────────────────────────────────────────────────┐ │ Solo Admins │ │ (admin, monia) │ ├─────────────────────────────────────────────────────────────┤ │ Admin_auth_schema │ │ (admin, monia, andrea, maria, sabrina, nicole, │ │ cucina, developer, elia.ballarani) │ ├─────────────────────────────────────────────────────────────┤ │ Gestori │ │ (from GET_GESTORI_USERS view) │ ├─────────────────────────────────────────────────────────────┤ │ Consuntivi │ │ (from GET_CONSUNTIVI_USERS view) │ ├─────────────────────────────────────────────────────────────┤ │ User Read/Write │ │ (based on USERS_READONLY.FLGWRITE flag) │ ├─────────────────────────────────────────────────────────────┤ │ Authenticated Users │ │ (basic application access) │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Database Objects for Authorization ### USERS_READONLY Table | Column | Type | Description | |--------|------|-------------| | USERNAME | VARCHAR2 | APEX username | | FLGWRITE | NUMBER | 0 = read-only, 1 = write | ### GET_GESTORI_USERS View Returns list of users with manager permissions. ### GET_CONSUNTIVI_USERS View Returns list of users with financial access. --- ## Migration Notes When migrating to .NET + React: 1. **Authentication** - Implement JWT or cookie-based authentication - Consider integration with existing Oracle users or migrate to new system 2. **Authorization** - Map authorization schemes to .NET roles/claims - Implement policy-based authorization in .NET 3. **Role Mapping** ```csharp public enum UserRole { User, // Basic authenticated user ReadOnly, // Read-only access Consuntivi, // Financial access Gestori, // Manager level Admin, // Admin_auth_schema equivalent SuperAdmin // Solo Admins equivalent } ``` 4. **Frontend Authorization** - Store user roles in JWT/session - Implement route guards in React - Conditionally render UI elements based on permissions 5. **Backend Authorization** ```csharp [Authorize(Policy = "Gestori")] public class EventController : Controller { [Authorize(Policy = "SoloAdmins")] public IActionResult DeleteEvent(int id) { ... } } ```