Some refactoring and app token management

This commit is contained in:
Lennart
2025-04-14 17:17:36 +02:00
parent 354c6c97eb
commit 2ce8529002
12 changed files with 256 additions and 135 deletions

View File

@@ -28,6 +28,7 @@ rustical_xml.workspace = true
toml.workspace = true
tokio.workspace = true
rand.workspace = true
uuid.workspace = true
[dev-dependencies]
rstest = { workspace = true }

View File

@@ -9,7 +9,14 @@ pub trait AuthenticationProvider: 'static {
async fn get_principal(&self, id: &str) -> Result<Option<User>, crate::Error>;
async fn insert_principal(&self, user: User) -> Result<(), crate::Error>;
async fn validate_user_token(&self, user_id: &str, token: &str) -> Result<Option<User>, Error>;
async fn add_app_token(&self, user_id: &str, name: String, token: String) -> Result<(), Error>;
/// Returns a token identifier
async fn add_app_token(
&self,
user_id: &str,
name: String,
token: String,
) -> Result<String, Error>;
async fn remove_app_token(&self, user_id: &str, token_id: &str) -> Result<(), Error>;
}
pub use middleware::AuthenticationMiddleware;

View File

@@ -101,9 +101,16 @@ impl AuthenticationProvider for TomlPrincipalStore {
Ok(None)
}
async fn add_app_token(&self, user_id: &str, name: String, token: String) -> Result<(), Error> {
/// Returns an identifier for the new app token
async fn add_app_token(
&self,
user_id: &str,
name: String,
token: String,
) -> Result<String, Error> {
let mut principals = self.principals.write().await;
if let Some(principal) = principals.get_mut(user_id) {
let id = uuid::Uuid::new_v4().to_string();
let salt = SaltString::generate(OsRng);
let token_hash = pbkdf2::Pbkdf2
.hash_password_customized(
@@ -122,11 +129,23 @@ impl AuthenticationProvider for TomlPrincipalStore {
name,
token: token_hash,
created_at: Some(chrono::Utc::now()),
id: id.clone(),
});
self.save(principals.deref())?;
Ok(())
Ok(id)
} else {
Err(Error::NotFound)
}
}
async fn remove_app_token(&self, user_id: &str, token_id: &str) -> Result<(), Error> {
let mut principals = self.principals.write().await;
if let Some(principal) = principals.get_mut(user_id) {
principal
.app_tokens
.retain(|AppToken { id, .. }| token_id != id);
self.save(principals.deref())?;
}
Ok(())
}
}

View File

@@ -37,6 +37,7 @@ impl ValueSerialize for PrincipalType {
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AppToken {
pub id: String,
pub name: String,
pub token: String,
pub created_at: Option<DateTime<Utc>>,

View File

@@ -1,6 +1,6 @@
use super::{CalDateTime, EventObject, JournalObject, TodoObject};
use crate::Error;
use ical::parser::{ical::component::IcalTimeZone, Component};
use ical::parser::{Component, ical::component::IcalTimeZone};
use serde::Serialize;
use sha2::{Digest, Sha256};
use std::{collections::HashMap, io::BufReader};
@@ -13,14 +13,19 @@ pub enum CalendarObjectType {
Journal = 2,
}
impl rustical_xml::ValueSerialize for CalendarObjectType {
fn serialize(&self) -> String {
impl CalendarObjectType {
pub fn as_str(&self) -> &'static str {
match self {
CalendarObjectType::Event => "VEVENT",
CalendarObjectType::Todo => "VTODO",
CalendarObjectType::Journal => "VJOURNAL",
}
.to_owned()
}
}
impl rustical_xml::ValueSerialize for CalendarObjectType {
fn serialize(&self) -> String {
self.as_str().to_owned()
}
}