from django.db import models from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ PERMISSION_CATEGORIES = { _("Identity & Profiles"): [ "is_searchable", "can_submit_verification", "can_view_full_profiles", "can_manage_institutions", ], _("Chat & Communications"): [ "can_send_direct_messages", "can_create_group_chats", "can_start_video_calls", "can_moderate_chat", "is_chat_muted", ], _("CMS & Articles"): [ "can_create_posts", "can_publish_posts_directly", "can_edit_own_posts", "can_delete_own_posts", "can_comment", ], _("LMS & Academics"): [ "can_enroll_courses", "can_create_courses", "can_publish_courses", "can_issue_certificates", "can_grade_submissions", "has_premium_lms_access", ], _("Meetings"): [ "can_request_meetings", "can_accept_meetings", ], _("Events"): [ "can_register_events", "can_create_events", "can_publish_events", "can_checkin_attendees", "can_export_attendee_list", ], _("Community Projects"): [ "can_volunteer", "can_create_projects", "can_manage_project_tasks", "can_approve_projects", ], _("Donations & Charity"): [ "can_make_donations", "can_create_donation_campaigns", "can_view_donation_reports", ], _("Support & Tickets"): [ "can_create_tickets", "can_reply_tickets", "can_manage_tickets", ], _("Dynamic Forms"): [ "can_submit_forms", "can_create_forms", "can_export_form_data", ], _("Diplomacy & Institutional"): [ "can_view_diplomatic_reports", "can_create_diplomatic_reports", ], _("Administration & Security"): [ "can_access_admin_panel", "can_manage_users", "can_ban_users", "can_view_analytics", ], } ALL_PERMISSION_FIELDS = [perm for perms in PERMISSION_CATEGORIES.values() for perm in perms] class Role(models.Model): name = models.CharField(max_length=100, unique=True, verbose_name=_("Role Name")) slug = models.SlugField(max_length=100, unique=True, blank=True, verbose_name=_("Slug / Identifier")) description = models.TextField(blank=True, verbose_name=_("Description")) is_default = models.BooleanField( default=False, verbose_name=_("Default Role for New Users"), help_text=_("Automatically assigned to new registrations if no other role is selected.") ) is_system = models.BooleanField( default=False, verbose_name=_("System Core Role"), help_text=_("Marks default system roles. Admins can configure permissions, but deletion is restricted.") ) # 1. Identity & Profiles is_searchable = models.BooleanField(default=True, verbose_name=_("Appear in User Searches / Directory")) can_submit_verification = models.BooleanField(default=True, verbose_name=_("Submit Verification Documents")) can_view_full_profiles = models.BooleanField(default=True, verbose_name=_("View Full Profiles")) can_manage_institutions = models.BooleanField(default=False, verbose_name=_("Manage Institutions")) # 2. Chat & Communications can_send_direct_messages = models.BooleanField(default=True, verbose_name=_("Send Direct Messages")) can_create_group_chats = models.BooleanField(default=True, verbose_name=_("Create Group Chats")) can_start_video_calls = models.BooleanField(default=False, verbose_name=_("Start Video Calls")) can_moderate_chat = models.BooleanField(default=False, verbose_name=_("Moderate Chat Rooms")) is_chat_muted = models.BooleanField(default=False, verbose_name=_("Chat Muted (Kill-switch)")) # 3. CMS & Articles can_create_posts = models.BooleanField(default=True, verbose_name=_("Create Posts")) can_publish_posts_directly = models.BooleanField(default=False, verbose_name=_("Publish Posts Directly (Bypass Moderation)")) can_edit_own_posts = models.BooleanField(default=True, verbose_name=_("Edit Own Posts")) can_delete_own_posts = models.BooleanField(default=True, verbose_name=_("Delete Own Posts")) can_comment = models.BooleanField(default=True, verbose_name=_("Comment on Posts")) # 4. LMS & Academics can_enroll_courses = models.BooleanField(default=True, verbose_name=_("Enroll in Courses")) can_create_courses = models.BooleanField(default=False, verbose_name=_("Create Courses")) can_publish_courses = models.BooleanField(default=False, verbose_name=_("Publish Courses Directly")) can_issue_certificates = models.BooleanField(default=False, verbose_name=_("Issue Certificates")) can_grade_submissions = models.BooleanField(default=False, verbose_name=_("Grade Submissions")) has_premium_lms_access = models.BooleanField(default=False, verbose_name=_("Premium LMS Access")) # 5. Meetings can_request_meetings = models.BooleanField(default=True, verbose_name=_("Send Meeting Requests")) can_accept_meetings = models.BooleanField(default=False, verbose_name=_("Accept / Host Meetings")) # 6. Events can_register_events = models.BooleanField(default=True, verbose_name=_("Register for Events")) can_create_events = models.BooleanField(default=False, verbose_name=_("Create Events")) can_publish_events = models.BooleanField(default=False, verbose_name=_("Publish Events Directly")) can_checkin_attendees = models.BooleanField(default=False, verbose_name=_("Check-in Attendees (Scan Tickets)")) can_export_attendee_list = models.BooleanField(default=False, verbose_name=_("Export Attendee List")) # 7. Community Projects can_volunteer = models.BooleanField(default=True, verbose_name=_("Volunteer for Projects")) can_create_projects = models.BooleanField(default=False, verbose_name=_("Create Projects")) can_manage_project_tasks = models.BooleanField(default=False, verbose_name=_("Manage Project Tasks")) can_approve_projects = models.BooleanField(default=False, verbose_name=_("Approve Projects")) # 8. Donations & Charity can_make_donations = models.BooleanField(default=True, verbose_name=_("Make Donations")) can_create_donation_campaigns = models.BooleanField(default=False, verbose_name=_("Create Donation Campaigns")) can_view_donation_reports = models.BooleanField(default=False, verbose_name=_("View Donation Reports")) # 9. Support & Tickets can_create_tickets = models.BooleanField(default=True, verbose_name=_("Create Support Tickets")) can_reply_tickets = models.BooleanField(default=True, verbose_name=_("Reply to Support Tickets")) can_manage_tickets = models.BooleanField(default=False, verbose_name=_("Manage Support Tickets")) # 10. Dynamic Forms can_submit_forms = models.BooleanField(default=True, verbose_name=_("Submit Dynamic Forms")) can_create_forms = models.BooleanField(default=False, verbose_name=_("Create Dynamic Forms")) can_export_form_data = models.BooleanField(default=False, verbose_name=_("Export Form Responses")) # 11. Diplomacy & Institutional can_view_diplomatic_reports = models.BooleanField(default=False, verbose_name=_("View Diplomatic Reports")) can_create_diplomatic_reports = models.BooleanField(default=False, verbose_name=_("Create Diplomatic Reports")) # 12. Administration & Security can_access_admin_panel = models.BooleanField(default=False, verbose_name=_("Access Admin Panel")) can_manage_users = models.BooleanField(default=False, verbose_name=_("Manage Users")) can_ban_users = models.BooleanField(default=False, verbose_name=_("Ban / Suspend Users")) can_view_analytics = models.BooleanField(default=False, verbose_name=_("View Analytics Dashboard")) created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created At")) updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated At")) class Meta: ordering = ('name',) verbose_name = _("Role") verbose_name_plural = _("Roles") def __str__(self): return self.name def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.name) if self.is_default: # Ensure only one default role exists Role.objects.filter(is_default=True).exclude(pk=self.pk).update(is_default=False) super().save(*args, **kwargs) def get_permissions_dict(self): """Returns a dict of all permission flags and their boolean values.""" return {perm: getattr(self, perm, False) for perm in ALL_PERMISSION_FIELDS}