in-memory storage #32
4 changed files with 80 additions and 59 deletions
|
@ -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)]
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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()?;
|
||||||
|
|
|
@ -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 {}
|
||||||
|
|
Loading…
Reference in a new issue