Add ServerPadlockGenerator, UserServerKeyGenerator prototypes

This commit is contained in:
Xiretza 2024-02-10 11:37:38 +00:00
parent 578c4e237f
commit fbab2494eb

View file

@ -1,13 +1,18 @@
use std::sync::Arc; use std::sync::Arc;
use base64::{prelude::BASE64_STANDARD, Engine};
use hmac::{Hmac, Mac};
use md5::Md5;
use rand::{seq::IteratorRandom, thread_rng}; use rand::{seq::IteratorRandom, thread_rng};
use secrecy::{ExposeSecret, SecretVec};
use thiserror::Error; use thiserror::Error;
use time::{macros::format_description, OffsetDateTime};
use tokio::sync::Mutex; use tokio::sync::Mutex;
use tracing::{event, instrument, Level}; use tracing::{event, instrument, Level};
use crate::{ use crate::{
db::{/* Database, */ Database, SqliteDatabase}, db::{/* Database, */ Database, SqliteDatabase},
secrets::{Password, UserToken}, secrets::{Password, ServerHash, ServerPadlock, UserServerKey, UserToken},
}; };
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -67,3 +72,57 @@ impl Authenticator {
Ok(()) Ok(())
} }
} }
pub struct ServerPadlockGenerator {
secret: SecretVec<u8>,
}
impl ServerPadlockGenerator {
pub fn new(/* secret */) -> Self {
todo!()
}
pub fn generate_padlock(&self, server_hash: &ServerHash) -> ServerPadlock {
todo!()
}
}
pub struct UserServerKeyGenerator {
user_authenticator: Arc<Authenticator>,
padlock_generator: Arc<ServerPadlockGenerator>,
}
impl UserServerKeyGenerator {
pub fn new(/* Authenticator, ServerPadlockGenerator? */) -> Self {
todo!()
}
pub async fn generate_user_server_key(
&self,
username: &str,
token: &UserToken,
server_hash: &ServerHash,
) -> Result<(UserServerKey, String), AuthenticationError> {
self.user_authenticator
.verify_user_token(username, token)
.await?;
let padlock = self.padlock_generator.generate_padlock(server_hash);
let timestamp = OffsetDateTime::now_utc()
.format(format_description!(
"[year repr:last_two][month][day][hour repr:24][minute][second]"
))
.expect("timestamp format should be validated at compile-time");
event!(Level::DEBUG, timestamp, "Generating user_server_key");
let mut mac: Hmac<Md5> = Hmac::new_from_slice(padlock.0.expose_secret().as_bytes())
.map_err(|_e| AuthenticationError::InvalidServerHash)?;
mac.update(format!("{}_{}_{}", username, padlock.0.expose_secret(), timestamp).as_bytes());
let user_server_key =
UserServerKey(BASE64_STANDARD.encode(mac.finalize().into_bytes()).into());
Ok((user_server_key, timestamp))
}
}