Пример #1
0
def test_anonymous_caller(network, args):
    if args.package == "liblogging":
        primary, _ = network.find_primary()

        # Create a new user but do not record its identity
        network.create_user("user5", args.participants_curve, record=False)

        log_id = 101
        msg = "This message is anonymous"
        with primary.client("user5") as c:
            r = c.post("/app/log/private/anonymous", {"id": log_id, "msg": msg})
            assert r.body.json() == True
            r = c.get(f"/app/log/private?id={log_id}")
            assert r.status_code == http.HTTPStatus.UNAUTHORIZED.value, r

        with primary.client("user0") as c:
            r = c.get(f"/app/log/private?id={log_id}")
            assert msg in r.body.json()["msg"], r

    else:
        LOG.warning(
            f"Skipping {inspect.currentframe().f_code.co_name} as application is not C++"
        )

    return network
Пример #2
0
def test_user(network, args, verify=True):
    # Note: This test should not be chained in the test suite as it creates
    # a new user and uses its own LoggingTxs
    primary, _ = network.find_nodes()
    new_user_local_id = "user3"
    new_user = network.create_user(new_user_local_id, args.participants_curve)
    user_data = {"lifetime": "temporary"}
    network.consortium.add_user(primary, new_user.local_id, user_data)
    txs = app.LoggingTxs(user_id=new_user.local_id)
    txs.issue(
        network=network,
        number_txs=1,
    )
    if verify:
        txs.verify()
    network.consortium.remove_user(primary, new_user.service_id)
    with primary.client(new_user_local_id) as c:
        r = c.get("/app/log/private")
        assert r.status_code == http.HTTPStatus.UNAUTHORIZED.value
    return network
Пример #3
0
def test_jinja_templates(network, args, verify=True):
    primary, _ = network.find_primary()

    new_user_local_id = "bob"
    new_user = network.create_user(new_user_local_id, args.participants_curve)

    with primary.client(new_user_local_id) as c:
        r = c.post("/app/log/private", {"id": 42, "msg": "New user test"})
        assert r.status_code == http.HTTPStatus.UNAUTHORIZED.value

    template_loader = jinja2.ChoiceLoader(
        [
            jinja2.FileSystemLoader(args.jinja_templates_path),
            jinja2.FileSystemLoader(os.path.dirname(new_user.cert_path)),
        ]
    )
    template_env = jinja2.Environment(
        loader=template_loader, undefined=jinja2.StrictUndefined
    )

    proposal_template = template_env.get_template("set_user_proposal.json.jinja")
    proposal_body = proposal_template.render(cert=os.path.basename(new_user.cert_path))
    proposal = network.consortium.get_any_active_member().propose(
        primary, proposal_body
    )

    ballot_template = template_env.get_template("ballot.json.jinja")
    ballot_body = ballot_template.render(**json.loads(proposal_body))
    network.consortium.vote_using_majority(primary, proposal, ballot_body)

    with primary.client(new_user_local_id) as c:
        r = c.post("/app/log/private", {"id": 42, "msg": "New user test"})
        assert r.status_code == http.HTTPStatus.OK.value

    network.consortium.remove_user(primary, new_user.service_id)
    with primary.client(new_user_local_id) as c:
        r = c.get("/app/log/private")
        assert r.status_code == http.HTTPStatus.UNAUTHORIZED.value

    return network
Пример #4
0
def test_actions(network, args):
    node = network.find_random_node()

    with node.client(None, "member0") as c:
        valid_set_member_data = proposal(
            action(
                "set_member_data",
                member_id=
                f"{network.consortium.get_member_by_local_id('member0').service_id}",
                member_data={"is_admin": True},
            ))

        r = c.post("/gov/proposals.js", valid_set_member_data)
        assert r.status_code == 200, r.body.text()

        valid_rekey_ledger = proposal(action("rekey_ledger"))
        r = c.post("/gov/proposals.js", valid_rekey_ledger)
        assert r.status_code == 200, r.body.text()

        valid_service_open = proposal(action("transition_service_to_open"))
        r = c.post("/gov/proposals.js", valid_service_open)
        assert r.status_code == 200, r.body.text()

        new_user_local_id = "js_user"
        new_user = network.create_user(new_user_local_id,
                                       args.participants_curve)
        LOG.info(f"Adding new user {new_user.service_id}")
        with open(
                os.path.join(network.common_dir,
                             f"{new_user_local_id}_cert.pem"), "r") as cert:
            valid_new_user = proposal(
                action("set_user",
                       cert=cert.read(),
                       user_data={"is_admin": True}))
        r = c.post("/gov/proposals.js", valid_new_user)
        assert r.status_code == 200, r.body.text()
    return network
