surrealdb/iam/
auth.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use crate::sql::statements::{DefineTokenStatement, DefineUserStatement};
use revision::revisioned;
use serde::{Deserialize, Serialize};

use super::{is_allowed, Action, Actor, Error, Level, Resource, Role};

/// Specifies the current authentication for the datastore execution context.
#[derive(Clone, Default, Debug, Eq, PartialEq, PartialOrd, Hash, Serialize, Deserialize)]
#[revisioned(revision = 1)]
pub struct Auth {
	actor: Actor,
}

impl Auth {
	pub fn new(actor: Actor) -> Self {
		Self {
			actor,
		}
	}

	pub fn id(&self) -> &str {
		self.actor.id()
	}

	/// Return current authentication level
	pub fn level(&self) -> &Level {
		self.actor.level()
	}

	/// Check if the current auth is anonymous
	pub fn is_anon(&self) -> bool {
		matches!(self.level(), Level::No)
	}

	/// Check if the current level is Root
	pub fn is_root(&self) -> bool {
		matches!(self.level(), Level::Root)
	}

	/// Check if the current level is Namespace
	pub fn is_ns(&self) -> bool {
		matches!(self.level(), Level::Namespace(_))
	}

	/// Check if the current level is Database
	pub fn is_db(&self) -> bool {
		matches!(self.level(), Level::Database(_, _))
	}

	/// Check if the current level is Scope
	pub fn is_scope(&self) -> bool {
		matches!(self.level(), Level::Scope(_, _, _))
	}

	/// System Auth helpers
	///
	/// These are not stored in the database and are used for internal operations
	/// Do not use for authentication
	pub fn for_root(role: Role) -> Self {
		Self::new(Actor::new("system_auth".into(), vec![role], Level::Root))
	}

	pub fn for_ns(role: Role, ns: &str) -> Self {
		Self::new(Actor::new("system_auth".into(), vec![role], (ns,).into()))
	}

	pub fn for_db(role: Role, ns: &str, db: &str) -> Self {
		Self::new(Actor::new("system_auth".into(), vec![role], (ns, db).into()))
	}

	pub fn for_sc(rid: String, ns: &str, db: &str, sc: &str) -> Self {
		Self::new(Actor::new(rid, vec![], (ns, db, sc).into()))
	}

	//
	// Permission checks
	//

	/// Checks if the current auth is allowed to perform an action on a given resource
	pub fn is_allowed(&self, action: Action, res: &Resource) -> Result<(), Error> {
		is_allowed(&self.actor, &action, res, None)
	}

	/// Checks if the current actor has a given role
	pub fn has_role(&self, role: &Role) -> bool {
		self.actor.has_role(role)
	}
}

impl std::convert::From<(&DefineUserStatement, Level)> for Auth {
	fn from(val: (&DefineUserStatement, Level)) -> Self {
		Self::new((val.0, val.1).into())
	}
}

impl std::convert::From<(&DefineTokenStatement, Level)> for Auth {
	fn from(val: (&DefineTokenStatement, Level)) -> Self {
		Self::new((val.0, val.1).into())
	}
}