surql_parser/upstream/sql/statements/define/
user.rs1use super::DefineKind;
2use crate::upstream::fmt::{CoverStmts, EscapeKwFreeIdent, QuoteStr};
3use crate::upstream::sql::{Base, Expr, Literal};
4use argon2::Argon2;
5use argon2::password_hash::{PasswordHasher, SaltString};
6use rand::Rng;
7use rand::distr::Alphanumeric;
8use rand::rngs::OsRng;
9use surrealdb_types::{SqlFormat, ToSql, write_sql};
10#[derive(Clone, Debug, Default, Eq, PartialEq)]
11#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
12pub enum PassType {
13 #[default]
14 Unset,
15 Hash(String),
16 Password(String),
17}
18#[derive(Clone, Debug, PartialEq, Eq)]
19pub struct DefineUserStatement {
20 pub kind: DefineKind,
21 pub name: Expr,
22 pub base: Base,
23 pub pass_type: PassType,
24 pub roles: Vec<String>,
25 pub token_duration: Expr,
26 pub session_duration: Expr,
27 pub comment: Expr,
28}
29impl Default for DefineUserStatement {
30 fn default() -> Self {
31 Self {
32 kind: DefineKind::Default,
33 name: Expr::Literal(Literal::None),
34 base: Base::Root,
35 pass_type: PassType::Unset,
36 roles: vec![],
37 token_duration: Expr::Literal(Literal::None),
38 session_duration: Expr::Literal(Literal::None),
39 comment: Expr::Literal(Literal::None),
40 }
41 }
42}
43impl ToSql for DefineUserStatement {
44 fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
45 write_sql!(f, fmt, "DEFINE USER");
46 match self.kind {
47 DefineKind::Default => {}
48 DefineKind::Overwrite => write_sql!(f, fmt, " OVERWRITE"),
49 DefineKind::IfNotExists => write_sql!(f, fmt, " IF NOT EXISTS"),
50 }
51 write_sql!(f, fmt, " {} ON {}", CoverStmts(&self.name), &self.base);
52 match self.pass_type {
53 PassType::Unset => {}
54 PassType::Hash(ref x) => write_sql!(f, fmt, " PASSHASH {}", QuoteStr(x)),
55 PassType::Password(ref x) => write_sql!(f, fmt, " PASSWORD {}", QuoteStr(x)),
56 }
57 write_sql!(f, fmt, " ROLES ");
58 for (idx, r) in self.roles.iter().enumerate() {
59 if idx != 0 {
60 f.push_str(", ");
61 }
62 let r = r.to_uppercase();
63 EscapeKwFreeIdent(&r).fmt_sql(f, fmt);
64 }
65 f.push_str(" DURATION FOR TOKEN ");
66 CoverStmts(&self.token_duration).fmt_sql(f, fmt);
67 f.push_str(", FOR SESSION ");
68 CoverStmts(&self.session_duration).fmt_sql(f, fmt);
69 if !matches!(self.comment, Expr::Literal(Literal::None)) {
70 write_sql!(f, fmt, " COMMENT {}", CoverStmts(&self.comment));
71 }
72 }
73}