surrealdb_core/dbs/
session.rs1use crate::ctx::MutableContext;
2use crate::iam::Auth;
3use crate::iam::{Level, Role};
4use crate::sql::value::Value;
5use chrono::Utc;
6use std::collections::BTreeMap;
7use std::sync::Arc;
8
9#[derive(Clone, Debug, Default, Eq, PartialEq)]
11#[non_exhaustive]
12pub struct Session {
13 pub au: Arc<Auth>,
15 pub rt: bool,
17 pub ip: Option<String>,
19 pub or: Option<String>,
21 pub id: Option<String>,
23 pub ns: Option<String>,
25 pub db: Option<String>,
27 pub ac: Option<String>,
29 pub tk: Option<Value>,
31 pub rd: Option<Value>,
33 pub exp: Option<i64>,
35 pub parameters: BTreeMap<String, Value>,
37}
38
39impl Session {
40 pub fn with_ns(mut self, ns: &str) -> Session {
42 self.ns = Some(ns.to_owned());
43 self
44 }
45
46 pub fn with_db(mut self, db: &str) -> Session {
48 self.db = Some(db.to_owned());
49 self
50 }
51
52 pub fn with_ac(mut self, ac: &str) -> Session {
54 self.ac = Some(ac.to_owned());
55 self
56 }
57
58 pub fn with_rt(mut self, rt: bool) -> Session {
60 self.rt = rt;
61 self
62 }
63
64 pub(crate) fn ns(&self) -> Option<Arc<str>> {
66 self.ns.as_deref().map(Into::into)
67 }
68
69 pub(crate) fn db(&self) -> Option<Arc<str>> {
71 self.db.as_deref().map(Into::into)
72 }
73
74 pub(crate) fn live(&self) -> bool {
76 self.rt
77 }
78
79 pub(crate) fn expired(&self) -> bool {
81 match self.exp {
82 Some(exp) => Utc::now().timestamp() > exp,
83 None => false,
85 }
86 }
87
88 pub(crate) fn values(&self) -> Vec<(&'static str, Value)> {
89 let access: Value = self.ac.to_owned().into();
90 let auth: Value = self.rd.to_owned().into();
91 let token: Value = self.tk.to_owned().into();
92 let session: Value = Value::from(map! {
93 "ac".to_string() => self.ac.to_owned().into(),
94 "exp".to_string() => self.exp.to_owned().into(),
95 "db".to_string() => self.db.to_owned().into(),
96 "id".to_string() => self.id.to_owned().into(),
97 "ip".to_string() => self.ip.to_owned().into(),
98 "ns".to_string() => self.ns.to_owned().into(),
99 "or".to_string() => self.or.to_owned().into(),
100 "rd".to_string() => self.rd.to_owned().into(),
101 "tk".to_string() => self.tk.to_owned().into(),
102 });
103
104 vec![("access", access), ("auth", auth), ("token", token), ("session", session)]
105 }
106
107 pub(crate) fn context(&self, ctx: &mut MutableContext) {
109 let vars = self.values().into_iter();
110
111 ctx.add_values(vars);
112 }
113
114 pub fn for_level(level: Level, role: Role) -> Session {
116 let mut sess = Session::default();
118 match level {
120 Level::Root => {
121 sess.au = Arc::new(Auth::for_root(role));
122 }
123 Level::Namespace(ns) => {
124 sess.au = Arc::new(Auth::for_ns(role, &ns));
125 sess.ns = Some(ns);
126 }
127 Level::Database(ns, db) => {
128 sess.au = Arc::new(Auth::for_db(role, &ns, &db));
129 sess.ns = Some(ns);
130 sess.db = Some(db);
131 }
132 _ => {}
133 }
134 sess
135 }
136
137 pub fn for_record(ns: &str, db: &str, ac: &str, rid: Value) -> Session {
139 Session {
140 ac: Some(ac.to_owned()),
141 au: Arc::new(Auth::for_record(rid.to_string(), ns, db, ac)),
142 rt: false,
143 ip: None,
144 or: None,
145 id: None,
146 ns: Some(ns.to_owned()),
147 db: Some(db.to_owned()),
148 tk: None,
149 rd: Some(rid),
150 exp: None,
151 parameters: Default::default(),
152 }
153 }
154
155 pub fn owner() -> Session {
157 Session::for_level(Level::Root, Role::Owner)
158 }
159
160 pub fn editor() -> Session {
162 Session::for_level(Level::Root, Role::Editor)
163 }
164
165 pub fn viewer() -> Session {
167 Session::for_level(Level::Root, Role::Viewer)
168 }
169}