mirror of
https://github.com/bitwarden/server.git
synced 2025-12-11 04:34:37 -06:00
Create config for akd and vrf storages
This commit is contained in:
parent
0a818755f3
commit
8b750aee0a
@ -14,6 +14,7 @@ config = { workspace = true }
|
|||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
thiserror = "2.0.17"
|
thiserror = "2.0.17"
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
|
hex = "0.4.3"
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|||||||
44
akd/crates/common/src/config/mod.rs
Normal file
44
akd/crates/common/src/config/mod.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
mod storage_manager_config;
|
||||||
|
mod vrf_config;
|
||||||
|
|
||||||
|
pub use storage_manager_config::*;
|
||||||
|
pub use vrf_config::*;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum ConfigError {
|
||||||
|
#[error("Failed to connect to database")]
|
||||||
|
DatabaseConnection(#[source] akd::errors::StorageError),
|
||||||
|
|
||||||
|
#[error("Configuration value 'cache_item_lifetime_ms' is invalid: value {value} exceeds maximum allowed ({max})")]
|
||||||
|
CacheLifetimeOutOfRange {
|
||||||
|
value: usize,
|
||||||
|
max: u64,
|
||||||
|
#[source]
|
||||||
|
source: std::num::TryFromIntError,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[error("Configuration value 'cache_clean_frequency_ms' is invalid: value {value} exceeds maximum allowed ({max})")]
|
||||||
|
CacheCleanFrequencyOutOfRange {
|
||||||
|
value: usize,
|
||||||
|
max: u64,
|
||||||
|
#[source]
|
||||||
|
source: std::num::TryFromIntError,
|
||||||
|
},
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
Custom(String),
|
||||||
|
|
||||||
|
#[error("Invalid hex string for VRF key material")]
|
||||||
|
InvalidVrfKeyMaterialHex(#[source] hex::FromHexError),
|
||||||
|
|
||||||
|
#[error("VRF key material must be exactly 32 bytes, got {actual} bytes")]
|
||||||
|
VrfKeyMaterialInvalidLength { actual: usize },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigError {
|
||||||
|
pub fn new(message: impl Into<String>) -> Self {
|
||||||
|
Self::Custom(message.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
59
akd/crates/common/src/config/storage_manager_config.rs
Normal file
59
akd/crates/common/src/config/storage_manager_config.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use crate::config::ConfigError;
|
||||||
|
use akd::storage::StorageManager;
|
||||||
|
use akd_storage::{db_config::DbConfig, DatabaseType};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// items live for 30s by default
|
||||||
|
pub const DEFAULT_ITEM_LIFETIME_MS: usize = 30_000;
|
||||||
|
/// clean the cache every 15s by default
|
||||||
|
pub const DEFAULT_CACHE_CLEAN_FREQUENCY_MS: usize = 15_000;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct StorageManagerConfig {
|
||||||
|
pub db_config: DbConfig,
|
||||||
|
pub cache_limit_bytes: Option<usize>,
|
||||||
|
#[serde(default = "default_cache_item_lifetime_ms")]
|
||||||
|
pub cache_item_lifetime_ms: usize,
|
||||||
|
#[serde(default = "default_cache_clean_frequency_ms")]
|
||||||
|
pub cache_clean_frequency_ms: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_cache_item_lifetime_ms() -> usize {
|
||||||
|
DEFAULT_ITEM_LIFETIME_MS
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_cache_clean_frequency_ms() -> usize {
|
||||||
|
DEFAULT_CACHE_CLEAN_FREQUENCY_MS
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StorageManagerConfig {
|
||||||
|
pub async fn create(&self) -> Result<StorageManager<DatabaseType>, ConfigError> {
|
||||||
|
Ok(StorageManager::new(
|
||||||
|
self.db_config
|
||||||
|
.connect()
|
||||||
|
.await
|
||||||
|
.map_err(ConfigError::DatabaseConnection)?,
|
||||||
|
Some(Duration::from_millis(
|
||||||
|
self.cache_item_lifetime_ms.try_into().map_err(|source| {
|
||||||
|
ConfigError::CacheLifetimeOutOfRange {
|
||||||
|
value: self.cache_item_lifetime_ms,
|
||||||
|
max: u64::MAX,
|
||||||
|
source,
|
||||||
|
}
|
||||||
|
})?,
|
||||||
|
)),
|
||||||
|
self.cache_limit_bytes,
|
||||||
|
Some(Duration::from_millis(
|
||||||
|
self.cache_clean_frequency_ms.try_into().map_err(|source| {
|
||||||
|
ConfigError::CacheCleanFrequencyOutOfRange {
|
||||||
|
value: self.cache_clean_frequency_ms,
|
||||||
|
max: u64::MAX,
|
||||||
|
source,
|
||||||
|
}
|
||||||
|
})?,
|
||||||
|
)),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
34
akd/crates/common/src/config/vrf_config.rs
Normal file
34
akd/crates/common/src/config/vrf_config.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::config::ConfigError;
|
||||||
|
use crate::VrfStorageType;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum VrfConfig {
|
||||||
|
HardCodedAkdVRF,
|
||||||
|
ConstantConfigurableVRF { key_material: String },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&VrfConfig> for VrfStorageType {
|
||||||
|
type Error = ConfigError;
|
||||||
|
fn try_from(config: &VrfConfig) -> Result<Self, ConfigError> {
|
||||||
|
match config {
|
||||||
|
VrfConfig::HardCodedAkdVRF => Ok(VrfStorageType::HardCodedAkdVRF),
|
||||||
|
VrfConfig::ConstantConfigurableVRF { key_material } => {
|
||||||
|
let key_material =
|
||||||
|
hex::decode(key_material).map_err(ConfigError::InvalidVrfKeyMaterialHex)?;
|
||||||
|
|
||||||
|
if key_material.len() != 32 {
|
||||||
|
return Err(ConfigError::VrfKeyMaterialInvalidLength {
|
||||||
|
actual: key_material.len(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(VrfStorageType::ConstantConfigurableVRF {
|
||||||
|
key_material: key_material.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
pub mod config;
|
||||||
mod vrf_type;
|
mod vrf_type;
|
||||||
|
|
||||||
pub use vrf_type::VrfStorageType;
|
pub use vrf_type::VrfStorageType;
|
||||||
|
|||||||
@ -1,19 +1,5 @@
|
|||||||
use akd::ecvrf::{HardCodedAkdVRF, VRFKeyStorage, VrfError};
|
use akd::ecvrf::{HardCodedAkdVRF, VRFKeyStorage, VrfError};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use serde::{Deserialize};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
|
||||||
pub enum VrfConfig {
|
|
||||||
HardCodedAkdVRF,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&VrfConfig> for VrfStorageType {
|
|
||||||
fn from(config: &VrfConfig) -> Self {
|
|
||||||
match config {
|
|
||||||
VrfConfig::HardCodedAkdVRF => VrfStorageType::HardCodedAkdVRF,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum VrfStorageType {
|
pub enum VrfStorageType {
|
||||||
@ -22,6 +8,9 @@ pub enum VrfStorageType {
|
|||||||
///
|
///
|
||||||
/// const KEY_MATERIAL: &str = "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721";
|
/// const KEY_MATERIAL: &str = "c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721";
|
||||||
HardCodedAkdVRF,
|
HardCodedAkdVRF,
|
||||||
|
ConstantConfigurableVRF {
|
||||||
|
key_material: Vec<u8>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
@ -29,6 +18,7 @@ impl VRFKeyStorage for VrfStorageType {
|
|||||||
async fn retrieve(&self) -> Result<Vec<u8>, VrfError> {
|
async fn retrieve(&self) -> Result<Vec<u8>, VrfError> {
|
||||||
match self {
|
match self {
|
||||||
VrfStorageType::HardCodedAkdVRF => HardCodedAkdVRF.retrieve().await,
|
VrfStorageType::HardCodedAkdVRF => HardCodedAkdVRF.retrieve().await,
|
||||||
|
VrfStorageType::ConstantConfigurableVRF { key_material } => Ok(key_material.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user