Skip to main content

oxgraph_postgres/
role.rs

1//! Access-control roles for graph admin and query surfaces.
2
3use crate::error::PostgresGraphError;
4
5/// Role required for graph operations.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum GraphRole {
8    /// Read-only graph queries.
9    Reader,
10    /// Registration, build, sync, and maintenance.
11    Admin,
12}
13
14impl GraphRole {
15    /// Returns Ok when `self` satisfies `required`.
16    ///
17    /// # Errors
18    ///
19    /// Returns [`PostgresGraphError::AccessDenied`] when the role is insufficient.
20    ///
21    /// # Performance
22    ///
23    /// This method is `O(1)`.
24    pub const fn satisfies(self, required: Self) -> Result<(), PostgresGraphError> {
25        match (self, required) {
26            (Self::Admin, _) | (Self::Reader, Self::Reader) => Ok(()),
27            (Self::Reader, Self::Admin) => Err(PostgresGraphError::AccessDenied {
28                required,
29                actual: self,
30            }),
31        }
32    }
33
34    /// Returns Ok when `self` satisfies `required`.
35    ///
36    /// # Errors
37    ///
38    /// Returns [`PostgresGraphError::AccessDenied`] when the role is insufficient.
39    ///
40    /// # Performance
41    ///
42    /// This method is `O(1)`.
43    pub const fn require(self, required: Self) -> Result<(), PostgresGraphError> {
44        self.satisfies(required)
45    }
46}
47
48#[cfg(kani)]
49mod proofs {
50    use super::GraphRole;
51
52    /// Admin satisfies every required role.
53    #[kani::proof]
54    fn admin_satisfies_all() {
55        let admin = GraphRole::Admin;
56        assert!(admin.satisfies(GraphRole::Reader).is_ok());
57        assert!(admin.satisfies(GraphRole::Admin).is_ok());
58    }
59
60    /// Reader satisfies reader but not admin.
61    #[kani::proof]
62    fn reader_lattice() {
63        let reader = GraphRole::Reader;
64        assert!(reader.satisfies(GraphRole::Reader).is_ok());
65        assert!(reader.satisfies(GraphRole::Admin).is_err());
66    }
67}