in-memory storage #32

Merged
quentin merged 65 commits from in-memory into main 2023-12-27 16:35:43 +00:00
4 changed files with 80 additions and 59 deletions
Showing only changes of commit 0722886efb - Show all commits

View file

@ -31,7 +31,7 @@ pub struct StaticGarageConfig {
pub aws_access_key_id: String, pub aws_access_key_id: String,
pub aws_secret_access_key: String, pub aws_secret_access_key: String,
pub bucket: Option<String>, pub bucket: String,
} }
#[derive(Serialize, Deserialize, Debug, Clone)] #[derive(Serialize, Deserialize, Debug, Clone)]

View file

@ -5,10 +5,9 @@ use log::debug;
use crate::config::*; use crate::config::*;
use crate::login::*; use crate::login::*;
use crate::storage;
pub struct LdapLoginProvider { pub struct LdapLoginProvider {
k2v_region: Region,
s3_region: Region,
ldap_server: String, ldap_server: String,
pre_bind_on_login: bool, pre_bind_on_login: bool,
@ -19,12 +18,9 @@ pub struct LdapLoginProvider {
username_attr: String, username_attr: String,
mail_attr: String, mail_attr: String,
aws_access_key_id_attr: String, storage_specific: StorageSpecific,
aws_secret_access_key_attr: String,
user_secret_attr: String, user_secret_attr: String,
alternate_user_secrets_attr: Option<String>, alternate_user_secrets_attr: Option<String>,
bucket_source: BucketSource,
} }
enum BucketSource { enum BucketSource {
@ -32,8 +28,13 @@ enum BucketSource {
Attr(String), Attr(String),
} }
enum StorageSpecific {
InMemory,
Garage { from_config: LdapGarageConfig, bucket_source: BucketSource },
}
impl LdapLoginProvider { impl LdapLoginProvider {
pub fn new(config: LoginLdapConfig, k2v_region: Region, s3_region: Region) -> Result<Self> { pub fn new(config: LoginLdapConfig) -> Result<Self> {
let bind_dn_and_pw = match (config.bind_dn, config.bind_password) { let bind_dn_and_pw = match (config.bind_dn, config.bind_password) {
(Some(dn), Some(pw)) => Some((dn, pw)), (Some(dn), Some(pw)) => Some((dn, pw)),
(None, None) => None, (None, None) => None,
@ -42,12 +43,6 @@ impl LdapLoginProvider {
), ),
}; };
let bucket_source = match (config.bucket, config.bucket_attr) {
(Some(b), None) => BucketSource::Constant(b),
(None, Some(a)) => BucketSource::Attr(a),
_ => bail!("Must set `bucket` or `bucket_attr`, but not both"),
};
if config.pre_bind_on_login && bind_dn_and_pw.is_none() { if config.pre_bind_on_login && bind_dn_and_pw.is_none() {
bail!("Cannot use `pre_bind_on_login` without setting `bind_dn` and `bind_password`"); bail!("Cannot use `pre_bind_on_login` without setting `bind_dn` and `bind_password`");
} }
@ -55,20 +50,34 @@ impl LdapLoginProvider {
let mut attrs_to_retrieve = vec![ let mut attrs_to_retrieve = vec![
config.username_attr.clone(), config.username_attr.clone(),
config.mail_attr.clone(), config.mail_attr.clone(),
config.aws_access_key_id_attr.clone(),
config.aws_secret_access_key_attr.clone(),
config.user_secret_attr.clone(), config.user_secret_attr.clone(),
]; ];
if let Some(a) = &config.alternate_user_secrets_attr { if let Some(a) = &config.alternate_user_secrets_attr {
attrs_to_retrieve.push(a.clone()); attrs_to_retrieve.push(a.clone());
} }
if let BucketSource::Attr(a) = &bucket_source {
attrs_to_retrieve.push(a.clone()); // storage specific
} let specific = match config.storage {
LdapStorage::InMemory => StorageSpecific::InMemory,
LdapStorage::Garage(grgconf) => {
let bucket_source = match (grgconf.default_bucket.clone(), grgconf.bucket_attr.clone()) {
(Some(b), None) => BucketSource::Constant(b),
(None, Some(a)) => BucketSource::Attr(a),
_ => bail!("Must set `bucket` or `bucket_attr`, but not both"),
};
if let BucketSource::Attr(a) = &bucket_source {
attrs_to_retrieve.push(a.clone());
}
StorageSpecific::Garage { from_config: grgconf, bucket_source }
},
};
Ok(Self { Ok(Self {
k2v_region,
s3_region,
ldap_server: config.ldap_server, ldap_server: config.ldap_server,
pre_bind_on_login: config.pre_bind_on_login, pre_bind_on_login: config.pre_bind_on_login,
bind_dn_and_pw, bind_dn_and_pw,
@ -76,29 +85,36 @@ impl LdapLoginProvider {
attrs_to_retrieve, attrs_to_retrieve,
username_attr: config.username_attr, username_attr: config.username_attr,
mail_attr: config.mail_attr, mail_attr: config.mail_attr,
aws_access_key_id_attr: config.aws_access_key_id_attr, storage_specific: specific,
aws_secret_access_key_attr: config.aws_secret_access_key_attr,
user_secret_attr: config.user_secret_attr, user_secret_attr: config.user_secret_attr,
alternate_user_secrets_attr: config.alternate_user_secrets_attr, alternate_user_secrets_attr: config.alternate_user_secrets_attr,
bucket_source,
}) })
} }
fn storage_creds_from_ldap_user(&self, user: &SearchEntry) -> Result<StorageCredentials> { fn storage_creds_from_ldap_user(&self, user: &SearchEntry) -> Result<Builders> {
let aws_access_key_id = get_attr(user, &self.aws_access_key_id_attr)?; let storage: Builders = match &self.storage_specific {
let aws_secret_access_key = get_attr(user, &self.aws_secret_access_key_attr)?; StorageSpecific::InMemory => Box::new(storage::in_memory::FullMem {}),
let bucket = match &self.bucket_source { StorageSpecific::Garage { from_config, bucket_source } => {
BucketSource::Constant(b) => b.clone(), let aws_access_key_id = get_attr(user, &from_config.aws_access_key_id_attr)?;
BucketSource::Attr(a) => get_attr(user, a)?, let aws_secret_access_key = get_attr(user, &from_config.aws_secret_access_key_attr)?;
let bucket = match bucket_source {
BucketSource::Constant(b) => b.clone(),
BucketSource::Attr(a) => get_attr(user, &a)?,
};
Box::new(storage::garage::GrgCreds {
region: from_config.aws_region.clone(),
s3_endpoint: from_config.s3_endpoint.clone(),
k2v_endpoint: from_config.k2v_endpoint.clone(),
aws_access_key_id,
aws_secret_access_key,
bucket
})
},
}; };
Ok(StorageCredentials { Ok(storage)
k2v_region: self.k2v_region.clone(),
s3_region: self.s3_region.clone(),
aws_access_key_id,
aws_secret_access_key,
bucket,
})
} }
} }
@ -204,7 +220,7 @@ impl LoginProvider for LdapLoginProvider {
let storage = self.storage_creds_from_ldap_user(&user)?; let storage = self.storage_creds_from_ldap_user(&user)?;
drop(ldap); drop(ldap);
let k2v_client = storage.k2v_client()?; let k2v_client = storage.row_store()?;
let (_, public_key) = CryptoKeys::load_salt_and_public(&k2v_client).await?; let (_, public_key) = CryptoKeys::load_salt_and_public(&k2v_client).await?;
Ok(PublicCredentials { Ok(PublicCredentials {

View file

@ -52,9 +52,16 @@ impl LoginProvider for StaticLoginProvider {
} }
tracing::debug!(user=%username, "fetch keys"); tracing::debug!(user=%username, "fetch keys");
let storage: storage::Builders = match user.storage { let storage: storage::Builders = match &user.storage {
StaticStorage::InMemory => Box::new(storage::in_memory::FullMem {}), StaticStorage::InMemory => Box::new(storage::in_memory::FullMem {}),
StaticStorage::Garage(c) => Box::new(storage::garage::GrgCreds {}), StaticStorage::Garage(grgconf) => Box::new(storage::garage::GrgCreds {
region: grgconf.aws_region.clone(),
k2v_endpoint: grgconf.k2v_endpoint.clone(),
s3_endpoint: grgconf.s3_endpoint.clone(),
aws_access_key_id: grgconf.aws_access_key_id.clone(),
aws_secret_access_key: grgconf.aws_secret_access_key.clone(),
bucket: grgconf.bucket.clone(),
}),
}; };
let keys = match (&user.master_key, &user.secret_key) { let keys = match (&user.master_key, &user.secret_key) {
@ -87,25 +94,16 @@ impl LoginProvider for StaticLoginProvider {
Some(u) => u, Some(u) => u,
}; };
/* let storage: storage::Builders = match &user.storage {
let bucket = user
.bucket
.clone()
.or_else(|| self.default_bucket.clone())
.ok_or(anyhow!(
"No bucket configured and no default bucket specieid"
))?;
let storage = StorageCredentials {
k2v_region: self.k2v_region.clone(),
s3_region: self.s3_region.clone(),
aws_access_key_id: user.aws_access_key_id.clone(),
aws_secret_access_key: user.aws_secret_access_key.clone(),
bucket,
};*/
let storage: storage::Builders = match user.storage {
StaticStorage::InMemory => Box::new(storage::in_memory::FullMem {}), StaticStorage::InMemory => Box::new(storage::in_memory::FullMem {}),
StaticStorage::Garage(c) => Box::new(storage::garage::GrgCreds {}), StaticStorage::Garage(grgconf) => Box::new(storage::garage::GrgCreds {
region: grgconf.aws_region.clone(),
k2v_endpoint: grgconf.k2v_endpoint.clone(),
s3_endpoint: grgconf.s3_endpoint.clone(),
aws_access_key_id: grgconf.aws_access_key_id.clone(),
aws_secret_access_key: grgconf.aws_secret_access_key.clone(),
bucket: grgconf.bucket.clone(),
}),
}; };
let k2v_client = storage.row_store()?; let k2v_client = storage.row_store()?;

View file

@ -1,7 +1,14 @@
use crate::storage::*; use crate::storage::*;
#[derive(Clone, Debug, Hash)] #[derive(Clone, Debug, Hash)]
pub struct GrgCreds {} pub struct GrgCreds {
pub region: String,
pub s3_endpoint: String,
pub k2v_endpoint: String,
pub aws_access_key_id: String,
pub aws_secret_access_key: String,
pub bucket: String,
}
pub struct GrgStore {} pub struct GrgStore {}
pub struct GrgRef {} pub struct GrgRef {}
pub struct GrgValue {} pub struct GrgValue {}