Ensure scope SIGNUP
and SIGNIN
works with guest access disabled (#2663)
This commit is contained in:
parent
b83b9d3e3e
commit
9f33d5dc27
3 changed files with 78 additions and 9 deletions
|
@ -116,9 +116,9 @@ pub async fn sc(
|
|||
// Setup the query params
|
||||
let vars = Some(vars.0);
|
||||
// Setup the system session for finding the signin record
|
||||
let sess = Session::viewer().with_ns(&ns).with_db(&db);
|
||||
let sess = Session::editor().with_ns(&ns).with_db(&db);
|
||||
// Compute the value with the params
|
||||
match kvs.compute(val, &sess, vars).await {
|
||||
match kvs.evaluate(val, &sess, vars).await {
|
||||
// The signin value succeeded
|
||||
Ok(val) => match val.record() {
|
||||
// There is a record returned
|
||||
|
|
|
@ -59,7 +59,7 @@ pub async fn sc(
|
|||
// Setup the system session for creating the signup record
|
||||
let sess = Session::editor().with_ns(&ns).with_db(&db);
|
||||
// Compute the value with the params
|
||||
match kvs.compute(val, &sess, vars).await {
|
||||
match kvs.evaluate(val, &sess, vars).await {
|
||||
// The signin value succeeded
|
||||
Ok(val) => match val.record() {
|
||||
// There is a record returned
|
||||
|
|
|
@ -787,7 +787,7 @@ impl Datastore {
|
|||
vars: Variables,
|
||||
) -> Result<Vec<Response>, Error> {
|
||||
// Check if anonymous actors can execute queries when auth is enabled
|
||||
// TODO(sgirones): Check this as part of the authoritzation layer
|
||||
// TODO(sgirones): Check this as part of the authorisation layer
|
||||
if self.auth_enabled && sess.au.is_anon() && !self.capabilities.allows_guest_access() {
|
||||
return Err(IamError::NotAllowed {
|
||||
actor: "anonymous".to_string(),
|
||||
|
@ -803,8 +803,8 @@ impl Datastore {
|
|||
.with_db(sess.db())
|
||||
.with_live(sess.live())
|
||||
.with_auth(sess.au.clone())
|
||||
.with_auth_enabled(self.auth_enabled)
|
||||
.with_strict(self.strict);
|
||||
.with_strict(self.strict)
|
||||
.with_auth_enabled(self.auth_enabled);
|
||||
// Create a new query executor
|
||||
let mut exe = Executor::new(self);
|
||||
// Create a default context
|
||||
|
@ -852,7 +852,7 @@ impl Datastore {
|
|||
vars: Variables,
|
||||
) -> Result<Value, Error> {
|
||||
// Check if anonymous actors can compute values when auth is enabled
|
||||
// TODO(sgirones): Check this as part of the authoritzation layer
|
||||
// TODO(sgirones): Check this as part of the authorisation layer
|
||||
if self.auth_enabled && !self.capabilities.allows_guest_access() {
|
||||
return Err(IamError::NotAllowed {
|
||||
actor: "anonymous".to_string(),
|
||||
|
@ -868,8 +868,77 @@ impl Datastore {
|
|||
.with_db(sess.db())
|
||||
.with_live(sess.live())
|
||||
.with_auth(sess.au.clone())
|
||||
.with_auth_enabled(self.auth_enabled)
|
||||
.with_strict(self.strict);
|
||||
.with_strict(self.strict)
|
||||
.with_auth_enabled(self.auth_enabled);
|
||||
// Create a default context
|
||||
let mut ctx = Context::default();
|
||||
// Set context capabilities
|
||||
ctx.add_capabilities(self.capabilities.clone());
|
||||
// Set the global query timeout
|
||||
if let Some(timeout) = self.query_timeout {
|
||||
ctx.add_timeout(timeout);
|
||||
}
|
||||
// Setup the notification channel
|
||||
if let Some(channel) = &self.notification_channel {
|
||||
ctx.add_notifications(Some(&channel.0));
|
||||
}
|
||||
// Start an execution context
|
||||
let ctx = sess.context(ctx);
|
||||
// Store the query variables
|
||||
let ctx = vars.attach(ctx)?;
|
||||
// Start a new transaction
|
||||
let txn = self.transaction(val.writeable(), false).await?.enclose();
|
||||
// Compute the value
|
||||
let res = val.compute(&ctx, &opt, &txn, None).await;
|
||||
// Store any data
|
||||
match (res.is_ok(), val.writeable()) {
|
||||
// If the compute was successful, then commit if writeable
|
||||
(true, true) => txn.lock().await.commit().await?,
|
||||
// Cancel if the compute was an error, or if readonly
|
||||
(_, _) => txn.lock().await.cancel().await?,
|
||||
};
|
||||
// Return result
|
||||
res
|
||||
}
|
||||
|
||||
/// Evaluates a SQL [`Value`] without checking authenticating config
|
||||
/// This is used in very specific cases, where we do not need to check
|
||||
/// whether authentication is enabled, or guest access is disabled.
|
||||
/// For example, this is used when processing a SCOPE SIGNUP or SCOPE
|
||||
/// SIGNIN clause, which still needs to work without guest access.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use surrealdb::kvs::Datastore;
|
||||
/// use surrealdb::err::Error;
|
||||
/// use surrealdb::dbs::Session;
|
||||
/// use surrealdb::sql::Future;
|
||||
/// use surrealdb::sql::Value;
|
||||
///
|
||||
/// #[tokio::main]
|
||||
/// async fn main() -> Result<(), Error> {
|
||||
/// let ds = Datastore::new("memory").await?;
|
||||
/// let ses = Session::owner();
|
||||
/// let val = Value::Future(Box::new(Future::from(Value::Bool(true))));
|
||||
/// let res = ds.evaluate(val, &ses, None).await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[instrument(level = "debug", skip_all)]
|
||||
pub async fn evaluate(
|
||||
&self,
|
||||
val: Value,
|
||||
sess: &Session,
|
||||
vars: Variables,
|
||||
) -> Result<Value, Error> {
|
||||
// Create a new query options
|
||||
let opt = Options::default()
|
||||
.with_id(self.id.0)
|
||||
.with_ns(sess.ns())
|
||||
.with_db(sess.db())
|
||||
.with_live(sess.live())
|
||||
.with_auth(sess.au.clone())
|
||||
.with_strict(self.strict)
|
||||
.with_auth_enabled(self.auth_enabled);
|
||||
// Create a default context
|
||||
let mut ctx = Context::default();
|
||||
// Set context capabilities
|
||||
|
|
Loading…
Reference in a new issue