Beispiel #1
0
def test_content_raises(identity: PrivateIdentity) -> None:
    """Request content to create claims and endorsements for an unique asset."""
    asset = Asset(asset_type_id="98765")
    with pytest.raises(TypeError) as exeinfo:
        asset.put_request_content(endorser=identity)
    assert (
        str(exeinfo.value)
        == "missing required keyword argument needed for endorsement: 'claims'"
    )
Beispiel #2
0
def test_content_create_asset_request() -> None:
    """Request content to create an account."""
    request_id = "123456"
    asset = Asset(asset_type_id="123456")

    content = json.loads(asset.put_request_content(request_id=request_id))
    assert content == {
        "_type": "CreateAssetRequest",
        "assetId": asset.asset_id,
        "assetTypeId": asset.asset_type_id,
        "requestId": request_id,
    }
Beispiel #3
0
def test_content_create_account(quantity: typing.Union[str, int, float]) -> None:
    """Request content to create an account."""
    request_id = "123456"
    asset = Asset(asset_type_id="123456", quantity=quantity)  # type: ignore[arg-type]

    content = json.loads(asset.put_request_content(request_id=request_id))
    assert content == {
        "_type": "CreateAssetRequest",
        "assetId": asset.asset_id,
        "assetTypeId": asset.asset_type_id,
        "quantity": str(int(float(quantity))),
        "requestId": request_id,
    }
Beispiel #4
0
def test_rep_account(quantity: typing.Union[int, float, str]) -> None:
    """Informal representation of an account."""
    asset = Asset(asset_type_id="123456", quantity=quantity)  # type: ignore[arg-type]
    assert (
        repr(asset) == f"Asset(asset_type_id='{asset.asset_type_id}', "  # type: ignore[arg-type]
        f"asset_id='{asset.asset_id}', quantity='{int(float(asset.quantity))}')"
    )
Beispiel #5
0
def test_repr() -> None:
    """Informal representation of an asset."""
    asset = Asset(asset_type_id="123456")
    assert (
        repr(asset)
        == f"Asset(asset_type_id='{asset.asset_type_id}', asset_id='{asset.asset_id}')"
    )
Beispiel #6
0
def read_endorsement(
    ctx: click.core.Context,
    identity: str,
    endorser_id: str,
    entity_type: str,
    entity_id: str,
    asset_type_id: str,
    claim: str,
) -> None:
    """Read specific endorsement of a claim (identity, asset type, unique asset)."""
    if entity_type.lower() == "asset":
        entity = Asset(asset_type_id=asset_type_id, asset_id=entity_id)
    else:
        raise NotImplementedError  # pragma: no cover
    id = _load_identity(identity)
    client = Client(ctx.obj["url"], id)
    response = client.get(
        entity,
        claim=claim.encode(),
        endorser_id=endorser_id,
        request_id=ctx.obj["request_id"],
    )
    print(f"{entity!r}")
    print(f"{claim!r}")
    print(f"endorser: {response.endorser_id!r}")  # type: ignore[union-attr]
Beispiel #7
0
def test_raise_invalid_asset_id(invalid_id: str) -> None:
    """Raise exception if the provided id contains invalid characters."""
    with pytest.raises(ValueError) as excinfo:
        Asset(asset_id=invalid_id, asset_type_id="123456")
    assert (
        str(excinfo.value)
        == f"invalid identifier '{invalid_id}' - valid characters are [a-zA-Z0-9._\\-+]"
    )
Beispiel #8
0
def test_node_id_cached(
    client: Client,
    mocked_requests_200: respx.MockTransport,
) -> None:
    """node_id is cached after the first GET request."""
    client.get(
        Asset(asset_type_id="1234567"),
        claim=b"claim-1",
        endorser_id=client.identity.identity_id,
    )
    client.get(
        Asset(asset_type_id="1234567"),
        claim=b"claim-1",
        endorser_id=client.identity.identity_id,
    )

    assert mocked_requests_200["read_node_info"].call_count == 1
Beispiel #9
0
def create_asset(ctx: click.core.Context, identity: str, asset_type_id: str,
                 asset_id: str) -> None:
    """Create an asset."""
    asset = Asset(asset_type_id=asset_type_id, asset_id=asset_id)
    id = _load_identity(identity)
    client = Client(ctx.obj["url"], id)
    _ = client.put(asset, request_id=ctx.obj["request_id"])
    print(f"asset_id: {asset}")
