aboutsummaryrefslogtreecommitdiff
path: root/crates/secd/src/auth
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/auth
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 'crates/secd/src/auth')
-rw-r--r--crates/secd/src/auth/n.rs91
-rw-r--r--crates/secd/src/auth/z/mod.rs3
2 files changed, 86 insertions, 8 deletions
diff --git a/crates/secd/src/auth/n.rs b/crates/secd/src/auth/n.rs
index dde6e7d..12a5411 100644
--- a/crates/secd/src/auth/n.rs
+++ b/crates/secd/src/auth/n.rs
@@ -5,12 +5,13 @@ use crate::{
DEFAULT_SIGNUP_EMAIL,
},
store::{
- AddressLens, AddressValidationLens, CredentialLens, IdentityLens, Storable, StoreError,
+ AddressLens, AddressValidationLens, CredentialLens, IdentityLens, ImpersonatorLens,
+ Storable, StoreError,
},
},
util::{self, ErrorContext},
Address, AddressType, AddressValidation, AddressValidationId, AddressValidationMethod,
- Credential, CredentialId, CredentialType, Identity, IdentityId, Secd, SecdError,
+ Credential, CredentialId, CredentialType, Identity, IdentityId, Impersonator, Secd, SecdError,
ADDRESSS_VALIDATION_CODE_SIZE, ADDRESS_VALIDATION_ALLOWS_ATTEMPTS,
ADDRESS_VALIDATION_IDENTITY_SURJECTION, EMAIL_VALIDATION_DURATION,
};
@@ -19,6 +20,7 @@ use log::warn;
use rand::Rng;
use std::str::FromStr;
use time::{Duration, OffsetDateTime};
+use tokio::join;
use uuid::Uuid;
impl Secd {
@@ -363,13 +365,13 @@ impl Secd {
Ok(identity)
}
- pub async fn validate_credential(&self, t: CredentialType) -> Result<Credential, SecdError> {
+ pub async fn validate_credential(&self, t: &CredentialType) -> Result<Credential, SecdError> {
let mut retrieved = Credential::find(
self.store.clone(),
&CredentialLens {
id: None,
identity_id: None,
- t: Some(&t),
+ t: Some(t),
},
)
.await?
@@ -396,7 +398,7 @@ impl Secd {
retrieved.hash_compare(&t, &self.crypter)?;
// Return the initially provided plaintext credential since it's valid
- retrieved.t = t;
+ retrieved.t = t.clone();
Ok(retrieved)
}
@@ -503,4 +505,83 @@ impl Secd {
credential.write(self.store.clone()).await?;
Ok(())
}
+
+ pub async fn impersonate(
+ &self,
+ impersonator_id: &IdentityId,
+ target_id: &IdentityId,
+ ) -> Result<Credential, SecdError> {
+ let impersonator_lens = IdentityLens {
+ id: Some(&impersonator_id),
+ address_type: None,
+ validated_address: None,
+ };
+ let target_lens = IdentityLens {
+ id: Some(&target_id),
+ address_type: None,
+ validated_address: None,
+ };
+ let (i, t) = join!(
+ Identity::find(self.store.clone(), &impersonator_lens,),
+ Identity::find(self.store.clone(), &target_lens,)
+ );
+
+ let (i, t) = (
+ i.ctx("failed to retrieve impersonator identity")?,
+ t.ctx("failed to retrieve target identity")?,
+ );
+ if i.is_empty() || t.is_empty() {
+ return Err(SecdError::IdentityNotFound)
+ .ctx("failed to retrieve impersonator or target identity for impersonation");
+ }
+
+ let existing_impersonation = Impersonator::find(
+ self.store.clone(),
+ &ImpersonatorLens {
+ impersonator_id: Some(impersonator_id),
+ target_id: Some(target_id),
+ },
+ )
+ .await
+ .ctx("failed to find existing impersonation")?;
+
+ // TODO: We could expire the session chain, but I think we want to handle this more intelligently.
+ // For now, just revoke the credential manually...pita I know...
+ if !existing_impersonation.is_empty() {
+ return Err(SecdError::ImpersonatorAlreadyExists)
+ .ctx("Target already being impersonated by the provided impersonator identity");
+ }
+
+ let new_identity = self
+ .create_credential(
+ Credential::new_session(*target_id)?.t,
+ Some(*target_id),
+ OffsetDateTime::now_utc().checked_add(Duration::minutes(30)),
+ )
+ .await
+ .ctx("failed to create new credential for target identity")?;
+
+ let new_session = new_identity
+ .new_credentials
+ .iter()
+ .next()
+ .ok_or(SecdError::InvalidCredential)
+ .ctx("failed to retrieve new session from newly created target credential")?
+ .clone();
+
+ Impersonator {
+ impersonator: i
+ .into_iter()
+ .next()
+ .ok_or(SecdError::IdentityNotFound)
+ .ctx("failed to find impersonator identity")?,
+ target: new_identity,
+ created_at: OffsetDateTime::now_utc(),
+ }
+ .write(self.store.clone())
+ .await
+ .ctx("failed to write new impersonator")?;
+
+ Ok(new_session)
+ }
}
diff --git a/crates/secd/src/auth/z/mod.rs b/crates/secd/src/auth/z/mod.rs
index d64f674..bde319a 100644
--- a/crates/secd/src/auth/z/mod.rs
+++ b/crates/secd/src/auth/z/mod.rs
@@ -49,9 +49,6 @@ impl Authorization for Secd {
.map(|e| Uuid::parse_str(e).unwrap())
.collect())
}
- async fn check_list_subjects(&self) -> Result<Vec<i32>, SecdError> {
- unimplemented!()
- }
async fn write(&self, ts: &[Relationship]) -> Result<(), SecdError> {
let spice = self
.spice