All checks were successful
continuous-integration/drone/push Build is passing
54 lines
1.6 KiB
Rust
54 lines
1.6 KiB
Rust
use jwt_simple::algorithms::RSAKeyPairLike;
|
|
use jwt_simple::claims::JWTClaims;
|
|
use jwt_simple::prelude::RS256KeyPair;
|
|
use serde::de::DeserializeOwned;
|
|
use serde::Serialize;
|
|
|
|
use base64::engine::general_purpose::URL_SAFE as BASE64_URL_URL_SAFE;
|
|
use base64::engine::general_purpose::URL_SAFE_NO_PAD as BASE64_URL_SAFE_NO_PAD;
|
|
use base64::Engine as _;
|
|
|
|
use crate::utils::err::Res;
|
|
use crate::utils::string_utils::rand_str;
|
|
|
|
/// Json Web Key <https://datatracker.ietf.org/doc/html/rfc7517>
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
|
pub struct JsonWebKey {
|
|
#[serde(rename = "alg")]
|
|
algorithm: String,
|
|
#[serde(rename = "kty")]
|
|
key_type: String,
|
|
#[serde(rename = "kid")]
|
|
key_id: String,
|
|
#[serde(rename = "n")]
|
|
modulus: String,
|
|
#[serde(rename = "e")]
|
|
public_exponent: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct JWTSigner(RS256KeyPair);
|
|
|
|
impl JWTSigner {
|
|
pub fn gen_from_memory() -> Res<Self> {
|
|
Ok(Self(
|
|
RS256KeyPair::generate(2048)?.with_key_id(&format!("key-{}", rand_str(15))),
|
|
))
|
|
}
|
|
|
|
pub fn get_json_web_key(&self) -> JsonWebKey {
|
|
let components = self.0.public_key().to_components();
|
|
JsonWebKey {
|
|
algorithm: "RS256".to_string(),
|
|
key_type: "RSA".to_string(),
|
|
key_id: self.0.key_id().as_ref().unwrap().to_string(),
|
|
public_exponent: BASE64_URL_URL_SAFE.encode(components.e),
|
|
modulus: BASE64_URL_SAFE_NO_PAD.encode(components.n),
|
|
}
|
|
}
|
|
|
|
pub fn sign_token<E: Serialize + DeserializeOwned>(&self, c: JWTClaims<E>) -> Res<String> {
|
|
Ok(self.0.sign(c)?)
|
|
}
|
|
}
|