Introduce the `EventManager` model to manage event roles and permissions. Roles include `OWNER`, `ADMIN`, `MODERATOR`, and `VIEWER`, each with specific default permissions. The model supports explicit permissions, relationships, constraints, and a helper method for initializing event owners.
110 lines
3.6 KiB
Python
110 lines
3.6 KiB
Python
from datetime import datetime, timezone
|
|
from enum import Enum
|
|
|
|
from sqlalchemy import Column, Boolean, ForeignKey, UniqueConstraint, Enum as SQLEnum, DateTime
|
|
from sqlalchemy.dialects.postgresql import UUID
|
|
from sqlalchemy.orm import relationship
|
|
|
|
from .base import Base, TimestampMixin, UUIDMixin
|
|
|
|
|
|
class EventManagerRole(str, Enum):
|
|
OWNER = "owner"
|
|
ADMIN = "admin"
|
|
MODERATOR = "moderator"
|
|
VIEWER = "viewer"
|
|
|
|
|
|
class EventManager(Base, UUIDMixin, TimestampMixin):
|
|
__tablename__ = 'event_managers'
|
|
|
|
# Foreign Keys
|
|
user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False)
|
|
event_id = Column(UUID(as_uuid=True), ForeignKey('events.id'), nullable=False)
|
|
assigned_by = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False)
|
|
|
|
# Role using Enum
|
|
role = Column(SQLEnum(EventManagerRole), nullable=False)
|
|
|
|
# Explicit permissions
|
|
can_edit = Column(Boolean, default=False, nullable=False)
|
|
can_invite = Column(Boolean, default=False, nullable=False)
|
|
can_manage_gifts = Column(Boolean, default=False, nullable=False)
|
|
can_send_updates = Column(Boolean, default=False, nullable=False)
|
|
can_view_analytics = Column(Boolean, default=False, nullable=False)
|
|
|
|
assigned_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False)
|
|
|
|
# Relationships
|
|
user = relationship("User", back_populates="managed_events", foreign_keys=[user_id])
|
|
event = relationship("Event", back_populates="managers")
|
|
assigner = relationship("User", foreign_keys=[assigned_by])
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint('user_id', 'event_id', name='uq_user_event_manager'),
|
|
)
|
|
|
|
def __repr__(self):
|
|
return f"<EventManager user_id={self.user_id} event_id={self.event_id} role={self.role.value}>"
|
|
|
|
@property
|
|
def permissions(self):
|
|
"""Get permissions based on role"""
|
|
return ROLE_PERMISSIONS[self.role]
|
|
|
|
def has_permission(self, permission: str) -> bool:
|
|
"""Check if manager has specific permission"""
|
|
return getattr(self, permission, False) or self.permissions.get(permission, False)
|
|
|
|
|
|
# Define default permissions for each role
|
|
ROLE_PERMISSIONS = {
|
|
EventManagerRole.OWNER: {
|
|
'can_edit': True,
|
|
'can_invite': True,
|
|
'can_manage_gifts': True,
|
|
'can_send_updates': True,
|
|
'can_view_analytics': True,
|
|
'can_manage_managers': True, # Special permission for owners
|
|
},
|
|
EventManagerRole.ADMIN: {
|
|
'can_edit': True,
|
|
'can_invite': True,
|
|
'can_manage_gifts': True,
|
|
'can_send_updates': True,
|
|
'can_view_analytics': True,
|
|
'can_manage_managers': False,
|
|
},
|
|
EventManagerRole.MODERATOR: {
|
|
'can_edit': False,
|
|
'can_invite': True,
|
|
'can_manage_gifts': True,
|
|
'can_send_updates': True,
|
|
'can_view_analytics': True,
|
|
'can_manage_managers': False,
|
|
},
|
|
EventManagerRole.VIEWER: {
|
|
'can_edit': False,
|
|
'can_invite': False,
|
|
'can_manage_gifts': False,
|
|
'can_send_updates': False,
|
|
'can_view_analytics': True,
|
|
'can_manage_managers': False,
|
|
}
|
|
}
|
|
|
|
|
|
def init_event_owner(user_id: UUID, event_id: UUID) -> EventManager:
|
|
"""Helper function to create an owner manager for a new event"""
|
|
return EventManager(
|
|
user_id=user_id,
|
|
event_id=event_id,
|
|
assigned_by=user_id, # Owner is self-assigned
|
|
role=EventManagerRole.OWNER,
|
|
can_edit=True,
|
|
can_invite=True,
|
|
can_manage_gifts=True,
|
|
can_send_updates=True,
|
|
can_view_analytics=True
|
|
)
|