11"""Utilities for specifying which verification method is in use for a given DID."""
22
33from abc import ABC , abstractmethod
4- from typing import List , Optional
4+ import logging
5+ from typing import Optional
56
7+ from acapy_agent .core .error import BaseError
68from acapy_agent .core .profile import Profile
79from acapy_agent .did .did_key import DIDKey
8- from acapy_agent .wallet .key_type import KeyType
9-
1010from acapy_agent .resolver .did_resolver import DIDResolver
1111
12+ LOGGER = logging .getLogger (__name__ )
13+
14+
15+ class VerificationKeyStrategyError (BaseError ):
16+ """Raised on issues with verfication method derivation."""
17+
1218
1319class BaseVerificationKeyStrategy (ABC ):
1420 """Base class for defining which verification method is in use."""
@@ -17,9 +23,9 @@ class BaseVerificationKeyStrategy(ABC):
1723 async def get_verification_method_id_for_did (
1824 self ,
1925 did : str ,
20- profile : Optional [Profile ],
26+ profile : Profile ,
27+ * ,
2128 proof_type : Optional [str ] = None ,
22- allowed_verification_method_types : Optional [List [KeyType ]] = None ,
2329 proof_purpose : Optional [str ] = None ,
2430 ) -> Optional [str ]:
2531 """Given a DID, returns the verification key ID in use.
@@ -40,6 +46,7 @@ class DefaultVerificationKeyStrategy(BaseVerificationKeyStrategy):
4046
4147 Supports did:key: and did:sov only.
4248 """
49+
4350 def __init__ (self ):
4451 """Initialize the key types mapping."""
4552 self .key_types_mapping = {
@@ -50,9 +57,9 @@ def __init__(self):
5057 async def get_verification_method_id_for_did (
5158 self ,
5259 did : str ,
53- profile : Optional [Profile ],
60+ profile : Profile ,
61+ * ,
5462 proof_type : Optional [str ] = None ,
55- allowed_verification_method_types : Optional [List [KeyType ]] = None ,
5663 proof_purpose : Optional [str ] = None ,
5764 ) -> Optional [str ]:
5865 """Given a did:key or did:sov, returns the verification key ID in use.
@@ -65,22 +72,45 @@ async def get_verification_method_id_for_did(
6572 :params proof_purpose: the verkey relationship (assertionMethod, keyAgreement, ..)
6673 :returns Optional[str]: the current verkey ID
6774 """
75+ proof_type = proof_type or "Ed25519Signature2018"
76+ proof_purpose = proof_purpose or "assertionMethod"
77+
78+ if proof_purpose not in (
79+ "authentication" ,
80+ "assertionMethod" ,
81+ "capabilityInvocation" ,
82+ "capabilityDelegation" ,
83+ ):
84+ raise ValueError ("Invalid proof purpose" )
85+
6886 if did .startswith ("did:key:" ):
6987 return DIDKey .from_did (did ).key_id
7088 elif did .startswith ("did:sov:" ):
7189 # key-1 is what uniresolver uses for key id
7290 return did + "#key-1"
73- elif did .startswith ("did:web:" ):
74- did_resolver = profile .inject (DIDResolver )
75- did_document = await did_resolver .resolve (profile = profile , did = did )
76- if proof_type :
77- verification_method_types = self .key_types_mapping [proof_type ]
78- verification_method_list = did_document .get ("verificationMethod" , None )
79- for method in verification_method_list :
80- if method .get ("type" ) in verification_method_types :
81- return method .get ("id" )
82- else :
83- # taking the first verification method from did document
84- verification_method_id = verification_method_list [0 ].get ("id" )
85- return verification_method_id
86- return None
91+
92+ resolver = profile .inject (DIDResolver )
93+ did_document = await resolver .resolve (profile = profile , did = did )
94+ method_types = self .key_types_mapping [proof_type ]
95+
96+ methods = did_document .get (proof_purpose , [])
97+ methods = [vm for vm in methods if vm .get ("type" ) in method_types ]
98+ if not methods :
99+ raise VerificationKeyStrategyError (
100+ f"No matching verification method found for did { did } with proof "
101+ f"type { proof_type } and purpose { proof_purpose } "
102+ )
103+
104+ if len (methods ) > 1 :
105+ LOGGER .info (
106+ (
107+ "More than 1 verification method matched for did %s with proof "
108+ "type %s and purpose %s; returning the first: %s"
109+ ),
110+ did ,
111+ proof_type ,
112+ proof_purpose ,
113+ methods [0 ].id ,
114+ )
115+
116+ return methods [0 ].id
0 commit comments