Skip to content

Commit a9514d3

Browse files
committed
jwt: replaced jwt, hmac, sha2 with jsonwebtoken
jwt seems abandoned 5 years ago Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
1 parent 97a4f0b commit a9514d3

3 files changed

Lines changed: 42 additions & 35 deletions

File tree

Cargo.toml

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ edition = "2021"
66
[dependencies]
77
async-trait = "0.1"
88
axum = { version = "0.7.9", features = ["tracing", "multipart", "macros"] }
9-
axum-server = { version = "0.8.0", features = ["rustls", "rustls-pemfile", "tls-rustls"] }
9+
axum-server = { version = "0.8.0", features = ["rustls", "tls-rustls"] }
1010
azure_blob_uploader = "0.1.4"
1111
azure_storage = "0.21.0"
1212
azure_storage_blobs = "0.21.0"
@@ -19,14 +19,12 @@ futures = "0.3.31"
1919
futures-util = "0.3.31"
2020
headers = "0.4.0"
2121
hex = "0.4.3"
22-
hmac = "0.13.0"
2322
http-body-util = "0.1.2"
24-
jwt = "0.16.0"
23+
jsonwebtoken = "10"
2524
rand = "0.8.5"
2625
reqwest = { version = "0.12.9", features = ["blocking"] }
2726
rustls = "0.23.20"
2827
serde = { version = "1.0.216", features = ["derive"] }
29-
sha2 = "0.11.0"
3028
sysinfo = { version = "0.35.2", features = ["serde"] }
3129
tempfile = "3.14.0"
3230
tokio = { version = "1.42.0", features = ["rt", "rt-multi-thread", "macros"] }
@@ -39,8 +37,6 @@ tracing-subscriber = "0.3.19"
3937

4038
[dev-dependencies]
4139
reqwest = { version = "0.12.9", features = ["blocking", "multipart"] }
42-
hmac = "0.13.0"
43-
jwt = "0.16.0"
44-
sha2 = "0.11.0"
40+
jsonwebtoken = "10"
4541
tokio = { version = "1.42.0", features = ["rt", "rt-multi-thread", "macros", "time", "process"] }
4642
tempfile = "3.14.0"

src/storjwt.rs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,31 @@
11
use crate::{debug_log, get_config_content};
2-
use hmac::{Hmac, Mac};
3-
use jwt::{Header, SignWithKey, Token, VerifyWithKey};
4-
use sha2::Sha256;
2+
use jsonwebtoken::{decode, encode, DecodingKey, EncodingKey, Header, Validation};
3+
use serde::{Deserialize, Serialize};
54
use std::collections::BTreeMap;
65
use toml::value::Table;
6+
7+
#[derive(Debug, Serialize, Deserialize)]
8+
struct Claims {
9+
email: String,
10+
}
11+
712
fn verify_with_key_str(
813
token_str: &str,
914
key_str: &str,
10-
) -> Result<BTreeMap<String, String>, jwt::Error> {
11-
let key: Hmac<Sha256> = Hmac::new_from_slice(key_str.as_bytes())?;
12-
let token: Token<Header, BTreeMap<String, String>, _> = token_str.verify_with_key(&key)?;
13-
let claims = token.claims();
14-
if claims.get("email").is_none() {
15-
debug_log!("email not found");
16-
return Err(jwt::Error::InvalidSignature);
17-
}
18-
Ok(claims.clone())
15+
) -> Result<BTreeMap<String, String>, jsonwebtoken::errors::Error> {
16+
let key = DecodingKey::from_secret(key_str.as_bytes());
17+
let mut validation = Validation::default();
18+
validation.required_spec_claims.clear();
19+
validation.validate_exp = false;
20+
let token_data = decode::<Claims>(token_str, &key, &validation)?;
21+
let mut claims = BTreeMap::new();
22+
claims.insert("email".to_string(), token_data.claims.email);
23+
Ok(claims)
1924
}
2025

