def test_is_equal_register_public_key(valid_key_name, valid_public_key_base58): key1 = RegisterPublicKey.build(valid_key_name, valid_public_key_base58, revoked=False) key2 = RegisterPublicKey.build(valid_key_name, valid_public_key_base58, revoked=False) assert key1.is_equal(key2)
def test_can_get_owner_public_key(valid_key_pair, other_key_pair): doc_id = make_identifier(valid_key_pair.public_bytes) owner_key = RegisterPublicKey('#Owner', valid_key_pair.public_base58, revoked=False) doc = RegisterDocumentBuilder() \ .add_public_key_obj(owner_key) \ .add_public_key_obj(RegisterPublicKey('#NotOwner', other_key_pair.public_base58, revoked=False)) \ .build(doc_id, DIDType.TWIN, proof='a proof, does not matter here', revoked=False) key = RegisterDocumentHelper.get_owner_register_public_key(doc) assert key == owner_key
def build_from_dict(self, data: dict) -> RegisterDocument: """ Build a valid immutable register document from dict. :param data: register document as dict :return: valid register document :raises: IdentityInvalidDocumentError: if invalid dict data IdentityInvalidDocumentError: if invalid document IdentityRegisterDocumentKeyConflictError: if key name is not unique """ try: for k in data['publicKey']: self.add_public_key_obj(RegisterPublicKey.from_dict(k)) for k in data.get('authentication', []): self.add_authentication_key_obj(RegisterAuthenticationPublicKey.from_dict(k)) for k in data.get('delegateAuthentication', []): self.add_authentication_delegation_obj(RegisterDelegationProof.from_dict(k)) for k in data.get('delegateControl', []): self.add_control_delegation_obj(RegisterDelegationProof.from_dict(k)) raw_controller = data.get('controller') controller = Issuer.from_string(raw_controller) if raw_controller else None return self.build(data['id'], DIDType(data['ioticsDIDType']), data['proof'], data.get('revoked', False), Metadata.from_dict(data.get('metadata', {})), data.get('creator'), data['ioticsSpecVersion'], data['updateTime'], controller) except (TypeError, KeyError, ValueError) as err: raise IdentityInvalidDocumentError(f'Can not parse invalid register document: \'{err}\'') from err
def test_can_revoke_delegation_proof(base_doc_issuer, valid_key_pair, get_api_call, doc_deleg_set, deleg_doc_did, deleg_name): doc = get_doc_with_keys(deleg_control=[ RegisterDelegationProof.build('#Deleg1', controller=Issuer( deleg_doc_did, '#plop2'), proof='proof', revoked=False) ], deleg_auth=[ RegisterDelegationProof.build( '#Deleg2', controller=Issuer(deleg_doc_did, '#plop2'), proof='proof', revoked=False) ], public_keys=[ RegisterPublicKey.build('#MandatoryKey', 'base58Key1', revoked=False) ], did=base_doc_issuer.did) resolver_client = ResolverClientTest(docs={base_doc_issuer.did: doc}) assert not doc_deleg_set(doc)[deleg_name].revoked api = AdvancedIdentityRegisterApi(resolver_client) get_api_call(api)(deleg_name, revoked=True, doc_owner_issuer=base_doc_issuer, doc_owner_key_pair=valid_key_pair) updated_doc = resolver_client.docs[base_doc_issuer.did] assert doc_deleg_set(updated_doc)[deleg_name].revoked
def invalid_doc(doc_did, valid_issuer_key): return get_doc_with_keys(did=doc_did, public_keys=[ RegisterPublicKey.build( '#Key1', valid_issuer_key.public_key_base58, revoked=False), ])
def get_delegation_doc_for(controller_name: str, doc_id: str, public_base58: str) -> RegisterDocument: return get_doc_with_keys(did=doc_id, public_keys=[ RegisterPublicKey.build(controller_name, public_base58, revoked=False), ])
def get_docs_for_issuer_key_from_public_keys( doc_did: str, issuer: Issuer) -> Dict[str, RegisterDocument]: """ The issuer is directly in the current doc public keys """ doc = get_doc_with_keys(public_keys=[ RegisterPublicKey.build(issuer.name, 'base58Key1', revoked=False) ]) return {doc_did: doc}
def simple_doc(doc_did, valid_issuer_key): return get_doc_with_keys( did=doc_did, public_keys=[ RegisterPublicKey.build(valid_issuer_key.issuer.name, valid_issuer_key.public_key_base58, revoked=False) ], )
def test_building_a_register_doc_raises_if_same_key_is_added_twice(doc_keys): duplicate_pub_key1 = RegisterPublicKey( name=doc_keys['#pub_key1'].name, base58=get_public_base_58_key(), revoked=doc_keys['#pub_key1'].revoked) with pytest.raises(IdentityRegisterDocumentKeyConflictError): RegisterDocumentBuilder() \ .add_public_key_obj(doc_keys['#pub_key1']) \ .add_public_key_obj(duplicate_pub_key1)
def doc_keys(a_controller): return { '#pub_key1': RegisterPublicKey(name='#pub_key1', base58=get_public_base_58_key(), revoked=False), '#pub_key2': RegisterPublicKey(name='#pub_key2', base58=get_public_base_58_key(), revoked=True), '#auth_key1': RegisterAuthenticationPublicKey(name='#auth_key1', base58=get_public_base_58_key(), revoked=False), '#auth_key2': RegisterAuthenticationPublicKey(name='#auth_key2', base58=get_public_base_58_key(), revoked=True), '#deleg_control_key1': RegisterDelegationProof( name='#deleg_control_key1', controller=a_controller, proof='a_deleg_proof_validated_by_the_resolver', revoked=False), '#deleg_control_key2': RegisterDelegationProof( name='#deleg_control_key2', controller=a_controller, proof='a_deleg_proof_validated_by_the_resolver', revoked=True), '#deleg_auth_key1': RegisterDelegationProof( name='#deleg_auth_key1', controller=a_controller, proof='a_deleg_proof_validated_by_the_resolver', revoked=False), '#deleg_auth_key2': RegisterDelegationProof( name='#deleg_auth_key2', controller=a_controller, proof='a_deleg_proof_validated_by_the_resolver', revoked=True), }
def invalid_doc_invalid_proof(valid_doc, doc_invalid_proof, valid_key_pair_secrets): public_base58 = KeyPairSecretsHelper.get_public_key_base58_from_key_pair_secrets( valid_key_pair_secrets) doc_id = valid_doc.did return RegisterDocumentBuilder() \ .add_public_key_obj(RegisterPublicKey('#Owner', public_base58, revoked=False)) \ .build(doc_id, DIDType.TWIN, proof=doc_invalid_proof.signature, revoked=False)
def invalid_doc_no_owner_key(valid_doc, valid_issuer, valid_key_pair_secrets, other_key_pair_secrets): public_base58 = KeyPairSecretsHelper.get_public_key_base58_from_key_pair_secrets( other_key_pair_secrets) doc_id = valid_doc.did return RegisterDocumentBuilder() \ .add_public_key_obj(RegisterPublicKey('#KeyNotFromOwner', public_base58, revoked=False)) \ .build(doc_id, DIDType.TWIN, proof=Proof.build(valid_key_pair_secrets, valid_issuer, content=doc_id.encode()).signature, revoked=False)
def test_can_get_issuer_by_public_key(valid_key_pair): doc_did = make_identifier(valid_key_pair.public_bytes) key_issuer = Issuer.build(doc_did, '#AnIssuer') doc = RegisterDocumentBuilder() \ .add_public_key_obj(RegisterPublicKey(key_issuer.name, valid_key_pair.public_base58, revoked=False)) \ .build(key_issuer.did, DIDType.TWIN, proof='a proof, does not matter here', revoked=False) issuer = RegisterDocumentHelper.get_issuer_from_public_key( doc, valid_key_pair.public_base58) assert issuer == key_issuer
def doc_with_doc_deleg(valid_issuer_key, doc_did, deleg_doc_did): doc = get_doc_with_keys( did=doc_did, public_keys=[ RegisterPublicKey.build('#Key1', 'base58Key1', revoked=False) ], deleg_control=[ RegisterDelegationProof.build(valid_issuer_key.issuer.name, controller=Issuer.build( deleg_doc_did, '#plop1'), proof='aproof', revoked=False), ], ) deleg_doc = get_doc_with_keys(did=deleg_doc_did, public_keys=[ RegisterPublicKey.build( valid_issuer_key.issuer.name, valid_issuer_key.public_key_base58, revoked=False), ]) return doc, deleg_doc
def test_can_build_register_public_key(valid_key_name, valid_public_key_base58): key = RegisterPublicKey.build(valid_key_name, valid_public_key_base58, revoked=False) assert key.name == valid_key_name assert key.base58 == valid_public_key_base58 assert not key.revoked assert key.to_dict() == { 'id': valid_key_name, 'type': DOCUMENT_PUBLIC_KEY_TYPE, 'publicKeyBase58': valid_public_key_base58, 'revoked': False }
def add_public_key(self, name: str, public_base58: str, revoked: Optional[bool] = False) -> 'RegisterDocumentBuilder': """ Add public key to document under build. :param name: key name :param public_base58: public key base58 :param revoked: is revoked (default=False) :return: self :raises: IdentityValidationError: if invalid public key IdentityRegisterDocumentKeyConflictError: if key name is not unique """ key = RegisterPublicKey.build(name, public_base58, revoked) self._check_and_update_map(name, key, self.public_keys, 'Public key name') return self
def get_valid_document_from_secret(secrets: KeyPairSecrets, issuer_name: str, controller: Issuer = None): public_base58 = KeyPairSecretsHelper.get_public_key_base58_from_key_pair_secrets( secrets) public_bytes = base58.b58decode(public_base58) doc_id = make_identifier(public_bytes) proof = Proof.build(secrets, Issuer.build(doc_id, issuer_name), content=doc_id.encode()) return RegisterDocumentBuilder() \ .add_public_key_obj(RegisterPublicKey(issuer_name, public_base58, revoked=False)) \ .build(doc_id, DIDType.TWIN, proof=proof.signature, revoked=False, controller=controller)
def get_docs_for_issuer_key_from_auth_delegation( doc_did: str, deleg_doc_did: str, issuer: Issuer) -> Dict[str, RegisterDocument]: """ The issuer is in the auth delegation of the provided doc And the issuer is in the auth keys of the delegation doc """ doc = get_doc_with_keys(deleg_control=[ RegisterDelegationProof.build(issuer.name, controller=Issuer( 'deleg_doc_did', '#plop'), proof='proof', revoked=False), ]) deleg_doc = get_doc_with_keys(public_keys=[ RegisterPublicKey.build(issuer.name, 'base58Key1', revoked=False) ]) return {doc_did: doc, deleg_doc_did: deleg_doc}
def get_valid_delegated_doc_and_deleg_proof(seed: bytes, issuer_name: str, delegating_doc_id: str, deleg_name: str): secrets = KeyPairSecrets.build(seed, 'iotics/0/something/twindeleg') public_base58 = KeyPairSecretsHelper.get_public_key_base58_from_key_pair_secrets( secrets) public_bytes = base58.b58decode(public_base58) doc_id = make_identifier(public_bytes) issuer = Issuer.build(doc_id, issuer_name) proof = Proof.build(secrets, issuer, content=doc_id.encode()) deleg_key = get_delegation_register_proof( subject_key_pair_secrets=secrets, content=delegating_doc_id.encode(), p_type=DelegationProofType.DID, subject_issuer=Issuer.build(doc_id, issuer_name), deleg_key_name=deleg_name) delegated_doc = RegisterDocumentBuilder() \ .add_public_key_obj(RegisterPublicKey(issuer_name, public_base58, revoked=False)) \ .build(doc_id, DIDType.TWIN, proof=proof.signature, revoked=False) return delegated_doc, deleg_key
def test_validate_delegation_raises_validation_error_if_public_key_not_in_deleg_controller_doc( doc_did, deleg_doc_did, valid_issuer_key, valid_key_pair_secrets): controller_name = '#AController' deleg_proof = get_delegation_register_proof( subject_key_pair_secrets=valid_key_pair_secrets, content=doc_did.encode(), p_type=DelegationProofType.DID, subject_issuer=Issuer.build(deleg_doc_did, controller_name)) deleg_doc = get_doc_with_keys(did=doc_did, public_keys=[ RegisterPublicKey.build( '#NotMatchingTheController', valid_issuer_key.public_key_base58, revoked=False), ]) resolver_client = ResolverClientTest({deleg_doc_did: deleg_doc}) with pytest.raises(IdentityInvalidDocumentDelegationError) as err_wrapper: DelegationValidation.validate_delegation(resolver_client, doc_id=doc_did, deleg_proof=deleg_proof) assert isinstance(err_wrapper.value.__cause__, IdentityValidationError)
def add_public_key_to_document(self, name: str, new_public_key_base58: str, doc_owner_key_pair: KeyPair, doc_owner_issuer: Issuer) -> Issuer: """ Add a new register public key to a register document. :param name: new public key name :param new_public_key_base58: public key base 58 :param doc_owner_key_pair: register document owner key pair :param doc_owner_issuer: register document owner issuer :return: new register document owner issuer :raises: IdentityValidationError: if invalid new public key name IdentityRegisterDocumentKeyConflictError: if public key name is not unique within the register document IdentityInvalidDocumentError: if invalid register document IdentityResolverError: if resolver error """ new_key = RegisterPublicKey.build(name, new_public_key_base58) self._update_doc(doc_owner_key_pair, doc_owner_issuer, get_updated_doc=self.public_key_api.add_doc_key, key=new_key) return Issuer.build(doc_owner_issuer.did, name)
def test_build_register_public_key_from_dict_raises_validation_error_if_invalid_dict( ): with pytest.raises(IdentityValidationError): RegisterPublicKey.from_dict({'invalid': 'data'})
def test_can_build_a_register_doc_from_an_other_doc_overriding_values( full_doc): existing_doc = full_doc new_creator = 'did:iotics:iotEEEEKpPGWyEC4FFo4d6oyzVVk6MEEEEgY' new_controller = Issuer.build( 'did:iotics:iotEEEEKpPGWyEC4FFo4d6oyzHHHHMEEEEgY', '#NewController') new_metadata = Metadata(label='a label') new_version = SUPPORTED_VERSIONS[0] new_pub_key = RegisterPublicKey(name='#new_pub_key1', base58=get_public_base_58_key(), revoked=False) new_auth_key = RegisterAuthenticationPublicKey( name='#new_auth_key1', base58=get_public_base_58_key(), revoked=False) a_controller = Issuer.from_string( 'did:iotics:iotHjrmKpPGWyEC4FFo4d6oyzVVk6MXEEEEE#AController') new_control_deleg_proof = RegisterDelegationProof( name='#new_deleg_control_key1', controller=a_controller, proof='a_deleg_proof_validated_by_the_resolver', revoked=False) new_auth_deleg_key = RegisterDelegationProof( name='#new_deleg_auth_key1', controller=a_controller, proof='a_deleg_proof_validated_by_the_resolver', revoked=False) new_doc = RegisterDocumentBuilder() \ .add_public_key_obj(new_pub_key) \ .add_authentication_key_obj(new_auth_key) \ .add_control_delegation_obj(new_control_deleg_proof) \ .add_authentication_delegation_obj(new_auth_deleg_key) \ .build_from_existing(existing_doc, revoked=True, metadata=new_metadata, creator=new_creator, spec_version=new_version, controller=new_controller) # Can not change assert new_doc.did == existing_doc.did assert new_doc.purpose == existing_doc.purpose assert new_doc.proof == existing_doc.proof # Overridden values assert new_doc.revoked assert new_doc.metadata == new_metadata assert new_doc.creator == new_creator assert new_doc.spec_version == new_version assert new_doc.controller == new_controller assert new_doc.public_keys == { **existing_doc.public_keys, **{ new_pub_key.name: new_pub_key } } assert new_doc.auth_keys == { **existing_doc.auth_keys, **{ new_auth_key.name: new_auth_key } } assert new_doc.control_delegation_proof == { **existing_doc.control_delegation_proof, **{ new_control_deleg_proof.name: new_control_deleg_proof } } assert new_doc.auth_delegation_proof == { **existing_doc.auth_delegation_proof, **{ new_auth_deleg_key.name: new_auth_deleg_key } } assert new_doc.update_time >= existing_doc.update_time
def test_build_register_public_key_raises_validation_error_if_invalid_name( valid_public_key_base58): with pytest.raises(IdentityValidationError): RegisterPublicKey.build('Invalid_name', valid_public_key_base58, revoked=False)
def min_doc_owner_pub_key(): return RegisterPublicKey('#Owner', 'pubbase58 value', revoked=False)
def authentication_subject_doc(other_key_pair_secrets, valid_key_pair, allowed_issuer_name): return RegisterDocumentBuilder() \ .add_public_key_obj(RegisterPublicKey(allowed_issuer_name, valid_key_pair.public_base58, revoked=False)) \ .build_from_existing(get_valid_document_from_secret(other_key_pair_secrets, '#Adoc'))
def public_keys(): return { '#Key1': RegisterPublicKey.build('#Key1', 'base58Key1', revoked=False), '#Key2': RegisterPublicKey.build('#Key2', 'base58Key2', revoked=False), '#Key3': RegisterPublicKey.build('#Key3', 'base58Key3', revoked=False) }
def register_doc_and_deleg_doc( doc_did: str, deleg_doc_did: str) -> Tuple[RegisterDocument, RegisterDocument]: """ Creates a document and a delegation document with all the key combinations (See KEY_NAMES) for the "get issuer from" tests with and without delegation and with and without included authentication """ doc = get_doc_with_keys( did=doc_did, public_keys=[ RegisterPublicKey.build(KEYS_NAMES.key_only_in_doc_pub_keys, 'base58Key1', revoked=False) ], auth_keys=[ RegisterAuthenticationPublicKey.build( KEYS_NAMES.key_only_in_doc_auth_keys, 'base58Key2', revoked=False) ], deleg_control=[ RegisterDelegationProof.build( KEYS_NAMES.key_in_doc_control_deleg_and_deleg_doc_pub_keys, controller=Issuer('deleg_doc_did', '#plop1'), proof='aproof', revoked=False), RegisterDelegationProof.build( KEYS_NAMES.key_in_doc_control_deleg_and_deleg_doc_auth_keys, controller=Issuer('deleg_doc_did', '#plop2'), proof='aproof', revoked=False), RegisterDelegationProof.build( KEYS_NAMES.key_in_doc_control_deleg_and_not_in_deleg_doc, controller=Issuer('deleg_doc_did', '#plop3'), proof='aproof', revoked=False), ], deleg_auth=[ RegisterDelegationProof.build( KEYS_NAMES.key_in_doc_auth_deleg_and_deleg_doc_pub_keys, controller=Issuer('deleg_doc_did', '#plop4'), proof='aproof', revoked=False), RegisterDelegationProof.build( KEYS_NAMES.key_in_doc_auth_deleg_and_deleg_doc_auth_keys, controller=Issuer('deleg_doc_did', '#plop5'), proof='aproof', revoked=False), RegisterDelegationProof.build( KEYS_NAMES.key_in_doc_auth_deleg_and_not_in_deleg_doc, controller=Issuer('deleg_doc_did', '#plop6'), proof='aproof', revoked=False), ], ) deleg_doc = get_doc_with_keys( did=deleg_doc_did, public_keys=[ RegisterPublicKey.build( KEYS_NAMES.key_in_doc_control_deleg_and_deleg_doc_pub_keys, 'base58K11', revoked=False), RegisterPublicKey.build( KEYS_NAMES.key_in_doc_auth_deleg_and_deleg_doc_pub_keys, 'base58K12', revoked=False) ], auth_keys=[ RegisterAuthenticationPublicKey.build( KEYS_NAMES.key_in_doc_control_deleg_and_deleg_doc_auth_keys, 'base58K13', revoked=False), RegisterAuthenticationPublicKey.build( KEYS_NAMES.key_in_doc_auth_deleg_and_deleg_doc_auth_keys, 'base58K14', revoked=False) ]) return doc, deleg_doc