Coverage for admin/misc.py: 60%
68 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-04-05 20:41 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2024-04-05 20:41 +0000
1# The MIT License (MIT)
2#
3# Copyright (c) 2021 RSK Labs Ltd
4#
5# Permission is hereby granted, free of charge, to any person obtaining a copy of
6# this software and associated documentation files (the "Software"), to deal in
7# the Software without restriction, including without limitation the rights to
8# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9# of the Software, and to permit persons to whom the Software is furnished to do
10# so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included in all
13# copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21# SOFTWARE.
23import sys
24import time
25from getpass import getpass
26from ledger.hsm2dongle import HSM2Dongle
27from ledger.pin import BasePin
28from .dongle_admin import DongleAdmin
29from .dongle_eth import DongleEth
31PIN_ERROR_MESSAGE = ("Invalid pin given. It must be exactly 8 alphanumeric "
32 "characters with at least one alphabetic character.")
33PIN_ERROR_MESSAGE_ANYCHARS = (
34 "Invalid pin given. It must be composed only of alphanumeric characters.")
36SIGNER_WAIT_TIME = 3 # seconds
39class AdminError(RuntimeError):
40 pass
43def info(s, nl=True):
44 newline = "\n" if nl else ""
45 sys.stdout.write(f"{s}{newline}")
46 sys.stdout.flush()
49def head(ss, fill="*", nl=True):
50 if type(ss) == str:
51 ss = [ss]
53 maxl = max(map(len, ss))
54 info(fill*maxl)
55 for s in ss:
56 info(s)
57 info(fill*maxl, nl=nl)
60def bls(b):
61 return "Yes" if b else "No"
64def not_implemented(options):
65 info(f"Operation {options.operation} not yet implemented")
66 return 1
69def get_hsm(debug):
70 info("Connecting to HSM... ", False)
71 hsm = HSM2Dongle(debug)
72 hsm.connect()
73 info("OK")
74 return hsm
77def get_admin_hsm(debug):
78 info("Connecting to HSM... ", False)
79 hsm = DongleAdmin(debug)
80 hsm.connect()
81 info("OK")
82 return hsm
85def dispose_hsm(hsm):
86 if hsm is None:
87 return
89 info("Disconnecting from HSM... ", False)
90 hsm.disconnect()
91 info("OK")
94def get_eth_dongle(debug):
95 info("Connecting to Ethereum App... ", False)
96 eth = DongleEth(debug)
97 eth.connect()
98 info("OK")
99 return eth
102def dispose_eth_dongle(eth):
103 if eth is None:
104 return
106 info("Disconnecting from Ethereum App... ", False)
107 eth.disconnect()
108 info("OK")
111def ask_for_pin(any_pin):
112 pin = None
113 while pin is None or not BasePin.is_valid(pin, any_pin):
114 pin = getpass("> ").encode()
115 if not BasePin.is_valid(pin, any_pin):
116 info(PIN_ERROR_MESSAGE if not any_pin else PIN_ERROR_MESSAGE_ANYCHARS)
117 return pin
120def wait_for_reconnection():
121 time.sleep(SIGNER_WAIT_TIME)