Skip to main content

surrealdb_expr/expr/statements/define/
access.rs

1use rand::distr::{Alphanumeric, SampleString};
2use surrealdb_strand::Strand;
3use surrealdb_types::{SqlFormat, ToSql};
4
5use super::DefineKind;
6use crate::expr::access::AccessDuration;
7use crate::expr::access_type::JwtAccessVerify;
8use crate::expr::{AccessType, Base, Expr, JwtAccess, Literal};
9
10#[derive(Clone, Debug, Eq, PartialEq, Hash)]
11pub struct DefineAccessStatement {
12	pub kind: DefineKind,
13	pub name: Expr,
14	pub base: Base,
15	pub access_type: AccessType,
16	pub authenticate: Option<Expr>,
17	pub context: Option<Expr>,
18	pub duration: AccessDuration,
19	pub comment: Expr,
20}
21
22impl Default for DefineAccessStatement {
23	fn default() -> Self {
24		Self {
25			kind: DefineKind::Default,
26			name: Expr::Literal(Literal::None),
27			base: Base::Root,
28			access_type: AccessType::default(),
29			authenticate: None,
30			context: None,
31			duration: AccessDuration::default(),
32			comment: Expr::Literal(Literal::None),
33		}
34	}
35}
36
37impl DefineAccessStatement {
38	/// Generate a random key to be used to sign session tokens
39	/// This key will be used to sign tokens issued with this access method
40	/// This value is used by default in every access method other than JWT
41	pub fn random_key() -> String {
42		Alphanumeric.sample_string(&mut rand::rng(), 128)
43	}
44}
45
46impl DefineAccessStatement {
47	/// Remove information from the access definition which should not be displayed.
48	pub fn redact(mut self) -> Self {
49		fn redact_jwt_access(acc: &mut JwtAccess) {
50			if let JwtAccessVerify::Key(ref mut v) = acc.verify
51				&& v.alg.is_symmetric()
52			{
53				v.key = Expr::Literal(Literal::String(Strand::new_static("[REDACTED]")));
54			}
55			if let Some(ref mut s) = acc.issue {
56				s.key = Expr::Literal(Literal::String(Strand::new_static("[REDACTED]")));
57			}
58		}
59
60		match self.access_type {
61			AccessType::Jwt(ref mut key) => {
62				redact_jwt_access(key);
63			}
64			AccessType::Bearer(ref mut b) => {
65				redact_jwt_access(&mut b.jwt);
66			}
67			AccessType::Record(ref mut r) => {
68				redact_jwt_access(&mut r.jwt);
69				if let Some(ref mut b) = r.bearer {
70					redact_jwt_access(&mut b.jwt);
71				}
72			}
73		}
74		self
75	}
76}
77
78impl ToSql for DefineAccessStatement {
79	fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
80		let stmt: crate::sql::statements::define::DefineAccessStatement = self.clone().into();
81		stmt.fmt_sql(f, fmt);
82	}
83}