def test_load_ed25519_public_key_signers(self): signers = [ { "weight": 10, "key": "XCRJANZNX6PX42O2PTZ5PTKAQYZNQOXHDRF7PI7ANSJSW4RKGT63XCDN", "type": "sha256_hash", }, { "weight": 1, "key": "GCV5YZ7R6IAKQCIGDP6TS6GHUXSNWVLP2CNRCUSIPQFRX67LGQRXTCL6", "type": "ed25519_public_key", }, { "weight": 2, "key": "GBUGPGCH6YTEOT2CQJDRYPIXK5KTVUZOWIQMLIAOLYKZMPWT23CVQMPH", "type": "ed25519_public_key", }, ] account_id = "GA7YNBW5CBTJZ3ZZOWX3ZNBKD6OE7A7IHUQVWMY62W2ZBG2SGZVOOPVH" sequence = 123123 account = Account(account_id=account_id, sequence=sequence) account.signers = signers assert account.load_ed25519_public_key_signers() == [ Ed25519PublicKeySigner( "GCV5YZ7R6IAKQCIGDP6TS6GHUXSNWVLP2CNRCUSIPQFRX67LGQRXTCL6", 1), Ed25519PublicKeySigner( "GBUGPGCH6YTEOT2CQJDRYPIXK5KTVUZOWIQMLIAOLYKZMPWT23CVQMPH", 2), ]
def test_post_fails_account_exists_client_attribution_no_client_signature( mock_load_account, client): kp = Keypair.random() client_domain_kp = Keypair.random() challenge_xdr = build_challenge_transaction( server_secret=settings.SIGNING_SEED, client_account_id=kp.public_key, home_domain=settings.SEP10_HOME_DOMAINS[0], web_auth_domain=urlparse(settings.HOST_URL).netloc, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE, client_domain="test.com", client_signing_key=client_domain_kp.public_key, ) envelope = TransactionEnvelope.from_xdr( challenge_xdr, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE) envelope.sign(kp) signed_challenge_xdr = envelope.to_xdr() mock_load_account.return_value = Mock( load_ed25519_public_key_signers=Mock( return_value=[Ed25519PublicKeySigner(kp.public_key, 0)]), thresholds=Mock(med_threshold=0), ) response = client.post(AUTH_PATH, {"transaction": signed_challenge_xdr}) content = response.json() assert response.status_code == 400, json.dumps(content, indent=2) assert ( content["error"] == "error while validating challenge: " "Transaction not signed by the source account of the 'client_domain' ManageData operation" )
def test_post_success_account_exists(mock_load_account, client): kp = Keypair.random() challenge_xdr = build_challenge_transaction( server_secret=settings.SIGNING_SEED, client_account_id=kp.public_key, home_domain=settings.SEP10_HOME_DOMAINS[0], web_auth_domain=urlparse(settings.HOST_URL).netloc, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE, ) envelope = TransactionEnvelope.from_xdr( challenge_xdr, network_passphrase=settings.STELLAR_NETWORK_PASSPHRASE) envelope.sign(kp) signed_challenge_xdr = envelope.to_xdr() mock_load_account.return_value = Mock( load_ed25519_public_key_signers=Mock( return_value=[Ed25519PublicKeySigner(kp.public_key, 0)]), thresholds=Mock(med_threshold=0), ) response = client.post(AUTH_PATH, {"transaction": signed_challenge_xdr}) content = response.json() assert response.status_code == 200, json.dumps(content, indent=2) jwt_contents = jwt.decode(content["token"], settings.SERVER_JWT_KEY, algorithms=["HS256"]) iat = jwt_contents.pop("iat") exp = jwt_contents.pop("exp") assert exp - iat == 24 * 60 * 60 assert jwt_contents == { "iss": os.path.join(settings.HOST_URL, "auth"), "sub": kp.public_key, "jti": envelope.hash().hex(), "client_domain": None, }
def test_verify_transaction_signatures(self): server_kp = Keypair.random() client_kp_a = Keypair.random() client_kp_b = Keypair.random() client_kp_c = Keypair.random() timeout = 600 network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE anchor_name = "SDF" challenge = build_challenge_transaction( server_secret=server_kp.secret, client_account_id=client_kp_a.public_key, anchor_name=anchor_name, network_passphrase=network_passphrase, timeout=timeout, ) transaction = TransactionEnvelope.from_xdr(challenge, network_passphrase) transaction.sign(client_kp_a) transaction.sign(client_kp_b) transaction.sign(client_kp_c) signers = [ Ed25519PublicKeySigner(client_kp_a.public_key, 1), Ed25519PublicKeySigner(client_kp_b.public_key, 2), Ed25519PublicKeySigner(client_kp_c.public_key, 3), Ed25519PublicKeySigner(Keypair.random().public_key, 4), ] signers_found = _verify_transaction_signatures(transaction, signers) assert signers_found == [ Ed25519PublicKeySigner(client_kp_a.public_key, 1), Ed25519PublicKeySigner(client_kp_b.public_key, 2), Ed25519PublicKeySigner(client_kp_c.public_key, 3), ]
def test_verify_challenge_transaction_threshold_raise_not_meet_threshold( self): server_kp = Keypair.random() client_kp_a = Keypair.random() client_kp_b = Keypair.random() client_kp_c = Keypair.random() timeout = 600 network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE domain_name = "example.com" challenge = build_challenge_transaction( server_secret=server_kp.secret, client_account_id=client_kp_a.public_key, domain_name=domain_name, network_passphrase=network_passphrase, timeout=timeout, ) transaction = TransactionEnvelope.from_xdr(challenge, network_passphrase) transaction.sign(client_kp_a) transaction.sign(client_kp_b) transaction.sign(client_kp_c) challenge_tx = transaction.to_xdr() signers = [ Ed25519PublicKeySigner(client_kp_a.public_key, 1), Ed25519PublicKeySigner(client_kp_b.public_key, 2), Ed25519PublicKeySigner(client_kp_c.public_key, 4), Ed25519PublicKeySigner(Keypair.random().public_key, 255), ] med_threshold = 10 with pytest.raises( InvalidSep10ChallengeError, match="signers with weight 7 do not meet threshold 10.", ): verify_challenge_transaction_threshold( challenge_tx, server_kp.public_key, domain_name, network_passphrase, med_threshold, signers, )
def test_verify_challenge_transaction_signers_raise_no_server_signature( self): server_kp = Keypair.random() client_kp_a = Keypair.random() client_kp_b = Keypair.random() client_kp_c = Keypair.random() timeout = 600 network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE domain_name = "example.com" challenge = build_challenge_transaction( server_secret=server_kp.secret, client_account_id=client_kp_a.public_key, domain_name=domain_name, network_passphrase=network_passphrase, timeout=timeout, ) transaction = TransactionEnvelope.from_xdr(challenge, network_passphrase) transaction.signatures = [] transaction.sign(client_kp_a) transaction.sign(client_kp_b) transaction.sign(client_kp_c) challenge_tx = transaction.to_xdr() signers = [ Ed25519PublicKeySigner(client_kp_a.public_key, 1), Ed25519PublicKeySigner(client_kp_b.public_key, 2), Ed25519PublicKeySigner(client_kp_c.public_key, 4), Ed25519PublicKeySigner(Keypair.random().public_key, 255), ] with pytest.raises( InvalidSep10ChallengeError, match="Transaction not signed by server: {}.".format( server_kp.public_key), ): verify_challenge_transaction_signers( challenge_tx, server_kp.public_key, domain_name, network_passphrase, signers, )
def test_verify_challenge_transaction_signers_raise_unrecognized_signatures( self): server_kp = Keypair.random() client_kp_a = Keypair.random() client_kp_b = Keypair.random() client_kp_c = Keypair.random() client_kp_unrecognized = Keypair.random() timeout = 600 network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE home_domain = "example.com" challenge = build_challenge_transaction( server_secret=server_kp.secret, client_account_id=client_kp_a.public_key, home_domain=home_domain, network_passphrase=network_passphrase, timeout=timeout, ) transaction = TransactionEnvelope.from_xdr(challenge, network_passphrase) transaction.sign(client_kp_a) transaction.sign(client_kp_b) transaction.sign(client_kp_c) transaction.sign(client_kp_unrecognized) challenge_tx = transaction.to_xdr() signers = [ Ed25519PublicKeySigner(client_kp_a.public_key, 1), Ed25519PublicKeySigner(client_kp_b.public_key, 2), Ed25519PublicKeySigner(client_kp_c.public_key, 4), Ed25519PublicKeySigner(Keypair.random().public_key, 255), ] with pytest.raises(InvalidSep10ChallengeError, match="Transaction has unrecognized signatures."): verify_challenge_transaction_signers( challenge_tx, server_kp.public_key, home_domain, network_passphrase, signers, )
def test_verify_challenge_transaction_signers_raise_no_client_signer_found( self): server_kp = Keypair.random() client_kp_a = Keypair.random() client_kp_b = Keypair.random() client_kp_c = Keypair.random() timeout = 600 network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE anchor_name = "SDF" challenge = build_challenge_transaction( server_secret=server_kp.secret, client_account_id=client_kp_a.public_key, anchor_name=anchor_name, network_passphrase=network_passphrase, timeout=timeout, ) transaction = TransactionEnvelope.from_xdr(challenge, network_passphrase) transaction.sign(client_kp_a) transaction.sign(client_kp_b) transaction.sign(client_kp_c) challenge_tx = transaction.to_xdr() signers = [ Ed25519PublicKeySigner(Keypair.random().public_key, 1), Ed25519PublicKeySigner(Keypair.random().public_key, 2), Ed25519PublicKeySigner(Keypair.random().public_key, 4), ] with pytest.raises( InvalidSep10ChallengeError, match="Transaction not signed by any client signer.", ): verify_challenge_transaction_signers(challenge_tx, server_kp.public_key, network_passphrase, signers)
def test_verify_challenge_transaction_threshold(self): server_kp = Keypair.random() client_kp_a = Keypair.random() client_kp_b = Keypair.random() client_kp_c = Keypair.random() timeout = 600 network_passphrase = Network.PUBLIC_NETWORK_PASSPHRASE domain_name = "example.com" challenge = build_challenge_transaction( server_secret=server_kp.secret, client_account_id=client_kp_a.public_key, domain_name=domain_name, network_passphrase=network_passphrase, timeout=timeout, ) transaction = TransactionEnvelope.from_xdr(challenge, network_passphrase) transaction.sign(client_kp_a) transaction.sign(client_kp_b) transaction.sign(client_kp_c) challenge_tx = transaction.to_xdr() signers = [ Ed25519PublicKeySigner(client_kp_a.public_key, 1), Ed25519PublicKeySigner(client_kp_b.public_key, 2), Ed25519PublicKeySigner(client_kp_c.public_key, 4), Ed25519PublicKeySigner(Keypair.random().public_key, 255), ] med_threshold = 7 signers_found = verify_challenge_transaction_threshold( challenge_tx, server_kp.public_key, domain_name, network_passphrase, med_threshold, signers, ) assert signers_found == [ Ed25519PublicKeySigner(client_kp_a.public_key, 1), Ed25519PublicKeySigner(client_kp_b.public_key, 2), Ed25519PublicKeySigner(client_kp_c.public_key, 4), ]
assert client_domain_op.data_value == CLIENT_ATTRIBUTION_DOMAIN.encode() assert client_domain_op.source == CLIENT_ATTRIBUTION_ADDRESS signatures = envelope_object.signatures assert len(signatures) == 1 tx_hash = envelope_object.hash() server_public_key = Keypair.from_public_key(settings.SIGNING_KEY) server_public_key.verify(tx_hash, signatures[0].signature) auth_str = "Bearer {}" mock_request = Mock(META={}) account_exists = Mock( load_ed25519_public_key_signers=Mock( return_value=[Ed25519PublicKeySigner(CLIENT_ADDRESS)]), thresholds=Mock(med_threshold=0), ) @patch( "polaris.sep10.views.settings.HORIZON_SERVER.load_account", Mock(return_value=account_exists), ) def test_auth_post_success_account_exists(client): """`POST <auth>` succeeds when given a proper JSON-encoded transaction.""" response = client.get(f"{endpoint}?account={CLIENT_ADDRESS}", follow=True) content = json.loads(response.content) # Sign the XDR with the client. envelope_xdr = content["transaction"]