Пример #1
0
def test_private_identity_converted_to_delegate() -> None:
    """Creates private identity and converts it to a delegate."""
    identity = PrivateIdentity(
        CryptoProtocol.SHA256WithRSA.generate_private_key(), "1234567"
    )
    delegate = identity.delegate_of("abcdefgh")
    assert delegate.identity_id == "1234567"
    assert isinstance(delegate.public_key, PublicKey)
    assert delegate.delegator_identity_id == "abcdefgh"
Пример #2
0
def test_create_identity_add_delegate_content(identity: PrivateIdentity) -> None:
    """Request content to add a delegate to an identity."""
    delegate = identity.delegate_of("abcdefgh")
    bytes_content, authorisation = identity.sign_entity(delegate)

    content = json.loads(bytes_content)

    assert content["_type"] == "AddDelegateRequest"
    assert content["delegateIdentityId"] == delegate.identity_id
    assert content["delegatorIdentityId"] == delegate.delegator_identity_id
Пример #3
0
def test_create_request_with_content_claims(
    client: Client,
    endorser: PrivateIdentity,
    mocked_requests_200: respx.MockTransport,
    entity: Entity,
) -> None:
    """Create endorsement request provided by a 3rd party endorser."""
    claims = [b"claim-1", b"claim-2"]

    # Create endorsement request with authorisation of endorser
    content, authorisation = endorser.endorse(entity, claims)

    # This will also add the subject holders authorisation
    client.put(
        entity,
        claims=claims,
        content=content,
        authorisations=[authorisation],
        create_claims=True
        # endorse=True # TODO - provide test that this does not have any effect
    )
    http_request, _ = mocked_requests_200["create_entity"].calls[0]

    claims_header = json.loads(
        iov42_decode(http_request.headers["x-iov42-claims"]))
    assert claims_header == {hashed_claim(c): c.decode() for c in claims}
Пример #4
0
def test_create_request_with_content(
    client: Client,
    endorser: PrivateIdentity,
    mocked_requests_200: respx.MockTransport,
    entity: Entity,
) -> None:
    """Create endorsement request provided by a 3rd party endorser."""
    claims = [b"claim-1", b"claim-2"]

    # Create endorsement request with authorisation of endorser
    content, authorisation = endorser.endorse(entity, claims)

    # This will also add the subject holders authorisation
    client.put(
        entity,
        claims=claims,
        content=content,
        authorisations=[authorisation],
        # endorse=True # TODO - provide test that this does not have any effect
    )
    http_request, _ = mocked_requests_200["create_entity"].calls[0]

    request_id = json.loads(content.decode())["requestId"]
    assert http_request.url.path.rsplit("/", 1)[1] == request_id

    claims_header = json.loads(
        iov42_decode(http_request.headers["x-iov42-claims"]))
    assert claims_header == {}

    authorisations = json.loads(
        iov42_decode(http_request.headers["x-iov42-authorisations"].encode()))
    expected_identities = [a["identityId"] for a in authorisations]
    assert client.identity.identity_id in expected_identities
    assert endorser.identity_id in expected_identities
Пример #5
0
def main() -> None:
    """Create identity, asset type and register products."""
    product_data = read_product_data("nfc-tags.csv")

    # Usually we would store the identity (ID and key) on a safe place.
    manufacturer = PrivateIdentity(
        CryptoProtocol.SHA256WithECDSA.generate_private_key())

    with Client(cfg.iov42_platform["url"], manufacturer) as client:
        # Create the identity
        client.put(manufacturer.public_identity)
        print(f"Created manufacturer identity: {manufacturer.identity_id}")

        # Create the asset typ used for the NFC tags.
        tag_type = AssetType()
        client.put(tag_type)
        print(f"Created tag asset type: {tag_type}")

        # Register the NFC tags on the distributed ledger in parallel.
        with ThreadPoolExecutor(max_workers=20) as executor:
            _ = executor.map(
                register_product,
                [client] * len(product_data),
                [tag_type] * len(product_data),
                product_data,
            )
            executor.shutdown(wait=True)
