blob: 606639629a490e1fdc3a362ad71e2386e29cb181 [file] [log] [blame]
use iggy::error::IggyError;
use iggy::utils::byte_size::IggyByteSize;
use iggy::utils::duration::IggyDuration;
use jsonwebtoken::{Algorithm, DecodingKey, EncodingKey};
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use serde_with::DisplayFromStr;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct HttpConfig {
pub enabled: bool,
pub address: String,
pub max_request_size: IggyByteSize,
pub cors: HttpCorsConfig,
pub jwt: HttpJwtConfig,
pub metrics: HttpMetricsConfig,
pub tls: HttpTlsConfig,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct HttpCorsConfig {
pub enabled: bool,
pub allowed_methods: Vec<String>,
pub allowed_origins: Vec<String>,
pub allowed_headers: Vec<String>,
pub exposed_headers: Vec<String>,
pub allow_credentials: bool,
pub allow_private_network: bool,
}
#[serde_as]
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct HttpJwtConfig {
pub algorithm: String,
pub issuer: String,
pub audience: String,
pub valid_issuers: Vec<String>,
pub valid_audiences: Vec<String>,
#[serde_as(as = "DisplayFromStr")]
pub access_token_expiry: IggyDuration,
#[serde_as(as = "DisplayFromStr")]
pub refresh_token_expiry: IggyDuration,
#[serde_as(as = "DisplayFromStr")]
pub clock_skew: IggyDuration,
#[serde_as(as = "DisplayFromStr")]
pub not_before: IggyDuration,
pub encoding_secret: String,
pub decoding_secret: String,
pub use_base64_secret: bool,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct HttpMetricsConfig {
pub enabled: bool,
pub endpoint: String,
}
#[derive(Debug)]
pub enum JwtSecret {
Default(String),
Base64(String),
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct HttpTlsConfig {
pub enabled: bool,
pub cert_file: String,
pub key_file: String,
}
impl HttpJwtConfig {
pub fn get_algorithm(&self) -> Result<Algorithm, IggyError> {
match self.algorithm.as_str() {
"HS256" => Ok(Algorithm::HS256),
"HS384" => Ok(Algorithm::HS384),
"HS512" => Ok(Algorithm::HS512),
"RS256" => Ok(Algorithm::RS256),
"RS384" => Ok(Algorithm::RS384),
"RS512" => Ok(Algorithm::RS512),
_ => Err(IggyError::InvalidJwtAlgorithm(self.algorithm.clone())),
}
}
pub fn get_decoding_secret(&self) -> JwtSecret {
self.get_secret(&self.decoding_secret)
}
pub fn get_encoding_secret(&self) -> JwtSecret {
self.get_secret(&self.encoding_secret)
}
pub fn get_decoding_key(&self) -> Result<DecodingKey, IggyError> {
if self.decoding_secret.is_empty() {
return Err(IggyError::InvalidJwtSecret);
}
Ok(match self.get_decoding_secret() {
JwtSecret::Default(ref secret) => DecodingKey::from_secret(secret.as_ref()),
JwtSecret::Base64(ref secret) => {
DecodingKey::from_base64_secret(secret).map_err(|_| IggyError::InvalidJwtSecret)?
}
})
}
pub fn get_encoding_key(&self) -> Result<EncodingKey, IggyError> {
if self.encoding_secret.is_empty() {
return Err(IggyError::InvalidJwtSecret);
}
Ok(match self.get_encoding_secret() {
JwtSecret::Default(ref secret) => EncodingKey::from_secret(secret.as_ref()),
JwtSecret::Base64(ref secret) => {
EncodingKey::from_base64_secret(secret).map_err(|_| IggyError::InvalidJwtSecret)?
}
})
}
fn get_secret(&self, secret: &str) -> JwtSecret {
if self.use_base64_secret {
JwtSecret::Base64(secret.to_string())
} else {
JwtSecret::Default(secret.to_string())
}
}
}