use md5::Digest;
use revision::revisioned;
use sha2::Sha256;
use surrealdb_types::ToSql;
use uuid::Uuid;
use crate::kvs::impl_kv_value_revisioned;
use crate::val::{Datetime, RecordId};
#[revisioned(revision = 1)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub(crate) enum Subject {
Record(RecordId),
User(String),
}
impl Subject {
pub fn id(&self) -> String {
match self {
Subject::Record(id) => id.to_sql(),
Subject::User(n) => n.clone(),
}
}
}
#[revisioned(revision = 1)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum Grant {
Jwt(GrantJwt),
Record(GrantRecord),
Bearer(GrantBearer),
}
impl Grant {
pub fn variant(&self) -> &str {
match self {
Grant::Jwt(_) => "jwt",
Grant::Record(_) => "record",
Grant::Bearer(_) => "bearer",
}
}
}
#[revisioned(revision = 1)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct GrantJwt {
pub jti: Uuid, pub token: Option<String>, }
#[revisioned(revision = 1)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct GrantRecord {
pub rid: Uuid, pub jti: Uuid, pub token: Option<String>, }
#[revisioned(revision = 1)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct GrantBearer {
pub id: String, pub key: String,
}
impl GrantBearer {
pub fn hashed(self) -> Self {
let mut hasher = Sha256::new();
hasher.update(self.key.as_str());
let hash = hasher.finalize();
let hash_hex = format!("{hash:x}");
Self {
key: hash_hex,
..self
}
}
}
#[revisioned(revision = 1)]
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub(crate) struct AccessGrant {
pub id: String, pub ac: String, pub creation: Datetime, pub expiration: Option<Datetime>, pub revocation: Option<Datetime>, pub subject: Subject, pub grant: Grant, }
impl_kv_value_revisioned!(AccessGrant);
impl AccessGrant {
pub(crate) fn redacted(mut self) -> AccessGrant {
self.grant = match self.grant {
Grant::Jwt(mut gr) => {
gr.token = None;
Grant::Jwt(gr)
}
Grant::Record(mut gr) => {
gr.token = None;
Grant::Record(gr)
}
Grant::Bearer(mut gr) => {
gr.key = "[REDACTED]".into();
Grant::Bearer(gr)
}
};
self
}
}