use rand::distr::{Alphanumeric, SampleString};
use surrealdb_strand::Strand;
use surrealdb_types::{SqlFormat, ToSql};
use super::DefineKind;
use crate::expr::access::AccessDuration;
use crate::expr::access_type::JwtAccessVerify;
use crate::expr::{AccessType, Base, Expr, JwtAccess, Literal};
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct DefineAccessStatement {
pub kind: DefineKind,
pub name: Expr,
pub base: Base,
pub access_type: AccessType,
pub authenticate: Option<Expr>,
pub context: Option<Expr>,
pub duration: AccessDuration,
pub comment: Expr,
}
impl Default for DefineAccessStatement {
fn default() -> Self {
Self {
kind: DefineKind::Default,
name: Expr::Literal(Literal::None),
base: Base::Root,
access_type: AccessType::default(),
authenticate: None,
context: None,
duration: AccessDuration::default(),
comment: Expr::Literal(Literal::None),
}
}
}
impl DefineAccessStatement {
pub fn random_key() -> String {
Alphanumeric.sample_string(&mut rand::rng(), 128)
}
}
impl DefineAccessStatement {
pub fn redact(mut self) -> Self {
fn redact_jwt_access(acc: &mut JwtAccess) {
if let JwtAccessVerify::Key(ref mut v) = acc.verify
&& v.alg.is_symmetric()
{
v.key = Expr::Literal(Literal::String(Strand::new_static("[REDACTED]")));
}
if let Some(ref mut s) = acc.issue {
s.key = Expr::Literal(Literal::String(Strand::new_static("[REDACTED]")));
}
}
match self.access_type {
AccessType::Jwt(ref mut key) => {
redact_jwt_access(key);
}
AccessType::Bearer(ref mut b) => {
redact_jwt_access(&mut b.jwt);
}
AccessType::Record(ref mut r) => {
redact_jwt_access(&mut r.jwt);
if let Some(ref mut b) = r.bearer {
redact_jwt_access(&mut b.jwt);
}
}
}
self
}
}
impl ToSql for DefineAccessStatement {
fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
let stmt: crate::sql::statements::define::DefineAccessStatement = self.clone().into();
stmt.fmt_sql(f, fmt);
}
}