63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
"""User model with role-based access control."""
|
|
|
|
from datetime import datetime
|
|
from enum import Enum as PyEnum
|
|
from sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, Enum
|
|
from sqlalchemy.orm import relationship
|
|
from ..database import Base
|
|
|
|
|
|
class UserRole(str, PyEnum):
|
|
"""User roles for access control."""
|
|
SUPER_ADMIN = "super_admin" # Can manage all tenants
|
|
ADMIN = "admin" # Can manage own tenant
|
|
TECHNICIAN = "technician" # Can connect to assigned gateways
|
|
VIEWER = "viewer" # Read-only access
|
|
|
|
|
|
class User(Base):
|
|
"""User model with multi-tenant support."""
|
|
|
|
__tablename__ = "users"
|
|
|
|
id = Column(Integer, primary_key=True, index=True)
|
|
tenant_id = Column(Integer, ForeignKey("tenants.id"), nullable=True) # NULL for super_admin
|
|
username = Column(String(255), nullable=False, unique=True, index=True)
|
|
password_hash = Column(String(255), nullable=False)
|
|
email = Column(String(255), nullable=False, unique=True)
|
|
full_name = Column(String(255), nullable=True)
|
|
role = Column(Enum(UserRole), default=UserRole.TECHNICIAN, nullable=False)
|
|
is_active = Column(Boolean, default=True, nullable=False)
|
|
last_login = Column(DateTime, nullable=True)
|
|
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
|
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
# Relationships
|
|
tenant = relationship("Tenant", back_populates="users")
|
|
gateway_access = relationship(
|
|
"UserGatewayAccess",
|
|
back_populates="user",
|
|
cascade="all, delete-orphan",
|
|
primaryjoin="User.id == UserGatewayAccess.user_id"
|
|
)
|
|
endpoint_access = relationship(
|
|
"UserEndpointAccess",
|
|
back_populates="user",
|
|
cascade="all, delete-orphan",
|
|
primaryjoin="User.id == UserEndpointAccess.user_id"
|
|
)
|
|
connection_logs = relationship("ConnectionLog", back_populates="user")
|
|
|
|
def __repr__(self):
|
|
return f"<User(id={self.id}, username='{self.username}', role='{self.role}')>"
|
|
|
|
@property
|
|
def is_super_admin(self) -> bool:
|
|
"""Check if user is super admin."""
|
|
return self.role == UserRole.SUPER_ADMIN
|
|
|
|
@property
|
|
def is_admin(self) -> bool:
|
|
"""Check if user has admin privileges."""
|
|
return self.role in (UserRole.SUPER_ADMIN, UserRole.ADMIN)
|