Skip to main content

rupg_catalog/
default_acl.rs

1//! The default privileges of `pg_default_acl`. They change as `SetDefaultACL` of `aclchk.c` changes them. An entry of a schema has an automatic dependency on the schema, so it goes with the schema.
2
3use std::sync::Arc;
4
5use super::{Catalog, DepKind, ObjRef, PG_NAMESPACE};
6
7/// The OID of `pg_default_acl`.
8pub const PG_DEFAULT_ACL: u32 = 826;
9
10/// The default privileges of a role for the new objects of a kind, one row of `pg_default_acl`.
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct DefaultAcl {
13    /// The OID.
14    pub oid: u32,
15    /// `defaclrole`: the OID of the role that creates the objects.
16    pub role: u32,
17    /// `defaclnamespace`: the OID of the schema, or 0 for the objects of all the schemas.
18    pub namespace: u32,
19    /// `defaclobjtype`: `r` for relations, `S` for sequences, `f` for functions, `T` for types, `n` for schemas and `L` for large objects.
20    pub objtype: u8,
21    /// `defaclacl`: the ACL, as `aclitem` texts.
22    pub acl: Vec<String>,
23}
24
25impl Catalog {
26    /// The default privileges, in the order of their OIDs.
27    pub fn default_acls(&self) -> impl Iterator<Item = &DefaultAcl> {
28        self.default_acls.values()
29    }
30
31    /// The default privileges with the OID.
32    pub fn default_acl(&self, oid: u32) -> Option<&DefaultAcl> {
33        self.default_acls.get(&oid)
34    }
35
36    /// `get_default_acl_internal`: the entry of the role, the schema and the kind of objects, or `None`.
37    pub fn find_default_acl(&self, role: u32, namespace: u32, objtype: u8) -> Option<&DefaultAcl> {
38        self.default_acls
39            .values()
40            .find(|d| d.role == role && d.namespace == namespace && d.objtype == objtype)
41    }
42
43    /// `SetDefaultACL`: sets the ACL of the entry of the role, the schema and the kind of objects. A new entry gets the next OID and, for a schema, an automatic dependency on the schema. `None` removes the entry.
44    pub fn set_default_acl(
45        &mut self,
46        role: u32,
47        namespace: u32,
48        objtype: u8,
49        acl: Option<Vec<String>>,
50    ) {
51        let found = self.find_default_acl(role, namespace, objtype).map(|d| d.oid);
52        match (found, acl) {
53            (Some(oid), Some(acl)) => {
54                if let Some(entry) = Arc::make_mut(&mut self.default_acls).get_mut(&oid) {
55                    entry.acl = acl;
56                }
57            }
58            (Some(oid), None) => {
59                Arc::make_mut(&mut self.default_acls).remove(&oid);
60                let me = ObjRef::new(PG_DEFAULT_ACL, oid);
61                self.depends.retain(|d| d.object != me);
62            }
63            (None, Some(acl)) => {
64                let oid = self.new_oid();
65                let entry = DefaultAcl { oid, role, namespace, objtype, acl };
66                Arc::make_mut(&mut self.default_acls).insert(oid, entry);
67                if namespace != 0 {
68                    let me = ObjRef::new(PG_DEFAULT_ACL, oid);
69                    self.depend(me, ObjRef::new(PG_NAMESPACE, namespace), DepKind::Auto);
70                }
71            }
72            (None, None) => {}
73        }
74    }
75
76    /// `doDeletion` of an entry.
77    pub(super) fn remove_default_acl(&mut self, oid: u32) {
78        if self.default_acls.contains_key(&oid) {
79            Arc::make_mut(&mut self.default_acls).remove(&oid);
80        }
81    }
82}