Verify API auth token

This commit is contained in:
2025-01-29 21:50:17 +01:00
parent b92149a77d
commit 6874aebfc7
12 changed files with 586 additions and 18 deletions

View File

@ -1,6 +1,7 @@
use s3::error::S3Error;
use s3::request::ResponseData;
use s3::{Bucket, BucketConfiguration};
use std::str::FromStr;
use thiserror::Error;
use crate::app_config::AppConfig;
@ -29,11 +30,28 @@ pub struct User {
pub email: String,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct APIClientID(pub uuid::Uuid);
impl APIClientID {
pub fn generate() -> Self {
Self(uuid::Uuid::new_v4())
}
}
impl FromStr for APIClientID {
type Err = uuid::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(uuid::Uuid::from_str(s)?))
}
}
/// Single API client information
#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct APIClient {
/// Client unique ID
pub id: uuid::Uuid,
pub id: APIClientID,
/// Client description
pub description: String,
@ -68,7 +86,7 @@ impl APIClient {
/// Generate a new API client
pub fn generate(description: String, network: Option<ipnet::IpNet>) -> Self {
Self {
id: uuid::Uuid::new_v4(),
id: APIClientID::generate(),
description,
network,
secret: rand_str(TOKEN_LEN),
@ -137,15 +155,15 @@ impl UserConfig {
}
/// Get current user configuration
pub async fn load(user_id: &UserID) -> anyhow::Result<Self> {
pub async fn load(user_id: &UserID, allow_non_existing: bool) -> anyhow::Result<Self> {
let res: Result<ResponseData, S3Error> = AppConfig::get()
.s3_bucket()?
.get_object(user_id.conf_path_in_bucket())
.await;
match res {
Ok(res) => Ok(serde_json::from_slice(res.as_slice())?),
Err(S3Error::HttpFailWithBody(404, _)) => {
match (res, allow_non_existing) {
(Ok(res), _) => Ok(serde_json::from_slice(res.as_slice())?),
(Err(S3Error::HttpFailWithBody(404, _)), true) => {
log::warn!("User configuration does not exists, generating a new one...");
Ok(Self {
user_id: user_id.clone(),
@ -155,7 +173,7 @@ impl UserConfig {
clients: vec![],
})
}
Err(e) => Err(UserError::FetchUserConfig(e).into()),
(Err(e), _) => Err(UserError::FetchUserConfig(e).into()),
}
}
@ -188,4 +206,9 @@ impl UserConfig {
})
.collect()
}
/// Find a client by its id
pub fn find_client_by_id(&self, id: &APIClientID) -> Option<&APIClient> {
self.clients.iter().find(|c| &c.id == id)
}
}