2023-11-20 14:54:27 +00:00
|
|
|
use crate::cnf::{INSECURE_FORWARD_SCOPE_ERRORS, SERVER_NAME};
|
2023-06-09 13:45:07 +00:00
|
|
|
use crate::dbs::Session;
|
2022-07-04 00:01:24 +00:00
|
|
|
use crate::err::Error;
|
|
|
|
use crate::iam::token::{Claims, HEADER};
|
2023-07-29 18:47:25 +00:00
|
|
|
use crate::iam::Auth;
|
|
|
|
use crate::iam::{Actor, Level};
|
2023-09-26 13:02:53 +00:00
|
|
|
use crate::kvs::{Datastore, LockType::*, TransactionType::*};
|
2023-06-09 13:45:07 +00:00
|
|
|
use crate::sql::Object;
|
|
|
|
use crate::sql::Value;
|
2022-07-04 00:01:24 +00:00
|
|
|
use chrono::{Duration, Utc};
|
|
|
|
use jsonwebtoken::{encode, EncodingKey};
|
2022-08-23 22:44:13 +00:00
|
|
|
use std::sync::Arc;
|
2024-03-12 11:03:27 +00:00
|
|
|
use uuid::Uuid;
|
2022-07-04 00:01:24 +00:00
|
|
|
|
2023-06-09 13:45:07 +00:00
|
|
|
pub async fn signup(
|
|
|
|
kvs: &Datastore,
|
|
|
|
session: &mut Session,
|
|
|
|
vars: Object,
|
|
|
|
) -> Result<Option<String>, Error> {
|
2022-08-21 12:13:38 +00:00
|
|
|
// Parse the specified variables
|
2022-07-04 00:01:24 +00:00
|
|
|
let ns = vars.get("NS").or_else(|| vars.get("ns"));
|
|
|
|
let db = vars.get("DB").or_else(|| vars.get("db"));
|
|
|
|
let sc = vars.get("SC").or_else(|| vars.get("sc"));
|
2022-08-21 12:13:38 +00:00
|
|
|
// Check if the parameters exist
|
2022-07-04 00:01:24 +00:00
|
|
|
match (ns, db, sc) {
|
|
|
|
(Some(ns), Some(db), Some(sc)) => {
|
|
|
|
// Process the provided values
|
2023-04-25 10:13:04 +00:00
|
|
|
let ns = ns.to_raw_string();
|
|
|
|
let db = db.to_raw_string();
|
|
|
|
let sc = sc.to_raw_string();
|
2023-07-29 18:47:25 +00:00
|
|
|
// Attempt to signup to specified scope
|
2023-07-05 21:26:13 +00:00
|
|
|
super::signup::sc(kvs, session, ns, db, sc, vars).await
|
2022-07-04 00:01:24 +00:00
|
|
|
}
|
2023-09-08 13:27:38 +00:00
|
|
|
_ => Err(Error::InvalidSignup),
|
2022-07-04 00:01:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-23 22:44:13 +00:00
|
|
|
pub async fn sc(
|
2023-06-09 13:45:07 +00:00
|
|
|
kvs: &Datastore,
|
2022-08-23 22:44:13 +00:00
|
|
|
session: &mut Session,
|
|
|
|
ns: String,
|
|
|
|
db: String,
|
|
|
|
sc: String,
|
|
|
|
vars: Object,
|
2023-02-11 15:56:14 +00:00
|
|
|
) -> Result<Option<String>, Error> {
|
2022-07-04 00:01:24 +00:00
|
|
|
// Create a new readonly transaction
|
2023-09-26 13:02:53 +00:00
|
|
|
let mut tx = kvs.transaction(Read, Optimistic).await?;
|
2023-09-02 21:22:41 +00:00
|
|
|
// Fetch the specified scope from storage
|
|
|
|
let scope = tx.get_sc(&ns, &db, &sc).await;
|
|
|
|
// Ensure that the transaction is cancelled
|
|
|
|
tx.cancel().await?;
|
2023-07-29 18:47:25 +00:00
|
|
|
// Check if the supplied Scope login exists
|
2023-09-02 21:22:41 +00:00
|
|
|
match scope {
|
2022-07-04 00:01:24 +00:00
|
|
|
Ok(sv) => {
|
|
|
|
match sv.signup {
|
2023-07-29 18:47:25 +00:00
|
|
|
// This scope allows signup
|
2022-07-04 00:01:24 +00:00
|
|
|
Some(val) => {
|
|
|
|
// Setup the query params
|
|
|
|
let vars = Some(vars.0);
|
2023-07-29 18:47:25 +00:00
|
|
|
// Setup the system session for creating the signup record
|
2023-11-17 21:33:11 +00:00
|
|
|
let mut sess = Session::editor().with_ns(&ns).with_db(&db);
|
|
|
|
sess.ip = session.ip.clone();
|
|
|
|
sess.or = session.or.clone();
|
2022-07-04 00:01:24 +00:00
|
|
|
// Compute the value with the params
|
2023-09-10 10:41:28 +00:00
|
|
|
match kvs.evaluate(val, &sess, vars).await {
|
2022-07-04 00:01:24 +00:00
|
|
|
// The signin value succeeded
|
2022-09-19 11:28:41 +00:00
|
|
|
Ok(val) => match val.record() {
|
2022-07-04 00:01:24 +00:00
|
|
|
// There is a record returned
|
|
|
|
Some(rid) => {
|
|
|
|
// Create the authentication key
|
|
|
|
let key = EncodingKey::from_secret(sv.code.as_ref());
|
|
|
|
// Create the authentication claim
|
2024-03-13 09:06:16 +00:00
|
|
|
let exp = Some(
|
|
|
|
match sv.session {
|
|
|
|
Some(v) => {
|
|
|
|
// The defined session duration must be valid
|
|
|
|
match Duration::from_std(v.0) {
|
|
|
|
// The resulting session expiration must be valid
|
|
|
|
Ok(d) => match Utc::now().checked_add_signed(d) {
|
|
|
|
Some(exp) => exp,
|
|
|
|
None => {
|
|
|
|
return Err(Error::InvalidSessionExpiration)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(_) => {
|
|
|
|
return Err(Error::InvalidSessionDuration)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => Utc::now() + Duration::hours(1),
|
|
|
|
}
|
|
|
|
.timestamp(),
|
|
|
|
);
|
2022-07-04 00:01:24 +00:00
|
|
|
let val = Claims {
|
2022-09-27 21:07:41 +00:00
|
|
|
iss: Some(SERVER_NAME.to_owned()),
|
|
|
|
iat: Some(Utc::now().timestamp()),
|
|
|
|
nbf: Some(Utc::now().timestamp()),
|
2024-03-12 11:03:27 +00:00
|
|
|
jti: Some(Uuid::new_v4().to_string()),
|
2024-03-13 09:06:16 +00:00
|
|
|
exp,
|
2022-08-23 22:44:13 +00:00
|
|
|
ns: Some(ns.to_owned()),
|
|
|
|
db: Some(db.to_owned()),
|
|
|
|
sc: Some(sc.to_owned()),
|
2022-07-04 00:01:24 +00:00
|
|
|
id: Some(rid.to_raw()),
|
|
|
|
..Claims::default()
|
|
|
|
};
|
2023-09-10 10:58:50 +00:00
|
|
|
// Log the authenticated scope info
|
|
|
|
trace!("Signing up to scope `{}`", sc);
|
2022-09-17 01:52:07 +00:00
|
|
|
// Create the authentication token
|
2022-11-23 09:09:24 +00:00
|
|
|
let enc = encode(&HEADER, &val, &key);
|
2022-09-17 01:50:10 +00:00
|
|
|
// Set the authentication on the session
|
2022-09-17 01:52:07 +00:00
|
|
|
session.tk = Some(val.into());
|
2022-09-04 23:53:35 +00:00
|
|
|
session.ns = Some(ns.to_owned());
|
|
|
|
session.db = Some(db.to_owned());
|
|
|
|
session.sc = Some(sc.to_owned());
|
2023-07-29 18:47:25 +00:00
|
|
|
session.sd = Some(Value::from(rid.to_owned()));
|
2024-03-13 09:06:16 +00:00
|
|
|
session.exp = exp;
|
2023-07-29 18:47:25 +00:00
|
|
|
session.au = Arc::new(Auth::new(Actor::new(
|
|
|
|
rid.to_string(),
|
|
|
|
Default::default(),
|
|
|
|
Level::Scope(ns, db, sc),
|
|
|
|
)));
|
2022-07-04 00:01:24 +00:00
|
|
|
// Create the authentication token
|
2022-09-17 01:52:07 +00:00
|
|
|
match enc {
|
2022-07-04 00:01:24 +00:00
|
|
|
// The auth token was created successfully
|
2023-02-11 15:56:14 +00:00
|
|
|
Ok(tk) => Ok(Some(tk)),
|
2023-09-08 13:27:38 +00:00
|
|
|
_ => Err(Error::TokenMakingFailed),
|
2022-07-04 00:01:24 +00:00
|
|
|
}
|
|
|
|
}
|
2023-09-08 13:27:38 +00:00
|
|
|
_ => Err(Error::NoRecordFound),
|
2022-07-04 00:01:24 +00:00
|
|
|
},
|
2023-10-28 12:39:46 +00:00
|
|
|
Err(e) => match e {
|
|
|
|
Error::Thrown(_) => Err(e),
|
2023-11-20 14:54:27 +00:00
|
|
|
e if *INSECURE_FORWARD_SCOPE_ERRORS => Err(e),
|
2023-10-28 12:39:46 +00:00
|
|
|
_ => Err(Error::SignupQueryFailed),
|
|
|
|
},
|
2022-07-04 00:01:24 +00:00
|
|
|
}
|
|
|
|
}
|
2023-09-08 13:27:38 +00:00
|
|
|
_ => Err(Error::ScopeNoSignup),
|
2022-07-04 00:01:24 +00:00
|
|
|
}
|
|
|
|
}
|
2023-09-08 13:27:38 +00:00
|
|
|
_ => Err(Error::NoScopeFound),
|
2022-07-04 00:01:24 +00:00
|
|
|
}
|
|
|
|
}
|