lizerk b0e88e8e8b refactor(backend): migrate calendar_app to scheduling app
- Rename calendar_app → scheduling (integration app for django-scheduler)
- Move schedule_patch.py → scheduling/patch.py with improved logging
- Create scheduling.notifications system for django-scheduler events
- Add scheduling.rules for django-rules integration
- Remove unused calendar_app models and API (not registered in urls)
- Remove backend/api/v1/calendar/ (dead code)
- Remove old tests for calendar_app
- Add comprehensive documentation in scheduling/README.md
- Update settings.py: calendar_app.apps.CalendarAppConfig → scheduling.apps.SchedulingConfig
- Clean api/apps.py: remove schedule_patch import (now in scheduling.apps)

The scheduling app provides:
- Patches for django-scheduler bugs (byweekday fix)
- Notification system for calendar events
- Access rules via django-rules
- Auto-applies on Django startup

Closes integration of django-scheduler for EUSRR calendar system.
2026-03-10 15:21:28 +03:00

115 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
django-rules: декларативные правила доступа для django-scheduler
Правила используются для проверки permissions на уровне объектов.
Интегрируется с CalendarRelation для управления доступом к календарям и событиям.
https://github.com/dfunckt/django-rules
"""
import rules
from django.contrib.contenttypes.models import ContentType
# -----------------------------------------------------------------------------
# ПРЕДИКАТЫ (predicates)
# -----------------------------------------------------------------------------
@rules.predicate
def is_superuser(user):
"""Суперпользователь имеет все права"""
return user.is_superuser
@rules.predicate
def can_view_calendar(user, calendar):
"""Проверяет доступ пользователя к календарю через CalendarRelation"""
if calendar is None:
return False
if user.is_superuser:
return True
try:
from schedule.models import CalendarRelation
user_ct = ContentType.objects.get_for_model(user)
return CalendarRelation.objects.filter(
calendar=calendar,
content_type=user_ct,
object_id=user.id
).exists()
except Exception:
return False
@rules.predicate
def can_edit_calendar(user, calendar):
"""Проверяет право на редактирование календаря"""
if calendar is None:
return False
if user.is_superuser:
return True
try:
from schedule.models import CalendarRelation
user_ct = ContentType.objects.get_for_model(user)
# Проверяем что пользователь имеет отношение с правом редактирования
relation = CalendarRelation.objects.filter(
calendar=calendar,
content_type=user_ct,
object_id=user.id,
distinction='owner' # или используйте ваше значение для владельца
).first()
return relation is not None
except Exception:
return False
@rules.predicate
def can_view_event(user, event):
"""Проверяет доступ пользователя к событию через календарь"""
if event is None:
return False
if user.is_superuser:
return True
# Проверяем доступ через календарь
return can_view_calendar(user, event.calendar)
@rules.predicate
def can_edit_event(user, event):
"""Проверяет право на редактирование события"""
if event is None:
return False
if user.is_superuser:
return True
# Проверяем доступ через календарь
return can_edit_calendar(user, event.calendar)
# -----------------------------------------------------------------------------
# ПРАВИЛА (rules) - регистрация в django-rules
# -----------------------------------------------------------------------------
# Календари
rules.add_rule('can_view_calendar', is_superuser | can_view_calendar)
rules.add_rule('can_edit_calendar', is_superuser | can_edit_calendar)
rules.add_rule('can_delete_calendar', is_superuser | can_edit_calendar)
# События
rules.add_rule('can_view_event', is_superuser | can_view_event)
rules.add_rule('can_edit_event', is_superuser | can_edit_event)
rules.add_rule('can_delete_event', is_superuser | can_edit_event)
# Для использования в DRF permissions или templates:
# {% if request.user|has_rule:'can_edit_calendar' calendar %}
# <button>Edit Calendar</button>
# {% endif %}