use actix_web::web;
use anyhow::{ensure, Context, Result};
use sqlx::{Pool, Sqlite};
pub use self::middleware::AuthMiddlewareFactory;
pub use self::token::Claims;
use self::{db::Users, token::Tokens};
use crate::conf;
mod db;
mod endpoints;
mod middleware;
mod passwd;
mod token;
const JWT_SECRET_VAR_NAME: &str = "DE_JWT_SECRET";
const MIN_SECRET_LEN: usize = 12;
const MAX_SECRET_LEN: usize = 86;
#[derive(Clone)]
pub struct Auth {
tokens: Tokens,
users: Users,
}
impl Auth {
pub async fn setup(pool: &'static Pool<Sqlite>) -> Result<Self> {
let jwt_secret: String = conf::mandatory(JWT_SECRET_VAR_NAME)?;
ensure!(
jwt_secret.len() >= MIN_SECRET_LEN,
"JWT secret is too short: {} < {}",
jwt_secret.len(),
MIN_SECRET_LEN
);
ensure!(
jwt_secret.len() <= MAX_SECRET_LEN,
"JWT secret is too long: {} > {}",
jwt_secret.len(),
MAX_SECRET_LEN
);
Ok(Self {
tokens: Tokens::new(jwt_secret.as_str()).context("Failed to initialize tokens")?,
users: Users::init(pool)
.await
.context("Failed to initialize users")?,
})
}
pub fn configure_root(&self, cfg: &mut web::ServiceConfig) {
cfg.app_data(web::Data::new(self.tokens.clone()));
cfg.app_data(web::Data::new(self.users.clone()));
}
pub fn configure_public(&self, cfg: &mut web::ServiceConfig) {
endpoints::configure(cfg);
}
}