Пример #6
0
def test_raise_identity_already_exists_2(client: Client) -> None:
    """Raise exception when an identity (with an other key) already exists."""
    client.identity = PrivateIdentity(
        CryptoProtocol.SHA256WithECDSA.generate_private_key(), "test-1234")
    with respx.mock(base_url=PLATFORM_URL) as respx_mock:
        respx_mock.put(
            re.compile("/api/v1/requests/.*$"),
            status_code=400,
            content=
            ('{"errors":[{"errorCode":2503,"errorType":"Authorisation",'
             '"message":"Signature L-IjTeba3wvJn4hHR40GPCG-H7iIeDWOzBo3hCK7x1mLZgif'
             "SdgR-YVxOZtvPzHaI86WdhIL3y-sNOwYUf2c0j7OfT31dAX71W9le-Cp2Mx1PgjjqI09f"
             "i0Nku-h5lgipQ07VKAm3gUx0foeG9GdDQe_I85QuCqtJsaAXWDVc8r0NeWpa3dnQEflIm"
             "W0-gecjO6pYDeyXPALcvp9h8Q_TxkuGVvreqpWvgKzdPMlXHMbN3wYoLNNLM3gpqrqAp"
             "Eze1aTqtlK6gCQUuhsJlKe4Bb2Nj8MRxXXXNpxIJqjJHM0IRps5J0U8gsnEEcny8Zf0tB"
             'h7NGkTteNv554QUbNVA cannot be verified with public credentials of identity test-1234."},'
             '{"errorCode":2503,"errorType":"Authorisation","message":"Signature '
             "L2PIREIx1MZsjV-j0fSMoN3u1eHP2wyqUpAs1mOWdp8k8yrnoBTbyH2Uxw8_9zYTzDHrz"
             "rI16fNKeRFuLlHosWqzoUf41M0Nip5zbW6gmPYiL05AWPdH1pg9qS-cgQa9IFXiMUkZh9"
             "EZltT7HHl9aRn35kcwoJYAoPm96Up1YPI0JWISx1iXXEAcxVOA1N_k-l0tT5Tb7lWNOI4"
             "5eh6flW_vVEeBQDjQhkl94rlP3qDFlDYZ9HZS2A3lTkiIo6MsU57pxeTD9FqwZ8uofJ3O"
             "Yx05TJKl106GPsscf2mnpnQGEzgS20QsJyqUs_u7dpZbAcjfBsaHucVz8gwkz_PoNg "
             'cannot be verified with public credentials of identity test-1234."},'
             '{"errorCode":2602,"errorType":"AssetExistence",'
             '"message":"Another identity with address test-1234 already exists"}],'
             '"requestId":"23343439","proof":"/api/v1/proofs/23343439"}'),
        )
        with pytest.raises(EntityAlreadyExists) as excinfo:
            client.put(client.identity.public_identity, request_id="1234567")
        assert str(excinfo.value) == "identity 'test-1234' already exists"
        assert excinfo.value.request_id == "1234567"
Пример #7
0
def test_add_delegate_to_identity(
    alice: PrivateIdentity,
    bob: PrivateIdentity,
    alice_client: Client,
) -> None:
    """Adds a delegate to an identity."""
    delegate = bob.delegate_of(alice.identity_id)
    content, authorisation = bob.sign_entity(delegate)

    response = alice_client.put(delegate,
                                content=content,
                                authorisations=[authorisation])

    for r in response.resources:  # type: ignore[union-attr]
        if "identities/" in r:
            assert alice.identity_id in r
Пример #8
0
def test_private_identity() -> None:
    """Creates private identity with ID."""
    identity = PrivateIdentity(
        CryptoProtocol.SHA256WithRSA.generate_private_key(), "1234567"
    )
    assert identity.identity_id == "1234567"
    assert isinstance(identity.private_key, PrivateKey)