Пример #5
0
def test_multi_auth(network, args):
    primary, _ = network.find_primary()
    user = network.users[0]
    member = network.consortium.members[0]

    with primary.client(user.local_id) as c:
        response = c.get("/app/api")
        supported_methods = response.body.json()["paths"]
        if "/multi_auth" in supported_methods.keys():
            response_bodies = set()

            def require_new_response(r):
                assert r.status_code == http.HTTPStatus.OK.value, r.status_code
                r_body = r.body.text()
                assert r_body not in response_bodies, r_body
                response_bodies.add(r_body)

            LOG.info("Anonymous, no auth")
            with primary.client() as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a user, via TLS cert")
            with primary.client(user.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as same user, now with user data")
            network.consortium.set_user_data(
                primary, user.service_id, {"some": ["interesting", "data", 42]}
            )
            with primary.client(user.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a different user, via TLS cert")
            with primary.client("user1") as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a member, via TLS cert")
            with primary.client(member.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as same member, now with user data")
            network.consortium.set_member_data(
                primary, member.service_id, {"distinct": {"arbitrary": ["data"]}}
            )
            with primary.client(member.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a different member, via TLS cert")
            with primary.client("member1") as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a user, via HTTP signature")
            with primary.client(None, user.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a member, via HTTP signature")
            with primary.client(None, member.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as user2 but sign as user1")
            with primary.client("user2", "user1") as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            network.create_user("user5", args.participants_curve, record=False)

            LOG.info("Authenticate as invalid user5 but sign as valid user3")
            with primary.client("user5", "user3") as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate via JWT token")
            jwt_key_priv_pem, _ = infra.crypto.generate_rsa_keypair(2048)
            jwt_cert_pem = infra.crypto.generate_cert(jwt_key_priv_pem)
            jwt_kid = "my_key_id"
            jwt_issuer = "https://example.issuer"
            # Add JWT issuer
            with tempfile.NamedTemporaryFile(prefix="ccf", mode="w+") as metadata_fp:
                jwt_cert_der = infra.crypto.cert_pem_to_der(jwt_cert_pem)
                der_b64 = base64.b64encode(jwt_cert_der).decode("ascii")
                data = {
                    "issuer": jwt_issuer,
                    "jwks": {
                        "keys": [{"kty": "RSA", "kid": jwt_kid, "x5c": [der_b64]}]
                    },
                }
                json.dump(data, metadata_fp)
                metadata_fp.flush()
                network.consortium.set_jwt_issuer(primary, metadata_fp.name)

            with primary.client() as c:
                jwt = infra.crypto.create_jwt({}, jwt_key_priv_pem, jwt_kid)
                r = c.get("/app/multi_auth", headers={"authorization": "Bearer " + jwt})
                require_new_response(r)

        else:
            LOG.warning(
                f"Skipping {inspect.currentframe().f_code.co_name} as application does not implement '/multi_auth'"
            )

    return network
Пример #6
0
def test_actions(network, args):
    node = network.find_random_node()

    # Rekey ledger
    network.consortium.trigger_ledger_rekey(node)

    # Add new user twice (with and without user data)
    new_user_local_id = "js_user"
    new_user = network.create_user(new_user_local_id, args.participants_curve)
    LOG.info(f"Adding new user {new_user.service_id}")

    user_data = None
    network.consortium.add_user(node, new_user.local_id, user_data)

    user_data = {"foo": "bar"}
    network.consortium.add_user(node, new_user.local_id, user_data)

    with node.client(new_user.local_id) as c:
        r = c.post("/app/log/private", {"id": 0, "msg": "JS"})
        assert r.status_code == 200, r.body.text()

    # Set user data
    network.consortium.set_user_data(node,
                                     new_user.service_id,
                                     user_data={"user": "******"})
    network.consortium.set_user_data(node, new_user.service_id, user_data=None)

    # Remove user
    network.consortium.remove_user(node, new_user.service_id)

    with node.client(new_user.local_id) as c:
        r = c.get("/app/log/private")
        assert r.status_code == 401, r.body.text()

    # Set member data
    network.consortium.set_member_data(
        node,
        network.consortium.get_member_by_local_id("member0").service_id,
        member_data={
            "is_operator": True,
            "is_admin": True
        },
    )

    # Set recovery threshold
    try:
        network.consortium.set_recovery_threshold(node, recovery_threshold=0)
        assert False, "Recovery threshold cannot be set to zero"
    except infra.proposal.ProposalNotCreated as e:
        assert (e.response.status_code == 400
                and e.response.body.json()["error"]["code"]
                == "ProposalFailedToValidate"), e.response.body.text()

    try:
        network.consortium.set_recovery_threshold(node, recovery_threshold=256)
        assert False, "Recovery threshold cannot be set to > 255"
    except infra.proposal.ProposalNotCreated as e:
        assert (e.response.status_code == 400
                and e.response.body.json()["error"]["code"]
                == "ProposalFailedToValidate"), e.response.body.text()

    try:
        network.consortium.set_recovery_threshold(node,
                                                  recovery_threshold=None)
        assert False, "Recovery threshold value must be passed as proposal argument"
    except infra.proposal.ProposalNotCreated as e:
        assert (e.response.status_code == 400
                and e.response.body.json()["error"]["code"]
                == "ProposalFailedToValidate"), e.response.body.text()

    try:
        network.consortium.set_recovery_threshold(
            node,
            recovery_threshold=len(
                network.consortium.get_active_recovery_members()) + 1,
        )
        assert (
            False
        ), "Recovery threshold cannot be greater than the number of active recovery members"
    except infra.proposal.ProposalNotAccepted:
        pass

    network.consortium.set_recovery_threshold(
        node, recovery_threshold=network.consortium.recovery_threshold - 1)

    # Refresh recovery shares
    network.consortium.trigger_recovery_shares_refresh(node)

    # Set member
    new_member = network.consortium.generate_and_add_new_member(
        node, args.participants_curve)

    member_data = {"foo": "bar"}
    new_member = network.consortium.generate_and_add_new_member(
        node, args.participants_curve, member_data=member_data)

    # Remove member
    network.consortium.remove_member(node, new_member)
    network.consortium.remove_member(node, new_member)

    return network
Пример #7
0
def test_multi_auth(network, args):
    if args.package == "liblogging":
        primary, _ = network.find_primary()

        response_bodies = set()

        def require_new_response(r):
            assert r.status_code == http.HTTPStatus.OK.value, r.status_code
            r_body = r.body.text()
            assert r_body not in response_bodies, r_body
            response_bodies.add(r_body)

        LOG.info("Anonymous, no auth")
        with primary.client() as c:
            r = c.get("/app/multi_auth")
            require_new_response(r)

        LOG.info("Authenticate as a user, via TLS cert")
        with primary.client("user0") as c:
            r = c.get("/app/multi_auth")
            require_new_response(r)

        LOG.info("Authenticate as a different user, via TLS cert")
        with primary.client("user1") as c:
            r = c.get("/app/multi_auth")
            require_new_response(r)

        LOG.info("Authenticate as a member, via TLS cert")
        with primary.client("member0") as c:
            r = c.get("/app/multi_auth")
            require_new_response(r)

        LOG.info("Authenticate as a different member, via TLS cert")
        with primary.client("member1") as c:
            r = c.get("/app/multi_auth")
            require_new_response(r)

        LOG.info("Authenticate as a user, via HTTP signature")
        with primary.client(None, "user0") as c:
            r = c.get("/app/multi_auth")
            require_new_response(r)

        LOG.info("Authenticate as a member, via HTTP signature")
        with primary.client(None, "member0") as c:
            r = c.get("/app/multi_auth")
            require_new_response(r)

        LOG.info("Authenticate as user2 but sign as user1")
        with primary.client("user2", "user1") as c:
            r = c.get("/app/multi_auth")
            require_new_response(r)

        network.create_user(5, args.participants_curve, record=False)

        LOG.info("Authenticate as invalid user5 but sign as valid user3")
        with primary.client("user5", "user3") as c:
            r = c.get("/app/multi_auth")
            require_new_response(r)

        LOG.info("Authenticate via JWT token")
        jwt_key_priv_pem, _ = infra.crypto.generate_rsa_keypair(2048)
        jwt_cert_pem = infra.crypto.generate_cert(jwt_key_priv_pem)
        jwt_kid = "my_key_id"
        jwt_issuer = "https://example.issuer"
        # Add JWT issuer
        with tempfile.NamedTemporaryFile(prefix="ccf",
                                         mode="w+") as metadata_fp:
            jwt_cert_der = infra.crypto.cert_pem_to_der(jwt_cert_pem)
            der_b64 = base64.b64encode(jwt_cert_der).decode("ascii")
            data = {
                "issuer": jwt_issuer,
                "jwks": {
                    "keys": [{
                        "kty": "RSA",
                        "kid": jwt_kid,
                        "x5c": [der_b64]
                    }]
                },
            }
            json.dump(data, metadata_fp)
            metadata_fp.flush()
            network.consortium.set_jwt_issuer(primary, metadata_fp.name)

        with primary.client() as c:
            jwt = infra.crypto.create_jwt({}, jwt_key_priv_pem, jwt_kid)
            r = c.get("/app/multi_auth",
                      headers={"authorization": "Bearer " + jwt})
            require_new_response(r)

    return network
Пример #8
0
def test_multi_auth(network, args):
    primary, _ = network.find_primary()
    user = network.users[0]
    member = network.consortium.members[0]

    with primary.client(user.local_id) as c:
        response = c.get("/app/api")
        supported_methods = response.body.json()["paths"]
        if "/multi_auth" in supported_methods.keys():
            response_bodies = set()

            def require_new_response(r):
                assert r.status_code == http.HTTPStatus.OK.value, r.status_code
                r_body = r.body.text()
                assert r_body not in response_bodies, r_body
                response_bodies.add(r_body)

            LOG.info("Anonymous, no auth")
            with primary.client() as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a user, via TLS cert")
            with primary.client(user.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as same user, now with user data")
            network.consortium.set_user_data(
                primary, user.service_id, {"some": ["interesting", "data", 42]}
            )
            with primary.client(user.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a different user, via TLS cert")
            with primary.client("user1") as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a member, via TLS cert")
            with primary.client(member.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as same member, now with user data")
            network.consortium.set_member_data(
                primary, member.service_id, {"distinct": {"arbitrary": ["data"]}}
            )
            with primary.client(member.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a different member, via TLS cert")
            with primary.client("member1") as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a user, via HTTP signature")
            with primary.client(None, user.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as a member, via HTTP signature")
            with primary.client(None, member.local_id) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate as user2 but sign as user1")
            with primary.client("user2", "user1") as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            network.create_user("user5", args.participants_curve, record=False)

            LOG.info("Authenticate as invalid user5 but sign as valid user3")
            with primary.client("user5", "user3") as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

            LOG.info("Authenticate via JWT token")
            jwt_issuer = infra.jwt_issuer.JwtIssuer()
            jwt_issuer.register(network)
            jwt = jwt_issuer.issue_jwt(claims={"user": "******"})

            with primary.client() as c:
                r = c.get("/app/multi_auth", headers={"authorization": "Bearer " + jwt})
                require_new_response(r)

            LOG.info("Authenticate via second JWT token")
            jwt2 = jwt_issuer.issue_jwt(claims={"user": "******"})

            with primary.client(
                common_headers={"authorization": "Bearer " + jwt2}
            ) as c:
                r = c.get("/app/multi_auth")
                require_new_response(r)

        else:
            LOG.warning(
                f"Skipping {inspect.currentframe().f_code.co_name} as application does not implement '/multi_auth'"
            )

    return network