surrealdb_core/sql/statements/remove/
access.rs

1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::err::Error;
4use crate::iam::{Action, ResourceKind};
5use crate::sql::{Base, Ident, Value};
6
7use revision::revisioned;
8use serde::{Deserialize, Serialize};
9use std::fmt::{self, Display, Formatter};
10
11#[revisioned(revision = 2)]
12#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
13#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
14#[non_exhaustive]
15pub struct RemoveAccessStatement {
16	pub name: Ident,
17	pub base: Base,
18	#[revision(start = 2)]
19	pub if_exists: bool,
20}
21
22impl RemoveAccessStatement {
23	/// Process this type returning a computed simple Value
24	pub(crate) async fn compute(&self, ctx: &Context, opt: &Options) -> Result<Value, Error> {
25		let future = async {
26			// Allowed to run?
27			opt.is_allowed(Action::Edit, ResourceKind::Actor, &self.base)?;
28			// Check the statement type
29			match &self.base {
30				Base::Root => {
31					// Get the transaction
32					let txn = ctx.tx();
33					// Get the definition
34					let ac = txn.get_root_access(&self.name).await?;
35					// Delete the definition
36					let key = crate::key::root::ac::new(&ac.name);
37					txn.del(key).await?;
38					// Delete any associated data including access grants.
39					let key = crate::key::root::access::all::new(&ac.name);
40					txn.delp(key).await?;
41					// Clear the cache
42					txn.clear();
43					// Ok all good
44					Ok(Value::None)
45				}
46				Base::Ns => {
47					// Get the transaction
48					let txn = ctx.tx();
49					// Get the definition
50					let ac = txn.get_ns_access(opt.ns()?, &self.name).await?;
51					// Delete the definition
52					let key = crate::key::namespace::ac::new(opt.ns()?, &ac.name);
53					txn.del(key).await?;
54					// Delete any associated data including access grants.
55					let key = crate::key::namespace::access::all::new(opt.ns()?, &ac.name);
56					txn.delp(key).await?;
57					// Clear the cache
58					txn.clear();
59					// Ok all good
60					Ok(Value::None)
61				}
62				Base::Db => {
63					// Get the transaction
64					let txn = ctx.tx();
65					// Get the definition
66					let (ns, db) = opt.ns_db()?;
67					let ac = txn.get_db_access(ns, db, &self.name).await?;
68					// Delete the definition
69					let key = crate::key::database::ac::new(ns, db, &ac.name);
70					txn.del(key).await?;
71					// Delete any associated data including access grants.
72					let key = crate::key::database::access::all::new(ns, db, &ac.name);
73					txn.delp(key).await?;
74					// Clear the cache
75					txn.clear();
76					// Ok all good
77					Ok(Value::None)
78				}
79				_ => Err(Error::InvalidLevel(self.base.to_string())),
80			}
81		}
82		.await;
83		match future {
84			Err(e) if self.if_exists => match e {
85				Error::AccessRootNotFound {
86					..
87				} => Ok(Value::None),
88				Error::AccessNsNotFound {
89					..
90				} => Ok(Value::None),
91				Error::AccessDbNotFound {
92					..
93				} => Ok(Value::None),
94				e => Err(e),
95			},
96			v => v,
97		}
98	}
99}
100
101impl Display for RemoveAccessStatement {
102	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
103		write!(f, "REMOVE ACCESS")?;
104		if self.if_exists {
105			write!(f, " IF EXISTS")?
106		}
107		write!(f, " {} ON {}", self.name, self.base)?;
108		Ok(())
109	}
110}