1use jose_jwk::Jwk;
2use serde::{Deserialize, Serialize};
3use serde_with::{serde_as, skip_serializing_none};
4
5use crate::{
6 did::Did,
7 did_url::{DidUrl, RelativeDidUrl},
8};
9
10#[skip_serializing_none]
11#[derive(Serialize, Deserialize, Debug, PartialEq)]
12#[serde(rename_all = "camelCase")]
13#[serde_as]
14pub struct Document {
15 pub id: Did,
16 pub also_known_as: Option<Vec<String>>,
17 #[serde_as(as = "Option<OneOrMany<_>>")]
18 pub controller: Option<Vec<Did>>,
19 pub verification_method: Option<Vec<VerificationMethodMap>>,
20 pub authentication: Option<Vec<VerificationMethod>>,
21 pub assertion_method: Option<Vec<VerificationMethod>>,
22 pub key_agreement: Option<Vec<VerificationMethod>>,
23 pub capability_invocation: Option<Vec<VerificationMethod>>,
24 pub capability_delegation: Option<Vec<VerificationMethod>>,
25 pub service: Option<Vec<ServiceEndpoint>>,
26}
27
28impl Document {
29 pub fn resolve_verification_method(
32 &self,
33 url: &DidUrl,
34 role: VerificationRole,
35 ) -> Option<VerificationMethodMap> {
36 let methods = match role {
37 VerificationRole::Assertion => self.assertion_method.as_deref(),
38 VerificationRole::Authentication => self.authentication.as_deref(),
39 VerificationRole::CapabilityDelegation => self.capability_delegation.as_deref(),
40 VerificationRole::CapabilityInvocation => self.capability_invocation.as_deref(),
41 VerificationRole::KeyAgreement => self.key_agreement.as_deref(),
42 }
43 .unwrap_or_default();
44
45 for method in methods {
46 match method {
47 VerificationMethod::Map(map) => {
48 if map.id == *url {
49 return Some(*map.clone());
50 }
51 }
52 VerificationMethod::RelativeUrl(relative_url) => {
53 return self.resolve_relative_url(relative_url);
54 }
55 VerificationMethod::Url(method_url) => {
56 if method_url.did == url.did {
57 if let Some(relative_url) = method_url.to_relative() {
58 return self.resolve_relative_url(&relative_url);
59 }
60 } else {
61 }
63 }
64 }
65 }
66
67 None
68 }
69
70 fn resolve_relative_url(&self, url: &RelativeDidUrl) -> Option<VerificationMethodMap> {
71 for method in self.verification_method.as_deref().unwrap_or_default() {
72 if method.id.to_relative().as_ref() == Some(url) {
73 return Some(method.clone());
74 }
75 }
76
77 None
78 }
79}
80
81#[derive(Debug, Copy, Clone, PartialEq, Eq)]
82pub enum VerificationRole {
83 Assertion,
84 Authentication,
85 CapabilityDelegation,
86 CapabilityInvocation,
87 KeyAgreement,
88}
89
90#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
91#[serde(untagged)]
92pub enum VerificationMethod {
93 Map(Box<VerificationMethodMap>),
94 RelativeUrl(RelativeDidUrl),
95 Url(DidUrl),
96}
97
98#[skip_serializing_none]
99#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
100pub struct VerificationMethodMap {
101 pub id: DidUrl,
102 pub controller: Did,
103 #[serde(rename = "type")]
104 pub typ: String,
105 pub public_key_jwk: Option<Jwk>,
106 pub public_key_multibase: Option<String>,
108}
109
110#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
111#[serde_as]
112pub struct ServiceEndpoint {
113 pub id: String,
114 #[serde(rename = "type")]
115 #[serde_as(as = "OneOrMany<_>")]
116 pub typ: Vec<String>,
117}