apac-ops-bot/backend/app/models/user.py
SamoilenkoVadym b284cadb86 Add test user authentication and RBAC admin panel
Implemented simple authentication for testing and admin panel for user management:

Backend:
- Add simple email/password login for test users (admin@test.local, user@test.local)
- Implement RBAC (Role-Based Access Control) with Permission enum
- Create admin endpoints for user management and system analytics
- Add bcrypt password hashing for test users
- Create script to generate test users in database

Frontend:
- Add SimpleLogin component for test authentication
- Create AdminPanel with user management and system analytics
- Add role-based navigation (Admin tab visible only for admins)
- Update AuthContext to support both MSAL and simple login
- Add API methods for admin operations

Features:
- Admins can view all users, manage roles, activate/deactivate accounts
- Admins can view system-wide analytics (users, conversations, tokens, costs)
- Regular users only see their own chats and usage
- Role badges in UI show user role (user/admin/superadmin)

Note: Simple authentication is for testing only. Production uses Azure AD MSAL.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 20:05:54 +00:00

46 lines
1.8 KiB
Python

"""
User model for storing user information from Azure AD
"""
from sqlalchemy import Column, String, Boolean, DateTime, JSON
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
import uuid
from app.database import Base
class User(Base):
"""
User model representing application users authenticated via Azure AD
"""
__tablename__ = "users"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, index=True)
azure_ad_id = Column(String(255), unique=True, nullable=False, index=True)
email = Column(String(255), unique=True, nullable=False, index=True)
display_name = Column(String(255))
given_name = Column(String(100))
surname = Column(String(100))
role = Column(String(50), default="user", nullable=False) # user, admin, superadmin
is_active = Column(Boolean, default=True, nullable=False)
# Timestamps
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
last_login_at = Column(DateTime(timezone=True))
# JSON fields for flexible data storage
preferences = Column(JSON, default=dict, nullable=False) # UI preferences
meta_data = Column(JSON, default=dict, nullable=False) # Additional metadata
# Relationships
conversations = relationship("Conversation", back_populates="user", cascade="all, delete-orphan")
sessions = relationship("Session", back_populates="user", cascade="all, delete-orphan")
token_usage = relationship("TokenUsage", back_populates="user")
memories = relationship("UserMemory", back_populates="user", cascade="all, delete-orphan")
def __repr__(self):
return f"<User {self.email}>"