21-
pub fn verify_jwt_token(token_str: &str) -> Result<BTreeMap<String, String>, jwt::Error> {
26+
pub fn verify_jwt_token(
27+
token_str: &str,
28+
) -> Result<BTreeMap<String, String>, jsonwebtoken::errors::Error> {
2229
let toml_cfg = get_config_content();
2330
let parsed_toml = toml_cfg.parse::<Table>().unwrap();
2431

@@ -49,7 +56,7 @@ pub fn verify_jwt_token(token_str: &str) -> Result<BTreeMap<String, String>, jwt
4956
}
5057
}
5158

52-
Err(jwt::Error::InvalidSignature)
59+
Err(jsonwebtoken::errors::ErrorKind::InvalidSignature.into())
5360
}
5461

5562
pub fn generate_jwt_secret() {
@@ -64,7 +71,7 @@ pub fn generate_jwt_secret() {
6471
debug_log!("jwt_secret=\"{}\"", secret);
6572
}
6673

67-
pub fn generate_jwt_token(email: &str) -> Result<String, jwt::Error> {
74+
pub fn generate_jwt_token(email: &str) -> Result<String, jsonwebtoken::errors::Error> {
6875
let toml_cfg = get_config_content();
6976
let parsed_toml = toml_cfg.parse::<Table>().unwrap();
7077
// For token generation, prefer jwt_secret, fall back to unified_secret
@@ -73,9 +80,9 @@ pub fn generate_jwt_token(email: &str) -> Result<String, jwt::Error> {
7380
.or_else(|| parsed_toml.get("unified_secret"))
7481
.and_then(|v| v.as_str())
7582
.expect("config must define jwt_secret or unified_secret");
76-
let key: Hmac<Sha256> = Hmac::new_from_slice(key_str.as_bytes())?;
77-
let mut claims = BTreeMap::new();
78-
claims.insert("email".to_string(), email.to_string());
79-
let token_str = claims.sign_with_key(&key)?;
80-
Ok(token_str)
83+
let key = EncodingKey::from_secret(key_str.as_bytes());
84+
let claims = Claims {
85+
email: email.to_string(),
86+
};
87+
encode(&Header::default(), &claims, &key)
8188
}

tests/e2e.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
// End-to-end tests for kernelci-storage using the local storage driver.
55
// These tests start the actual server binary and exercise the HTTP API.
66

7-
use hmac::{Hmac, Mac};
8-
use jwt::SignWithKey;
7+
use jsonwebtoken::{encode, EncodingKey, Header};
98
use reqwest::blocking::multipart;
10-
use sha2::Sha256;
11-
use std::collections::BTreeMap;
9+
use serde::Serialize;
1210
use std::net::TcpListener;
1311
use std::path::PathBuf;
1412
use std::process::{Child, Command};
@@ -18,6 +16,11 @@ const JWT_SECRET: &str = "test-secret-for-e2e-testing";
1816
const TEST_EMAIL: &str = "test@kernelci.org";
1917
const RESTRICTED_EMAIL: &str = "restricted@kernelci.org";
2018

19+
#[derive(Serialize)]
20+
struct Claims {
21+
email: String,
22+
}
23+
2124
/// Find an available TCP port
2225
fn get_free_port() -> u16 {
2326
let listener = TcpListener::bind("127.0.0.1:0").expect("Failed to bind to ephemeral port");
@@ -26,10 +29,11 @@ fn get_free_port() -> u16 {
2629

2730
/// Generate a JWT token for the given email using the test secret
2831
fn generate_token(email: &str) -> String {
29-
let key: Hmac<Sha256> = Hmac::new_from_slice(JWT_SECRET.as_bytes()).unwrap();
30-
let mut claims = BTreeMap::new();
31-
claims.insert("email".to_string(), email.to_string());
32-
claims.sign_with_key(&key).unwrap()
32+
let key = EncodingKey::from_secret(JWT_SECRET.as_bytes());
33+
let claims = Claims {
34+
email: email.to_string(),
35+
};
36+
encode(&Header::default(), &claims, &key).unwrap()
3337
}
3438

3539
/// Test server handle - kills the server process on drop

0 commit comments

Comments
 (0)