Beispiel #10
0
def test_raises_invalid_quantity(
    invalid_quantity: typing.Union[str, int, float]
) -> None:
    """Request content to create claims on an unique asset."""
    with pytest.raises(ValueError) as excinfo:
        Asset(asset_type_id="123456", quantity=invalid_quantity),  # type: ignore[arg-type]
    assert (
        str(excinfo.value) == f"must be a whole, positive number: '{invalid_quantity}'"
    )
Beispiel #11
0
def register_product(client: Client, tag_type: AssetType,
                     product: Tuple[str, str]) -> None:
    """Register product on iov42 platform and add product information as claim."""
    tag_id, claim = product
    tag = Asset(asset_id=tag_id, asset_type_id=tag_type.asset_type_id)
    client.put(tag)
    print(f"Created tag: {tag_id}")
    client.put(tag, claims=[claim.encode()], endorse=True)
    print(f"Tag [{tag_id}]: added enrosement on claim '{claim}'")
Beispiel #12
0
def test_content_create_asset_claims_request() -> None:
    """Request content to create claims on an unique asset."""
    request_id = "123456"
    claims = [b"claim-1", b"claim-2"]
    asset = Asset(asset_type_id="123456")

    content = json.loads(
        asset.put_request_content(claims=claims, request_id=request_id)
    )
    hashed_claims = content.pop("claims")
    assert content == {
        "_type": "CreateAssetClaimsRequest",
        "subjectId": asset.asset_id,
        "subjectTypeId": asset.asset_type_id,
        "requestId": request_id,
    }
    assert len(hashed_claims) == len(claims)
    for hc in [hashed_claim(c) for c in claims]:
        assert hc in hashed_claims
Beispiel #13
0
def test_response_asset(
    client: Client,
    mocked_requests_200: respx.MockTransport,
) -> None:
    """Platform response to the request to create an asset type."""
    entity = Asset(asset_type_id=str(uuid.uuid4()))
    response = client.put(entity)
    assert response.resources == [  # type: ignore[union-attr]
        "/".join(("/api/v1/asset-types", entity.asset_type_id, "assets",
                  entity.asset_id))
    ]
def test_create_asset(alice_client: Client,
                      existing_asset_type_id: str) -> None:
    """Create an unique asset on an iov42 platform."""
    asset = Asset(asset_type_id=existing_asset_type_id)

    response = alice_client.put(asset)

    assert ("/".join(
        ("/api/v1/asset-types", asset.asset_type_id, "assets",
         asset.asset_id)) == response.resources[0]  # type: ignore[union-attr]
            )
def test_unknown_method(identity: PrivateIdentity) -> None:
    """We create the request even if the method is bogus."""
    request = Request(
        "FOO",
        "https://example.org",
        Asset(asset_type_id="123456"),
    )
    request.add_authentication_header(identity)
    assert [*request.headers] == []
    assert request.url == "https://example.org"
    assert request.content == b""
    assert not hasattr(request, "resource")
Beispiel #16
0
def test_read_unique_asset_endorsement_header(
    client: Client,
    endorser: PublicIdentity,
    mocked_requests_200: respx.MockTransport,
) -> None:
    """GET request has only x-iov42-authentication header."""
    asset = Asset(asset_type_id="1234567")
    client.get(asset, claim=b"claim-1", endorser_id=endorser.identity_id)

    assert mocked_requests_200["read_asset_endorsement"].call_count == 1
    http_request, _ = mocked_requests_200["read_asset_endorsement"].calls[0]
    assert "x-iov42-authentication" in [*http_request.headers]
def test_create_account(alice_client: Client,
                        existing_quantifiable_asset_type_id: str) -> None:
    """Create an account on an iov42 platform."""
    account = Asset(asset_type_id=existing_quantifiable_asset_type_id,
                    quantity=0)  # type: ignore[arg-type]

    response = alice_client.put(account)

    assert ("/".join((
        "/api/v1/asset-types", account.asset_type_id, "assets",
        account.asset_id)) == response.resources[0]  # type: ignore[union-attr]
            )
Beispiel #18
0
def test_get_node_id(
    client: Client,
    mocked_requests_200: respx.MockTransport,
) -> None:
    """Retrieve node_id on the very first GET request."""
    client.get(
        Asset(asset_type_id="1234567"),
        claim=b"claim-1",
        endorser_id=client.identity.identity_id,
    )

    assert client.node_id == "node-1"
    assert mocked_requests_200["read_node_info"].call_count == 1
