//! # API tokens management use crate::api_tokens; use crate::api_tokens::{NewToken, TokenID, TokenRights}; use crate::controllers::api_tokens_controller::rest_token::RestToken; use crate::controllers::HttpResult; use actix_web::{web, HttpResponse}; use basic_jwt::JWTPrivateKey; /// Create a special module for REST token to enforce usage of constructor function mod rest_token { use crate::api_tokens::Token; #[derive(serde::Serialize)] pub struct RestToken { #[serde(flatten)] token: Token, } impl RestToken { pub fn new(mut token: Token) -> Self { token.pub_key = None; Self { token } } } } #[derive(serde::Serialize)] struct CreateTokenResult { token: RestToken, priv_key: JWTPrivateKey, } /// Create a new API token pub async fn create(new_token: web::Json) -> HttpResult { if let Some(err) = new_token.check_error() { log::error!("Failed to validate new API token information! {err}"); return Ok(HttpResponse::BadRequest().json(format!( "Failed to validate new API token information! {err}" ))); } let (token, priv_key) = api_tokens::create(&new_token).await?; Ok(HttpResponse::Ok().json(CreateTokenResult { token: RestToken::new(token), priv_key, })) } /// Get the list of API tokens pub async fn list() -> HttpResult { let list = api_tokens::full_list() .await? .into_iter() .map(RestToken::new) .collect::>(); Ok(HttpResponse::Ok().json(list)) } #[derive(serde::Deserialize)] pub struct TokenIDInPath { uid: TokenID, } /// Get the information about a single token pub async fn get_single(path: web::Path) -> HttpResult { let token = api_tokens::get_single(path.uid).await?; Ok(HttpResponse::Ok().json(RestToken::new(token))) } #[derive(serde::Deserialize)] pub struct UpdateTokenBody { rights: TokenRights, } /// Update a token pub async fn update( path: web::Path, body: web::Json, ) -> HttpResult { if let Some(err) = body.rights.check_error() { log::error!("Failed to validate updated API token information! {err}"); return Ok(HttpResponse::BadRequest() .json(format!("Failed to validate API token information! {err}"))); } api_tokens::update_rights(path.uid, body.0.rights).await?; Ok(HttpResponse::Accepted().finish()) } /// Delete a token pub async fn delete(path: web::Path) -> HttpResult { api_tokens::delete(path.uid).await?; Ok(HttpResponse::Accepted().finish()) }