Add API tokens support #9

Merged
pierre merged 40 commits from api into master 2024-04-23 17:04:45 +00:00
6 changed files with 19 additions and 19 deletions
Showing only changes of commit 865494572f - Show all commits

View File

@ -600,9 +600,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]] [[package]]
name = "basic-jwt" name = "basic-jwt"
version = "0.1.0" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20108a39851e5d33abc309904eb8f65c9b7c08c1ef3f107dfbe455de75111699" checksum = "741afb780192f091b1ceebdc794540a956f3eb96628939f83c5d15e0cb98fa71"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"elliptic-curve", "elliptic-curve",

View File

@ -45,4 +45,4 @@ rust-embed = { version = "8.3.0" }
mime_guess = "2.0.4" mime_guess = "2.0.4"
dotenvy = "0.15.7" dotenvy = "0.15.7"
nix = { version = "0.28.0", features = ["net"] } nix = { version = "0.28.0", features = ["net"] }
basic-jwt = "0.1.0" basic-jwt = "0.2.0"

View File

@ -1,4 +1,4 @@
use basic_jwt::{sign_jwt, TokenPrivKey}; use basic_jwt::JWTPrivateKey;
use clap::Parser; use clap::Parser;
use std::os::unix::prelude::CommandExt; use std::os::unix::prelude::CommandExt;
use std::process::Command; use std::process::Command;
@ -41,7 +41,7 @@ fn main() {
let full_url = format!("{}{}", args.virtweb_url, args.uri); let full_url = format!("{}{}", args.virtweb_url, args.uri);
log::debug!("Full URL: {full_url}"); log::debug!("Full URL: {full_url}");
let key = TokenPrivKey::ES384 { let key = JWTPrivateKey::ES384 {
r#priv: args.token_key, r#priv: args.token_key,
}; };
let claims = TokenClaims { let claims = TokenClaims {
@ -53,7 +53,7 @@ fn main() {
nonce: uuid::Uuid::new_v4().to_string(), nonce: uuid::Uuid::new_v4().to_string(),
}; };
let jwt = sign_jwt(&key, &claims).expect("Failed to sign JWT!"); let jwt = key.sign_jwt(&claims).expect("Failed to sign JWT!");
Command::new("curl") Command::new("curl")
.args(["-X", &args.verb]) .args(["-X", &args.verb])

View File

@ -4,7 +4,7 @@ use crate::app_config::AppConfig;
use crate::constants; use crate::constants;
use crate::utils::time_utils::time; use crate::utils::time_utils::time;
use actix_http::Method; use actix_http::Method;
use basic_jwt::{TokenPrivKey, TokenPubKey}; use basic_jwt::{JWTPrivateKey, JWTPublicKey};
use std::path::Path; use std::path::Path;
use std::str::FromStr; use std::str::FromStr;
@ -76,7 +76,7 @@ pub struct Token {
created: u64, created: u64,
updated: u64, updated: u64,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub pub_key: Option<TokenPubKey>, pub pub_key: Option<JWTPublicKey>,
pub rights: TokenRights, pub rights: TokenRights,
pub last_used: u64, pub last_used: u64,
pub ip_restriction: Option<ipnetwork::IpNetwork>, pub ip_restriction: Option<ipnetwork::IpNetwork>,
@ -195,8 +195,9 @@ impl NewToken {
} }
/// Create a new Token /// Create a new Token
pub async fn create(t: &NewToken) -> anyhow::Result<(Token, TokenPrivKey)> { pub async fn create(t: &NewToken) -> anyhow::Result<(Token, JWTPrivateKey)> {
let (pub_key, priv_key) = basic_jwt::generate_ec384_keypair()?; let priv_key = JWTPrivateKey::generate_ec384_signing_key()?;
let pub_key = priv_key.to_public_key()?;
let token = Token { let token = Token {
name: t.name.to_string(), name: t.name.to_string(),

View File

@ -5,7 +5,7 @@ use crate::api_tokens::{NewToken, TokenID, TokenRights};
use crate::controllers::api_tokens_controller::rest_token::RestToken; use crate::controllers::api_tokens_controller::rest_token::RestToken;
use crate::controllers::HttpResult; use crate::controllers::HttpResult;
use actix_web::{web, HttpResponse}; use actix_web::{web, HttpResponse};
use basic_jwt::TokenPrivKey; use basic_jwt::JWTPrivateKey;
/// Create a special module for REST token to enforce usage of constructor function /// Create a special module for REST token to enforce usage of constructor function
mod rest_token { mod rest_token {
@ -28,7 +28,7 @@ mod rest_token {
#[derive(serde::Serialize)] #[derive(serde::Serialize)]
struct CreateTokenResult { struct CreateTokenResult {
token: RestToken, token: RestToken,
priv_key: TokenPrivKey, priv_key: JWTPrivateKey,
} }
/// Create a new API token /// Create a new API token

View File

@ -71,13 +71,12 @@ impl FromRequest for ApiAuthExtractor {
return Err(ErrorBadRequest("Unable to validate token!")); return Err(ErrorBadRequest("Unable to validate token!"));
} }
let claims = match basic_jwt::validate_jwt::<TokenClaims>( let claims = match token
&token .pub_key
.pub_key .as_ref()
.clone() .expect("All tokens shall have public key!")
.expect("All tokens shall have public key!"), .validate_jwt::<TokenClaims>(&token_jwt)
&token_jwt, {
) {
Ok(c) => c, Ok(c) => c,
Err(e) => { Err(e) => {
log::error!("Failed to validate JWT: {e}"); log::error!("Failed to validate JWT: {e}");