diff options
| author | benj <benj@rse8.com> | 2023-06-19 17:18:21 -0700 |
|---|---|---|
| committer | benj <benj@rse8.com> | 2023-06-19 17:18:21 -0700 |
| commit | ab6d5cefbea1e8ddf41f385dd85918f651958287 (patch) | |
| tree | ac3a6b45b1a0e6a833a627307d07e94a95ba3c23 /crates/secd/src/client | |
| parent | 3406b370fe290559ff2445097a380d6f48d0f9af (diff) | |
| download | secdiam-ab6d5cefbea1e8ddf41f385dd85918f651958287.tar secdiam-ab6d5cefbea1e8ddf41f385dd85918f651958287.tar.gz secdiam-ab6d5cefbea1e8ddf41f385dd85918f651958287.tar.bz2 secdiam-ab6d5cefbea1e8ddf41f385dd85918f651958287.tar.lz secdiam-ab6d5cefbea1e8ddf41f385dd85918f651958287.tar.xz secdiam-ab6d5cefbea1e8ddf41f385dd85918f651958287.tar.zst secdiam-ab6d5cefbea1e8ddf41f385dd85918f651958287.zip | |
hack to allow impersonator to impersonate target
Diffstat (limited to '')
| -rw-r--r-- | crates/secd/src/client/store/mod.rs | 53 | ||||
| -rw-r--r-- | crates/secd/src/client/store/sql_db.rs | 70 |
2 files changed, 115 insertions, 8 deletions
diff --git a/crates/secd/src/client/store/mod.rs b/crates/secd/src/client/store/mod.rs index 6c42dba..f08aa41 100644 --- a/crates/secd/src/client/store/mod.rs +++ b/crates/secd/src/client/store/mod.rs @@ -1,4 +1,4 @@ -pub(crate) mod sql_db; +pub mod sql_db; use async_trait::async_trait; use sqlx::{Postgres, Sqlite}; @@ -7,7 +7,7 @@ use uuid::Uuid; use crate::{ Address, AddressType, AddressValidation, Credential, CredentialId, CredentialType, Identity, - IdentityId, + IdentityId, Impersonator, }; use self::sql_db::SqlClient; @@ -19,6 +19,7 @@ pub enum StoreError { ParseError(#[from] strum::ParseError), StoreValueCannotBeParsedInvariant, IdempotentCheckAlreadyExists, + ExpectedEntity, } #[async_trait] @@ -32,7 +33,7 @@ pub enum StoreType { } #[async_trait] -pub(crate) trait Storable<'a> { +pub trait Storable<'a> { type Item; type Lens; @@ -43,33 +44,39 @@ pub(crate) trait Storable<'a> { ) -> Result<Vec<Self::Item>, StoreError>; } -pub(crate) trait Lens {} +pub trait Lens {} -pub(crate) struct AddressLens<'a> { +pub struct AddressLens<'a> { pub id: Option<&'a Uuid>, pub t: Option<&'a AddressType>, } impl<'a> Lens for AddressLens<'a> {} -pub(crate) struct AddressValidationLens<'a> { +pub struct AddressValidationLens<'a> { pub id: Option<&'a Uuid>, } impl<'a> Lens for AddressValidationLens<'a> {} -pub(crate) struct IdentityLens<'a> { +pub struct IdentityLens<'a> { pub id: Option<&'a Uuid>, pub address_type: Option<&'a AddressType>, pub validated_address: Option<bool>, } impl<'a> Lens for IdentityLens<'a> {} -pub(crate) struct CredentialLens<'a> { +pub struct CredentialLens<'a> { pub id: Option<CredentialId>, pub identity_id: Option<IdentityId>, pub t: Option<&'a CredentialType>, } impl<'a> Lens for CredentialLens<'a> {} +pub struct ImpersonatorLens<'a> { + pub impersonator_id: Option<&'a IdentityId>, + pub target_id: Option<&'a IdentityId>, +} +impl<'a> Lens for ImpersonatorLens<'a> {} + #[async_trait] impl<'a> Storable<'a> for Address { type Item = Address; @@ -179,3 +186,33 @@ impl<'a> Storable<'a> for Credential { }) } } + +#[async_trait] +impl<'a> Storable<'a> for Impersonator { + type Item = Impersonator; + type Lens = ImpersonatorLens<'a>; + + async fn write(&self, store: Arc<dyn Store>) -> Result<(), StoreError> { + match store.get_type() { + StoreType::Postgres { c } => c.write_impersonator(self).await?, + StoreType::Sqlite { c } => c.write_impersonator(self).await?, + } + Ok(()) + } + + async fn find( + store: Arc<dyn Store>, + lens: &'a Self::Lens, + ) -> Result<Vec<Self::Item>, StoreError> { + Ok(match store.get_type() { + StoreType::Postgres { c } => { + c.find_impersonator(lens.impersonator_id, lens.target_id) + .await? + } + StoreType::Sqlite { c } => { + c.find_impersonator(lens.impersonator_id, lens.target_id) + .await? + } + }) + } +} diff --git a/crates/secd/src/client/store/sql_db.rs b/crates/secd/src/client/store/sql_db.rs index 7b3a68e..5777704 100644 --- a/crates/secd/src/client/store/sql_db.rs +++ b/crates/secd/src/client/store/sql_db.rs @@ -1,4 +1,5 @@ use super::{Store, StoreError, StoreType}; +use crate::Impersonator; use crate::{ util::ErrorContext, Address, AddressType, AddressValidation, AddressValidationMethod, Credential, CredentialId, CredentialType, Identity, IdentityId, @@ -26,6 +27,8 @@ const WRITE_CREDENTIAL: &str = "write_credential"; const FIND_CREDENTIAL: &str = "find_credential"; const WRITE_IDENTITY: &str = "write_identity"; const FIND_IDENTITY: &str = "find_identity"; +const WRITE_IMPERSONATOR: &str = "write_impersonator"; +const FIND_IMPERSONATOR: &str = "find_impersonator"; const ERR_MSG_MIGRATION_FAILED: &str = "Failed to apply secd migrations to a sql db. File a bug at https://www.github.com/branchcontrol/secdiam"; @@ -64,6 +67,14 @@ lazy_static! { FIND_CREDENTIAL, include_str!("../../../store/sqlite/sql/find_credential.sql"), ), + ( + WRITE_IMPERSONATOR, + include_str!("../../../store/sqlite/sql/write_impersonator.sql"), + ), + ( + FIND_IMPERSONATOR, + include_str!("../../../store/sqlite/sql/find_impersonator.sql"), + ), ] .iter() .cloned() @@ -102,6 +113,14 @@ lazy_static! { FIND_CREDENTIAL, include_str!("../../../store/pg/sql/find_credential.sql"), ), + ( + WRITE_IMPERSONATOR, + include_str!("../../../store/pg/sql/write_impersonator.sql"), + ), + ( + FIND_IMPERSONATOR, + include_str!("../../../store/pg/sql/find_impersonator.sql"), + ), ] .iter() .cloned() @@ -525,6 +544,57 @@ where Ok(res) } + + pub async fn write_impersonator(&self, i: &Impersonator) -> Result<(), StoreError> { + let sqls = get_sqls(&self.sqls_root, WRITE_IMPERSONATOR); + sqlx::query(&sqls[0]) + .bind(i.impersonator.id) + .bind(i.target.id) + .bind(i.target.new_credentials.get(0).map(|e| &e.id)) + .bind(i.created_at) + .fetch_all(&self.pool) + .await + .extend_err()?; + Ok(()) + } + pub async fn find_impersonator( + &self, + impersonator_id: Option<&Uuid>, + target_id: Option<&Uuid>, + ) -> Result<Vec<Impersonator>, StoreError> { + let sqls = get_sqls(&self.sqls_root, FIND_IMPERSONATOR); + let rs = sqlx::query_as::<_, (Uuid, Uuid, OffsetDateTime)>(&sqls[0]) + .bind(impersonator_id) + .bind(target_id) + .bind(OffsetDateTime::now_utc()) + .fetch_all(&self.pool) + .await + .extend_err()?; + + let mut res = vec![]; + for (impersonator_id, target_id, created_at) in rs.into_iter() { + let impersonator = self + .find_identity(Some(&impersonator_id), None, None) + .await? + .into_iter() + .next() + .ok_or(StoreError::ExpectedEntity)?; + let target = self + .find_identity(Some(&target_id), None, None) + .await? + .into_iter() + .next() + .ok_or(StoreError::ExpectedEntity)?; + + res.push(Impersonator { + impersonator, + target, + created_at, + }) + } + + Ok(res) + } } fn get_sqls(root: &str, file: &str) -> Vec<String> { |
