123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- from datetime import timedelta
- from django import forms
- from django.contrib.auth import get_user_model
- from django.core.exceptions import PermissionDenied
- from django.template.defaultfilters import date as format_date
- from django.utils import timezone
- from django.utils.translation import gettext_lazy as _
- from misago.acl import algebra
- from misago.acl.decorators import return_boolean
- from misago.acl.models import Role
- from misago.admin.forms import YesNoSwitch
- from misago.users.bans import get_user_ban
- __all__ = [
- "allow_rename_user",
- "can_rename_user",
- "allow_moderate_avatar",
- "can_moderate_avatar",
- "allow_moderate_signature",
- "can_moderate_signature",
- "allow_edit_profile_details",
- "can_edit_profile_details",
- "allow_ban_user",
- "can_ban_user",
- "allow_lift_ban",
- "can_lift_ban",
- ]
- class PermissionsForm(forms.Form):
- legend = _("Users moderation")
- can_rename_users = YesNoSwitch(label=_("Can rename users"))
- can_moderate_avatars = YesNoSwitch(label=_("Can moderate avatars"))
- can_moderate_signatures = YesNoSwitch(label=_("Can moderate signatures"))
- can_moderate_profile_details = YesNoSwitch(label=_("Can moderate profile details"))
- can_ban_users = YesNoSwitch(label=_("Can ban users"))
- max_ban_length = forms.IntegerField(
- label=_("Max length, in days, of imposed ban"),
- help_text=_("Enter zero to let moderators impose permanent bans."),
- min_value=0,
- initial=0,
- )
- can_lift_bans = YesNoSwitch(label=_("Can lift bans"))
- max_lifted_ban_length = forms.IntegerField(
- label=_("Max length, in days, of lifted ban"),
- help_text=_("Enter zero to let moderators lift permanent bans."),
- min_value=0,
- initial=0,
- )
- def change_permissions_form(role):
- if isinstance(role, Role) and role.special_role != "anonymous":
- return PermissionsForm
- else:
- return None
- def build_acl(acl, roles, key_name):
- new_acl = {
- "can_rename_users": 0,
- "can_moderate_avatars": 0,
- "can_moderate_signatures": 0,
- "can_moderate_profile_details": 0,
- "can_ban_users": 0,
- "max_ban_length": 2,
- "can_lift_bans": 0,
- "max_lifted_ban_length": 2,
- }
- new_acl.update(acl)
- return algebra.sum_acls(
- new_acl,
- roles=roles,
- key=key_name,
- can_rename_users=algebra.greater,
- can_moderate_avatars=algebra.greater,
- can_moderate_signatures=algebra.greater,
- can_moderate_profile_details=algebra.greater,
- can_ban_users=algebra.greater,
- max_ban_length=algebra.greater_or_zero,
- can_lift_bans=algebra.greater,
- max_lifted_ban_length=algebra.greater_or_zero,
- )
- def add_acl_to_user(user_acl, target):
- target.acl["can_rename"] = can_rename_user(user_acl, target)
- target.acl["can_moderate_avatar"] = can_moderate_avatar(user_acl, target)
- target.acl["can_moderate_signature"] = can_moderate_signature(user_acl, target)
- target.acl["can_edit_profile_details"] = can_edit_profile_details(user_acl, target)
- target.acl["can_ban"] = can_ban_user(user_acl, target)
- target.acl["max_ban_length"] = user_acl["max_ban_length"]
- target.acl["can_lift_ban"] = can_lift_ban(user_acl, target)
- mod_permissions = ["can_rename", "can_moderate_avatar", "can_moderate_signature"]
- for permission in mod_permissions:
- if target.acl[permission]:
- target.acl["can_moderate"] = True
- break
- def register_with(registry):
- registry.acl_annotator(get_user_model(), add_acl_to_user)
- def allow_rename_user(user_acl, target):
- if not user_acl["can_rename_users"]:
- raise PermissionDenied(_("You can't rename users."))
- if not user_acl["is_superuser"] and (target.is_staff or target.is_superuser):
- raise PermissionDenied(_("You can't rename administrators."))
- can_rename_user = return_boolean(allow_rename_user)
- def allow_moderate_avatar(user_acl, target):
- if not user_acl["can_moderate_avatars"]:
- raise PermissionDenied(_("You can't moderate avatars."))
- if not user_acl["is_superuser"] and (target.is_staff or target.is_superuser):
- raise PermissionDenied(_("You can't moderate administrators avatars."))
- can_moderate_avatar = return_boolean(allow_moderate_avatar)
- def allow_moderate_signature(user_acl, target):
- if not user_acl["can_moderate_signatures"]:
- raise PermissionDenied(_("You can't moderate signatures."))
- if not user_acl["is_superuser"] and (target.is_staff or target.is_superuser):
- message = _("You can't moderate administrators signatures.")
- raise PermissionDenied(message)
- can_moderate_signature = return_boolean(allow_moderate_signature)
- def allow_edit_profile_details(user_acl, target):
- if user_acl["is_anonymous"]:
- raise PermissionDenied(_("You have to sign in to edit profile details."))
- if (
- user_acl["user_id"] != target.id
- and not user_acl["can_moderate_profile_details"]
- ):
- raise PermissionDenied(_("You can't edit other users details."))
- if not user_acl["is_superuser"] and (target.is_staff or target.is_superuser):
- message = _("You can't edit administrators details.")
- raise PermissionDenied(message)
- can_edit_profile_details = return_boolean(allow_edit_profile_details)
- def allow_ban_user(user_acl, target):
- if not user_acl["can_ban_users"]:
- raise PermissionDenied(_("You can't ban users."))
- if target.is_staff or target.is_superuser:
- raise PermissionDenied(_("You can't ban administrators."))
- can_ban_user = return_boolean(allow_ban_user)
- def allow_lift_ban(user_acl, target):
- if not user_acl["can_lift_bans"]:
- raise PermissionDenied(_("You can't lift bans."))
- ban = get_user_ban(target, user_acl["cache_versions"])
- if not ban:
- raise PermissionDenied(_("This user is not banned."))
- if user_acl["max_lifted_ban_length"]:
- expiration_limit = timedelta(days=user_acl["max_lifted_ban_length"])
- lift_cutoff = (timezone.now() + expiration_limit).date()
- if not ban.valid_until:
- raise PermissionDenied(_("You can't lift permanent bans."))
- elif ban.valid_until > lift_cutoff:
- message = _("You can't lift bans that expire after %(expiration)s.")
- raise PermissionDenied(message % {"expiration": format_date(lift_cutoff)})
- can_lift_ban = return_boolean(allow_lift_ban)
|