use crate::log::LogLevel;
use crate::{BootstrapConfigLoadingError, BootstrapConfigRaw};
use serde::{Deserialize, Serialize};
use std::time::Duration;
use url::Url;
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LockTransport {
#[default]
Rest,
#[cfg(feature = "grpc")]
Grpc,
}
#[cfg(feature = "grpc")]
const PARSE_LOCK_TRANSPORT_ERR: &str = "Invalid lock transport. Must be `rest` or `grpc`";
#[cfg(not(feature = "grpc"))]
const PARSE_LOCK_TRANSPORT_ERR: &str = "Invalid lock transport. Must be `rest`";
impl std::str::FromStr for LockTransport {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"rest" => Ok(Self::Rest),
#[cfg(feature = "grpc")]
"grpc" => Ok(Self::Grpc),
_ => Err(PARSE_LOCK_TRANSPORT_ERR.to_string()),
}
}
}
impl std::fmt::Display for LockTransport {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
LockTransport::Rest => write!(f, "rest"),
#[cfg(feature = "grpc")]
LockTransport::Grpc => write!(f, "grpc"),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct LockServiceConfig {
pub log_level: LogLevel,
pub config_uri: Url,
pub dynamic_config: bool,
pub ssa_jwt: Option<String>,
#[cfg(not(target_arch = "wasm32"))]
pub access_token_jwt: Option<String>,
pub log_interval: Option<Duration>,
pub health_interval: Option<Duration>,
pub telemetry_interval: Option<Duration>,
pub listen_sse: bool,
pub accept_invalid_certs: bool,
pub transport: LockTransport,
pub log_channel_capacity: usize,
pub log_max_retries: u32,
}
impl LockServiceConfig {
pub(super) const DEFAULT_CHANNEL_CAPACITY: usize = 100;
pub(super) const DEFAULT_LOG_MAX_RETRIES: u32 = 5;
}
#[derive(Debug, Clone, PartialEq)]
pub struct LockServiceConfigRaw {
pub log_level: LogLevel,
pub config_uri: String,
pub dynamic_config: bool,
pub ssa_jwt: Option<String>,
#[cfg(not(target_arch = "wasm32"))]
pub access_token_jwt: Option<String>,
pub log_interval: Option<Duration>,
pub health_interval: Option<Duration>,
pub telemetry_interval: Option<Duration>,
pub listen_sse: bool,
pub accept_invalid_certs: bool,
pub transport: LockTransport,
pub log_channel_capacity: usize,
pub log_max_retries: u32,
}
impl Default for LockServiceConfig {
fn default() -> Self {
Self {
log_level: LogLevel::INFO,
config_uri: "http://localhost:8080/.well-known/lock-server-configuration"
.parse()
.expect("Failed to parse default lock server configuration URI"),
dynamic_config: false,
ssa_jwt: None,
#[cfg(not(target_arch = "wasm32"))]
access_token_jwt: None,
log_interval: None,
health_interval: None,
telemetry_interval: None,
listen_sse: false,
accept_invalid_certs: false,
transport: LockTransport::default(),
log_channel_capacity: Self::DEFAULT_CHANNEL_CAPACITY,
log_max_retries: Self::DEFAULT_LOG_MAX_RETRIES,
}
}
}
impl From<LockServiceConfigRaw> for LockServiceConfig {
fn from(raw: LockServiceConfigRaw) -> Self {
Self {
log_level: raw.log_level,
config_uri: raw
.config_uri
.parse()
.expect("Failed to parse lock server configuration URI from raw config"),
dynamic_config: raw.dynamic_config,
ssa_jwt: raw.ssa_jwt,
#[cfg(not(target_arch = "wasm32"))]
access_token_jwt: raw.access_token_jwt,
log_interval: raw.log_interval,
health_interval: raw.health_interval,
telemetry_interval: raw.telemetry_interval,
listen_sse: raw.listen_sse,
accept_invalid_certs: raw.accept_invalid_certs,
transport: raw.transport,
log_channel_capacity: raw.log_channel_capacity,
log_max_retries: raw.log_max_retries,
}
}
}
impl TryFrom<&BootstrapConfigRaw> for LockServiceConfig {
type Error = BootstrapConfigLoadingError;
fn try_from(raw: &BootstrapConfigRaw) -> Result<Self, Self::Error> {
let config_uri = raw
.lock_server_configuration_uri
.clone()
.ok_or(BootstrapConfigLoadingError::MissingLockServerConfigUri)?
.parse()?;
let ssa_jwt = raw.lock_ssa_jwt.clone();
#[cfg(not(target_arch = "wasm32"))]
let access_token_jwt = raw.lock_access_token_jwt.clone();
let log_interval =
(raw.audit_log_interval > 0).then(|| Duration::from_secs(raw.audit_log_interval));
let health_interval =
(raw.audit_health_interval > 0).then(|| Duration::from_secs(raw.audit_health_interval));
let telemetry_interval = (raw.audit_telemetry_interval > 0)
.then(|| Duration::from_secs(raw.audit_telemetry_interval));
let listen_sse = raw.listen_sse.into();
Ok(LockServiceConfig {
config_uri,
dynamic_config: raw.dynamic_configuration.into(),
ssa_jwt,
#[cfg(not(target_arch = "wasm32"))]
access_token_jwt,
log_interval,
health_interval,
telemetry_interval,
listen_sse,
log_level: raw.log_level,
accept_invalid_certs: raw.accept_invalid_certs.into(),
transport: raw.lock_transport,
log_channel_capacity: raw.lock_log_channel_capacity,
log_max_retries: raw.lock_log_max_retries,
})
}
}