aboutsummaryrefslogtreecommitdiff
path: root/crates/secd/src/client
diff options
context:
space:
mode:
authorbenj <benj@rse8.com>2023-06-19 17:18:21 -0700
committerbenj <benj@rse8.com>2023-06-19 17:18:21 -0700
commitab6d5cefbea1e8ddf41f385dd85918f651958287 (patch)
treeac3a6b45b1a0e6a833a627307d07e94a95ba3c23 /crates/secd/src/client
parent3406b370fe290559ff2445097a380d6f48d0f9af (diff)
downloadsecdiam-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.rs53
-rw-r--r--crates/secd/src/client/store/sql_db.rs70
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> {