Пример #9
0
def delegate(identity: PrivateIdentity) -> PrivateIdentity:
    """Generate a private delegate identity for test runs."""
    return PrivateIdentity(
        private_key=identity.private_key,
        identity_id=identity.identity_id,
        delegate_identity_id="abcdefgh",
    )
Пример #10
0
def test_private_identity_invalid_delegate_identity_id(invalid_id: str) -> None:
    """Raises ValueError in case the provided ID is invalid."""
    with pytest.raises(ValueError) as excinfo:
        PrivateIdentity(
            CryptoProtocol.SHA256WithECDSA.generate_private_key(), "123456", invalid_id
        )
    assert (
        str(excinfo.value)
        == f"invalid identifier '{invalid_id}' - valid characters are [a-zA-Z0-9._\\-+]"
    )
Пример #11
0
def create_identity(ctx: click.core.Context, identity_id: str,
                    crypto_protocol: str) -> None:
    """Create an identity."""
    private_key = generate_private_key(crypto_protocol)
    identity = PrivateIdentity(private_key, identity_id)
    client = Client(ctx.obj["url"], identity)

    _ = client.put(identity.public_identity, request_id=ctx.obj["request_id"])

    print(_identity_json(identity))
Пример #12
0
def test_create_identity_endorsements_content(identity: PrivateIdentity) -> None:
    """Request type to create claims and endorsements against an identity."""
    request_id = "123456"
    claims = [b"claim-1", b"claim-2"]

    content = json.loads(
        identity.public_identity.put_request_content(
            request_id=request_id, claims=claims, endorser=identity
        )
    )

    # Signatures are always different, we have to verify the signature
    endorsements = content.pop("endorsements")
    assert content == {
        "_type": "CreateIdentityEndorsementsRequest",
        "subjectId": identity.identity_id,
        "endorserId": identity.identity_id,
        "requestId": request_id,
    }
    for c, s in endorsements.items():
        identity.verify_signature(s, ";".join((identity.identity_id, c)).encode())
Пример #13
0
def test_content_create_endorsements(identity: PrivateIdentity) -> None:
    """Request content to create claims and endorsements for an unique asset."""
    request_id = "123456"
    claims = [b"claim-1", b"claim-2"]
    asset = Asset(asset_type_id="98765")
    content = json.loads(
        asset.put_request_content(
            claims=claims, endorser=identity, request_id=request_id
        )
    )
    endorsements = content.pop("endorsements")
    assert content == {
        "_type": "CreateAssetEndorsementsRequest",
        "subjectId": asset.asset_id,
        "subjectTypeId": asset.asset_type_id,
        "endorserId": identity.identity_id,
        "requestId": request_id,
    }
    for c, s in endorsements.items():
        identity.verify_signature(
            s, ";".join((asset.asset_id, asset.asset_type_id, c)).encode()
        )
Пример #14
0
def test_raise_identity_already_exists(client: Client) -> None:
    """Raise exception when an identity already exists."""
    client.identity = PrivateIdentity(
        CryptoProtocol.SHA256WithECDSA.generate_private_key(), "test-1234")
    with respx.mock(base_url=PLATFORM_URL) as respx_mock:
        respx_mock.put(
            re.compile("/api/v1/requests/.*$"),
            status_code=400,
            content=
            ('{"errors":[{"errorCode":2602,"errorType":"AssetExistence",'
             '"message":"Another identity with address test-1234 already exists"}],'
             '"requestId":"1234567","proof":"/api/v1/proofs/23343456"}'),
        )
        with pytest.raises(EntityAlreadyExists) as excinfo:
            client.put(client.identity.public_identity, request_id="1234567")
        assert str(excinfo.value) == "identity 'test-1234' already exists"
        assert excinfo.value.request_id == "1234567"
