Dataherald / dataherald

Interact with your SQL database, Natural Language to SQL using LLMs
https://dataherald.readthedocs.io/en/latest/
Apache License 2.0
3.33k stars 234 forks source link

Use sub in auth service to authenticate the user. #491

Closed rwatts3 closed 4 months ago

rwatts3 commented 4 months ago

Pull Request Description

Overview

This pull request introduces several enhancements and refactors to the user service and authorization modules. The primary focus is on adding support for user authentication via sub (subject) in addition to the existing email-based authentication. This change fixes a bug in the previous logic where the auth service assumed auth0_issuer + "email" was a valid key in the payload dictionary. This key was not present in the mongo database nor the payload upon debugging and inspection. However the sub key was present in both Auth0 documentation, the payload as well as the mongo database and appears to be a more future safe key to leverage.

Changes Made

  1. Repository Layer Modifications:

    • Updated the get_user method in repository.py to include a new function get_user_by_sub. This function retrieves a user based on the sub field from the payload.
      def get_user_by_sub(self, sub: str) -> User:
       user = MongoDB.find_one(USER_COL, {"sub": sub})
       return User(id=str(user["_id"])) if user else None
  2. Service Layer Modifications:

    • Added a new method get_user_by_sub in service.py to utilize the repository function for fetching user data based on sub.
      def get_user_by_sub(self, sub: str) -> UserResponse:
       """Helper function to get user by Auth0 sub."""
       user = self.repo.get_user_by_sub(sub)
       return user if user else None
  3. Authorization Layer Modifications:

    • Updated the Authorize class in auth.py to support user fetching by sub. The decode payload method now extracts sub from the payload and retrieves the user based on sub instead of email.
      class Authorize:
       def user(self, payload: dict) -> User:
           sub = payload['sub']
           user = user_service.get_user_by_sub(sub)
           if not user:
               raise UnauthorizedUserError(email=sub)
           return user
  4. Existing Functionality:

    • Maintained existing email-based user retrieval to ensure backward compatibility.

Summary

These changes enhance the user service by adding flexibility in user authentication mechanisms, allowing the use of sub for user identification. This improvement is part of ongoing efforts to align with modern security practices and support diverse authentication strategies.

Please review these changes and provide feedback or approval as necessary.