123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- 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."))
- # FIXME: this will require cache version delegation
- ban = get_user_ban(target, user_ac["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)
|