Skip to content

Commit 47dd24d

Browse files
committed
fix: correct erroneous DeviceDID to CanonicalDid
1 parent a03b0f7 commit 47dd24d

20 files changed

Lines changed: 153 additions & 56 deletions

File tree

crates/auths-id/src/attestation/create.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,15 @@ pub fn create_signed_attestation(
9494
#[allow(clippy::disallowed_methods)]
9595
// INVARIANT: identity_did is an IdentityDID which guarantees valid DID format
9696
let issuer_canonical = CanonicalDid::new_unchecked(identity_did.as_str());
97+
#[allow(clippy::disallowed_methods)]
98+
// INVARIANT: device_did is a validated DeviceDID from the caller
99+
let subject_canonical = CanonicalDid::new_unchecked(device_did.as_str());
97100
let delegated_canonical = delegated_by.as_ref().map(|d| CanonicalDid::from(d.clone()));
98101
let data_to_canonicalize = CanonicalAttestationData {
99102
version: ATTESTATION_VERSION,
100103
rid,
101104
issuer: &issuer_canonical,
102-
subject: device_did,
105+
subject: &subject_canonical,
103106
device_public_key,
104107
payload: &payload,
105108
timestamp: &meta.timestamp,
@@ -161,7 +164,7 @@ pub fn create_signed_attestation(
161164
// Construct final attestation
162165
Ok(Attestation {
163166
version: ATTESTATION_VERSION,
164-
subject: device_did.clone(),
167+
subject: subject_canonical,
165168
issuer: issuer_canonical,
166169
rid: ResourceId::new(rid),
167170
payload: payload.clone(),

crates/auths-id/src/attestation/revoke.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ pub fn create_signed_revocation(
8888
let revocation_issuer = CanonicalDid::new_unchecked(identity_did.as_str());
8989
Ok(Attestation {
9090
version: REVOCATION_VERSION,
91-
subject: device_did.clone(),
91+
#[allow(clippy::disallowed_methods)]
92+
// INVARIANT: device_did is a validated DeviceDID from the caller
93+
subject: CanonicalDid::new_unchecked(device_did.as_str()),
9294
issuer: revocation_issuer,
9395
rid: ResourceId::new(rid),
9496
payload: payload_arg.clone(),

crates/auths-id/src/policy/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub fn context_from_attestation(
7272
att: &Attestation,
7373
now: DateTime<Utc>,
7474
) -> Result<EvalContext, DidParseError> {
75-
let mut ctx = EvalContext::try_from_strings(now, &att.issuer, &att.subject.to_string())?;
75+
let mut ctx = EvalContext::try_from_strings(now, &att.issuer, att.subject.as_ref())?;
7676

7777
ctx = ctx.revoked(att.is_revoked());
7878

crates/auths-id/src/storage/indexed.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,11 @@ impl AttestationSource for IndexedAttestationStorage {
151151
return self.inner.discover_device_dids();
152152
}
153153

154-
// Collect unique device DIDs from the index
155-
let mut dids: Vec<DeviceDID> = active.into_iter().map(|a| a.device_did.clone()).collect();
154+
// Collect unique device DIDs from the index (filter to did:key: only)
155+
let mut dids: Vec<DeviceDID> = active
156+
.into_iter()
157+
.filter_map(|a| DeviceDID::parse(a.device_did.as_str()).ok())
158+
.collect();
156159
dids.sort_by(|a, b| a.as_str().cmp(b.as_str()));
157160
dids.dedup();
158161
Ok(dids)

crates/auths-id/src/testing/contracts/registry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ macro_rules! registry_backend_contract_tests {
166166
loaded.is_some(),
167167
"attestation should be present after store"
168168
);
169-
assert_eq!(loaded.unwrap().subject, did);
169+
assert_eq!(loaded.unwrap().subject.as_str(), did.as_str());
170170
}
171171

172172
#[test]

crates/auths-id/src/testing/fakes/attestation.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl AttestationSource for FakeAttestationSource {
6565
let guard = self.attestations.lock().unwrap();
6666
Ok(guard
6767
.iter()
68-
.filter(|a| a.subject == *device_did)
68+
.filter(|a| a.subject.as_str() == device_did.as_str())
6969
.cloned()
7070
.collect())
7171
}
@@ -76,8 +76,10 @@ impl AttestationSource for FakeAttestationSource {
7676

7777
fn discover_device_dids(&self) -> Result<Vec<DeviceDID>, StorageError> {
7878
let guard = self.attestations.lock().unwrap();
79-
let dids: std::collections::HashSet<DeviceDID> =
80-
guard.iter().map(|a| a.subject.clone()).collect();
79+
let dids: std::collections::HashSet<DeviceDID> = guard
80+
.iter()
81+
.filter_map(|a| DeviceDID::parse(a.subject.as_str()).ok())
82+
.collect();
8183
Ok(dids.into_iter().collect())
8284
}
8385
}

crates/auths-id/src/testing/fakes/registry.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use crate::storage::registry::schemas::{RegistryMetadata, TipInfo};
1717
struct FakeState {
1818
events: HashMap<String, Vec<Event>>,
1919
key_states: HashMap<String, KeyState>,
20-
attestations: HashMap<DeviceDID, Attestation>,
21-
attestation_history: HashMap<DeviceDID, Vec<Attestation>>,
20+
attestations: HashMap<CanonicalDid, Attestation>,
21+
attestation_history: HashMap<CanonicalDid, Vec<Attestation>>,
2222
org_members: HashMap<(String, String), Attestation>,
2323
}
2424

@@ -205,7 +205,10 @@ impl RegistryBackend for FakeRegistryBackend {
205205

206206
fn load_attestation(&self, did: &DeviceDID) -> Result<Option<Attestation>, RegistryError> {
207207
let state = self.state.lock().unwrap();
208-
Ok(state.attestations.get(did).cloned())
208+
#[allow(clippy::disallowed_methods)]
209+
// INVARIANT: did.as_str() is a valid DID string from DeviceDID
210+
let canonical = CanonicalDid::new_unchecked(did.as_str());
211+
Ok(state.attestations.get(&canonical).cloned())
209212
}
210213

211214
fn visit_attestation_history(
@@ -214,7 +217,10 @@ impl RegistryBackend for FakeRegistryBackend {
214217
visitor: &mut dyn FnMut(&Attestation) -> ControlFlow<()>,
215218
) -> Result<(), RegistryError> {
216219
let state = self.state.lock().unwrap();
217-
if let Some(history) = state.attestation_history.get(did) {
220+
#[allow(clippy::disallowed_methods)]
221+
// INVARIANT: did.as_str() is a valid DID string from DeviceDID
222+
let canonical = CanonicalDid::new_unchecked(did.as_str());
223+
if let Some(history) = state.attestation_history.get(&canonical) {
218224
for att in history {
219225
if visitor(att).is_break() {
220226
break;
@@ -229,8 +235,10 @@ impl RegistryBackend for FakeRegistryBackend {
229235
visitor: &mut dyn FnMut(&DeviceDID) -> ControlFlow<()>,
230236
) -> Result<(), RegistryError> {
231237
let state = self.state.lock().unwrap();
232-
for did in state.attestations.keys() {
233-
if visitor(did).is_break() {
238+
for canonical_did in state.attestations.keys() {
239+
if let Ok(device_did) = DeviceDID::parse(canonical_did.as_str())
240+
&& visitor(&device_did).is_break()
241+
{
234242
break;
235243
}
236244
}

crates/auths-id/src/testing/fixtures.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub fn test_attestation(device_did: &DeviceDID, issuer: &str) -> Attestation {
8282
version: 1,
8383
rid: ResourceId::new("test-rid"),
8484
issuer,
85-
subject: device_did.clone(),
85+
subject: device_did.clone().into(),
8686
device_public_key: Ed25519PublicKey::from_bytes([0u8; 32]),
8787
identity_signature: Ed25519Signature::empty(),
8888
device_signature: Ed25519Signature::empty(),

crates/auths-index/src/index.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::error::Result;
22
use crate::schema;
33
use auths_verifier::core::{CommitOid, ResourceId};
44
use auths_verifier::keri::{Prefix, Said};
5-
use auths_verifier::types::{CanonicalDid, DeviceDID, IdentityDID};
5+
use auths_verifier::types::{CanonicalDid, IdentityDID};
66
use chrono::{DateTime, Utc};
77
use serde::{Deserialize, Serialize};
88
use sqlite::Connection;
@@ -16,8 +16,8 @@ pub struct IndexedAttestation {
1616
pub rid: ResourceId,
1717
/// DID of the issuer (controller)
1818
pub issuer_did: IdentityDID,
19-
/// DID of the device this attestation is for
20-
pub device_did: DeviceDID,
19+
/// DID of the attestation subject (device or identity).
20+
pub device_did: CanonicalDid,
2121
/// Git ref path (e.g., refs/auths/devices/nodes/...)
2222
pub git_ref: String,
2323
/// Git commit OID for loading full attestation (None when OID is not yet known)
@@ -281,7 +281,7 @@ impl AttestationIndex {
281281
let issuer_did = IdentityDID::new_unchecked(issuer_did);
282282
#[allow(clippy::disallowed_methods)]
283283
// INVARIANT: device_did was validated on insert via upsert_attestation and stored in SQLite
284-
let device_did = DeviceDID::new_unchecked(device_did);
284+
let device_did = CanonicalDid::new_unchecked(device_did);
285285

286286
Ok(IndexedAttestation {
287287
rid: ResourceId::new(rid),
@@ -479,7 +479,7 @@ mod tests {
479479
#[allow(clippy::disallowed_methods)] // INVARIANT: test-only hardcoded DID string literal
480480
let issuer_did = IdentityDID::new_unchecked("did:key:issuer123");
481481
#[allow(clippy::disallowed_methods)] // INVARIANT: test-only DID string from caller
482-
let device_did = DeviceDID::new_unchecked(device);
482+
let device_did = CanonicalDid::new_unchecked(device);
483483

484484
IndexedAttestation {
485485
rid: ResourceId::new(rid),

crates/auths-index/src/rebuild.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::error::Result;
22
use crate::index::{AttestationIndex, IndexedAttestation};
33
use auths_verifier::core::{CommitOid, ResourceId};
4-
use auths_verifier::types::{DeviceDID, IdentityDID};
4+
use auths_verifier::types::{CanonicalDid, IdentityDID};
55
use chrono::Utc;
66
use git2::Repository;
77
use std::path::Path;
@@ -123,7 +123,7 @@ fn extract_attestation_from_ref(
123123
let issuer_did = IdentityDID::new_unchecked(&issuer_did);
124124
#[allow(clippy::disallowed_methods)]
125125
// INVARIANT: device_did extracted from attestation JSON stored in a signed Git commit
126-
let device_did = DeviceDID::new_unchecked(&device_did);
126+
let device_did = CanonicalDid::new_unchecked(&device_did);
127127

128128
Ok(IndexedAttestation {
129129
rid: ResourceId::new(rid),

0 commit comments

Comments
 (0)