Пример #15
0
def test_3rd_party_endorsements_on_new_claims(
    alice_client: Client,
    existing_asset: Asset,
    bob: PrivateIdentity,
) -> None:
    """Provide endorsements on someone elses claims which do not exist yet."""
    new_claims = [b"alice-claim-100", b"alice-claims-200"]
    content, authorisation = bob.endorse(existing_asset, new_claims)

    # Content and authorisation has to be handed over from the endorser to the
    # identity owning the asset. The asset owner creates the request to add the
    # claims with endorsements which implicitely adds also the owner's authorisation.
    response = alice_client.put(
        existing_asset,
        claims=new_claims,
        content=content,
        authorisations=[authorisation],
        create_claims=True,
    )

    for r in response.resources:  # type: ignore[union-attr]
        if "endorsements/" in r:
            assert bob.identity_id in r
Пример #16
0
def identity(private_key: PrivateKey) -> PrivateIdentity:
    """Generate private identity for test runs."""
    return PrivateIdentity(private_key)
Пример #17
0
def _load_identity(identity: str) -> PrivateIdentity:
    with open(identity) as identity_file:
        id = json.load(identity_file)
        return PrivateIdentity(load_private_key(id["private_key"]),
                               id["identity_id"])
Пример #18
0
def endorser() -> PrivateIdentity:
    """Mock an identity used to endorse claims on different entities."""
    return PrivateIdentity(
        CryptoProtocol.SHA256WithECDSA.generate_private_key())
Пример #19
0
def test__private_identity_raises_typerror() -> None:
    """Raise TypeError in case no private key is provided."""
    with pytest.raises(TypeError) as excinfo:
        PrivateIdentity("123456")  # type: ignore[arg-type]
    assert str(excinfo.value) == "must be PrivateKey, not str"
Пример #20
0
def test_private_identity_generated_id() -> None:
    """If no ID is provided generate an UUID as ID."""
    identity = PrivateIdentity(CryptoProtocol.SHA256WithECDSA.generate_private_key())
    assert uuid.UUID(identity.identity_id)
Пример #21
0
def alice() -> PrivateIdentity:
    """Returns Alice's new identity with which we create stuff."""
    # TODO: identity = Identity(CryptoProtocol.SHA256WithECDSA)
    return PrivateIdentity(
        CryptoProtocol.SHA256WithECDSA.generate_private_key())
Пример #22
0
def bob() -> PrivateIdentity:
    """Create Bob's identity used to endorse claims on Alice or her assets."""
    return PrivateIdentity(
        CryptoProtocol.SHA256WithECDSA.generate_private_key())
Пример #23
0
import typing
import uuid

import pytest

from iov42.core import CryptoProtocol
from iov42.core import hashed_claim
from iov42.core import PrivateIdentity
from iov42.core import PrivateKey
from iov42.core import PublicIdentity
from iov42.core import PublicKey


identities = [
    PrivateIdentity(
        CryptoProtocol.SHA256WithECDSA.generate_private_key(),
        identity_id="my.private.identity",
    ),
    PublicIdentity(identity_id="my.public.identity"),
]


def test_private_identity() -> None:
    """Creates private identity with ID."""
    identity = PrivateIdentity(
        CryptoProtocol.SHA256WithRSA.generate_private_key(), "1234567"
    )
    assert identity.identity_id == "1234567"
    assert isinstance(identity.private_key, PrivateKey)


def test_private_identity_with_delegate_identity_id() -> None:
Пример #24
0
import pytest
import respx

from iov42.core import Asset
from iov42.core import AssetType
from iov42.core import Client
from iov42.core import CryptoProtocol
from iov42.core import Entity
from iov42.core import hashed_claim
from iov42.core import InvalidSignature
from iov42.core import PrivateIdentity
from iov42.core._crypto import iov42_decode

entities = [
    PrivateIdentity(
        CryptoProtocol.SHA256WithECDSA.generate_private_key()).public_identity,
    AssetType(),
    Asset(asset_type_id="123456"),
]


def id_class_name(value: typing.Any) -> str:
    """Provide class name for test identifier."""
    return str(value.__class__.__name__)


def test_hased_claim() -> None:
    """Hash of a claim."""
    assert "RIREN5QE4J55V0aOmXdmRWOoSV_EIUtf0o_tdF4hInM" == hashed_claim(
        b"claim-1")