1use core::convert::TryInto as _;
5use core::fmt::Display;
6use core::fmt::Formatter;
7use std::collections::HashMap;
8use std::convert::Infallible;
9
10use identity_did::DIDCompositeJwk;
11use identity_did::DIDJwk;
12use identity_verification::jose::jwk::Jwk;
13use identity_verification::jose::jws::DecodedJws;
14use identity_verification::jose::jws::Decoder;
15use identity_verification::jose::jws::JwsVerifier;
16use serde::Serialize;
17
18use identity_core::common::Object;
19use identity_core::common::OneOrSet;
20use identity_core::common::OrderedSet;
21use identity_core::common::Url;
22use identity_core::convert::FmtJson;
23use serde::Serializer;
24
25use crate::document::DocumentBuilder;
26use crate::error::Error;
27use crate::error::Result;
28use crate::service::Service;
29use crate::utils::DIDUrlQuery;
30use crate::utils::Queryable;
31use crate::verifiable::JwsVerificationOptions;
32use identity_did::CoreDID;
33use identity_did::DIDUrl;
34use identity_verification::MethodRef;
35use identity_verification::MethodRelationship;
36use identity_verification::MethodScope;
37use identity_verification::VerificationMethod;
38
39#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
40#[rustfmt::skip]
41pub(crate) struct CoreDocumentData
42{
43 pub(crate) id: CoreDID,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub(crate) controller: Option<OneOrSet<CoreDID>>,
46 #[serde(default = "Default::default", rename = "alsoKnownAs", skip_serializing_if = "OrderedSet::is_empty")]
47 pub(crate) also_known_as: OrderedSet<Url>,
48 #[serde(default = "Default::default", rename = "verificationMethod", skip_serializing_if = "OrderedSet::is_empty")]
49 pub(crate) verification_method: OrderedSet<VerificationMethod>,
50 #[serde(default = "Default::default", skip_serializing_if = "OrderedSet::is_empty")]
51 pub(crate) authentication: OrderedSet<MethodRef>,
52 #[serde(default = "Default::default", rename = "assertionMethod", skip_serializing_if = "OrderedSet::is_empty")]
53 pub(crate) assertion_method: OrderedSet<MethodRef>,
54 #[serde(default = "Default::default", rename = "keyAgreement", skip_serializing_if = "OrderedSet::is_empty")]
55 pub(crate) key_agreement: OrderedSet<MethodRef>,
56 #[serde(default = "Default::default", rename = "capabilityDelegation", skip_serializing_if = "OrderedSet::is_empty")]
57 pub(crate) capability_delegation: OrderedSet<MethodRef>,
58 #[serde(default = "Default::default", rename = "capabilityInvocation", skip_serializing_if = "OrderedSet::is_empty")]
59 pub(crate) capability_invocation: OrderedSet<MethodRef>,
60 #[serde(default = "Default::default", skip_serializing_if = "OrderedSet::is_empty")]
61 pub(crate) service: OrderedSet<Service>,
62 #[serde(flatten)]
63 pub(crate) properties: Object,
64}
65
66impl CoreDocumentData {
67 fn check_id_constraints(&self) -> Result<()> {
72 let max_unique_method_ids = self.verification_method.len()
73 + self.authentication.len()
74 + self.assertion_method.len()
75 + self.key_agreement.len()
76 + self.capability_delegation.len()
77 + self.capability_invocation.len();
78
79 let mut method_identifiers: HashMap<&DIDUrl, bool> = HashMap::with_capacity(max_unique_method_ids);
82
83 for (id, is_embedded) in self
84 .authentication
85 .iter()
86 .chain(self.assertion_method.iter())
87 .chain(self.key_agreement.iter())
88 .chain(self.capability_delegation.iter())
89 .chain(self.capability_invocation.iter())
90 .map(|method_ref| match method_ref {
91 MethodRef::Embed(_) => (method_ref.id(), true),
92 MethodRef::Refer(_) => (method_ref.id(), false),
93 })
94 {
95 if let Some(previous) = method_identifiers.insert(id, is_embedded) {
96 match previous {
97 true => {
99 return Err(Error::InvalidDocument(
100 "attempted to construct document with a duplicated or aliased embedded method",
101 None,
102 ));
103 }
104 false => {
106 if is_embedded {
107 return Err(Error::InvalidDocument(
108 "attempted to construct document with an aliased embedded method",
109 None,
110 ));
111 }
112 }
113 }
114 }
115 }
116
117 for method_id in self.verification_method.iter().map(|method| method.id()) {
118 if method_identifiers
119 .insert(method_id, false)
120 .filter(|value| *value)
121 .is_some()
122 {
123 return Err(Error::InvalidDocument(
124 "attempted to construct document with a duplicated embedded method",
125 None,
126 ));
127 }
128 }
129
130 for service_id in self.service.iter().map(|service| service.id()) {
131 if method_identifiers.contains_key(service_id) {
132 return Err(Error::InvalidDocument(
133 "attempted to construct document with a service identifier shared with a verification method",
134 None,
135 ));
136 }
137 }
138
139 Ok(())
140 }
141
142 fn try_map<F, G, H, L, E>(
145 self,
146 id_map: F,
147 mut controller_map: G,
148 mut method_map: H,
149 mut services_map: L,
150 ) -> Result<Self, E>
151 where
152 F: FnOnce(CoreDID) -> std::result::Result<CoreDID, E>,
153 G: FnMut(CoreDID) -> std::result::Result<CoreDID, E>,
154 H: FnMut(CoreDID) -> std::result::Result<CoreDID, E>,
155 L: FnMut(CoreDID) -> std::result::Result<CoreDID, E>,
156 {
157 let current_data = self;
158 let id = id_map(current_data.id)?;
160 let controller = if let Some(controllers) = current_data.controller {
162 Some(controllers.try_map(&mut controller_map)?)
163 } else {
164 None
165 };
166
167 let verification_method = current_data
170 .verification_method
171 .into_iter()
172 .map(|method| method.try_map(&mut method_map))
173 .collect::<Result<_, E>>()?;
174
175 let authentication = current_data
176 .authentication
177 .into_iter()
178 .map(|method_ref| method_ref.try_map(&mut method_map))
179 .collect::<Result<_, E>>()?;
180
181 let assertion_method = current_data
182 .assertion_method
183 .into_iter()
184 .map(|method_ref| method_ref.try_map(&mut method_map))
185 .collect::<Result<_, E>>()?;
186
187 let key_agreement = current_data
188 .key_agreement
189 .into_iter()
190 .map(|method_ref| method_ref.try_map(&mut method_map))
191 .collect::<Result<_, E>>()?;
192
193 let capability_delegation = current_data
194 .capability_delegation
195 .into_iter()
196 .map(|method_ref| method_ref.try_map(&mut method_map))
197 .collect::<Result<_, E>>()?;
198
199 let capability_invocation = current_data
200 .capability_invocation
201 .into_iter()
202 .map(|method_ref| method_ref.try_map(&mut method_map))
203 .collect::<Result<_, E>>()?;
204
205 let service = current_data
207 .service
208 .into_iter()
209 .map(|service| service.try_map(&mut services_map))
210 .collect::<Result<_, E>>()?;
211
212 Ok(CoreDocumentData {
213 id,
214 controller,
215 also_known_as: current_data.also_known_as,
216 verification_method,
217 authentication,
218 assertion_method,
219 key_agreement,
220 capability_delegation,
221 capability_invocation,
222 service,
223 properties: current_data.properties,
224 })
225 }
226}
227
228#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
232#[rustfmt::skip]
233#[serde(try_from = "CoreDocumentData")]
234pub struct CoreDocument
235{
236 pub(crate) data: CoreDocumentData,
237}
238
239impl Serialize for CoreDocument {
241 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
242 where
243 S: Serializer,
244 {
245 self.data.serialize(serializer)
246 }
247}
248
249macro_rules! method_ref_mut_helper {
251 ($doc:ident, $method: ident, $query: ident) => {
252 match $doc.data.$method.query_mut($query.into())? {
253 MethodRef::Embed(method) => Some(method),
254 MethodRef::Refer(ref did) => $doc.data.verification_method.query_mut(did),
255 }
256 };
257}
258
259impl CoreDocument {
260 pub fn builder(properties: Object) -> DocumentBuilder {
264 DocumentBuilder::new(properties)
265 }
266
267 pub fn from_builder(builder: DocumentBuilder) -> Result<Self> {
269 Self::try_from(CoreDocumentData {
270 id: builder.id.ok_or(Error::InvalidDocument("missing id", None))?,
271 controller: Some(builder.controller)
272 .filter(|controllers| !controllers.is_empty())
273 .map(TryFrom::try_from)
274 .transpose()
275 .map_err(|err| Error::InvalidDocument("controller", Some(err)))?,
276 also_known_as: builder
277 .also_known_as
278 .try_into()
279 .map_err(|err| Error::InvalidDocument("also_known_as", Some(err)))?,
280 verification_method: builder
281 .verification_method
282 .try_into()
283 .map_err(|err| Error::InvalidDocument("verification_method", Some(err)))?,
284 authentication: builder
285 .authentication
286 .try_into()
287 .map_err(|err| Error::InvalidDocument("authentication", Some(err)))?,
288 assertion_method: builder
289 .assertion_method
290 .try_into()
291 .map_err(|err| Error::InvalidDocument("assertion_method", Some(err)))?,
292 key_agreement: builder
293 .key_agreement
294 .try_into()
295 .map_err(|err| Error::InvalidDocument("key_agreement", Some(err)))?,
296 capability_delegation: builder
297 .capability_delegation
298 .try_into()
299 .map_err(|err| Error::InvalidDocument("capability_delegation", Some(err)))?,
300 capability_invocation: builder
301 .capability_invocation
302 .try_into()
303 .map_err(|err| Error::InvalidDocument("capability_invocation", Some(err)))?,
304 service: builder
305 .service
306 .try_into()
307 .map_err(|err| Error::InvalidDocument("service", Some(err)))?,
308 properties: builder.properties,
309 })
310 }
311
312 pub fn id(&self) -> &CoreDID {
314 &self.data.id
315 }
316
317 pub fn id_mut_unchecked(&mut self) -> &mut CoreDID {
325 &mut self.data.id
326 }
327
328 pub fn controller(&self) -> Option<&OneOrSet<CoreDID>> {
330 self.data.controller.as_ref()
331 }
332
333 pub fn controller_mut(&mut self) -> &mut Option<OneOrSet<CoreDID>> {
335 &mut self.data.controller
336 }
337
338 pub fn also_known_as(&self) -> &OrderedSet<Url> {
340 &self.data.also_known_as
341 }
342
343 pub fn also_known_as_mut(&mut self) -> &mut OrderedSet<Url> {
345 &mut self.data.also_known_as
346 }
347
348 pub fn verification_method(&self) -> &OrderedSet<VerificationMethod> {
350 &self.data.verification_method
351 }
352
353 pub fn authentication(&self) -> &OrderedSet<MethodRef> {
355 &self.data.authentication
356 }
357
358 pub fn assertion_method(&self) -> &OrderedSet<MethodRef> {
360 &self.data.assertion_method
361 }
362
363 pub fn key_agreement(&self) -> &OrderedSet<MethodRef> {
365 &self.data.key_agreement
366 }
367
368 pub fn capability_delegation(&self) -> &OrderedSet<MethodRef> {
370 &self.data.capability_delegation
371 }
372
373 pub fn capability_invocation(&self) -> &OrderedSet<MethodRef> {
375 &self.data.capability_invocation
376 }
377
378 pub fn service(&self) -> &OrderedSet<Service> {
380 &self.data.service
381 }
382
383 pub fn service_mut_unchecked(&mut self) -> &mut OrderedSet<Service> {
388 &mut self.data.service
389 }
390
391 pub fn properties(&self) -> &Object {
393 &self.data.properties
394 }
395
396 pub fn properties_mut_unchecked(&mut self) -> &mut Object {
404 &mut self.data.properties
405 }
406
407 pub fn insert_method(&mut self, method: VerificationMethod, scope: MethodScope) -> Result<()> {
413 if self.resolve_method(method.id(), None).is_some() || self.service().query(method.id()).is_some() {
418 return Err(Error::MethodInsertionError);
419 }
420 match scope {
421 MethodScope::VerificationMethod => self.data.verification_method.append(method),
422 MethodScope::VerificationRelationship(MethodRelationship::Authentication) => {
423 self.data.authentication.append(MethodRef::Embed(method))
424 }
425 MethodScope::VerificationRelationship(MethodRelationship::AssertionMethod) => {
426 self.data.assertion_method.append(MethodRef::Embed(method))
427 }
428 MethodScope::VerificationRelationship(MethodRelationship::KeyAgreement) => {
429 self.data.key_agreement.append(MethodRef::Embed(method))
430 }
431 MethodScope::VerificationRelationship(MethodRelationship::CapabilityDelegation) => {
432 self.data.capability_delegation.append(MethodRef::Embed(method))
433 }
434 MethodScope::VerificationRelationship(MethodRelationship::CapabilityInvocation) => {
435 self.data.capability_invocation.append(MethodRef::Embed(method))
436 }
437 };
438
439 Ok(())
440 }
441
442 pub fn remove_method(&mut self, did_url: &DIDUrl) -> Option<VerificationMethod> {
449 self.remove_method_and_scope(did_url).map(|(method, _scope)| method)
450 }
451
452 pub fn remove_method_and_scope(&mut self, did_url: &DIDUrl) -> Option<(VerificationMethod, MethodScope)> {
460 for (method_ref, scope) in [
461 self.data.authentication.remove(did_url).map(|method_ref| {
462 (
463 method_ref,
464 MethodScope::VerificationRelationship(MethodRelationship::Authentication),
465 )
466 }),
467 self.data.assertion_method.remove(did_url).map(|method_ref| {
468 (
469 method_ref,
470 MethodScope::VerificationRelationship(MethodRelationship::AssertionMethod),
471 )
472 }),
473 self.data.key_agreement.remove(did_url).map(|method_ref| {
474 (
475 method_ref,
476 MethodScope::VerificationRelationship(MethodRelationship::KeyAgreement),
477 )
478 }),
479 self.data.capability_delegation.remove(did_url).map(|method_ref| {
480 (
481 method_ref,
482 MethodScope::VerificationRelationship(MethodRelationship::CapabilityDelegation),
483 )
484 }),
485 self.data.capability_invocation.remove(did_url).map(|method_ref| {
486 (
487 method_ref,
488 MethodScope::VerificationRelationship(MethodRelationship::CapabilityInvocation),
489 )
490 }),
491 ]
492 .into_iter()
493 .flatten()
494 {
495 if let (MethodRef::Embed(embedded_method), scope) = (method_ref, scope) {
496 return Some((embedded_method, scope));
499 }
500 }
501
502 self
503 .data
504 .verification_method
505 .remove(did_url)
506 .map(|method| (method, MethodScope::VerificationMethod))
507 }
508
509 pub fn insert_service(&mut self, service: Service) -> Result<()> {
515 let service_id = service.id();
516 let id_exists = self
517 .verification_relationships()
518 .map(|method_ref| method_ref.id())
519 .chain(self.verification_method().iter().map(|method| method.id()))
520 .any(|id| id == service_id);
521
522 ((!id_exists) && self.data.service.append(service))
523 .then_some(())
524 .ok_or(Error::InvalidServiceInsertion)
525 }
526
527 pub fn remove_service(&mut self, id: &DIDUrl) -> Option<Service> {
529 self.data.service.remove(id)
530 }
531
532 pub fn attach_method_relationship<'query, Q>(
540 &mut self,
541 method_query: Q,
542 relationship: MethodRelationship,
543 ) -> Result<bool>
544 where
545 Q: Into<DIDUrlQuery<'query>>,
546 {
547 let method_query: DIDUrlQuery<'query> = method_query.into();
548
549 match self.resolve_method(method_query.clone(), Some(MethodScope::VerificationMethod)) {
550 None => match self.resolve_method(method_query, None) {
551 Some(_) => Err(Error::InvalidMethodEmbedded),
552 None => Err(Error::MethodNotFound),
553 },
554 Some(method) => {
555 let method_ref = MethodRef::Refer(method.id().clone());
556
557 let was_attached = match relationship {
558 MethodRelationship::Authentication => self.data.authentication.append(method_ref),
559 MethodRelationship::AssertionMethod => self.data.assertion_method.append(method_ref),
560 MethodRelationship::KeyAgreement => self.data.key_agreement.append(method_ref),
561 MethodRelationship::CapabilityDelegation => self.data.capability_delegation.append(method_ref),
562 MethodRelationship::CapabilityInvocation => self.data.capability_invocation.append(method_ref),
563 };
564
565 Ok(was_attached)
566 }
567 }
568 }
569
570 pub fn detach_method_relationship<'query, Q>(
583 &mut self,
584 method_query: Q,
585 relationship: MethodRelationship,
586 ) -> Result<bool>
587 where
588 Q: Into<DIDUrlQuery<'query>>,
589 {
590 let method_query: DIDUrlQuery<'query> = method_query.into();
591 match self.resolve_method(method_query.clone(), Some(MethodScope::VerificationMethod)) {
592 None => match self.resolve_method(method_query, None) {
593 Some(_) => Err(Error::InvalidMethodEmbedded),
594 None => Err(Error::MethodNotFound),
595 },
596 Some(method) => {
597 let did_url: DIDUrl = method.id().clone();
598
599 let was_detached = match relationship {
600 MethodRelationship::Authentication => self.data.authentication.remove(&did_url),
601 MethodRelationship::AssertionMethod => self.data.assertion_method.remove(&did_url),
602 MethodRelationship::KeyAgreement => self.data.key_agreement.remove(&did_url),
603 MethodRelationship::CapabilityDelegation => self.data.capability_delegation.remove(&did_url),
604 MethodRelationship::CapabilityInvocation => self.data.capability_invocation.remove(&did_url),
605 };
606
607 Ok(was_detached.is_some())
608 }
609 }
610 }
611
612 pub fn methods(&self, scope: Option<MethodScope>) -> Vec<&VerificationMethod> {
616 if let Some(scope) = scope {
617 match scope {
618 MethodScope::VerificationMethod => self.verification_method().iter().collect(),
619 MethodScope::VerificationRelationship(MethodRelationship::AssertionMethod) => self
620 .assertion_method()
621 .iter()
622 .filter_map(|method_ref| self.resolve_method_ref(method_ref))
623 .collect(),
624 MethodScope::VerificationRelationship(MethodRelationship::Authentication) => self
625 .authentication()
626 .iter()
627 .filter_map(|method_ref| self.resolve_method_ref(method_ref))
628 .collect(),
629 MethodScope::VerificationRelationship(MethodRelationship::CapabilityDelegation) => self
630 .capability_delegation()
631 .iter()
632 .filter_map(|method_ref| self.resolve_method_ref(method_ref))
633 .collect(),
634 MethodScope::VerificationRelationship(MethodRelationship::CapabilityInvocation) => self
635 .capability_invocation()
636 .iter()
637 .filter_map(|method_ref| self.resolve_method_ref(method_ref))
638 .collect(),
639 MethodScope::VerificationRelationship(MethodRelationship::KeyAgreement) => self
640 .key_agreement()
641 .iter()
642 .filter_map(|method_ref| self.resolve_method_ref(method_ref))
643 .collect(),
644 }
645 } else {
646 self.all_methods().collect()
647 }
648 }
649
650 fn all_methods(&self) -> impl Iterator<Item = &VerificationMethod> {
654 fn __filter_ref(method: &MethodRef) -> Option<&VerificationMethod> {
655 match method {
656 MethodRef::Embed(method) => Some(method),
657 MethodRef::Refer(_) => None,
658 }
659 }
660
661 self
662 .data
663 .verification_method
664 .iter()
665 .chain(self.data.authentication.iter().filter_map(__filter_ref))
666 .chain(self.data.assertion_method.iter().filter_map(__filter_ref))
667 .chain(self.data.key_agreement.iter().filter_map(__filter_ref))
668 .chain(self.data.capability_delegation.iter().filter_map(__filter_ref))
669 .chain(self.data.capability_invocation.iter().filter_map(__filter_ref))
670 }
671
672 pub fn verification_relationships(&self) -> impl Iterator<Item = &MethodRef> {
676 self
677 .data
678 .authentication
679 .iter()
680 .chain(self.data.assertion_method.iter())
681 .chain(self.data.key_agreement.iter())
682 .chain(self.data.capability_delegation.iter())
683 .chain(self.data.capability_invocation.iter())
684 }
685
686 pub fn resolve_method<'query, 'me, Q>(
691 &'me self,
692 method_query: Q,
693 scope: Option<MethodScope>,
694 ) -> Option<&'me VerificationMethod>
695 where
696 Q: Into<DIDUrlQuery<'query>>,
697 {
698 match scope {
699 Some(scope) => {
700 let resolve_ref_helper = |method_ref: &'me MethodRef| self.resolve_method_ref(method_ref);
701
702 match scope {
703 MethodScope::VerificationMethod => self.data.verification_method.query(method_query.into()),
704 MethodScope::VerificationRelationship(MethodRelationship::Authentication) => self
705 .data
706 .authentication
707 .query(method_query.into())
708 .and_then(resolve_ref_helper),
709 MethodScope::VerificationRelationship(MethodRelationship::AssertionMethod) => self
710 .data
711 .assertion_method
712 .query(method_query.into())
713 .and_then(resolve_ref_helper),
714 MethodScope::VerificationRelationship(MethodRelationship::KeyAgreement) => self
715 .data
716 .key_agreement
717 .query(method_query.into())
718 .and_then(resolve_ref_helper),
719 MethodScope::VerificationRelationship(MethodRelationship::CapabilityDelegation) => self
720 .data
721 .capability_delegation
722 .query(method_query.into())
723 .and_then(resolve_ref_helper),
724 MethodScope::VerificationRelationship(MethodRelationship::CapabilityInvocation) => self
725 .data
726 .capability_invocation
727 .query(method_query.into())
728 .and_then(resolve_ref_helper),
729 }
730 }
731 None => self.resolve_method_inner(method_query.into()),
732 }
733 }
734
735 pub fn resolve_method_mut<'query, 'me, Q>(
744 &'me mut self,
745 method_query: Q,
746 scope: Option<MethodScope>,
747 ) -> Option<&'me mut VerificationMethod>
748 where
749 Q: Into<DIDUrlQuery<'query>>,
750 {
751 match scope {
752 Some(scope) => match scope {
753 MethodScope::VerificationMethod => self.data.verification_method.query_mut(method_query.into()),
754 MethodScope::VerificationRelationship(MethodRelationship::Authentication) => {
755 method_ref_mut_helper!(self, authentication, method_query)
756 }
757 MethodScope::VerificationRelationship(MethodRelationship::AssertionMethod) => {
758 method_ref_mut_helper!(self, assertion_method, method_query)
759 }
760 MethodScope::VerificationRelationship(MethodRelationship::KeyAgreement) => {
761 method_ref_mut_helper!(self, key_agreement, method_query)
762 }
763 MethodScope::VerificationRelationship(MethodRelationship::CapabilityDelegation) => {
764 method_ref_mut_helper!(self, capability_delegation, method_query)
765 }
766 MethodScope::VerificationRelationship(MethodRelationship::CapabilityInvocation) => {
767 method_ref_mut_helper!(self, capability_invocation, method_query)
768 }
769 },
770 None => self.resolve_method_mut_inner(method_query.into()),
771 }
772 }
773
774 pub fn resolve_service<'query, 'me, Q>(&'me self, service_query: Q) -> Option<&'me Service>
778 where
779 Q: Into<DIDUrlQuery<'query>>,
780 {
781 self.service().query(service_query.into())
782 }
783
784 #[doc(hidden)]
785 pub fn resolve_method_ref<'a>(&'a self, method_ref: &'a MethodRef) -> Option<&'a VerificationMethod> {
786 match method_ref {
787 MethodRef::Embed(method) => Some(method),
788 MethodRef::Refer(did) => self.data.verification_method.query(did),
789 }
790 }
791
792 fn resolve_method_inner(&self, query: DIDUrlQuery<'_>) -> Option<&VerificationMethod> {
793 let mut method: Option<&MethodRef> = None;
794
795 if method.is_none() {
796 method = self.data.authentication.query(query.clone());
797 }
798
799 if method.is_none() {
800 method = self.data.assertion_method.query(query.clone());
801 }
802
803 if method.is_none() {
804 method = self.data.key_agreement.query(query.clone());
805 }
806
807 if method.is_none() {
808 method = self.data.capability_delegation.query(query.clone());
809 }
810
811 if method.is_none() {
812 method = self.data.capability_invocation.query(query.clone());
813 }
814
815 match method {
816 Some(MethodRef::Embed(method)) => Some(method),
817 Some(MethodRef::Refer(did)) => self.data.verification_method.query(&did.to_string()),
818 None => self.data.verification_method.query(query),
819 }
820 }
821
822 fn resolve_method_mut_inner(&mut self, query: DIDUrlQuery<'_>) -> Option<&mut VerificationMethod> {
823 let mut method: Option<&mut MethodRef> = None;
824
825 if method.is_none() {
826 method = self.data.authentication.query_mut(query.clone());
827 }
828
829 if method.is_none() {
830 method = self.data.assertion_method.query_mut(query.clone());
831 }
832
833 if method.is_none() {
834 method = self.data.key_agreement.query_mut(query.clone());
835 }
836
837 if method.is_none() {
838 method = self.data.capability_delegation.query_mut(query.clone());
839 }
840
841 if method.is_none() {
842 method = self.data.capability_invocation.query_mut(query.clone());
843 }
844
845 match method {
846 Some(MethodRef::Embed(method)) => Some(method),
847 Some(MethodRef::Refer(did)) => self.data.verification_method.query_mut(&did.to_string()),
848 None => self.data.verification_method.query_mut(query),
849 }
850 }
851
852 pub fn try_map<F, G, H, L, M, E>(
863 self,
864 id_update: F,
865 controller_update: G,
866 methods_update: H,
867 service_update: L,
868 error_cast: M,
869 ) -> Result<Self, E>
870 where
871 F: FnOnce(CoreDID) -> std::result::Result<CoreDID, E>,
872 G: FnMut(CoreDID) -> std::result::Result<CoreDID, E>,
873 H: FnMut(CoreDID) -> std::result::Result<CoreDID, E>,
874 L: FnMut(CoreDID) -> std::result::Result<CoreDID, E>,
875 M: FnOnce(crate::Error) -> E,
876 {
877 let data = self
878 .data
879 .try_map(id_update, controller_update, methods_update, service_update)?;
880 CoreDocument::try_from(data).map_err(error_cast)
881 }
882
883 pub fn map_unchecked<F, G, H, L>(
885 self,
886 id_update: F,
887 mut controller_update: G,
888 mut methods_update: H,
889 mut service_update: L,
890 ) -> Self
891 where
892 F: FnOnce(CoreDID) -> CoreDID,
893 G: FnMut(CoreDID) -> CoreDID,
894 H: FnMut(CoreDID) -> CoreDID,
895 L: FnMut(CoreDID) -> CoreDID,
896 {
897 type InfallibleCoreDIDResult = std::result::Result<CoreDID, Infallible>;
898
899 let id_map = |did: CoreDID| -> InfallibleCoreDIDResult { Ok(id_update(did)) };
900 let controller_map = |did: CoreDID| -> InfallibleCoreDIDResult { Ok(controller_update(did)) };
901 let method_map = |did: CoreDID| -> InfallibleCoreDIDResult { Ok(methods_update(did)) };
902 let services_map = |did: CoreDID| -> InfallibleCoreDIDResult { Ok(service_update(did)) };
903 let data = self
904 .data
905 .try_map(id_map, controller_map, method_map, services_map)
906 .expect("unwrapping infallible should be fine");
907 CoreDocument { data }
908 }
909}
910
911impl AsRef<CoreDocument> for CoreDocument {
912 fn as_ref(&self) -> &CoreDocument {
913 self
914 }
915}
916
917impl TryFrom<CoreDocumentData> for CoreDocument {
918 type Error = crate::error::Error;
919 fn try_from(value: CoreDocumentData) -> Result<Self, Self::Error> {
920 match value.check_id_constraints() {
921 Ok(_) => Ok(Self { data: value }),
922 Err(err) => Err(err),
923 }
924 }
925}
926
927impl Display for CoreDocument {
928 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
929 self.fmt_json(f)
930 }
931}
932
933impl CoreDocument {
937 pub fn verify_jws<'jws, T: JwsVerifier>(
948 &self,
949 jws: &'jws str,
950 detached_payload: Option<&'jws [u8]>,
951 signature_verifier: &T,
952 options: &JwsVerificationOptions,
953 ) -> Result<DecodedJws<'jws>> {
954 let validation_item = Decoder::new()
955 .decode_compact_serialization(jws.as_bytes(), detached_payload)
956 .map_err(Error::JwsVerificationError)?;
957
958 let nonce: Option<&str> = options.nonce.as_deref();
959 if validation_item.nonce() != nonce {
961 return Err(Error::JwsVerificationError(
962 identity_verification::jose::error::Error::InvalidParam("invalid nonce value"),
963 ));
964 }
965
966 let method_url_query: DIDUrlQuery<'_> = match &options.method_id {
967 Some(method_id) => method_id.into(),
968 None => validation_item
969 .kid()
970 .ok_or(Error::JwsVerificationError(
971 identity_verification::jose::error::Error::InvalidParam("missing kid value"),
972 ))?
973 .into(),
974 };
975
976 let public_key: &Jwk = self
977 .resolve_method(method_url_query, options.method_scope)
978 .ok_or(Error::MethodNotFound)?
979 .data()
980 .try_public_key_jwk()
981 .map_err(Error::InvalidKeyMaterial)?;
982
983 validation_item
984 .verify(signature_verifier, public_key)
985 .map_err(Error::JwsVerificationError)
986 }
987
988 pub fn verify_jws_hybrid<'jws, TRV: JwsVerifier, PQV: JwsVerifier>(
999 &self,
1000 jws: &'jws str,
1001 detached_payload: Option<&'jws [u8]>,
1002 traditional_verifier: &TRV,
1003 pq_verifier: &PQV,
1004 options: &JwsVerificationOptions,
1005 ) -> Result<DecodedJws<'jws>> {
1006 let validation_item = Decoder::new()
1007 .decode_compact_serialization(jws.as_bytes(), detached_payload)
1008 .map_err(Error::JwsVerificationError)?;
1009
1010 let nonce: Option<&str> = options.nonce.as_deref();
1011 if validation_item.nonce() != nonce {
1013 return Err(Error::JwsVerificationError(
1014 identity_verification::jose::error::Error::InvalidParam("invalid nonce value"),
1015 ));
1016 }
1017
1018 let method_url_query: DIDUrlQuery<'_> = match &options.method_id {
1019 Some(method_id) => method_id.into(),
1020 None => validation_item
1021 .kid()
1022 .ok_or(Error::JwsVerificationError(
1023 identity_verification::jose::error::Error::InvalidParam("missing kid value"),
1024 ))?
1025 .into(),
1026 };
1027
1028 let composite_public_key = self
1029 .resolve_method(method_url_query, options.method_scope)
1030 .ok_or(Error::MethodNotFound)?
1031 .data()
1032 .try_composite_public_key()
1033 .map_err(Error::InvalidKeyMaterial)?;
1034
1035 validation_item
1036 .verify_hybrid(
1037 traditional_verifier,
1038 pq_verifier,
1039 composite_public_key.traditional_public_key(),
1040 composite_public_key.pq_public_key(),
1041 )
1042 .map_err(Error::JwsVerificationError)
1043 }
1044}
1045
1046impl CoreDocument {
1047 pub fn expand_did_jwk(did_jwk: DIDJwk) -> Result<Self, Error> {
1049 let verification_method = VerificationMethod::try_from(did_jwk.clone()).map_err(Error::InvalidKeyMaterial)?;
1050 let verification_method_id = verification_method.id().clone();
1051
1052 DocumentBuilder::default()
1053 .id(did_jwk.into())
1054 .verification_method(verification_method)
1055 .assertion_method(verification_method_id.clone())
1056 .authentication(verification_method_id.clone())
1057 .capability_invocation(verification_method_id.clone())
1058 .capability_delegation(verification_method_id.clone())
1059 .build()
1060 }
1061}
1062
1063impl CoreDocument {
1064 pub fn expand_did_compositejwk(did_compositejwk: DIDCompositeJwk) -> Result<Self, Error> {
1066 let verification_method =
1067 VerificationMethod::try_from(did_compositejwk.clone()).map_err(Error::InvalidKeyMaterial)?;
1068 let verification_method_id = verification_method.id().clone();
1069
1070 DocumentBuilder::default()
1071 .id(did_compositejwk.into())
1072 .verification_method(verification_method)
1073 .assertion_method(verification_method_id.clone())
1074 .authentication(verification_method_id.clone())
1075 .capability_invocation(verification_method_id.clone())
1076 .capability_delegation(verification_method_id.clone())
1077 .build()
1078 }
1079}
1080
1081#[cfg(test)]
1082mod tests {
1083 use identity_core::convert::FromJson;
1084 use identity_core::convert::ToJson;
1085 use identity_did::DID;
1086 use identity_verification::MethodType;
1087
1088 use crate::service::ServiceBuilder;
1089 use identity_verification::MethodBuilder;
1090 use identity_verification::MethodData;
1091
1092 use super::*;
1093
1094 fn controller() -> CoreDID {
1095 "did:example:1234".parse().unwrap()
1096 }
1097
1098 fn method(controller: &CoreDID, fragment: &str) -> VerificationMethod {
1099 VerificationMethod::builder(Default::default())
1100 .id(controller.to_url().join(fragment).unwrap())
1101 .controller(controller.clone())
1102 .type_(MethodType::ED25519_VERIFICATION_KEY_2018)
1103 .data(MethodData::new_multibase(fragment.as_bytes()))
1104 .build()
1105 .unwrap()
1106 }
1107
1108 fn document() -> CoreDocument {
1109 let controller: CoreDID = controller();
1110
1111 CoreDocument::builder(Default::default())
1112 .id(controller.clone())
1113 .verification_method(method(&controller, "#key-1"))
1114 .verification_method(method(&controller, "#key-2"))
1115 .verification_method(method(&controller, "#key-3"))
1116 .authentication(method(&controller, "#auth-key"))
1117 .authentication(controller.to_url().join("#key-3").unwrap())
1118 .key_agreement(controller.to_url().join("#key-4").unwrap())
1119 .build()
1120 .unwrap()
1121 }
1122
1123 #[test]
1124 fn test_controller() {
1125 {
1127 let mut document: CoreDocument = document();
1128 let expected: CoreDID = CoreDID::parse("did:example:one1234").unwrap();
1129 *document.controller_mut() = Some(OneOrSet::new_one(expected.clone()));
1130 assert_eq!(document.controller().unwrap().as_slice(), &[expected]);
1131 *document.controller_mut() = None;
1133 assert!(document.controller().is_none());
1134 }
1135
1136 {
1138 let mut document: CoreDocument = document();
1139 let expected_controllers: Vec<CoreDID> = vec![
1140 CoreDID::parse("did:example:many1234").unwrap(),
1141 CoreDID::parse("did:example:many4567").unwrap(),
1142 CoreDID::parse("did:example:many8910").unwrap(),
1143 ];
1144 *document.controller_mut() = Some(expected_controllers.clone().try_into().unwrap());
1145 assert_eq!(document.controller().unwrap().as_slice(), &expected_controllers);
1146 *document.controller_mut() = None;
1148 assert!(document.controller().is_none());
1149 }
1150 }
1151
1152 #[rustfmt::skip]
1153 #[test]
1154 fn test_resolve_method() {
1155 let document: CoreDocument = document();
1156
1157 assert_eq!(document.resolve_method("#key-1", None).unwrap().id().to_string(), "did:example:1234#key-1");
1159 assert_eq!(document.resolve_method("#key-2", None).unwrap().id().to_string(), "did:example:1234#key-2");
1160 assert_eq!(document.resolve_method("#key-3", None).unwrap().id().to_string(), "did:example:1234#key-3");
1161
1162 assert_eq!(document.resolve_method("key-1", None).unwrap().id().to_string(), "did:example:1234#key-1");
1164 assert_eq!(document.resolve_method("key-2", None).unwrap().id().to_string(), "did:example:1234#key-2");
1165 assert_eq!(document.resolve_method("key-3", None).unwrap().id().to_string(), "did:example:1234#key-3");
1166
1167 assert_eq!(document.resolve_method("did:example:1234#key-1", None).unwrap().id().to_string(), "did:example:1234#key-1");
1169 assert_eq!(document.resolve_method("did:example:1234#key-2", None).unwrap().id().to_string(), "did:example:1234#key-2");
1170 assert_eq!(document.resolve_method("did:example:1234#key-3", None).unwrap().id().to_string(), "did:example:1234#key-3");
1171
1172 assert_eq!(
1174 document.resolve_method("#key-1", Some(MethodScope::VerificationMethod)).unwrap().id().to_string(), "did:example:1234#key-1"
1175 );
1176 }
1177
1178 #[rustfmt::skip]
1179 #[test]
1180 fn test_resolve_method_mut() {
1181 let mut document: CoreDocument = document();
1182
1183 assert_eq!(document.resolve_method_mut("#key-1", None).unwrap().id().to_string(), "did:example:1234#key-1");
1185 assert_eq!(document.resolve_method_mut("#key-3", None).unwrap().id().to_string(), "did:example:1234#key-3");
1186 assert_eq!(document.resolve_method_mut("#key-2", None).unwrap().id().to_string(), "did:example:1234#key-2");
1187
1188 assert_eq!(document.resolve_method_mut("key-1", None).unwrap().id().to_string(), "did:example:1234#key-1");
1190 assert_eq!(document.resolve_method_mut("key-2", None).unwrap().id().to_string(), "did:example:1234#key-2");
1191 assert_eq!(document.resolve_method_mut("key-3", None).unwrap().id().to_string(), "did:example:1234#key-3");
1192
1193 assert_eq!(document.resolve_method_mut("did:example:1234#key-1", None).unwrap().id().to_string(), "did:example:1234#key-1");
1195 assert_eq!(document.resolve_method_mut("did:example:1234#key-2", None).unwrap().id().to_string(), "did:example:1234#key-2");
1196 assert_eq!(document.resolve_method_mut("did:example:1234#key-3", None).unwrap().id().to_string(), "did:example:1234#key-3");
1197
1198 assert_eq!(
1200 document.resolve_method_mut("#key-1", Some(MethodScope::VerificationMethod)).unwrap().id().to_string(), "did:example:1234#key-1"
1201 );
1202 }
1203
1204 #[test]
1205 fn test_resolve_method_fails() {
1206 let document: CoreDocument = document();
1207
1208 assert_eq!(document.resolve_method("#key-4", None), None);
1210
1211 assert_eq!(document.resolve_method("did:example:1234", None), None);
1213
1214 assert_eq!(document.resolve_method("", None), None);
1216
1217 assert_eq!(
1219 document.resolve_method("#key-1", Some(MethodScope::key_agreement())),
1220 None
1221 );
1222 }
1223
1224 #[test]
1225 fn test_resolve_method_mut_fails() {
1226 let mut document: CoreDocument = document();
1227
1228 assert_eq!(document.resolve_method_mut("#key-4", None), None);
1230
1231 assert_eq!(document.resolve_method_mut("did:example:1234", None), None);
1233
1234 assert_eq!(document.resolve_method_mut("", None), None);
1236
1237 assert_eq!(
1239 document.resolve_method_mut("#key-1", Some(MethodScope::key_agreement())),
1240 None
1241 );
1242 }
1243
1244 #[rustfmt::skip]
1245 #[test]
1246 fn test_methods_index() {
1247 let document: CoreDocument = document();
1248
1249 assert_eq!(document.methods(None).first().unwrap().id().to_string(), "did:example:1234#key-1");
1251 assert_eq!(document.methods(None).get(2).unwrap().id().to_string(), "did:example:1234#key-3");
1252 }
1253
1254 #[test]
1255 fn test_methods_scope() {
1256 let document: CoreDocument = document();
1257
1258 let verification_methods: Vec<&VerificationMethod> = document.methods(Some(MethodScope::VerificationMethod));
1260 assert_eq!(
1261 verification_methods.first().unwrap().id().to_string(),
1262 "did:example:1234#key-1"
1263 );
1264 assert_eq!(
1265 verification_methods.get(1).unwrap().id().to_string(),
1266 "did:example:1234#key-2"
1267 );
1268 assert_eq!(
1269 verification_methods.get(2).unwrap().id().to_string(),
1270 "did:example:1234#key-3"
1271 );
1272 assert_eq!(verification_methods.len(), 3);
1273
1274 let authentication: Vec<&VerificationMethod> = document.methods(Some(MethodScope::authentication()));
1276 assert_eq!(
1277 authentication.first().unwrap().id().to_string(),
1278 "did:example:1234#auth-key"
1279 );
1280 assert_eq!(
1281 authentication.get(1).unwrap().id().to_string(),
1282 "did:example:1234#key-3"
1283 );
1284 assert_eq!(authentication.len(), 2);
1285 }
1286
1287 #[test]
1288 fn test_attach_verification_relationships() {
1289 let mut document: CoreDocument = document();
1290
1291 let fragment = "#attach-test";
1292 let method = method(document.id(), fragment);
1293 document.insert_method(method, MethodScope::VerificationMethod).unwrap();
1294
1295 assert!(document
1296 .attach_method_relationship(
1297 document.id().to_url().join(fragment).unwrap(),
1298 MethodRelationship::CapabilityDelegation,
1299 )
1300 .unwrap());
1301
1302 assert_eq!(document.verification_relationships().count(), 4);
1303
1304 assert!(!document
1306 .attach_method_relationship(
1307 document.id().to_url().join(fragment).unwrap(),
1308 MethodRelationship::CapabilityDelegation,
1309 )
1310 .unwrap());
1311
1312 assert_eq!(document.verification_relationships().count(), 4);
1314
1315 assert!(document
1317 .attach_method_relationship(
1318 document.id().to_url().join("#doesNotExist").unwrap(),
1319 MethodRelationship::CapabilityDelegation,
1320 )
1321 .is_err());
1322
1323 assert!(document
1325 .attach_method_relationship(
1326 document.id().to_url().join("#auth-key").unwrap(),
1327 MethodRelationship::CapabilityDelegation,
1328 )
1329 .is_err());
1330 }
1331
1332 #[test]
1333 fn test_detach_verification_relationships() {
1334 let mut document: CoreDocument = document();
1335
1336 let fragment = "#detach-test";
1337 let method = method(document.id(), fragment);
1338 document.insert_method(method, MethodScope::VerificationMethod).unwrap();
1339
1340 assert!(document
1341 .attach_method_relationship(
1342 document.id().to_url().join(fragment).unwrap(),
1343 MethodRelationship::AssertionMethod,
1344 )
1345 .is_ok());
1346
1347 assert!(document
1348 .detach_method_relationship(
1349 document.id().to_url().join(fragment).unwrap(),
1350 MethodRelationship::AssertionMethod,
1351 )
1352 .unwrap());
1353
1354 assert_eq!(document.verification_relationships().count(), 3);
1356
1357 assert!(!document
1359 .detach_method_relationship(
1360 document.id().to_url().join(fragment).unwrap(),
1361 MethodRelationship::AssertionMethod,
1362 )
1363 .unwrap());
1364
1365 assert_eq!(document.verification_relationships().count(), 3);
1367
1368 assert!(document
1370 .detach_method_relationship(
1371 document.id().to_url().join("#doesNotExist").unwrap(),
1372 MethodRelationship::AssertionMethod,
1373 )
1374 .is_err());
1375 }
1376
1377 #[test]
1378 fn test_method_insert_duplication() {
1379 let mut document: CoreDocument = document();
1380
1381 let fragment = "#duplication-test";
1382 let method1 = method(document.id(), fragment);
1383 assert!(document
1384 .insert_method(method1.clone(), MethodScope::VerificationMethod)
1385 .is_ok());
1386 assert!(document
1387 .insert_method(method1.clone(), MethodScope::VerificationMethod)
1388 .is_err());
1389 assert!(document
1390 .insert_method(method1.clone(), MethodScope::authentication())
1391 .is_err());
1392
1393 let fragment = "#duplication-test-2";
1394 let method2 = method(document.id(), fragment);
1395 assert!(document.insert_method(method2, MethodScope::assertion_method()).is_ok());
1396 assert!(document
1397 .insert_method(method1.clone(), MethodScope::VerificationMethod)
1398 .is_err());
1399 assert!(document
1400 .insert_method(method1, MethodScope::capability_delegation())
1401 .is_err());
1402 }
1403
1404 #[test]
1405 fn test_method_remove_existence() {
1406 let mut document: CoreDocument = document();
1407
1408 let fragment = "#existence-test";
1409 let method1 = method(document.id(), fragment);
1410 assert!(document
1411 .insert_method(method1.clone(), MethodScope::VerificationMethod)
1412 .is_ok());
1413 assert_eq!(method1, document.remove_method(method1.id()).unwrap());
1414 assert!(document.remove_method(method1.id()).is_none());
1415
1416 let fragment = "#existence-test-2";
1417 let method2 = method(document.id(), fragment);
1418 assert!(document.insert_method(method2, MethodScope::assertion_method()).is_ok());
1419 assert!(document.remove_method(method1.id()).is_none());
1420 assert!(document.remove_method(method1.id()).is_none());
1421
1422 let fragment = "#removal-test-3";
1423 let method3 = method(document.id(), fragment);
1424 assert!(document
1425 .insert_method(method3.clone(), MethodScope::VerificationMethod)
1426 .is_ok());
1427 assert!(document
1428 .attach_method_relationship(fragment, MethodRelationship::CapabilityDelegation)
1429 .is_ok());
1430
1431 assert_eq!(method3, document.remove_method(method3.id()).unwrap());
1432
1433 assert!(document.capability_delegation().query(method3.id()).is_none());
1435 assert!(document.verification_method().query(method3.id()).is_none());
1436 }
1437
1438 #[test]
1439 fn test_service_updates() {
1440 let mut document = document();
1441 let service_id = document.id().to_url().join("#service-update-test").unwrap();
1442 let service_type = "test";
1443 let service_endpoint = Url::parse("https://example.com").unwrap();
1444
1445 let service: Service = ServiceBuilder::default()
1446 .id(service_id)
1447 .type_(service_type)
1448 .service_endpoint(service_endpoint)
1449 .build()
1450 .unwrap();
1451 assert!(document.insert_service(service.clone()).is_ok());
1453 let mut service_clone = service.clone();
1455 *service_clone.service_endpoint_mut() = Url::parse("https://other-example.com").unwrap().into();
1456 assert!(document.insert_service(service_clone).is_err());
1457 assert_eq!(service, document.remove_service(service.id()).unwrap());
1459 assert!(document.insert_service(service.clone()).is_ok());
1461
1462 let method: VerificationMethod = MethodBuilder::default()
1464 .type_(MethodType::ED25519_VERIFICATION_KEY_2018)
1465 .data(MethodData::PublicKeyBase58(
1466 "3M5RCDjPTWPkKSN3sxUmmMqHbmRPegYP1tjcKyrDbt9J".into(),
1467 ))
1468 .id(service.id().clone())
1469 .controller(document.id().clone())
1470 .build()
1471 .unwrap();
1472
1473 let method_scopes = [
1474 MethodScope::VerificationMethod,
1475 MethodScope::assertion_method(),
1476 MethodScope::authentication(),
1477 MethodScope::key_agreement(),
1478 MethodScope::capability_delegation(),
1479 MethodScope::capability_invocation(),
1480 ];
1481 for scope in method_scopes {
1482 let mut document_clone = document.clone();
1483 assert!(document_clone.insert_method(method.clone(), scope).is_err());
1484 assert!(document_clone.remove_service(service.id()).is_some());
1486 assert!(document_clone.insert_method(method.clone(), scope).is_ok());
1487 }
1488
1489 for scope in method_scopes {
1491 let mut doc_clone = document.clone();
1492 let valid_method_id = document.id().to_url().join("#valid-method-identifier").unwrap();
1493 let mut valid_method = method.clone();
1494 valid_method.set_id(valid_method_id.clone()).unwrap();
1495 assert!(doc_clone.insert_method(valid_method.clone(), scope).is_ok());
1497 let mut service_clone = service.clone();
1498 service_clone.set_id(valid_method_id).unwrap();
1499 assert!(doc_clone.insert_service(service_clone.clone()).is_err());
1500 assert!(doc_clone.remove_method(valid_method.id()).is_some());
1502 assert!(doc_clone.insert_service(service_clone).is_ok());
1503 }
1504
1505 assert!(document
1507 .remove_service(&service.id().join("#service-does-not-exist").unwrap())
1508 .is_none());
1509 }
1510
1511 #[test]
1512 fn serialize_deserialize_roundtrip() {
1513 let document: CoreDocument = document();
1514 let doc_json: String = document.to_json().unwrap();
1515 let doc_json_value: serde_json::Value = document.to_json_value().unwrap();
1516 let doc_json_vec: Vec<u8> = document.to_json_vec().unwrap();
1517 assert_eq!(document, CoreDocument::from_json(&doc_json).unwrap());
1518 assert_eq!(document, CoreDocument::from_json_value(doc_json_value).unwrap());
1519
1520 assert_eq!(document, CoreDocument::from_json_slice(&doc_json_vec).unwrap());
1521 }
1522
1523 #[test]
1524 fn deserialize_valid() {
1525 const JSON_DOCUMENT: &str = r#"{
1528 "@context": [
1529 "https://www.w3.org/ns/did/v1",
1530 "https://w3id.org/security/suites/ed25519-2020/v1"
1531 ],
1532 "id": "did:example:123",
1533 "authentication": [
1534 {
1535 "id": "did:example:123#z6MkecaLyHuYWkayBDLw5ihndj3T1m6zKTGqau3A51G7RBf3",
1536 "type": "Ed25519VerificationKey2018",
1537 "controller": "did:example:123",
1538 "publicKeyMultibase": "zAKJP3f7BD6W4iWEQ9jwndVTCBq8ua2Utt8EEjJ6Vxsf"
1539 }
1540 ],
1541 "capabilityInvocation": [
1542 {
1543 "id": "did:example:123#z6MkhdmzFu659ZJ4XKj31vtEDmjvsi5yDZG5L7Caz63oP39k",
1544 "type": "Ed25519VerificationKey2018",
1545 "controller": "did:example:123",
1546 "publicKeyMultibase": "z4BWwfeqdp1obQptLLMvPNgBw48p7og1ie6Hf9p5nTpNN"
1547 }
1548 ],
1549 "capabilityDelegation": [
1550 {
1551 "id": "did:example:123#z6Mkw94ByR26zMSkNdCUi6FNRsWnc2DFEeDXyBGJ5KTzSWyi",
1552 "type": "Ed25519VerificationKey2018",
1553 "controller": "did:example:123",
1554 "publicKeyMultibase": "zHgo9PAmfeoxHG8Mn2XHXamxnnSwPpkyBHAMNF3VyXJCL"
1555 }
1556 ],
1557 "assertionMethod": [
1558 {
1559 "id": "did:example:123#z6MkiukuAuQAE8ozxvmahnQGzApvtW7KT5XXKfojjwbdEomY",
1560 "type": "Ed25519VerificationKey2018",
1561 "controller": "did:example:123",
1562 "publicKeyMultibase": "z5TVraf9itbKXrRvt2DSS95Gw4vqU3CHAdetoufdcKazA"
1563 }
1564 ]
1565 }"#;
1566 let doc: std::result::Result<CoreDocument, Box<dyn std::error::Error>> =
1567 CoreDocument::from_json(JSON_DOCUMENT).map_err(Into::into);
1568 dbg!(&doc);
1570 assert!(doc.is_ok());
1571 }
1572
1573 #[test]
1574 fn deserialize_duplicate_method_different_scopes() {
1575 const JSON_VERIFICATION_METHOD_KEY_AGREEMENT: &str = r#"{
1576 "id": "did:example:1234",
1577 "verificationMethod": [
1578 {
1579 "id": "did:example:1234#key1",
1580 "controller": "did:example:1234",
1581 "type": "Ed25519VerificationKey2018",
1582 "publicKeyBase58": "3M5RCDjPTWPkKSN3sxUmmMqHbmRPegYP1tjcKyrDbt9J"
1583 }
1584 ],
1585 "keyAgreement": [
1586 {
1587 "id": "did:example:1234#key1",
1588 "controller": "did:example:1234",
1589 "type": "X25519KeyAgreementKey2019",
1590 "publicKeyBase58": "FbQWLPRhTH95MCkQUeFYdiSoQt8zMwetqfWoxqPgaq7x"
1591 }
1592 ]
1593 }"#;
1594
1595 const JSON_KEY_AGREEMENT_CAPABILITY_INVOCATION: &str = r#"{
1596 "id": "did:example:1234",
1597 "capabilityInvocation": [
1598 {
1599 "id": "did:example:1234#key1",
1600 "controller": "did:example:1234",
1601 "type": "Ed25519VerificationKey2018",
1602 "publicKeyBase58": "3M5RCDjPTWPkKSN3sxUmmMqHbmRPegYP1tjcKyrDbt9J"
1603 }
1604 ],
1605 "keyAgreement": [
1606 {
1607 "id": "did:example:1234#key1",
1608 "controller": "did:example:1234",
1609 "type": "X25519KeyAgreementKey2019",
1610 "publicKeyBase58": "FbQWLPRhTH95MCkQUeFYdiSoQt8zMwetqfWoxqPgaq7x"
1611 }
1612 ]
1613 }"#;
1614
1615 const JSON_ASSERTION_METHOD_CAPABILITY_INVOCATION: &str = r#"{
1616 "id": "did:example:1234",
1617 "assertionMethod": [
1618 {
1619 "id": "did:example:1234#key1",
1620 "controller": "did:example:1234",
1621 "type": "Ed25519VerificationKey2018",
1622 "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
1623 }
1624 ],
1625 "capabilityInvocation": [
1626 {
1627 "id": "did:example:1234#key1",
1628 "controller": "did:example:1234",
1629 "type": "Ed25519VerificationKey2018",
1630 "publicKeyBase58": "3M5RCDjPTWPkKSN3sxUmmMqHbmRPegYP1tjcKyrDbt9J"
1631 }
1632 ]
1633 }"#;
1634
1635 const JSON_VERIFICATION_METHOD_AUTHENTICATION: &str = r#"{
1636 "id": "did:example:1234",
1637 "verificationMethod": [
1638 {
1639 "id": "did:example:1234#key1",
1640 "controller": "did:example:1234",
1641 "type": "Ed25519VerificationKey2018",
1642 "publicKeyBase58": "3M5RCDjPTWPkKSN3sxUmmMqHbmRPegYP1tjcKyrDbt9J"
1643 }
1644 ],
1645 "authentication": [
1646 {
1647 "id": "did:example:1234#key1",
1648 "controller": "did:example:1234",
1649 "type": "Ed25519VerificationKey2018",
1650 "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
1651 }
1652 ]
1653 }"#;
1654
1655 const JSON_CAPABILITY_DELEGATION_ASSERTION_METHOD: &str = r#"{
1656 "id": "did:example:1234",
1657 "capabilityDelegation": [
1658 {
1659 "id": "did:example:1234#key1",
1660 "controller": "did:example:1234",
1661 "type": "Ed25519VerificationKey2018",
1662 "publicKeyBase58": "3M5RCDjPTWPkKSN3sxUmmMqHbmRPegYP1tjcKyrDbt9J"
1663 }
1664 ],
1665 "assertionMethod": [
1666 {
1667 "id": "did:example:1234#key1",
1668 "controller": "did:example:1234",
1669 "type": "Ed25519VerificationKey2018",
1670 "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
1671 }
1672 ]
1673 }"#;
1674
1675 let verifier = |json: &str| {
1676 let result: std::result::Result<CoreDocument, Box<dyn std::error::Error>> =
1677 CoreDocument::from_json(json).map_err(Into::into);
1678 println!("the following non-spec compliant document was deserialized: \n {json}");
1680 assert!(result.is_err());
1681 };
1682
1683 for json in [
1684 JSON_VERIFICATION_METHOD_KEY_AGREEMENT,
1685 JSON_KEY_AGREEMENT_CAPABILITY_INVOCATION,
1686 JSON_ASSERTION_METHOD_CAPABILITY_INVOCATION,
1687 JSON_VERIFICATION_METHOD_AUTHENTICATION,
1688 JSON_CAPABILITY_DELEGATION_ASSERTION_METHOD,
1689 ] {
1690 verifier(json);
1691 }
1692 }
1693
1694 #[test]
1695 fn deserialize_invalid_id_references() {
1696 const JSON_KEY_AGREEMENT_CAPABILITY_INVOCATION: &str = r#"{
1697 "id": "did:example:1234",
1698 "capabilityInvocation": [
1699 "did:example:1234#key1"
1700 ],
1701 "keyAgreement": [
1702 {
1703 "id": "did:example:1234#key1",
1704 "controller": "did:example:1234",
1705 "type": "X25519KeyAgreementKey2019",
1706 "publicKeyBase58": "FbQWLPRhTH95MCkQUeFYdiSoQt8zMwetqfWoxqPgaq7x"
1707 }
1708 ]
1709 }"#;
1710
1711 const JSON_ASSERTION_METHOD_CAPABILITY_INVOCATION: &str = r#"{
1712 "id": "did:example:1234",
1713 "assertionMethod": [
1714 "did:example:1234#key1",
1715 {
1716 "id": "did:example:1234#key2",
1717 "controller": "did:example:1234",
1718 "type": "Ed25519VerificationKey2018",
1719 "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
1720 }
1721 ],
1722 "capabilityInvocation": [
1723 {
1724 "id": "did:example:1234#key1",
1725 "controller": "did:example:1234",
1726 "type": "Ed25519VerificationKey2018",
1727 "publicKeyBase58": "3M5RCDjPTWPkKSN3sxUmmMqHbmRPegYP1tjcKyrDbt9J"
1728 }
1729 ]
1730 }"#;
1731
1732 const JSON_AUTHENTICATION_KEY_AGREEMENT: &str = r#"{
1733 "id": "did:example:1234",
1734 "keyAgreement": [
1735 "did:example:1234#key1"
1736 ],
1737 "authentication": [
1738 {
1739 "id": "did:example:1234#key1",
1740 "controller": "did:example:1234",
1741 "type": "Ed25519VerificationKey2018",
1742 "publicKeyMultibase": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
1743 }
1744 ]
1745 }"#;
1746
1747 const JSON_CAPABILITY_DELEGATION_ASSERTION_METHOD: &str = r#"{
1748 "id": "did:example:1234",
1749 "capabilityDelegation": [
1750 "did:example:1234#key1"
1751 ],
1752 "assertionMethod": [
1753 {
1754 "id": "did:example:1234#key1",
1755 "controller": "did:example:1234",
1756 "type": "X25519KeyAgreementKey2019",
1757 "publicKeyBase58": "FbQWLPRhTH95MCkQUeFYdiSoQt8zMwetqfWoxqPgaq7x"
1758 }
1759 ]
1760 }"#;
1761
1762 let verifier = |json: &str| {
1763 let result: std::result::Result<CoreDocument, Box<dyn std::error::Error>> =
1764 CoreDocument::from_json(json).map_err(Into::into);
1765 println!("the following non-spec compliant document was deserialized: \n {json}");
1767 assert!(result.is_err());
1768 };
1769
1770 for json in [
1771 JSON_KEY_AGREEMENT_CAPABILITY_INVOCATION,
1772 JSON_ASSERTION_METHOD_CAPABILITY_INVOCATION,
1773 JSON_AUTHENTICATION_KEY_AGREEMENT,
1774 JSON_CAPABILITY_DELEGATION_ASSERTION_METHOD,
1775 ] {
1776 verifier(json);
1777 }
1778 }
1779
1780 #[test]
1781 fn test_did_jwk_expansion() {
1782 let did_jwk = "did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ1c2UiOiJlbmMiLCJ4IjoiM3A3YmZYdDl3YlRUVzJIQzdPUTFOei1EUThoYmVHZE5yZngtRkctSUswOCJ9"
1783 .parse::<DIDJwk>()
1784 .unwrap();
1785 let target_doc = serde_json::from_value(serde_json::json!({
1786 "id": "did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ1c2UiOiJlbmMiLCJ4IjoiM3A3YmZYdDl3YlRUVzJIQzdPUTFOei1EUThoYmVHZE5yZngtRkctSUswOCJ9",
1787 "verificationMethod": [
1788 {
1789 "id": "did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ1c2UiOiJlbmMiLCJ4IjoiM3A3YmZYdDl3YlRUVzJIQzdPUTFOei1EUThoYmVHZE5yZngtRkctSUswOCJ9#0",
1790 "type": "JsonWebKey2020",
1791 "controller": "did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ1c2UiOiJlbmMiLCJ4IjoiM3A3YmZYdDl3YlRUVzJIQzdPUTFOei1EUThoYmVHZE5yZngtRkctSUswOCJ9",
1792 "publicKeyJwk": {
1793 "kty":"OKP",
1794 "crv":"X25519",
1795 "use":"enc",
1796 "x":"3p7bfXt9wbTTW2HC7OQ1Nz-DQ8hbeGdNrfx-FG-IK08"
1797 }
1798 }
1799 ],
1800 "assertionMethod": ["did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ1c2UiOiJlbmMiLCJ4IjoiM3A3YmZYdDl3YlRUVzJIQzdPUTFOei1EUThoYmVHZE5yZngtRkctSUswOCJ9#0"],
1801 "authentication": ["did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ1c2UiOiJlbmMiLCJ4IjoiM3A3YmZYdDl3YlRUVzJIQzdPUTFOei1EUThoYmVHZE5yZngtRkctSUswOCJ9#0"],
1802 "capabilityInvocation": ["did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ1c2UiOiJlbmMiLCJ4IjoiM3A3YmZYdDl3YlRUVzJIQzdPUTFOei1EUThoYmVHZE5yZngtRkctSUswOCJ9#0"],
1803 "capabilityDelegation": ["did:jwk:eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ1c2UiOiJlbmMiLCJ4IjoiM3A3YmZYdDl3YlRUVzJIQzdPUTFOei1EUThoYmVHZE5yZngtRkctSUswOCJ9#0"]
1804 })).unwrap();
1805
1806 assert_eq!(CoreDocument::expand_did_jwk(did_jwk).unwrap(), target_doc);
1807 }
1808}