Skip to content

Commit

Permalink
🧪 Test keyfile controller
Browse files Browse the repository at this point in the history
  • Loading branch information
coccoinomane committed May 18, 2023
1 parent c5feae3 commit 3103cc6
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 6 deletions.
5 changes: 3 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

### Top priority

- Test keyfile controller
- Test signer from keyfile
- Test get_signer() switch function
- Refactor code to use get_signer() switch function
- Do we really need both app.chain_name and app.chain?
- Define function that parses chain and signer args, creates objects, extends app object. Call this function in each command, rather than in args.py, and make it replace all the calls to chain_ready_or_raise and signer_ready_or_rise

### Commands
Expand Down
15 changes: 12 additions & 3 deletions src/web3cli/controllers/keyfile_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,20 @@ def decode(self) -> None:
@ex(
help="Create a new keyfile from a private key",
arguments=[
(["path"], {"help": "path of output keyfile"}),
(
["path"],
{
"help": "path of output keyfile; omit to print to screen",
"nargs": "?",
},
),
],
aliases=["encode", "encrypt"],
)
def create(self) -> None:
keyfile_dict = encrypt_to_keyfile()
json.dump(keyfile_dict, open(self.app.pargs.path, "w"))
self.app.log.info(f"Keyfile saved to {self.app.pargs.path}")
if self.app.pargs.path:
json.dump(keyfile_dict, open(self.app.pargs.path, "w"))
self.app.log.info(f"Keyfile saved to {self.app.pargs.path}")
else:
self.app.print(json.dumps(keyfile_dict))
2 changes: 1 addition & 1 deletion src/web3cli/helpers/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def decrypt_keyfile_dict(keyfile_dict: dict[str, Any]) -> str:
private_key = Account.decrypt(keyfile_dict, password)
except ValueError as e:
raise Web3CliError(f"Could not decrypt keyfile: {e}")
return private_key.hex()
return private_key.hex().replace("0x", "")


def encrypt_to_keyfile(kdf: str = None, iterations: int = None) -> dict[str, Any]:
Expand Down
43 changes: 43 additions & 0 deletions tests/web3cli/controllers/test_keyfile_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import json
from pathlib import Path
from typing import Any, Dict, List

import pytest

from tests.web3cli.main import Web3CliTest
from web3cli.helpers.crypto import decrypt_keyfile_dict


def test_keyfile_create(
signers: List[Dict[str, Any]], monkeypatch: pytest.MonkeyPatch
) -> None:
for s in signers:
with Web3CliTest() as app:
# Create a keyfile JSON string from test signer private key
responses = iter([s["private_key"], s["keyfile_password"]])
monkeypatch.setattr("getpass.getpass", lambda _: next(responses))
app.set_args(["keyfile", "create"]).run()
data, output = app.last_rendered
# Decrypt the keyfile to get again the private key
keyfile_dict = json.loads(data["out"])
monkeypatch.setattr("getpass.getpass", lambda _: s["keyfile_password"])
decoded_private_key = decrypt_keyfile_dict(keyfile_dict)
# Test that the private key is the same
assert decoded_private_key == s["private_key"]


def test_keyfile_decode(
signers: List[Dict[str, Any]], monkeypatch: pytest.MonkeyPatch, tmp_path: Path
) -> None:
for s in signers:
# Create a keyfile from test signer
f = tmp_path / f"keyfile_{s['name']}.json"
f.write_text(s["keyfile"])
keyfile = str(f)
# Decode the keyfile
with Web3CliTest() as app:
responses = iter([s["keyfile_password"]])
monkeypatch.setattr("getpass.getpass", lambda _: next(responses))
app.set_args(["keyfile", "decrypt", keyfile]).run()
data, output = app.last_rendered
assert data["out"] == s["private_key"]
6 changes: 6 additions & 0 deletions tests/web3core/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,22 @@ def signers() -> List[Dict[str, Any]]:
"name": "vanity_1",
"address": "0x0c2010dc4736bab060740D3968cf1dDF86196D81",
"private_key": "d94e4166f0b3c85ffebed3e0eaa7f7680ae296cf8a7229d637472b7452c8602c",
"keyfile": '{"address": "0c2010dc4736bab060740d3968cf1ddf86196d81", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "44bb6afb52fa1eb4e273f2dc972aa9c9"}, "ciphertext": "ca4bd4f91bfc51a34e5fd72340cfe058ae77108c51fdad8413c1a7c1eb54ea5c", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "34eb69126e4c28c3b96ff2bbafc30fd6"}, "mac": "e30f84c256b85ad757527a9963da856a3dc0c8ff7691eaa30dce8a6025db0044"}, "id": "5dcac562-ed62-42be-85af-458082ae5621", "version": 3}',
"keyfile_password": "secret_1",
},
{
"name": "vanity_2",
"address": "0x206D4d644c22dDFc343b3AD23bBc7A42c8B201fc",
"private_key": "3bc2f9b05ac28389fd65fd40068a10f730ec66b6293f9cfd8fe804d212ce06bb",
"keyfile": '{"address": "206d4d644c22ddfc343b3ad23bbc7a42c8b201fc", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "8eb93057b97baef092028a49d729fadb"}, "ciphertext": "5bcb8cc45abc29098e6157953218f90ce992c410fefa5cd6ccba5f90301abbfc", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "9a9bae4fbef319b359dbc1a19757898c"}, "mac": "a890fbe5e0472cecff264b50ed7be3d56c22082a45e836712604a117ccc2ea24"}, "id": "c77dd2d2-d657-4d4a-ab7c-b491c4be0eb9", "version": 3}',
"keyfile_password": "secret_2",
},
{
"name": "vanity_3",
"address": "0x9fF0c40eDe4585a5E9f0F00009ce79b6344cB663",
"private_key": "f76c67c2dd62222a5ec747116a66c573f3795c53276c0cdeafbcb5f597e2f8d4",
"keyfile": '{"address": "9ff0c40ede4585a5e9f0f00009ce79b6344cb663", "crypto": {"cipher": "aes-128-ctr", "cipherparams": {"iv": "efddd96d2ce2f840af8b58d681d1330c"}, "ciphertext": "95d4fc9dde914a8cdb679fda7b0ead7312fcc3053bfeb82bd5f6ffa5db22da4b", "kdf": "scrypt", "kdfparams": {"dklen": 32, "n": 262144, "r": 1, "p": 8, "salt": "1dc311b9bd5c76ed686ef39003716294"}, "mac": "63cdddd9e8f3987dff63a88ef838cc24ecfeb7b568916f581deb061844850f5e"}, "id": "c78bb6ff-fb12-474a-bf84-5a6d6e8e8bcc", "version": 3}',
"keyfile_password": "secret_3",
},
]

Expand Down

0 comments on commit 3103cc6

Please sign in to comment.