databend_common_ast/ast/statements/
user.rs

1// Copyright 2021 Datafuse Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::Display;
16use std::fmt::Formatter;
17
18use derive_visitor::Drive;
19use derive_visitor::DriveMut;
20
21use crate::ast::write_comma_separated_list;
22use crate::ast::AuthType;
23use crate::ast::CreateOption;
24use crate::ast::PrincipalIdentity;
25use crate::ast::ShowOptions;
26use crate::ast::UserIdentity;
27use crate::ast::UserPrivilegeType;
28
29#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
30pub struct CreateUserStmt {
31    pub create_option: CreateOption,
32    pub user: UserIdentity,
33    pub auth_option: AuthOption,
34    pub user_options: Vec<UserOptionItem>,
35}
36
37impl Display for CreateUserStmt {
38    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
39        write!(f, "CREATE")?;
40        if let CreateOption::CreateOrReplace = self.create_option {
41            write!(f, " OR REPLACE")?;
42        }
43        write!(f, " USER")?;
44        if let CreateOption::CreateIfNotExists = self.create_option {
45            write!(f, " IF NOT EXISTS")?;
46        }
47        write!(f, " {} IDENTIFIED", self.user)?;
48        write!(f, " {}", self.auth_option)?;
49        if !self.user_options.is_empty() {
50            write!(f, " WITH ")?;
51            write_comma_separated_list(f, &self.user_options)?;
52        }
53
54        Ok(())
55    }
56}
57
58#[derive(Debug, Clone, PartialEq, Eq, Default, Drive, DriveMut)]
59pub struct AuthOption {
60    pub auth_type: Option<AuthType>,
61    pub password: Option<String>,
62}
63
64impl Display for AuthOption {
65    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
66        if let Some(auth_type) = &self.auth_type {
67            write!(f, "WITH {auth_type} ")?;
68        }
69        if let Some(password) = &self.password {
70            write!(f, "BY '{password}'")?;
71        }
72
73        Ok(())
74    }
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
78pub struct AlterUserStmt {
79    // None means current user
80    pub user: Option<UserIdentity>,
81    // None means no change to make
82    pub auth_option: Option<AuthOption>,
83    pub user_options: Vec<UserOptionItem>,
84}
85
86impl Display for AlterUserStmt {
87    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
88        write!(f, "ALTER USER")?;
89        if let Some(user) = &self.user {
90            write!(f, " {}", user)?;
91        } else {
92            write!(f, " USER()")?;
93        }
94        if let Some(auth_option) = &self.auth_option {
95            write!(f, " IDENTIFIED {}", auth_option)?;
96        }
97        if !self.user_options.is_empty() {
98            write!(f, " WITH ")?;
99            write_comma_separated_list(f, &self.user_options)?;
100        }
101
102        Ok(())
103    }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
107pub struct GrantStmt {
108    pub source: AccountMgrSource,
109    pub principal: PrincipalIdentity,
110}
111
112impl Display for GrantStmt {
113    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
114        write!(f, "GRANT")?;
115        write!(f, "{}", self.source)?;
116
117        write!(f, " TO")?;
118        write!(f, "{}", self.principal)
119    }
120}
121
122#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
123pub struct RevokeStmt {
124    pub source: AccountMgrSource,
125    pub principal: PrincipalIdentity,
126}
127
128impl Display for RevokeStmt {
129    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
130        write!(f, "REVOKE")?;
131        write!(f, "{}", self.source)?;
132
133        write!(f, " FROM")?;
134        write!(f, "{}", self.principal)
135    }
136}
137
138#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
139pub struct ShowGranteesOfRoleStmt {
140    pub name: String,
141    pub show_option: Option<ShowOptions>,
142}
143
144impl Display for ShowGranteesOfRoleStmt {
145    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
146        write!(f, "SHOW GRANTS OF ROLE {}", self.name)?;
147
148        if let Some(show_option) = &self.show_option {
149            write!(f, " {show_option}")?;
150        }
151        Ok(())
152    }
153}
154
155#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
156pub struct ShowObjectPrivilegesStmt {
157    pub object: GrantObjectName,
158    pub show_option: Option<ShowOptions>,
159}
160
161#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
162pub enum GrantObjectName {
163    Database(String),
164    Table(Option<String>, String),
165    UDF(String),
166    Stage(String),
167    Warehouse(String),
168    Connection(String),
169    Sequence(String),
170}
171
172impl Display for GrantObjectName {
173    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
174        match self {
175            GrantObjectName::Database(database_name) => {
176                write!(f, "DATABASE {database_name}")
177            }
178            GrantObjectName::Table(database_name, table_name) => {
179                if let Some(database_name) = database_name {
180                    write!(f, "TABLE {database_name}.{table_name}")
181                } else {
182                    write!(f, "TABLE {table_name}")
183                }
184            }
185            GrantObjectName::UDF(udf) => write!(f, " UDF {udf}"),
186            GrantObjectName::Stage(stage) => write!(f, " STAGE {stage}"),
187            GrantObjectName::Warehouse(w) => write!(f, " WAREHOUSE {w}"),
188            GrantObjectName::Connection(c) => write!(f, " CONNECTION {c}"),
189            GrantObjectName::Sequence(s) => write!(f, " SEQUENCE {s}"),
190        }
191    }
192}
193
194impl Display for ShowObjectPrivilegesStmt {
195    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
196        write!(f, "SHOW GRANTS ON {}", self.object)?;
197
198        if let Some(show_option) = &self.show_option {
199            write!(f, " {show_option}")?;
200        }
201        Ok(())
202    }
203}
204
205#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
206pub enum AccountMgrSource {
207    Role {
208        role: String,
209    },
210    Privs {
211        privileges: Vec<UserPrivilegeType>,
212        level: AccountMgrLevel,
213    },
214    ALL {
215        level: AccountMgrLevel,
216    },
217}
218
219impl Display for AccountMgrSource {
220    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
221        match self {
222            AccountMgrSource::Role { role } => write!(f, " ROLE '{role}'")?,
223            AccountMgrSource::Privs { privileges, level } => {
224                write!(f, " ")?;
225                write_comma_separated_list(f, privileges.iter().map(|p| p.to_string()))?;
226                write!(f, " ON")?;
227                write!(f, " {}", level)?;
228            }
229            AccountMgrSource::ALL { level, .. } => {
230                write!(f, " ALL PRIVILEGES")?;
231                write!(f, " ON")?;
232                write!(f, " {}", level)?;
233            }
234        }
235        Ok(())
236    }
237}
238
239#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
240pub enum AccountMgrLevel {
241    Global,
242    Database(Option<String>),
243    Table(Option<String>, String),
244    UDF(String),
245    Stage(String),
246    Warehouse(String),
247    Connection(String),
248    Sequence(String),
249}
250
251impl Display for AccountMgrLevel {
252    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
253        match self {
254            AccountMgrLevel::Global => write!(f, " *.*"),
255            AccountMgrLevel::Database(database_name) => {
256                if let Some(database_name) = database_name {
257                    write!(f, " {database_name}.*")
258                } else {
259                    write!(f, " *")
260                }
261            }
262            AccountMgrLevel::Table(database_name, table_name) => {
263                if let Some(database_name) = database_name {
264                    write!(f, " {database_name}.{table_name}")
265                } else {
266                    write!(f, " {table_name}")
267                }
268            }
269            AccountMgrLevel::UDF(udf) => write!(f, " UDF {udf}"),
270            AccountMgrLevel::Stage(stage) => write!(f, " STAGE {stage}"),
271            AccountMgrLevel::Warehouse(w) => write!(f, " WAREHOUSE {w}"),
272            AccountMgrLevel::Connection(c) => write!(f, " CONNECTION {c}"),
273            AccountMgrLevel::Sequence(s) => write!(f, " SEQUENCE {s}"),
274        }
275    }
276}
277
278#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
279pub enum SecondaryRolesOption {
280    None,
281    All,
282    SpecifyRole(Vec<String>),
283}
284
285#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
286pub enum UserOptionItem {
287    TenantSetting(bool),
288    DefaultRole(String),
289    Disabled(bool),
290    SetNetworkPolicy(String),
291    UnsetNetworkPolicy,
292    SetPasswordPolicy(String),
293    UnsetPasswordPolicy,
294    MustChangePassword(bool),
295    SetWorkloadGroup(String),
296    UnsetWorkloadGroup,
297}
298
299impl Display for UserOptionItem {
300    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
301        match self {
302            UserOptionItem::TenantSetting(true) => write!(f, "TENANTSETTING"),
303            UserOptionItem::TenantSetting(false) => write!(f, "NOTENANTSETTING"),
304            UserOptionItem::DefaultRole(v) => write!(f, "DEFAULT_ROLE = '{}'", v),
305            UserOptionItem::SetNetworkPolicy(v) => write!(f, "SET NETWORK POLICY = '{}'", v),
306            UserOptionItem::UnsetNetworkPolicy => write!(f, "UNSET NETWORK POLICY"),
307            UserOptionItem::SetPasswordPolicy(v) => write!(f, "SET PASSWORD POLICY = '{}'", v),
308            UserOptionItem::SetWorkloadGroup(v) => write!(f, "SET WORKLOAD GROUP = '{}'", v),
309            UserOptionItem::UnsetWorkloadGroup => write!(f, "UNSET WORKLOAD GROUP"),
310            UserOptionItem::UnsetPasswordPolicy => write!(f, "UNSET PASSWORD POLICY"),
311            UserOptionItem::Disabled(v) => write!(f, "DISABLED = {}", v),
312            UserOptionItem::MustChangePassword(v) => write!(f, "MUST_CHANGE_PASSWORD = {}", v),
313        }
314    }
315}