Skip to main content

surrealdb_expr/expr/convert/statements/alter/
user.rs

1//! `sql` -> `expr` conversions for [`crate::sql::statements::alter::user`].
2//!
3//! Lives in core rather than beside the AST: `surrealdb-sql` sits below
4//! core, so it cannot name `expr` types.
5
6use crate::iam::ScramCredential;
7use crate::sql::statements::alter::AlterKind;
8use crate::sql::statements::alter::user::*;
9use crate::sql::statements::define::user::PassType;
10
11impl From<AlterUserStatement> for crate::expr::statements::alter::AlterUserStatement {
12	fn from(v: AlterUserStatement) -> Self {
13		// Determine the SCRAM change before consuming `pass_type` for the hash.
14		// An explicit PASSSCRAM wins; PASSWORD derives a new verifier; PASSHASH
15		// clears any stale verifier (the plaintext is unknown); no clause leaves
16		// SCRAM untouched. The verifier is validated at parse time, so `expect`
17		// upholds that invariant loudly rather than silently clearing a bad one.
18		let scram = if let Some(ref s) = v.scram {
19			Some(Some(
20				ScramCredential::from_verifier_string(s)
21					.expect("PASSSCRAM verifier must be validated at parse time"),
22			))
23		} else {
24			match v.pass_type {
25				Some(PassType::Password(ref p)) => Some(Some(ScramCredential::generate(p))),
26				Some(PassType::Hash(_)) => Some(None),
27				Some(PassType::Unset) | None => None,
28			}
29		};
30
31		let hash = v.pass_type.and_then(|pt| match pt {
32			PassType::Unset => None,
33			PassType::Hash(h) => Some(h),
34			PassType::Password(p) => Some(crate::iam::hash_password(&p)),
35		});
36
37		crate::expr::statements::alter::AlterUserStatement {
38			name: v.name.into(),
39			base: v.base.into(),
40			if_exists: v.if_exists,
41			hash,
42			scram,
43			roles: match v.roles {
44				AlterKind::Set(x) => crate::expr::statements::alter::AlterKind::Set(x),
45				AlterKind::Drop => crate::expr::statements::alter::AlterKind::Drop,
46				AlterKind::None => crate::expr::statements::alter::AlterKind::None,
47			},
48			token_duration: match v.token_duration {
49				AlterKind::Set(d) => crate::expr::statements::alter::AlterKind::Set(Some(d)),
50				AlterKind::Drop => crate::expr::statements::alter::AlterKind::Set(None),
51				AlterKind::None => crate::expr::statements::alter::AlterKind::None,
52			},
53			session_duration: match v.session_duration {
54				AlterKind::Set(d) => crate::expr::statements::alter::AlterKind::Set(Some(d)),
55				AlterKind::Drop => crate::expr::statements::alter::AlterKind::Set(None),
56				AlterKind::None => crate::expr::statements::alter::AlterKind::None,
57			},
58			comment: v.comment.into(),
59		}
60	}
61}
62
63impl From<crate::expr::statements::alter::AlterUserStatement> for AlterUserStatement {
64	fn from(v: crate::expr::statements::alter::AlterUserStatement) -> Self {
65		AlterUserStatement {
66			name: v.name.into(),
67			base: v.base.into(),
68			if_exists: v.if_exists,
69			pass_type: v.hash.map(PassType::Hash),
70			// A cleared verifier (`Some(None)`) has no SQL representation; the
71			// accompanying PASSHASH already conveys the password change.
72			scram: v.scram.flatten().map(|c| c.to_verifier_string()),
73			roles: match v.roles {
74				crate::expr::statements::alter::AlterKind::Set(x) => AlterKind::Set(x),
75				crate::expr::statements::alter::AlterKind::Drop => AlterKind::Drop,
76				crate::expr::statements::alter::AlterKind::None => AlterKind::None,
77			},
78			token_duration: match v.token_duration {
79				crate::expr::statements::alter::AlterKind::Set(Some(d)) => AlterKind::Set(d),
80				crate::expr::statements::alter::AlterKind::Set(None) => AlterKind::Drop,
81				crate::expr::statements::alter::AlterKind::Drop => AlterKind::Drop,
82				crate::expr::statements::alter::AlterKind::None => AlterKind::None,
83			},
84			session_duration: match v.session_duration {
85				crate::expr::statements::alter::AlterKind::Set(Some(d)) => AlterKind::Set(d),
86				crate::expr::statements::alter::AlterKind::Set(None) => AlterKind::Drop,
87				crate::expr::statements::alter::AlterKind::Drop => AlterKind::Drop,
88				crate::expr::statements::alter::AlterKind::None => AlterKind::None,
89			},
90			comment: v.comment.into(),
91		}
92	}
93}