Coverage for admin/misc.py: 60%

68 statements  

« 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. 

22 

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 

30 

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.") 

35 

36SIGNER_WAIT_TIME = 3 # seconds 

37 

38 

39class AdminError(RuntimeError): 

40 pass 

41 

42 

43def info(s, nl=True): 

44 newline = "\n" if nl else "" 

45 sys.stdout.write(f"{s}{newline}") 

46 sys.stdout.flush() 

47 

48 

49def head(ss, fill="*", nl=True): 

50 if type(ss) == str: 

51 ss = [ss] 

52 

53 maxl = max(map(len, ss)) 

54 info(fill*maxl) 

55 for s in ss: 

56 info(s) 

57 info(fill*maxl, nl=nl) 

58 

59 

60def bls(b): 

61 return "Yes" if b else "No" 

62 

63 

64def not_implemented(options): 

65 info(f"Operation {options.operation} not yet implemented") 

66 return 1 

67 

68 

69def get_hsm(debug): 

70 info("Connecting to HSM... ", False) 

71 hsm = HSM2Dongle(debug) 

72 hsm.connect() 

73 info("OK") 

74 return hsm 

75 

76 

77def get_admin_hsm(debug): 

78 info("Connecting to HSM... ", False) 

79 hsm = DongleAdmin(debug) 

80 hsm.connect() 

81 info("OK") 

82 return hsm 

83 

84 

85def dispose_hsm(hsm): 

86 if hsm is None: 

87 return 

88 

89 info("Disconnecting from HSM... ", False) 

90 hsm.disconnect() 

91 info("OK") 

92 

93 

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 

100 

101 

102def dispose_eth_dongle(eth): 

103 if eth is None: 

104 return 

105 

106 info("Disconnecting from Ethereum App... ", False) 

107 eth.disconnect() 

108 info("OK") 

109 

110 

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 

118 

119 

120def wait_for_reconnection(): 

121 time.sleep(SIGNER_WAIT_TIME)