feat: allow raw PEM file content as an input for JwtAuthorizer (#15)

* Allow raw PEM file content as an input for JwtAuthorizer

* Add tests for text-based KeySourceType variants
This commit is contained in:
Cyril Plisko 2023-03-28 09:03:43 +03:00 committed by GitHub
parent 2bca19be64
commit 783ed7e340
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 105 additions and 0 deletions

View file

@ -49,8 +49,11 @@ fn read_data(path: &str) -> Result<Vec<u8>, InitError> {
pub enum KeySourceType {
RSA(String),
RSAString(String),
EC(String),
ECString(String),
ED(String),
EDString(String),
Secret(String),
Jwks(String),
JwksString(String), // TODO: expose JwksString in JwtAuthorizer or remove it
@ -80,6 +83,18 @@ where
validation,
}
}
KeySourceType::RSAString(text) => {
let key = DecodingKey::from_rsa_pem(text.as_bytes())?;
Authorizer {
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
kid: None,
alg: vec![Algorithm::RS256, Algorithm::RS384, Algorithm::RS512],
key,
})),
claims_checker,
validation,
}
}
KeySourceType::EC(path) => {
let key = DecodingKey::from_ec_pem(&read_data(path.as_str())?)?;
Authorizer {
@ -92,6 +107,18 @@ where
validation,
}
}
KeySourceType::ECString(text) => {
let key = DecodingKey::from_ec_pem(text.as_bytes())?;
Authorizer {
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
kid: None,
alg: vec![Algorithm::ES256, Algorithm::ES384],
key,
})),
claims_checker,
validation,
}
}
KeySourceType::ED(path) => {
let key = DecodingKey::from_ed_pem(&read_data(path.as_str())?)?;
Authorizer {
@ -104,6 +131,18 @@ where
validation,
}
}
KeySourceType::EDString(text) => {
let key = DecodingKey::from_ed_pem(text.as_bytes())?;
Authorizer {
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
kid: None,
alg: vec![Algorithm::EdDSA],
key,
})),
claims_checker,
validation,
}
}
KeySourceType::Secret(secret) => {
let key = DecodingKey::from_secret(secret.as_bytes());
Authorizer {
@ -242,6 +281,42 @@ mod tests {
assert!(k.await.is_ok());
}
#[tokio::test]
async fn build_from_text() {
let a = Authorizer::<Value>::build(
&KeySourceType::RSAString(include_str!("../../config/rsa-public1.pem").to_owned()),
None,
None,
Validation::new(),
)
.await
.unwrap();
let k = a.key_source.get_key(Header::new(Algorithm::RS256));
assert!(k.await.is_ok());
let a = Authorizer::<Value>::build(
&KeySourceType::ECString(include_str!("../../config/ecdsa-public1.pem").to_owned()),
None,
None,
Validation::new(),
)
.await
.unwrap();
let k = a.key_source.get_key(Header::new(Algorithm::ES256));
assert!(k.await.is_ok());
let a = Authorizer::<Value>::build(
&KeySourceType::EDString(include_str!("../../config/ed25519-public1.pem").to_owned()),
None,
None,
Validation::new(),
)
.await
.unwrap();
let k = a.key_source.get_key(Header::new(Algorithm::EdDSA));
assert!(k.await.is_ok());
}
#[tokio::test]
async fn build_file_errors() {
let a = Authorizer::<Value>::build(

View file

@ -69,6 +69,16 @@ where
}
}
/// Builds Authorizer Layer from an RSA PEM raw text
pub fn from_rsa_pem_text(text: &str) -> JwtAuthorizer<C> {
JwtAuthorizer {
key_source_type: KeySourceType::RSAString(text.to_owned()),
refresh: Default::default(),
claims_checker: None,
validation: None,
}
}
/// Builds Authorizer Layer from a EC PEM file
pub fn from_ec_pem(path: &str) -> JwtAuthorizer<C> {
JwtAuthorizer {
@ -79,6 +89,16 @@ where
}
}
/// Builds Authorizer Layer from a EC PEM raw text
pub fn from_ec_pem_text(text: &str) -> JwtAuthorizer<C> {
JwtAuthorizer {
key_source_type: KeySourceType::ECString(text.to_owned()),
refresh: Default::default(),
claims_checker: None,
validation: None,
}
}
/// Builds Authorizer Layer from a EC PEM file
pub fn from_ed_pem(path: &str) -> JwtAuthorizer<C> {
JwtAuthorizer {
@ -89,6 +109,16 @@ where
}
}
/// Builds Authorizer Layer from a EC PEM raw text
pub fn from_ed_pem_text(text: &str) -> JwtAuthorizer<C> {
JwtAuthorizer {
key_source_type: KeySourceType::EDString(text.to_owned()),
refresh: Default::default(),
claims_checker: None,
validation: None,
}
}
/// Builds Authorizer Layer from a secret phrase
pub fn from_secret(secret: &str) -> JwtAuthorizer<C> {
JwtAuthorizer {