Skip to main content

surrealdb_expr/expr/
access_type.rs

1use crate::expr::statements::DefineAccessStatement;
2use crate::expr::{Algorithm, Expr, Literal};
3
4/// The type of access methods available
5
6#[derive(Debug, Hash, Clone, Eq, PartialEq)]
7pub enum AccessType {
8	Record(Box<RecordAccess>),
9	Jwt(JwtAccess),
10	Bearer(BearerAccess),
11}
12
13impl Default for AccessType {
14	fn default() -> Self {
15		// Access type defaults to the most specific
16		Self::Record(Box::new(RecordAccess {
17			..Default::default()
18		}))
19	}
20}
21
22impl AccessType {
23	/// Returns whether or not the access method can issue non-token grants
24	/// In this context, token refers exclusively to JWT
25	#[allow(dead_code)]
26	pub fn can_issue_grants(&self) -> bool {
27		match self {
28			// The JWT access method cannot issue stateful grants.
29			AccessType::Jwt(_) => false,
30			// The record access method can be used to issue grants if defined with bearer AKA
31			// refresh.
32			AccessType::Record(ac) => ac.bearer.is_some(),
33			AccessType::Bearer(_) => true,
34		}
35	}
36	/// Returns whether or not the access method can issue tokens
37	/// In this context, tokens refers exclusively to JWT
38	#[allow(dead_code)]
39	pub fn can_issue_tokens(&self) -> bool {
40		match self {
41			// The JWT access method can only issue tokens if an issuer is set
42			AccessType::Jwt(jwt) => jwt.issue.is_some(),
43			_ => true,
44		}
45	}
46}
47
48#[derive(Debug, Hash, Clone, Eq, PartialEq)]
49pub struct JwtAccess {
50	// Verify is required
51	pub verify: JwtAccessVerify,
52	// Issue is optional
53	// It is possible to only verify externally issued tokens
54	pub issue: Option<JwtAccessIssue>,
55	/// Accepted values for the token `aud` claim. When set, verification
56	/// requires the claim to be present and to intersect this list.
57	pub audience: Option<Vec<Expr>>,
58}
59
60impl Default for JwtAccess {
61	fn default() -> Self {
62		// Defaults to HS512 with a randomly generated key
63		let alg = Algorithm::Hs512;
64		let key = DefineAccessStatement::random_key();
65		// By default the access method can verify and issue tokens
66		Self {
67			verify: JwtAccessVerify::Key(JwtAccessVerifyKey {
68				alg,
69				key: Expr::Literal(Literal::String(key.clone().into())),
70			}),
71			issue: Some(JwtAccessIssue {
72				alg,
73				key: Expr::Literal(Literal::String(key.into())),
74			}),
75			audience: None,
76		}
77	}
78}
79
80#[derive(Debug, Hash, Clone, Eq, PartialEq)]
81pub struct JwtAccessIssue {
82	pub alg: Algorithm,
83	pub key: Expr,
84}
85
86impl Default for JwtAccessIssue {
87	fn default() -> Self {
88		Self {
89			// Defaults to HS512
90			alg: Algorithm::Hs512,
91			// Avoid defaulting to empty key
92			key: Expr::Literal(Literal::String(DefineAccessStatement::random_key().into())),
93		}
94	}
95}
96
97#[derive(Debug, Hash, Clone, Eq, PartialEq)]
98pub enum JwtAccessVerify {
99	Key(JwtAccessVerifyKey),
100	Jwks(JwtAccessVerifyJwks),
101}
102
103impl Default for JwtAccessVerify {
104	fn default() -> Self {
105		Self::Key(JwtAccessVerifyKey {
106			..Default::default()
107		})
108	}
109}
110#[derive(Debug, Hash, Clone, Eq, PartialEq)]
111pub struct JwtAccessVerifyKey {
112	pub alg: Algorithm,
113	pub key: Expr,
114}
115
116impl Default for JwtAccessVerifyKey {
117	fn default() -> Self {
118		Self {
119			// Defaults to HS512
120			alg: Algorithm::Hs512,
121			// Avoid defaulting to empty key
122			key: Expr::Literal(Literal::String(DefineAccessStatement::random_key().into())),
123		}
124	}
125}
126
127#[derive(Debug, Hash, Clone, Eq, PartialEq)]
128pub struct JwtAccessVerifyJwks {
129	pub url: Expr,
130}
131
132#[derive(Debug, Hash, Clone, Eq, PartialEq)]
133pub struct RecordAccess {
134	pub signup: Option<Expr>,
135	pub signin: Option<Expr>,
136	pub jwt: JwtAccess,
137	pub bearer: Option<BearerAccess>,
138}
139
140impl Default for RecordAccess {
141	fn default() -> Self {
142		Self {
143			signup: None,
144			signin: None,
145			jwt: JwtAccess {
146				..Default::default()
147			},
148			bearer: None,
149		}
150	}
151}
152
153#[derive(Debug, Hash, Clone, Eq, PartialEq)]
154pub struct BearerAccess {
155	pub kind: BearerAccessType,
156	pub subject: BearerAccessSubject,
157	pub jwt: JwtAccess,
158}
159
160impl Default for BearerAccess {
161	fn default() -> Self {
162		Self {
163			kind: BearerAccessType::Bearer,
164			subject: BearerAccessSubject::User,
165			jwt: JwtAccess {
166				..Default::default()
167			},
168		}
169	}
170}
171
172#[derive(Debug, Hash, Clone, Eq, PartialEq)]
173pub enum BearerAccessType {
174	Bearer,
175	Refresh,
176}
177
178impl BearerAccessType {
179	/// The grant-key prefix for this access type.
180	pub fn prefix(&self) -> &'static str {
181		match self {
182			Self::Bearer => "surreal-bearer",
183			Self::Refresh => "surreal-refresh",
184		}
185	}
186}
187
188#[derive(Debug, Hash, Clone, Eq, PartialEq)]
189pub enum BearerAccessSubject {
190	Record,
191	User,
192}