parent
4c98717f1d
commit
a7444a7c8e
7 changed files with 91 additions and 13 deletions
|
@ -22,6 +22,8 @@ pub struct Session {
|
|||
pub db: Option<String>,
|
||||
/// The currently selected authentication scope
|
||||
pub sc: Option<String>,
|
||||
/// The current scope authentication token
|
||||
pub tk: Option<Value>,
|
||||
/// The current scope authentication data
|
||||
pub sd: Option<Value>,
|
||||
}
|
||||
|
@ -101,13 +103,14 @@ impl Session {
|
|||
// Add session value
|
||||
let key = String::from("session");
|
||||
let val: Value = Value::from(map! {
|
||||
"ip".to_string() => self.ip.to_owned().into(),
|
||||
"or".to_string() => self.or.to_owned().into(),
|
||||
"id".to_string() => self.id.to_owned().into(),
|
||||
"ns".to_string() => self.ns.to_owned().into(),
|
||||
"db".to_string() => self.db.to_owned().into(),
|
||||
"id".to_string() => self.id.to_owned().into(),
|
||||
"ip".to_string() => self.ip.to_owned().into(),
|
||||
"ns".to_string() => self.ns.to_owned().into(),
|
||||
"or".to_string() => self.or.to_owned().into(),
|
||||
"sc".to_string() => self.sc.to_owned().into(),
|
||||
"sd".to_string() => self.sd.to_owned().into(),
|
||||
"tk".to_string() => self.tk.to_owned().into(),
|
||||
});
|
||||
ctx.add_value(key, val);
|
||||
// Output context
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub mod clear;
|
||||
pub mod parse;
|
||||
pub mod signin;
|
||||
pub mod signup;
|
||||
pub mod token;
|
||||
|
|
15
src/iam/parse.rs
Normal file
15
src/iam/parse.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use crate::err::Error;
|
||||
use std::str;
|
||||
use surrealdb::sql::json;
|
||||
use surrealdb::sql::Value;
|
||||
|
||||
pub fn parse(value: &str) -> Result<Value, Error> {
|
||||
// Extract the middle part of the token
|
||||
let value = value.splitn(3, '.').skip(1).take(1).next().ok_or(Error::InvalidAuth)?;
|
||||
// Decode the base64 token data content
|
||||
let value = base64::decode(value).map_err(|_| Error::InvalidAuth)?;
|
||||
// Convert the decoded data to a string
|
||||
let value = str::from_utf8(&value).map_err(|_| Error::InvalidAuth)?;
|
||||
// Parse the token data into SurrealQL
|
||||
json(value).map_err(|_| Error::InvalidAuth)
|
||||
}
|
|
@ -144,14 +144,17 @@ pub async fn sc(
|
|||
id: Some(rid.to_raw()),
|
||||
..Claims::default()
|
||||
};
|
||||
// Create the authentication token
|
||||
let enc = encode(&*HEADER, &val, &key);
|
||||
// Set the authentication on the session
|
||||
session.tk = Some(val.into());
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.db = Some(db.to_owned());
|
||||
session.sc = Some(sc.to_owned());
|
||||
session.sd = Some(Value::from(rid));
|
||||
session.au = Arc::new(Auth::Sc(ns, db, sc));
|
||||
// Create the authentication token
|
||||
match encode(&*HEADER, &val, &key) {
|
||||
// Check the authentication token
|
||||
match enc {
|
||||
// The auth token was created successfully
|
||||
Ok(tk) => Ok(tk),
|
||||
// There was an error creating the token
|
||||
|
@ -206,10 +209,15 @@ pub async fn db(
|
|||
id: Some(user),
|
||||
..Claims::default()
|
||||
};
|
||||
// Set the authentication on the session
|
||||
session.au = Arc::new(Auth::Db(ns, db));
|
||||
// Create the authentication token
|
||||
match encode(&*HEADER, &val, &key) {
|
||||
let enc = encode(&*HEADER, &val, &key);
|
||||
// Set the authentication on the session
|
||||
session.tk = Some(val.into());
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.db = Some(db.to_owned());
|
||||
session.au = Arc::new(Auth::Db(ns, db));
|
||||
// Check the authentication token
|
||||
match enc {
|
||||
// The auth token was created successfully
|
||||
Ok(tk) => Ok(tk),
|
||||
// There was an error creating the token
|
||||
|
@ -255,10 +263,14 @@ pub async fn ns(
|
|||
id: Some(user),
|
||||
..Claims::default()
|
||||
};
|
||||
// Set the authentication on the session
|
||||
session.au = Arc::new(Auth::Ns(ns));
|
||||
// Create the authentication token
|
||||
match encode(&*HEADER, &val, &key) {
|
||||
let enc = encode(&*HEADER, &val, &key);
|
||||
// Set the authentication on the session
|
||||
session.tk = Some(val.into());
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.au = Arc::new(Auth::Ns(ns));
|
||||
// Check the authentication token
|
||||
match enc {
|
||||
// The auth token was created successfully
|
||||
Ok(tk) => Ok(tk),
|
||||
// There was an error creating the token
|
||||
|
|
|
@ -79,14 +79,17 @@ pub async fn sc(
|
|||
id: Some(rid.to_raw()),
|
||||
..Claims::default()
|
||||
};
|
||||
// Create the authentication token
|
||||
let enc = encode(&*HEADER, &val, &key);
|
||||
// Set the authentication on the session
|
||||
session.tk = Some(val.into());
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.db = Some(db.to_owned());
|
||||
session.sc = Some(sc.to_owned());
|
||||
session.sd = Some(Value::from(rid));
|
||||
session.au = Arc::new(Auth::Sc(ns, db, sc));
|
||||
// Create the authentication token
|
||||
match encode(&*HEADER, &val, &key) {
|
||||
match enc {
|
||||
// The auth token was created successfully
|
||||
Ok(tk) => Ok(tk),
|
||||
// There was an error creating the token
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use jsonwebtoken::{Algorithm, Header};
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use surrealdb::sql::Object;
|
||||
use surrealdb::sql::Value;
|
||||
|
||||
pub static HEADER: Lazy<Header> = Lazy::new(|| Header::new(Algorithm::HS512));
|
||||
|
||||
|
@ -36,3 +38,37 @@ pub struct Claims {
|
|||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub id: Option<String>,
|
||||
}
|
||||
|
||||
impl From<Claims> for Value {
|
||||
fn from(v: Claims) -> Value {
|
||||
// Set default value
|
||||
let mut out = Object::default();
|
||||
// Add default fields
|
||||
out.insert("iat".to_string(), v.iat.into());
|
||||
out.insert("nbf".to_string(), v.nbf.into());
|
||||
out.insert("exp".to_string(), v.exp.into());
|
||||
out.insert("iss".to_string(), v.iss.into());
|
||||
// Add NS field if set
|
||||
if let Some(ns) = v.ns {
|
||||
out.insert("NS".to_string(), ns.into());
|
||||
}
|
||||
// Add DB field if set
|
||||
if let Some(db) = v.db {
|
||||
out.insert("DB".to_string(), db.into());
|
||||
}
|
||||
// Add SC field if set
|
||||
if let Some(sc) = v.sc {
|
||||
out.insert("SC".to_string(), sc.into());
|
||||
}
|
||||
// Add TK field if set
|
||||
if let Some(tk) = v.tk {
|
||||
out.insert("TK".to_string(), tk.into());
|
||||
}
|
||||
// Add NS field if set
|
||||
if let Some(id) = v.id {
|
||||
out.insert("ID".to_string(), id.into());
|
||||
}
|
||||
// Return value
|
||||
out.into()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,8 @@ pub async fn token(session: &mut Session, auth: String) -> Result<(), Error> {
|
|||
let kvs = DB.get().unwrap();
|
||||
// Decode the token without verifying
|
||||
let token = decode::<Claims>(auth, &KEY, &DUD)?;
|
||||
// Parse the token and catch any errors
|
||||
let value = super::parse::parse(auth)?;
|
||||
// Check the token authentication claims
|
||||
match token.claims {
|
||||
// Check if this is scope token authentication
|
||||
|
@ -181,6 +183,7 @@ pub async fn token(session: &mut Session, auth: String) -> Result<(), Error> {
|
|||
// Log the success
|
||||
debug!(target: LOG, "Authenticated to scope `{}` with token `{}`", sc, tk);
|
||||
// Set the session
|
||||
session.tk = Some(value);
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.db = Some(db.to_owned());
|
||||
session.sc = Some(sc.to_owned());
|
||||
|
@ -210,6 +213,7 @@ pub async fn token(session: &mut Session, auth: String) -> Result<(), Error> {
|
|||
// Log the success
|
||||
debug!(target: LOG, "Authenticated to scope `{}`", sc);
|
||||
// Set the session
|
||||
session.tk = Some(value);
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.db = Some(db.to_owned());
|
||||
session.sc = Some(sc.to_owned());
|
||||
|
@ -236,6 +240,7 @@ pub async fn token(session: &mut Session, auth: String) -> Result<(), Error> {
|
|||
// Log the success
|
||||
debug!(target: LOG, "Authenticated to database `{}` with token `{}`", db, tk);
|
||||
// Set the session
|
||||
session.tk = Some(value);
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.db = Some(db.to_owned());
|
||||
session.au = Arc::new(Auth::Db(ns, db));
|
||||
|
@ -260,6 +265,7 @@ pub async fn token(session: &mut Session, auth: String) -> Result<(), Error> {
|
|||
// Log the success
|
||||
debug!(target: LOG, "Authenticated to database `{}` with login `{}`", db, id);
|
||||
// Set the session
|
||||
session.tk = Some(value);
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.db = Some(db.to_owned());
|
||||
session.au = Arc::new(Auth::Db(ns, db));
|
||||
|
@ -283,6 +289,7 @@ pub async fn token(session: &mut Session, auth: String) -> Result<(), Error> {
|
|||
// Log the success
|
||||
trace!(target: LOG, "Authenticated to namespace `{}` with token `{}`", ns, tk);
|
||||
// Set the session
|
||||
session.tk = Some(value);
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.au = Arc::new(Auth::Ns(ns));
|
||||
return Ok(());
|
||||
|
@ -305,6 +312,7 @@ pub async fn token(session: &mut Session, auth: String) -> Result<(), Error> {
|
|||
// Log the success
|
||||
trace!(target: LOG, "Authenticated to namespace `{}` with login `{}`", ns, id);
|
||||
// Set the session
|
||||
session.tk = Some(value);
|
||||
session.ns = Some(ns.to_owned());
|
||||
session.au = Arc::new(Auth::Ns(ns));
|
||||
return Ok(());
|
||||
|
|
Loading…
Reference in a new issue