grant/config/
role.rs

1use anyhow::Result;
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5pub use super::role_database::RoleDatabaseLevel;
6pub use super::role_schema::RoleSchemaLevel;
7pub use super::role_table::RoleTableLevel;
8
9#[derive(Debug, PartialEq, Eq)]
10pub enum RoleLevelType {
11    Database,
12    Schema,
13    Table,
14}
15
16impl fmt::Display for RoleLevelType {
17    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18        match self {
19            RoleLevelType::Database => write!(f, "database"),
20            RoleLevelType::Schema => write!(f, "schema"),
21            RoleLevelType::Table => write!(f, "table"),
22        }
23    }
24}
25
26/// Configuration for a role.
27#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
28#[serde(tag = "type")]
29pub enum Role {
30    #[serde(rename = "database")]
31    Database(RoleDatabaseLevel),
32    #[serde(rename = "schema")]
33    Schema(RoleSchemaLevel),
34    #[serde(rename = "table")]
35    Table(RoleTableLevel),
36}
37
38pub trait RoleValidate {
39    fn validate(&self) -> Result<()>;
40}
41
42impl Role {
43    pub fn to_sql(&self, user: &str) -> String {
44        match self {
45            Role::Database(role) => role.to_sql(user),
46            Role::Schema(role) => role.to_sql(user),
47            Role::Table(role) => role.to_sql(user),
48        }
49    }
50
51    pub fn validate(&self) -> Result<()> {
52        match self {
53            Role::Database(role) => role.validate(),
54            Role::Schema(role) => role.validate(),
55            Role::Table(role) => role.validate(),
56        }
57    }
58
59    pub fn get_name(&self) -> String {
60        match self {
61            Role::Database(role) => role.name.clone(),
62            Role::Schema(role) => role.name.clone(),
63            Role::Table(role) => role.name.clone(),
64        }
65    }
66
67    pub fn find(&self, name: &str) -> bool {
68        // role name can contain '-', so we need to remove it before comparing
69        let name = name.replace('-', "");
70
71        match self {
72            Role::Database(role) => role.name == name,
73            Role::Schema(role) => role.name == name,
74            Role::Table(role) => role.name == name,
75        }
76    }
77
78    pub fn get_level(&self) -> RoleLevelType {
79        match self {
80            Role::Database(_) => RoleLevelType::Database,
81            Role::Schema(_) => RoleLevelType::Schema,
82            Role::Table(_) => RoleLevelType::Table,
83        }
84    }
85
86    pub fn get_grants(&self) -> Vec<String> {
87        match self {
88            Role::Database(role) => role.grants.clone(),
89            Role::Schema(role) => role.grants.clone(),
90            Role::Table(role) => role.grants.clone(),
91        }
92    }
93
94    pub fn get_databases(&self) -> Vec<String> {
95        match self {
96            Role::Database(role) => role.databases.clone(),
97            _ => vec![],
98        }
99    }
100
101    pub fn get_schemas(&self) -> Vec<String> {
102        match self {
103            Role::Schema(role) => role.schemas.clone(),
104            Role::Table(role) => role.schemas.clone(),
105            _ => vec![],
106        }
107    }
108
109    pub fn get_tables(&self) -> Vec<String> {
110        match self {
111            Role::Table(role) => role.tables.clone(),
112            _ => vec![],
113        }
114    }
115}