Beispiel #19
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()
        )
Beispiel #20
0
def test_authentication_header(
    client: Client,
    endorser: PublicIdentity,
    mocked_requests_200: respx.MockTransport,
) -> None:
    """The x-iov42-authentication header is signed by the identity."""
    asset = Asset(asset_type_id="1234567")
    client.get(asset, claim=b"claim-1", endorser_id=endorser.identity_id)

    http_request, _ = mocked_requests_200["read_asset_endorsement"].calls[0]
    authentication = json.loads(
        iov42_decode(http_request.headers["x-iov42-authentication"].encode()))
    assert len(authentication) == 3
    assert authentication["identityId"] == client.identity.identity_id
    assert authentication[
        "protocolId"] == client.identity.private_key.protocol.name
Beispiel #21
0
def test_authentication_header_signature(
    client: Client,
    endorser: PublicIdentity,
    mocked_requests_200: respx.MockTransport,
) -> None:
    """Signature of x-iov42-authentication header is the signed request URL."""
    asset = Asset(asset_type_id="1234567")
    client.get(asset, claim=b"claim-1", endorser_id=endorser.identity_id)

    http_request, _ = mocked_requests_200["read_asset_endorsement"].calls[0]
    authentication = json.loads(
        iov42_decode(http_request.headers["x-iov42-authentication"].encode()))
    try:
        content = http_request.url.raw_path
        client.identity.verify_signature(authentication["signature"], content)
    except InvalidSignature:
        pytest.fail("Signature verification failed")
Beispiel #22
0
def create_endorsement(
    ctx: click.core.Context,
    identity: str,
    entity_type: str,
    entity_id: str,
    asset_type_id: str,
    claims: List[str],
) -> None:
    """Endorse claims about an entity (identity, asset type, unique asset)."""
    if entity_type.lower() == "asset":
        entity = Asset(asset_type_id=asset_type_id, asset_id=entity_id)
    else:
        raise NotImplementedError  # pragma: no cover
    id = _load_identity(identity)
    client = Client(ctx.obj["url"], id)
    claims_bytes = [c.encode() for c in claims]
    response = client.put(entity,
                          claims=claims_bytes,
                          endorse=True,
                          request_id=ctx.obj["request_id"])
    print(f"claims on {entity}: {entity_id}")
    print(f"affected resources: {response.resources}"
          )  # type: ignore[union-attr]
Beispiel #23
0
def test_account(quantity: typing.Union[int, float, str]) -> None:
    """Create an account with initial quantity."""
    account = Asset(asset_type_id="98765", quantity=quantity)  # type: ignore[arg-type]
    assert account.quantity == str(int(float(quantity)))
def existing_asset(alice_client: Client, existing_asset_type_id: str) -> Asset:
    """Creates an asset oqned ba Alice on an iov42 platform ."""
    asset = Asset(asset_type_id=existing_asset_type_id)
    alice_client.put(asset)
    return asset
import uuid

import pytest

from iov42.core import Asset
from iov42.core import AssetType
from iov42.core import CryptoProtocol
from iov42.core import Entity
from iov42.core import PrivateIdentity
from iov42.core import Request

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


def id_class_name(value: Entity) -> str:
    """Provide class name as test identifier."""
    return str(value.__class__.__name__)


@pytest.mark.parametrize("entity", entities, ids=id_class_name)
def test_request_with_id(entity: Entity) -> None:
    """Request with request_id."""
    request = Request("PUT",
                      "https://example.org",
                      entity,
                      request_id="123456")
Beispiel #26
0
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")


@pytest.mark.parametrize("entity", entities, ids=id_class_name)
Beispiel #27
0
def test_asset() -> None:
    """Provide asset ID explicitely."""
    asset = Asset(asset_type_id="123456", asset_id="98765")
    assert asset.asset_id == "98765"
    assert asset.asset_type_id == "123456"
Beispiel #28
0
def test_relative_path() -> None:
    """Return relative URL where the asset information can be read."""
    asset = Asset(asset_type_id="123456")
    assert asset.resource == "/".join(
        ("/api/v1/asset-types", asset.asset_type_id, "assets", asset.asset_id)
    )
Beispiel #29
0
def test_asset_generated_id() -> None:
    """Asset with no ID generates an UUID as ID."""
    asset = Asset(asset_type_id="123456")
    assert uuid.UUID(asset.asset_id)