databend_common_ast/ast/statements/
password_policy.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::quote::QuotedString;
22use crate::ast::CreateOption;
23
24#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
25pub struct CreatePasswordPolicyStmt {
26    pub create_option: CreateOption,
27    pub name: String,
28    pub set_options: PasswordSetOptions,
29}
30
31impl Display for CreatePasswordPolicyStmt {
32    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
33        write!(f, "CREATE ")?;
34        if let CreateOption::CreateOrReplace = self.create_option {
35            write!(f, "OR REPLACE ")?;
36        }
37        write!(f, "PASSWORD POLICY ")?;
38        if let CreateOption::CreateIfNotExists = self.create_option {
39            write!(f, "IF NOT EXISTS ")?;
40        }
41        write!(f, "{}", self.name)?;
42        write!(f, "{}", self.set_options)?;
43
44        Ok(())
45    }
46}
47
48#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
49pub struct AlterPasswordPolicyStmt {
50    pub if_exists: bool,
51    pub name: String,
52    pub action: AlterPasswordAction,
53}
54
55impl Display for AlterPasswordPolicyStmt {
56    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
57        write!(f, "ALTER PASSWORD POLICY ")?;
58        if self.if_exists {
59            write!(f, "IF EXISTS ")?;
60        }
61        write!(f, "{} ", self.name)?;
62        write!(f, "{}", self.action)?;
63
64        Ok(())
65    }
66}
67
68#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
69pub enum AlterPasswordAction {
70    SetOptions(PasswordSetOptions),
71    UnSetOptions(PasswordUnSetOptions),
72}
73
74impl Display for AlterPasswordAction {
75    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
76        match self {
77            AlterPasswordAction::SetOptions(set_options) => {
78                write!(f, "SET {}", set_options)?;
79            }
80            AlterPasswordAction::UnSetOptions(unset_options) => {
81                write!(f, "UNSET {}", unset_options)?;
82            }
83        }
84
85        Ok(())
86    }
87}
88
89#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
90pub struct PasswordSetOptions {
91    pub min_length: Option<u64>,
92    pub max_length: Option<u64>,
93    pub min_upper_case_chars: Option<u64>,
94    pub min_lower_case_chars: Option<u64>,
95    pub min_numeric_chars: Option<u64>,
96    pub min_special_chars: Option<u64>,
97    pub min_age_days: Option<u64>,
98    pub max_age_days: Option<u64>,
99    pub max_retries: Option<u64>,
100    pub lockout_time_mins: Option<u64>,
101    pub history: Option<u64>,
102    pub comment: Option<String>,
103}
104
105impl Display for PasswordSetOptions {
106    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
107        if let Some(min_length) = self.min_length {
108            write!(f, " PASSWORD_MIN_LENGTH = {}", min_length)?;
109        }
110        if let Some(max_length) = self.max_length {
111            write!(f, " PASSWORD_MAX_LENGTH = {}", max_length)?;
112        }
113        if let Some(min_upper_case_chars) = self.min_upper_case_chars {
114            write!(
115                f,
116                " PASSWORD_MIN_UPPER_CASE_CHARS = {}",
117                min_upper_case_chars
118            )?;
119        }
120        if let Some(min_lower_case_chars) = self.min_lower_case_chars {
121            write!(
122                f,
123                " PASSWORD_MIN_LOWER_CASE_CHARS = {}",
124                min_lower_case_chars
125            )?;
126        }
127        if let Some(min_numeric_chars) = self.min_numeric_chars {
128            write!(f, " PASSWORD_MIN_NUMERIC_CHARS = {}", min_numeric_chars)?;
129        }
130        if let Some(min_special_chars) = self.min_special_chars {
131            write!(f, " PASSWORD_MIN_SPECIAL_CHARS = {}", min_special_chars)?;
132        }
133        if let Some(min_age_days) = self.min_age_days {
134            write!(f, " PASSWORD_MIN_AGE_DAYS = {}", min_age_days)?;
135        }
136        if let Some(max_age_days) = self.max_age_days {
137            write!(f, " PASSWORD_MAX_AGE_DAYS = {}", max_age_days)?;
138        }
139        if let Some(max_retries) = self.max_retries {
140            write!(f, " PASSWORD_MAX_RETRIES = {}", max_retries)?;
141        }
142        if let Some(lockout_time_mins) = self.lockout_time_mins {
143            write!(f, " PASSWORD_LOCKOUT_TIME_MINS = {}", lockout_time_mins)?;
144        }
145        if let Some(history) = self.history {
146            write!(f, " PASSWORD_HISTORY = {}", history)?;
147        }
148        if let Some(comment) = &self.comment {
149            write!(f, " COMMENT = {}", QuotedString(comment, '\''))?;
150        }
151
152        Ok(())
153    }
154}
155
156#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
157pub struct PasswordUnSetOptions {
158    pub min_length: bool,
159    pub max_length: bool,
160    pub min_upper_case_chars: bool,
161    pub min_lower_case_chars: bool,
162    pub min_numeric_chars: bool,
163    pub min_special_chars: bool,
164    pub min_age_days: bool,
165    pub max_age_days: bool,
166    pub max_retries: bool,
167    pub lockout_time_mins: bool,
168    pub history: bool,
169    pub comment: bool,
170}
171
172impl Display for PasswordUnSetOptions {
173    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
174        if self.min_length {
175            write!(f, " PASSWORD_MIN_LENGTH")?;
176        }
177        if self.max_length {
178            write!(f, " PASSWORD_MAX_LENGTH")?;
179        }
180        if self.min_upper_case_chars {
181            write!(f, " PASSWORD_MIN_UPPER_CASE_CHARS")?;
182        }
183        if self.min_lower_case_chars {
184            write!(f, " PASSWORD_MIN_LOWER_CASE_CHARS")?;
185        }
186        if self.min_numeric_chars {
187            write!(f, " PASSWORD_MIN_NUMERIC_CHARS")?;
188        }
189        if self.min_special_chars {
190            write!(f, " PASSWORD_MIN_SPECIAL_CHARS")?;
191        }
192        if self.min_age_days {
193            write!(f, " PASSWORD_MIN_AGE_DAYS")?;
194        }
195        if self.max_age_days {
196            write!(f, " PASSWORD_MAX_AGE_DAYS")?;
197        }
198        if self.max_retries {
199            write!(f, " PASSWORD_MAX_RETRIES")?;
200        }
201        if self.lockout_time_mins {
202            write!(f, " PASSWORD_LOCKOUT_TIME_MINS")?;
203        }
204        if self.history {
205            write!(f, " PASSWORD_HISTORY")?;
206        }
207        if self.comment {
208            write!(f, " COMMENT")?;
209        }
210
211        Ok(())
212    }
213}
214
215#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
216pub struct DropPasswordPolicyStmt {
217    pub if_exists: bool,
218    pub name: String,
219}
220
221impl Display for DropPasswordPolicyStmt {
222    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
223        write!(f, "DROP PASSWORD POLICY ")?;
224        if self.if_exists {
225            write!(f, "IF EXISTS ")?;
226        }
227        write!(f, "{}", self.name)?;
228
229        Ok(())
230    }
231}
232
233#[derive(Debug, Clone, PartialEq, Drive, DriveMut)]
234pub struct DescPasswordPolicyStmt {
235    pub name: String,
236}
237
238impl Display for DescPasswordPolicyStmt {
239    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
240        write!(f, "DESCRIBE PASSWORD POLICY {}", self.name)?;
241
242        Ok(())
243    }
244}