Improve API
This commit is contained in:
parent
9f56be95de
commit
4e8797d68d
67
src/lib.rs
67
src/lib.rs
@ -35,37 +35,40 @@ pub fn generate_ec384_keypair() -> anyhow::Result<(TokenPubKey, TokenPrivKey)> {
|
|||||||
TokenPrivKey::ES384 { r#priv: priv_pem },
|
TokenPrivKey::ES384 { r#priv: priv_pem },
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
impl TokenPrivKey {
|
||||||
|
/// Sign a JWT
|
||||||
|
pub fn sign_jwt<C: Serialize>(&self, claims: &C) -> anyhow::Result<String> {
|
||||||
|
match self {
|
||||||
|
TokenPrivKey::ES384 { r#priv } => {
|
||||||
|
let encoding_key = EncodingKey::from_ec_pem(r#priv.as_bytes())?;
|
||||||
|
|
||||||
/// Sign JWT with a private key
|
Ok(jsonwebtoken::encode(
|
||||||
pub fn sign_jwt<C: Serialize>(key: &TokenPrivKey, claims: &C) -> anyhow::Result<String> {
|
&jsonwebtoken::Header::new(Algorithm::ES384),
|
||||||
match key {
|
&claims,
|
||||||
TokenPrivKey::ES384 { r#priv } => {
|
&encoding_key,
|
||||||
let encoding_key = EncodingKey::from_ec_pem(r#priv.as_bytes())?;
|
)?)
|
||||||
|
}
|
||||||
Ok(jsonwebtoken::encode(
|
|
||||||
&jsonwebtoken::Header::new(Algorithm::ES384),
|
|
||||||
&claims,
|
|
||||||
&encoding_key,
|
|
||||||
)?)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validate a given JWT
|
impl TokenPubKey {
|
||||||
pub fn validate_jwt<E: DeserializeOwned>(key: &TokenPubKey, token: &str) -> anyhow::Result<E> {
|
/// Validate a given JWT
|
||||||
match key {
|
pub fn validate_jwt<E: DeserializeOwned>(&self, jwt: &str) -> anyhow::Result<E> {
|
||||||
TokenPubKey::ES384 { r#pub } => {
|
match self {
|
||||||
let decoding_key = DecodingKey::from_ec_pem(r#pub.as_bytes())?;
|
TokenPubKey::ES384 { r#pub } => {
|
||||||
|
let decoding_key = DecodingKey::from_ec_pem(r#pub.as_bytes())?;
|
||||||
|
|
||||||
let validation = Validation::new(Algorithm::ES384);
|
let validation = Validation::new(Algorithm::ES384);
|
||||||
Ok(jsonwebtoken::decode::<E>(token, &decoding_key, &validation)?.claims)
|
Ok(jsonwebtoken::decode::<E>(jwt, &decoding_key, &validation)?.claims)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{generate_ec384_keypair, sign_jwt, validate_jwt};
|
use crate::generate_ec384_keypair;
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -96,8 +99,10 @@ mod test {
|
|||||||
fn jwt_encode_sign_verify_valid() {
|
fn jwt_encode_sign_verify_valid() {
|
||||||
let (pub_key, priv_key) = generate_ec384_keypair().unwrap();
|
let (pub_key, priv_key) = generate_ec384_keypair().unwrap();
|
||||||
let claims = Claims::default();
|
let claims = Claims::default();
|
||||||
let jwt = sign_jwt(&priv_key, &claims).expect("Failed to sign JWT!");
|
let jwt = priv_key.sign_jwt(&claims).expect("Failed to sign JWT!");
|
||||||
let claims_out = validate_jwt::<Claims>(&pub_key, &jwt).expect("Failed to validate JWT!");
|
let claims_out = pub_key
|
||||||
|
.validate_jwt::<Claims>(&jwt)
|
||||||
|
.expect("Failed to validate JWT!");
|
||||||
|
|
||||||
assert_eq!(claims, claims_out)
|
assert_eq!(claims, claims_out)
|
||||||
}
|
}
|
||||||
@ -107,14 +112,17 @@ mod test {
|
|||||||
let (_pub_key, priv_key) = generate_ec384_keypair().unwrap();
|
let (_pub_key, priv_key) = generate_ec384_keypair().unwrap();
|
||||||
let (pub_key_2, _priv_key_2) = generate_ec384_keypair().unwrap();
|
let (pub_key_2, _priv_key_2) = generate_ec384_keypair().unwrap();
|
||||||
let claims = Claims::default();
|
let claims = Claims::default();
|
||||||
let jwt = sign_jwt(&priv_key, &claims).expect("Failed to sign JWT!");
|
let jwt = priv_key.sign_jwt(&claims).expect("Failed to sign JWT!");
|
||||||
validate_jwt::<Claims>(&pub_key_2, &jwt).expect_err("JWT should not have validated!");
|
pub_key_2
|
||||||
|
.validate_jwt::<Claims>(&jwt)
|
||||||
|
.expect_err("JWT should not have validated!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn jwt_verify_random_string() {
|
fn jwt_verify_random_string() {
|
||||||
let (pub_key, _priv_key) = generate_ec384_keypair().unwrap();
|
let (pub_key, _priv_key) = generate_ec384_keypair().unwrap();
|
||||||
validate_jwt::<Claims>(&pub_key, "random_string")
|
pub_key
|
||||||
|
.validate_jwt::<Claims>("random_string")
|
||||||
.expect_err("JWT should not have validated!");
|
.expect_err("JWT should not have validated!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,16 +133,19 @@ mod test {
|
|||||||
exp: time() - 100,
|
exp: time() - 100,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let jwt = sign_jwt(&priv_key, &claims).expect("Failed to sign JWT!");
|
let jwt = priv_key.sign_jwt(&claims).expect("Failed to sign JWT!");
|
||||||
validate_jwt::<Claims>(&pub_key, &jwt).expect_err("JWT should not have validated!");
|
pub_key
|
||||||
|
.validate_jwt::<Claims>(&jwt)
|
||||||
|
.expect_err("JWT should not have validated!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn jwt_invalid_signature() {
|
fn jwt_invalid_signature() {
|
||||||
let (pub_key, priv_key) = generate_ec384_keypair().unwrap();
|
let (pub_key, priv_key) = generate_ec384_keypair().unwrap();
|
||||||
let claims = Claims::default();
|
let claims = Claims::default();
|
||||||
let jwt = sign_jwt(&priv_key, &claims).expect("Failed to sign JWT!");
|
let jwt = priv_key.sign_jwt(&claims).expect("Failed to sign JWT!");
|
||||||
validate_jwt::<Claims>(&pub_key, &format!("{jwt}bad"))
|
pub_key
|
||||||
|
.validate_jwt::<Claims>(&format!("{jwt}bad"))
|
||||||
.expect_err("JWT should not have validated!");
|
.expect_err("JWT should not have validated!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user