Skip to content

Commit

Permalink
Update PermissionsConfig to dump to int for JSON serialization
Browse files Browse the repository at this point in the history
Accept `access_token` in `MQRequest` model as an alternate auth method
  • Loading branch information
NeonDaniel committed Oct 30, 2024
1 parent 64f08af commit 6c1a73f
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
4 changes: 4 additions & 0 deletions neon_users_service/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ class PermissionsConfig(BaseModel):
hub: AccessRoles = AccessRoles.NONE
llm: AccessRoles = AccessRoles.NONE

class Config:
use_enum_values = True


class TokenConfig(BaseModel):
username: str
Expand Down Expand Up @@ -143,4 +146,5 @@ class MQRequest(BaseModel):
operation: Literal["create", "read", "update", "delete"]
username: str
password: Optional[str] = None
access_token: Optional[str] = None
user: Optional[User] = None
7 changes: 4 additions & 3 deletions neon_users_service/mq_connector.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Optional

import pika.channel
from ovos_utils import LOG, wait_for_exit_signal
from ovos_utils import LOG
from ovos_config.config import Configuration
from neon_mq_connector.connector import MQConnector
from neon_mq_connector.utils.network_utils import b64_to_dict, dict_to_b64
Expand Down Expand Up @@ -39,9 +39,10 @@ def parse_mq_request(self, mq_req: dict) -> dict:
mq_req.user.password_hash = mq_req.password
user = self.service.create_user(mq_req.user)
elif mq_req.operation == "read":
if mq_req.password:
if mq_req.password or mq_req.access_token:
user = self.service.read_authenticated_user(mq_req.username,
mq_req.password)
mq_req.password,
mq_req.access_token)
else:
user = self.service.read_unauthenticated_user(
mq_req.username)
Expand Down
34 changes: 25 additions & 9 deletions neon_users_service/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ def create_user(self, user: User) -> User:
user.password_hash = self._ensure_hashed(user.password_hash)
return self.database.create_user(user)

def _read_user(self, user_spec: str, password: Optional[str] = None,
auth_token: Optional[str] = None) -> User:
user = self.database.read_user(user_spec)
if password and self._ensure_hashed(password) == user.password_hash:
return user
elif auth_token and any((tok.access_token == auth_token
for tok in user.tokens)):
return user
else:
user.password_hash = None
user.tokens = []
return user

def read_unauthenticated_user(self, user_spec: str) -> User:
"""
Helper to get a user from the database with sensitive data removed.
Expand All @@ -62,24 +75,27 @@ def read_unauthenticated_user(self, user_spec: str) -> User:
@param user_spec: username or user_id to retrieve
@returns: Redacted User object with sensitive information removed
"""
user = self.database.read_user(user_spec)
user.password_hash = None
user.tokens = []
return user
return self._read_user(user_spec)

def read_authenticated_user(self, username: str, password: str) -> User:
def read_authenticated_user(self, username: str,
password: Optional[str] = None,
auth_token: Optional[str] = None) -> User:
"""
Helper to get a user from the database, only if the requested username
and password match a database entry.
@param username: The username or user ID to retrieve
@param password: The hashed or plaintext password for the username
@param auth_token: A valid authentication token for the username
@returns: User object from the database if authentication was successful
"""
# This will raise a `UserNotFound` exception if the user doesn't exist
user = self.database.read_user(username)

hashed_password = self._ensure_hashed(password)
if hashed_password != user.password_hash:
if password:
user = self._read_user(username, password)
elif auth_token:
user = self._read_user(username, auth_token=auth_token)
else:
raise AuthenticationError("No password or token provided")
if user.password_hash is None:
raise AuthenticationError(f"Invalid password for {username}")
return user

Expand Down

0 comments on commit 6c1a73f

Please sign in to comment.