Skip to main content

surql_parser/upstream/sql/statements/define/
user.rs

1use 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::distributions::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}