Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
refactor(server): remodel authentication flow
Browse files Browse the repository at this point in the history
  • Loading branch information
kodzonko committed Sep 20, 2023
1 parent 4b87313 commit df48825
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 114 deletions.
Binary file modified server/database.db
Binary file not shown.
27 changes: 27 additions & 0 deletions server/id_rsa
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEApWw5SiTFwinwot10q4Y0DOL9F+5G6xlMYBirdxYkku3Q55U0
1YS4bC0KtQcxX1a6wBB84IZMsaNMjRK7Bnvu9LFxukvc5DxRHJdfl62jP0hORDKd
S1erN3Y4ng3imGeBIndHo+gjyFah3vGWFKxS7KDrzPw3kjh3/YsA38Z/eee28Xlc
f8xrDwpALBhMxS4jf742/pTWAxLxApJb5IbjV3GEvIsF7rDf5TR3DfjE7uQ+qgxg
3uGrUl97TQey4ySLOZ6cGbHYQtgY1F8epTO3q9v841MS9fwFbXxzBcRm5gtmSvTQ
8PIgcDgjQcroXCQGCNEgry2OticN2fsYELWBcwIDAQABAoIBABnts7EeaxeQUVUw
ga1c9LhMX+qqANhazRuG4mFhHsx06uNRrMgG7I1Fe2x9OyI8IDt4mh+V4rGOl1zJ
Yc1AtxIIOiY+5oRTu/b6TGkkNfag/mY2yhbZdU8qgEdYhSWURlZrpywBd+ev7zat
sUjTleUxzU6s/dzfwwGtEa8BmFDisyr7+ANZN3ZCTjOH/OD3t+Lg8T/wWLOJKm+7
PD/da5GzEQ57OwOp1TGPw6FJUIY8GKQJOwd+70QKM7dQbiqBDxD+81KQ7gSrfk5a
SVqwuAoiXh3/2WV5MakboV3G3HPklcmvOHhoAO5XvZk93z6HNo6lvcqo+ZRWIfMa
b+9V3mkCgYEA4hlaho6sPBFhS856xtktVuEE3k3/x/jmd5jEXF6EAngixyyjYYMW
3J5lRWo/r/Hodf8M3/61Pe89jOOYoK6uNwtj+DyiW8l800DwviRdbxUVoJimGeAM
Zkli84M6RoJT2M0MyAXaVfBMBR9rTuOVGNXj9exxtrxYOj7L7uqNcLUCgYEAu0yo
Sx0uTVMpmF5btlyZbemXhmgfAvYEBPVlqVFzvpgd0VYDiJG6Ck2KBjEvnun6X+/g
HhgsMTxzib3nuEYb9U/lt4nZqqNnE6dvvyNr/hpTBLemKvyZ7Bcqn7K3D+5UEQUQ
EBrfM/MiKClQk5I7g0dN+9Lnu3/maWCcCF3YCocCgYEA14H5ElZ9fsfGKJ6H0m+B
UtUqccaA7helfQuE5tJEG6Js69H1bOWpbeIgfziVudvnikjv+bVrBby6u0bY3ReD
AP5/bEZHLxvvOeElVueMk2vScH/vmqw+xWRfx+ImMrzYtMZFz4YcpVtk6mEXRFuS
ati871RO0zHVGrduZKz24h0CgYEAo+bTJtgkWpo5vhJkY1LpGNvfM0kOSkMLBWPR
ULfsd48aGMQSV4JesQFllUGZkJDj/uwkzXENyxBBcvnyOrlvYd5HAbPp/H79hp9x
FGxk5noWx/wFt3xRHd6v+AwmUhSXEEXD5rP9OrK64zY0Qs8msRzGy2WmT9f+w5w9
Lr0gfyUCgYEAqpX3E4uOYyQAGR/Y9yxWTCXOX+UyP1aO0L9L9MverTv1mCJA1C2E
63hyuhrCKm0CMKSwjRNrjzRFRFBKfuvxE0MS9CfrMqCxaTermw07lLk0tHLAjN+6
AFC23Me7Mref5bJeojQmune4kCr3C8UGG0L19BHjk4yAo0C5wJAaMfE=
-----END RSA PRIVATE KEY-----
8 changes: 8 additions & 0 deletions server/id_rsa.pub
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEApWw5SiTFwinwot10q4Y0DOL9F+5G6xlMYBirdxYkku3Q55U01YS4
bC0KtQcxX1a6wBB84IZMsaNMjRK7Bnvu9LFxukvc5DxRHJdfl62jP0hORDKdS1er
N3Y4ng3imGeBIndHo+gjyFah3vGWFKxS7KDrzPw3kjh3/YsA38Z/eee28Xlcf8xr
DwpALBhMxS4jf742/pTWAxLxApJb5IbjV3GEvIsF7rDf5TR3DfjE7uQ+qgxg3uGr
Ul97TQey4ySLOZ6cGbHYQtgY1F8epTO3q9v841MS9fwFbXxzBcRm5gtmSvTQ8PIg
cDgjQcroXCQGCNEgry2OticN2fsYELWBcwIDAQAB
-----END RSA PUBLIC KEY-----
29 changes: 28 additions & 1 deletion server/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions server/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ python-dotenv = "^0.21.1"
loguru = "^0.6.0"
fastapi-socketio = "^0.0.10"
bidict = "^0.22.1"
rsa = "^4.9"

[tool.poetry.group.dev.dependencies]
mockito = "^1.4.0"
Expand Down
10 changes: 4 additions & 6 deletions server/src/sdex_server/connection/payload_sanitizers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ def validate_connect_payload(data: Any) -> bool:

