Skip to content

Commit 68244b2

Browse files
authored
fix: deprecation warning, update poorman handshake (#42)
* fix: deprecation warning, update poorman handshake * typing + change file extension for accuracy * fix reqs
1 parent 87274f2 commit 68244b2

File tree

2 files changed

+112
-38
lines changed

2 files changed

+112
-38
lines changed

hivemind_bus_client/identity.py

Lines changed: 111 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,176 @@
11
from os.path import basename, dirname
2-
from poorman_handshake.asymmetric.utils import export_private_key, create_private_key
3-
2+
from poorman_handshake.asymmetric.utils import export_RSA_key, create_RSA_key
43
from json_database import JsonConfigXDG
4+
from typing import Optional
55

66

77
class NodeIdentity:
8+
"""
9+
A class representing a node's identity within a HiveMind network.
10+
11+
Attributes:
12+
IDENTITY_FILE (JsonConfigXDG): A configuration file containing the node's identity information.
13+
"""
814

9-
def __init__(self, identity_file=None):
15+
def __init__(self, identity_file: Optional[str] = None):
16+
"""
17+
Initialize the NodeIdentity instance with an optional identity file.
18+
19+
Args:
20+
identity_file (Optional[str]): Path to a custom identity file (default: None, uses default configuration).
21+
"""
1022
self.IDENTITY_FILE = identity_file or JsonConfigXDG("_identity", subfolder="hivemind")
1123

1224
@property
13-
def name(self):
14-
"""human readable label, not guaranteed unique
15-
can describe functionality, brand, capabilities or something else...
25+
def name(self) -> str:
26+
"""
27+
Get or set the human-readable label for the node.
28+
29+
The name is not guaranteed to be unique and can describe functionality, brand, capabilities, or other attributes.
30+
31+
Returns:
32+
str: The name of the node, defaulting to "unnamed-node" if not set.
1633
"""
1734
if not self.IDENTITY_FILE.get("name") and self.IDENTITY_FILE.get("key"):
1835
self.IDENTITY_FILE["name"] = basename(self.IDENTITY_FILE["key"])
1936
return self.IDENTITY_FILE.get("name") or "unnamed-node"
2037

2138
@name.setter
22-
def name(self, val):
39+
def name(self, val: str):
40+
"""Set the name of the node."""
2341
self.IDENTITY_FILE["name"] = val
2442

2543
@property
26-
def public_key(self):
27-
"""ASCI public PGP key"""
44+
def public_key(self) -> Optional[str]:
45+
"""
46+
Get or set the public RSA key for the node.
47+
48+
Returns:
49+
Optional[str]: The public RSA key, if available.
50+
"""
2851
return self.IDENTITY_FILE.get("public_key")
2952

3053
@public_key.setter
31-
def public_key(self, val):
54+
def public_key(self, val: str):
55+
"""Set the public RSA key for the node."""
3256
self.IDENTITY_FILE["public_key"] = val
3357

3458
@property
35-
def private_key(self):
36-
"""path to PRIVATE .asc PGP key, this cryptographic key
37-
uniquely identifies this device across the hive and proves it's identity"""
59+
def private_key(self) -> str:
60+
"""
61+
Get or set the path to the private RSA PEM file for the node.
62+
63+
The private key is used to uniquely identify the device and prove its identity within the HiveMind network.
64+
65+
Returns:
66+
str: The path to the private key file.
67+
"""
3868
return self.IDENTITY_FILE.get("secret_key") or \
39-
f"{dirname(self.IDENTITY_FILE.path)}/{self.name}.asc"
69+
f"{dirname(self.IDENTITY_FILE.path)}/{self.name}.pem"
4070

4171
@private_key.setter
42-
def private_key(self, val):
72+
def private_key(self, val: str):
73+
"""Set the path to the private RSA PEM file for the node."""
4374
self.IDENTITY_FILE["secret_key"] = val
4475

4576
@property
46-
def password(self):
47-
"""password is used to generate a session aes key on handshake.
48-
It should be used instead of users manually setting an encryption key.
49-
This password can be thought as identifying a sub-hive where all devices
50-
can connect to each other (access keys still need to be valid)"""
77+
def password(self) -> Optional[str]:
78+
"""
79+
Get or set the password for the node.
80+
81+
The password is used to generate a session AES key during the non-RSA handshake process.
82+
83+
Returns:
84+
Optional[str]: The password used for session encryption.
85+
"""
5186
return self.IDENTITY_FILE.get("password")
5287

5388
@password.setter
54-
def password(self, val):
89+
def password(self, val: str):
90+
"""Set the password for the node."""
5591
self.IDENTITY_FILE["password"] = val
5692

5793
@property
58-
def access_key(self):
94+
def access_key(self) -> Optional[str]:
95+
"""
96+
Get or set the access key for the node.
97+
98+
Returns:
99+
Optional[str]: The access key for the node.
100+
"""
59101
return self.IDENTITY_FILE.get("access_key")
60102

61103
@access_key.setter
62-
def access_key(self, val):
104+
def access_key(self, val: str):
105+
"""Set the access key for the node."""
63106
self.IDENTITY_FILE["access_key"] = val
64107

65108
@property
66-
def site_id(self):
109+
def site_id(self) -> Optional[str]:
110+
"""
111+
Get or set the site ID for the node.
112+
113+
Returns:
114+
Optional[str]: The site ID for the node.
115+
"""
67116
return self.IDENTITY_FILE.get("site_id")
68117

69118
@site_id.setter
70-
def site_id(self, val):
119+
def site_id(self, val: str):
120+
"""Set the site ID for the node."""
71121
self.IDENTITY_FILE["site_id"] = val
72122

73123
@property
74-
def default_master(self):
124+
def default_master(self) -> Optional[str]:
125+
"""
126+
Get or set the host for default master of the node.
127+
128+
Returns:
129+
Optional[str]: The default master for the node.
130+
"""
75131
return self.IDENTITY_FILE.get("default_master")
76132

77133
@default_master.setter
78-
def default_master(self, val):
134+
def default_master(self, val: str):
135+
"""Set the host for the default master of the node."""
79136
self.IDENTITY_FILE["default_master"] = val
80137

81138
@property
82-
def default_port(self):
139+
def default_port(self) -> Optional[int]:
140+
"""
141+
Get or set the default port for the node.
142+
143+
Returns:
144+
Optional[int]: The default port for the node.
145+
"""
83146
return self.IDENTITY_FILE.get("default_port")
84147

85148
@default_port.setter
86-
def default_port(self, val):
149+
def default_port(self, val: int):
150+
"""Set the default port for the node."""
87151
self.IDENTITY_FILE["default_port"] = val
88152

89-
def save(self):
153+
def save(self) -> None:
154+
"""
155+
Save the current node identity to the identity file.
156+
"""
90157
self.IDENTITY_FILE.store()
91158

92-
def reload(self):
159+
def reload(self) -> None:
160+
"""
161+
Reload the node identity from the identity file.
162+
"""
93163
self.IDENTITY_FILE.reload()
94164

95-
def create_keys(self):
96-
key = create_private_key("HiveMindComs")
97-
priv = f"{dirname(self.IDENTITY_FILE.path)}/HiveMindComs.asc"
98-
export_private_key(priv, key)
99-
pub = str(key.pubkey)
165+
def create_keys(self) -> None:
166+
"""
167+
Generate a new RSA key pair (public and private) and store them in the identity file.
168+
169+
This method generates a new private key, stores it in a PEM file, and updates the node's public and private keys
170+
in the identity file.
171+
"""
172+
secret, pub = create_RSA_key()
173+
priv = f"{dirname(self.IDENTITY_FILE.path)}/HiveMindComs.pem"
174+
export_RSA_key(secret, priv)
100175
self.private_key = priv
101176
self.public_key = pub

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
poorman-handshake>=0.2.2a3
1+
poorman-handshake>=1.0.0,<2.0.0
22
ovos_bus_client>=0.0.6a19
33
ovos_utils>=0.0.38
44
bitstring>=4.1.1
5-
PGPy>=0.6.0
65
cryptography>=41.0.1
76
pycryptodomex>=3.18.0
87
pybase64

0 commit comments

Comments
 (0)