Newer
Older
cortex-hub / ai-hub / app / core / services / user.py
from typing import Optional, Union
import uuid
from datetime import datetime
from sqlalchemy.orm import Session
from sqlalchemy.exc import SQLAlchemyError

# Assuming the models are in a file named `models.py` in the `app.db` directory
from app.db import models

class UserService:
    def __init__(self):
        pass

    def save_user(self, db: Session, oidc_id: str, email: str, username: str) -> str:
        """
        Saves or updates a user record based on their OIDC ID.
        If a user with this OIDC ID exists, it returns their existing ID.
        Otherwise, it creates a new user record.
        Returns the user's ID.
        """
        try:
            # Check if a user with this OIDC ID already exists
            existing_user = db.query(models.User).filter(models.User.oidc_id == oidc_id).first()

            if existing_user:
                # Update the user's information if needed
                existing_user.email = email
                existing_user.username = username
                db.commit()
                return existing_user.id
            else:
                # Create a new user record
                new_user = models.User(
                    id=str(uuid.uuid4()),  # Generate a unique ID for the user
                    oidc_id=oidc_id,
                    email=email,
                    username=username,
                    created_at=datetime.utcnow()
                )
                db.add(new_user)
                db.commit()
                db.refresh(new_user)
                return new_user.id
        except SQLAlchemyError as e:
            db.rollback()
            raise
        
    def get_user_by_id(self, db: Session, user_id: str) -> Optional[models.User]:
        """
        Retrieves a user record by their unique ID.
        Returns the User object if found, otherwise None.
        """
        try:
            # Query the database for a user with the given ID
            user = db.query(models.User).filter(models.User.id == user_id).first()
            return user
        except SQLAlchemyError as e:
            # Log the error and return None in case of a database issue.
            print(f"Database error while fetching user by ID: {e}")
            return None

# --- Framework-dependent helper functions ---
# These functions are placeholders and would need to be integrated with your
# specific web framework (e.g., FastAPI, Flask, Django).

def login_required(f):
    """
    A decorator to protect API endpoints and web pages.
    It ensures a user is logged in and is a registered (non-anonymous) user.
    If not, it redirects them to the login page.
    This is a generic implementation. You would replace the logic inside
    with code specific to your web framework's authentication system.
    """
    async def wrapper(*args, **kwargs):
        # Placeholder logic: Check for user in the request context
        # For example, in FastAPI, you might use Depends(get_current_user)
        # In Flask, you might use session or current_user
        user_id = kwargs.get("user_id")  # Assuming user_id is passed in via a dependency
        if not user_id:
            # Depending on the framework, this would return an Unauthorized error or a redirect
            # For example: raise HTTPException(status_code=401, detail="Unauthorized")
            pass
        return await f(*args, **kwargs)
    return wrapper


def get_current_user_id() -> Optional[str]:
    """
    A helper function to get the current user's ID from the session.
    This is a placeholder and needs to be implemented with your framework's
    session/authentication management system.
    """
    # Placeholder logic
    # Example for FastAPI:
    # from fastapi import Depends, Request
    # from app.auth import get_current_user
    #
    # return get_current_user(request).id

    # For now, we return None as a generic placeholder
    return None