Skip to main content

plsql_privileges/
model.rs

1use serde::{Deserialize, Serialize};
2
3use plsql_catalog::{AccessibleByTarget, GrantPrivilege, Grantee};
4use plsql_core::{Confidence, Evidence, ObjectName, RoleName, SchemaName, UnknownReason, UserName};
5
6/// Authorization mode for a PL/SQL compilation unit.
7#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
8pub enum AuthorizationMode {
9    /// `AUTHID DEFINER` — runs under the owner's privileges.
10    #[default]
11    Definer,
12    /// `AUTHID CURRENT_USER` — runs under the caller's privileges.
13    Invoker,
14}
15
16/// Whether a privilege grant can be further delegated.
17#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
18pub enum GrantOption {
19    /// `WITH GRANT OPTION` — grantee can re-grant.
20    Grantable,
21    /// `WITH HIERARCHY OPTION` — grantee can grant to sub-objects.
22    Hierarchy,
23    #[default]
24    /// No delegation rights.
25    None,
26}
27
28/// Resolved privilege for a specific principal (user/role/public) on a specific object.
29#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
30pub struct ResolvedPrivilege {
31    /// The target schema.
32    pub object_owner: SchemaName,
33    /// The target object.
34    pub object_name: ObjectName,
35    /// The privilege granted.
36    pub privilege: GrantPrivilege,
37    /// The grantee (user, role, or PUBLIC).
38    pub grantee: Grantee,
39    /// Whether this grant is delegatable.
40    pub grant_option: GrantOption,
41    /// The role through which this grant was inherited, if any.
42    pub via_role: Option<RoleName>,
43    /// Confidence in this resolution.
44    pub confidence: Confidence,
45    /// Evidence for this resolution.
46    pub evidence: Evidence,
47}
48
49/// Whether a unit is accessible by specific callers.
50#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
51pub struct AccessControlEntry {
52    /// The unit that declares the `ACCESSIBLE BY` clause.
53    pub declaring_schema: SchemaName,
54    pub declaring_object: ObjectName,
55    /// The allowed callers.
56    pub allowed_callers: Vec<AccessibleByTarget>,
57}
58
59/// Cross-schema write — a unit writes to an object in a different schema.
60#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
61pub struct CrossSchemaWrite {
62    /// The calling unit's schema.
63    pub caller_schema: SchemaName,
64    pub caller_object: ObjectName,
65    /// The target object's schema (different from caller_schema).
66    pub target_schema: SchemaName,
67    pub target_object: ObjectName,
68    /// The privilege required.
69    pub privilege: GrantPrivilege,
70    /// Confidence in this write being authorized.
71    pub confidence: Confidence,
72    /// Evidence.
73    pub evidence: Evidence,
74    /// If resolution is uncertain due to runtime role state.
75    pub runtime_ambiguity: Option<UnknownReason>,
76}
77
78/// A resolved privilege that was inferred through a synonym chain.
79#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
80pub struct SynonymPrivilegePath {
81    /// The original synonym name.
82    pub synonym_schema: SchemaName,
83    pub synonym_name: ObjectName,
84    /// The resolved target.
85    pub target_schema: SchemaName,
86    pub target_object: ObjectName,
87    /// Whether the synonym is public.
88    pub is_public: bool,
89    /// Confidence (synonym targets can change).
90    pub confidence: Confidence,
91}
92
93/// Aggregated privilege model for an analysis run.
94#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
95pub struct PrivilegeModel {
96    /// All resolved privileges.
97    pub privileges: Vec<ResolvedPrivilege>,
98    /// All `ACCESSIBLE BY` entries.
99    pub access_control: Vec<AccessControlEntry>,
100    /// Cross-schema write surface.
101    pub cross_schema_writes: Vec<CrossSchemaWrite>,
102    /// Synonym-mediated privilege paths.
103    pub synonym_paths: Vec<SynonymPrivilegePath>,
104    /// Grants to `PUBLIC`.
105    pub public_grants: Vec<ResolvedPrivilege>,
106    /// Ambiguous authorizations due to runtime role state.
107    pub runtime_ambiguities: Vec<AuthorizationAmbiguity>,
108    /// Diagnostics generated during privilege resolution.
109    pub diagnostics: Vec<plsql_core::Diagnostic>,
110}
111
112/// An authorization that cannot be resolved statically because it depends
113/// on runtime role state.
114#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
115pub struct AuthorizationAmbiguity {
116    /// The unit that has the ambiguous authorization.
117    pub schema: SchemaName,
118    pub object: ObjectName,
119    /// The reason the authorization is ambiguous.
120    pub reason: UnknownReason,
121    /// The roles that could change the outcome.
122    pub dependent_roles: Vec<RoleName>,
123    /// Evidence.
124    pub evidence: Evidence,
125}
126
127/// Configuration for privilege resolution.
128#[derive(Clone, Debug, Default)]
129pub struct PrivilegeConfig {
130    /// The current schema for resolution context.
131    pub current_schema: Option<SchemaName>,
132    /// The current user for resolution context.
133    pub current_user: Option<UserName>,
134    /// Roles to assume as enabled.
135    pub enabled_roles: Vec<RoleName>,
136}