def validate_register_init_payload(data: Any) -> bool:
"""Validate payload for request to authenticate/register from user."""
if not isinstance(data, dict):
return False
if "publicKey" not in data.keys():
if not isinstance(data, str):
return False
return True

Expand All @@ -23,11 +21,11 @@ def validate_register_follow_up_payload(data: Any) -> bool:
"""Validate the payload for user registration."""
if not isinstance(data, dict):
return False
if not data.get("publicKey", None):
if not data.get("login", None):
return False
if not data.get("privateKeyHash", None):
if not data.get("publicKey", None):
return False
if not data.get("salt", None):
if not data.get("signature", None):
return False
return True

Expand Down
6 changes: 3 additions & 3 deletions server/src/sdex_server/crypto/randomness.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import string


def generate_salt() -> str:
"""Generate a random salt for the client's private key."""
def generate_challenge() -> str:
"""Generate a random challenge for the client to authenticate."""
alphabet = string.ascii_letters + string.digits
return "".join(secrets.choice(alphabet) for i in range(512))
return "".join(secrets.choice(alphabet) for i in range(512)) # type: ignore
105 changes: 70 additions & 35 deletions server/src/sdex_server/database/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,58 @@ def __init__(self, db_path: Path | str) -> None:
except Exception as e:
raise DBConnectionError(e)

def get_user_by_login(self, login: str) -> User | None:
"""Get user data from the database by login."""
try:
cursor: sqlite3.Cursor = self.client.execute(
"""
SELECT
id, login, public_key
FROM
users
WHERE
login = :login;
""",
{"login": login},
)
output = cursor.fetchone()
if not output:
logger.info("User not found.")
return None
user = User(
id=output[0],
login=output[1],
public_key=output[2],
)
logger.info("User data fetched successfully.")
return user
except Exception as e:
raise DBConnectionError(e)

def get_user_by_public_key(self, public_key: str) -> User | None:
"""Get user data from the database by public key."""
try:
cursor: sqlite3.Cursor = self.client.execute(
"""
SELECT id, public_key, private_key_hash, salt
FROM users
WHERE public_key = :rsa_key;
SELECT
id, login, public_key
FROM
users
WHERE
public_key = :rsa_key;
""",
{"rsa_key": public_key},
)
output = cursor.fetchone()
if not output:
log_msg = "User not found."
logger.info(log_msg)
logger.info("User not found.")
return None
user = User(
id=output[0],
public_key=output[1],
private_key_hash=output[2],
salt=output[3],
login=output[1],
public_key=output[2],
)
log_msg = "User data fetched successfully."
logger.info(log_msg)
logger.info("User data fetched successfully.")
return user
except Exception as e:
raise DBConnectionError(e)
Expand All @@ -46,7 +74,14 @@ def check_public_key(self, public_key: str) -> bool:
"""Check if public key exists in the database."""
try:
cursor: sqlite3.Cursor = self.client.execute(
"SELECT * FROM users WHERE public_key = :key;",
"""
SELECT
*
FROM
users
WHERE
public_key = :key;
""",
{"key": public_key},
)
output = cursor.fetchone()
Expand All @@ -56,14 +91,17 @@ def check_public_key(self, public_key: str) -> bool:
except Exception as e:
raise DBConnectionError(e)

def update_user(self, previous_rsa: str, user_new_data: User) -> bool:
def update_user(self, previous_rsa: str, new_rsa: str) -> bool:
"""Update user public key in the database."""
try:
find_user_cursor: sqlite3.Cursor = self.client.execute(
"""
SELECT *
FROM users
WHERE public_key = :rsa;
SELECT
*
FROM
users
WHERE
public_key = :rsa;
""",
{"rsa": previous_rsa},
)
Expand All @@ -73,16 +111,15 @@ def update_user(self, previous_rsa: str, user_new_data: User) -> bool:
else:
self.client.execute(
"""
UPDATE users
SET public_key = :public_rsa,
private_key_hash = :private_rsa_hash,
salt = :salt
WHERE public_key = :previous_rsa;
UPDATE
users
SET
public_key = :new_rsa,
WHERE
public_key = :previous_rsa;
""",
{
"public_rsa": user_new_data.public_key,
"private_rsa_hash": user_new_data.private_key_hash,
"salt": user_new_data.salt,
"new_rsa": new_rsa,
"previous_rsa": previous_rsa,
},
)
Expand All @@ -96,29 +133,27 @@ def add_user(self, user: User) -> bool:
try:
self.client.execute(
"""
INSERT INTO users (public_key, private_key_hash, salt)
VALUES (:public_rsa, :private_rsa_hash, :salt);
INSERT INTO users (login, public_key)
VALUES (:login, :public_rsa);
""",
{
"public_rsa": user.public_key,
"private_rsa_hash": user.private_key_hash,
"salt": user.salt,
},
{"login": user.login, "public_rsa": user.public_key},
)
self.client.commit()
return self.client.total_changes > 0
except Exception as e:
raise DBConnectionError(e)

def remove_user(self, public_key: str) -> bool:
"""Add new user to the database."""
def remove_user(self, login: str) -> bool:
"""Remove user from the database."""
try:
self.client.execute(
"""
DELETE FROM users
WHERE public_key = :rsa;
DELETE FROM
users
WHERE
login = :login;
""",
{"rsa": public_key},
{"login": login},
)
self.client.commit()
return self.client.total_changes > 0
Expand Down
3 changes: 1 addition & 2 deletions server/src/sdex_server/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class User(BaseModel):
login: str
public_key: str
private_key_hash: str
salt: str
id: Optional[int] = None
Loading

0 comments on commit df48825

Please sign in to comment.