surrealdb_core/iam/
auth.rs1use crate::sql::statements::{DefineAccessStatement, DefineUserStatement};
2use revision::revisioned;
3use serde::{Deserialize, Serialize};
4
5use super::{is_allowed, Action, Actor, Error, Level, Resource, Role};
6
7#[revisioned(revision = 1)]
9#[derive(Clone, Default, Debug, Eq, PartialEq, PartialOrd, Hash, Serialize, Deserialize)]
10#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
11#[non_exhaustive]
12pub struct Auth {
13 actor: Actor,
14}
15
16impl Auth {
17 pub fn new(actor: Actor) -> Self {
18 Self {
19 actor,
20 }
21 }
22
23 pub fn id(&self) -> &str {
24 self.actor.id()
25 }
26
27 pub fn level(&self) -> &Level {
29 self.actor.level()
30 }
31
32 pub fn is_anon(&self) -> bool {
34 matches!(self.level(), Level::No)
35 }
36
37 pub fn is_root(&self) -> bool {
39 matches!(self.level(), Level::Root)
40 }
41
42 pub fn is_ns(&self) -> bool {
44 matches!(self.level(), Level::Namespace(_))
45 }
46
47 pub fn is_db(&self) -> bool {
49 matches!(self.level(), Level::Database(_, _))
50 }
51
52 pub fn is_record(&self) -> bool {
54 matches!(self.level(), Level::Record(_, _, _))
55 }
56
57 pub fn is_ns_check(&self, ns: &str) -> bool {
59 matches!(self.level(), Level::Namespace(n) if n.eq(ns))
60 }
61
62 pub fn is_db_check(&self, ns: &str, db: &str) -> bool {
64 matches!(self.level(), Level::Database(n, d) if n.eq(ns) && d.eq(db))
65 }
66
67 pub fn for_root(role: Role) -> Self {
72 Self::new(Actor::new("system_auth".into(), vec![role], Level::Root))
73 }
74
75 pub fn for_ns(role: Role, ns: &str) -> Self {
76 Self::new(Actor::new("system_auth".into(), vec![role], (ns,).into()))
77 }
78
79 pub fn for_db(role: Role, ns: &str, db: &str) -> Self {
80 Self::new(Actor::new("system_auth".into(), vec![role], (ns, db).into()))
81 }
82
83 pub fn for_record(rid: String, ns: &str, db: &str, ac: &str) -> Self {
84 Self::new(Actor::new(rid.to_string(), vec![], (ns, db, ac).into()))
85 }
86
87 pub fn is_allowed(&self, action: Action, res: &Resource) -> Result<(), Error> {
93 is_allowed(&self.actor, &action, res, None)
94 }
95
96 pub fn has_role(&self, role: Role) -> bool {
98 self.actor.has_role(role)
99 }
100
101 pub fn has_owner_role(&self) -> bool {
103 self.actor.has_owner_role()
104 }
105
106 pub fn has_editor_role(&self) -> bool {
108 self.actor.has_editor_role()
109 }
110
111 pub fn has_viewer_role(&self) -> bool {
113 self.actor.has_viewer_role()
114 }
115}
116
117impl std::convert::TryFrom<(&DefineUserStatement, Level)> for Auth {
118 type Error = Error;
119 fn try_from(val: (&DefineUserStatement, Level)) -> Result<Self, Self::Error> {
120 Ok(Self::new((val.0, val.1).try_into()?))
121 }
122}
123
124impl std::convert::From<(&DefineAccessStatement, Level)> for Auth {
125 fn from(val: (&DefineAccessStatement, Level)) -> Self {
126 Self::new((val.0, val.1).into())
127 }
128}