Can update and delete API tokens
This commit is contained in:
parent
e938b5a423
commit
0ee2c41f3c
@ -10,6 +10,15 @@ use std::path::Path;
|
||||
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug)]
|
||||
pub struct TokenID(pub uuid::Uuid);
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct TokenRight {
|
||||
verb: TokenVerb,
|
||||
uri: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct TokenRights(Vec<TokenRight>);
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct Token {
|
||||
pub id: TokenID,
|
||||
@ -19,7 +28,7 @@ pub struct Token {
|
||||
updated: u64,
|
||||
#[serde(skip_serializing_if = "TokenPubKey::is_invalid")]
|
||||
pub pub_key: TokenPubKey,
|
||||
pub rights: Vec<TokenRights>,
|
||||
pub rights: TokenRights,
|
||||
pub last_used: Option<u64>,
|
||||
pub ip_restriction: Option<ipnetwork::IpNetwork>,
|
||||
pub delete_after_inactivity: Option<u64>,
|
||||
@ -27,8 +36,12 @@ pub struct Token {
|
||||
|
||||
impl Token {
|
||||
/// Turn the token into a JSON string
|
||||
pub fn to_json(&self) -> String {
|
||||
serde_json::to_string(self).expect("Failed to serialize an API token!")
|
||||
fn save(&self) -> anyhow::Result<()> {
|
||||
let json = serde_json::to_string(self)?;
|
||||
|
||||
std::fs::write(AppConfig::get().api_token_definition_path(self.id), json)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Load token information from a file
|
||||
@ -46,22 +59,27 @@ pub enum TokenVerb {
|
||||
DELETE,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct TokenRights {
|
||||
verb: TokenVerb,
|
||||
uri: String,
|
||||
}
|
||||
|
||||
/// Structure used to create a token
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct NewToken {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub rights: Vec<TokenRights>,
|
||||
pub rights: TokenRights,
|
||||
pub ip_restriction: Option<ipnetwork::IpNetwork>,
|
||||
pub delete_after_inactivity: Option<u64>,
|
||||
}
|
||||
|
||||
impl TokenRights {
|
||||
pub fn check_error(&self) -> Option<&'static str> {
|
||||
for r in &self.0 {
|
||||
if !r.uri.starts_with("/api/") {
|
||||
return Some("All API rights shall start with /api/");
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl NewToken {
|
||||
/// Check for error in token
|
||||
pub fn check_error(&self) -> Option<&'static str> {
|
||||
@ -81,10 +99,8 @@ impl NewToken {
|
||||
return Some("Description is too long!");
|
||||
}
|
||||
|
||||
for r in &self.rights {
|
||||
if !r.uri.starts_with("/api/") {
|
||||
return Some("All API rights shall start with /api/");
|
||||
}
|
||||
if let Some(err) = self.rights.check_error() {
|
||||
return Some(err);
|
||||
}
|
||||
|
||||
if let Some(t) = self.delete_after_inactivity {
|
||||
@ -114,11 +130,6 @@ pub async fn create(t: &NewToken) -> anyhow::Result<(Token, TokenPrivKey)> {
|
||||
delete_after_inactivity: t.delete_after_inactivity,
|
||||
};
|
||||
|
||||
std::fs::write(
|
||||
AppConfig::get().api_token_definition_path(token.id),
|
||||
token.to_json(),
|
||||
)?;
|
||||
|
||||
Ok((token, priv_key))
|
||||
}
|
||||
|
||||
@ -135,3 +146,21 @@ pub async fn full_list() -> anyhow::Result<Vec<Token>> {
|
||||
pub async fn get_single(id: TokenID) -> anyhow::Result<Token> {
|
||||
Token::load_from_file(&AppConfig::get().api_token_definition_path(id))
|
||||
}
|
||||
|
||||
/// Update API tokens rights
|
||||
pub async fn update_rights(id: TokenID, rights: TokenRights) -> anyhow::Result<()> {
|
||||
let mut token = get_single(id).await?;
|
||||
token.rights = rights;
|
||||
token.updated = time();
|
||||
token.save()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Delete an API token
|
||||
pub async fn delete(id: TokenID) -> anyhow::Result<()> {
|
||||
let path = AppConfig::get().api_token_definition_path(id);
|
||||
if path.exists() {
|
||||
std::fs::remove_file(path)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! # API tokens management
|
||||
|
||||
use crate::api_tokens;
|
||||
use crate::api_tokens::{NewToken, TokenID};
|
||||
use crate::api_tokens::{NewToken, TokenID, TokenRights};
|
||||
use crate::controllers::api_tokens_controller::rest_token::RestToken;
|
||||
use crate::controllers::HttpResult;
|
||||
use crate::utils::jwt_utils::TokenPrivKey;
|
||||
@ -70,3 +70,31 @@ pub async fn get_single(path: web::Path<TokenIDInPath>) -> HttpResult {
|
||||
|
||||
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<TokenIDInPath>,
|
||||
body: web::Json<UpdateTokenBody>,
|
||||
) -> 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<TokenIDInPath>) -> HttpResult {
|
||||
api_tokens::delete(path.uid).await?;
|
||||
|
||||
Ok(HttpResponse::Accepted().finish())
|
||||
}
|
||||
|
@ -290,14 +290,14 @@ async fn main() -> std::io::Result<()> {
|
||||
"/api/tokens/{uid}",
|
||||
web::get().to(api_tokens_controller::get_single),
|
||||
)
|
||||
/* TODO .route(
|
||||
.route(
|
||||
"/api/tokens/{uid}",
|
||||
web::put().to(api_tokens_controller::update),
|
||||
web::patch().to(api_tokens_controller::update),
|
||||
)
|
||||
.route(
|
||||
"/api/tokens/{uid}",
|
||||
web::delete().to(api_tokens_controller::delete),
|
||||
)*/
|
||||
)
|
||||
// Static assets
|
||||
.route("/", web::get().to(static_controller::root_index))
|
||||
.route(
|
||||
|
Loading…
Reference in New Issue
Block a user