kopia lustrzana https://github.com/wagtail/wagtail
Move GroupApprovalTask to workflows submodule
rodzic
eb36ff3570
commit
855dcd4bb6
|
@ -17,7 +17,6 @@ import posixpath
|
|||
import uuid
|
||||
from warnings import warn
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.contrib.contenttypes.fields import GenericRelation
|
||||
|
@ -125,7 +124,9 @@ from .sites import Site, SiteManager, SiteRootPath # noqa: F401
|
|||
from .specific import SpecificMixin
|
||||
from .view_restrictions import BaseViewRestriction
|
||||
from .workflows import ( # noqa: F401
|
||||
AbstractGroupApprovalTask,
|
||||
AbstractWorkflow,
|
||||
GroupApprovalTask,
|
||||
Task,
|
||||
TaskManager,
|
||||
TaskQuerySet,
|
||||
|
@ -2705,97 +2706,6 @@ class WorkflowPage(models.Model):
|
|||
verbose_name_plural = _("workflow pages")
|
||||
|
||||
|
||||
class AbstractGroupApprovalTask(Task):
|
||||
groups = models.ManyToManyField(
|
||||
Group,
|
||||
verbose_name=_("groups"),
|
||||
help_text=_(
|
||||
"Pages/snippets at this step in a workflow will be moderated or approved by these groups of users"
|
||||
),
|
||||
)
|
||||
|
||||
admin_form_fields = Task.admin_form_fields + ["groups"]
|
||||
admin_form_widgets = {
|
||||
"groups": forms.CheckboxSelectMultiple,
|
||||
}
|
||||
|
||||
def start(self, workflow_state, user=None):
|
||||
if (
|
||||
isinstance(workflow_state.content_object, LockableMixin)
|
||||
and workflow_state.content_object.locked_by
|
||||
):
|
||||
# If the person who locked the object isn't in one of the groups, unlock the object
|
||||
if not workflow_state.content_object.locked_by.groups.filter(
|
||||
id__in=self.groups.all()
|
||||
).exists():
|
||||
workflow_state.content_object.locked = False
|
||||
workflow_state.content_object.locked_by = None
|
||||
workflow_state.content_object.locked_at = None
|
||||
workflow_state.content_object.save(
|
||||
update_fields=["locked", "locked_by", "locked_at"]
|
||||
)
|
||||
|
||||
return super().start(workflow_state, user=user)
|
||||
|
||||
def _user_in_groups(self, user):
|
||||
# Cache the check whether "this user is in any of this
|
||||
# GroupApprovalTask's groups" on the user object, in case we do it
|
||||
# against the same user and task multiple times in a request.
|
||||
# Use a dict to map the task id to the check result, in case we also
|
||||
# check against different GroupApprovalTasks for the same user.
|
||||
cache_attr = "_group_approval_task_checks"
|
||||
if not (checks_cache := getattr(user, cache_attr, {})):
|
||||
setattr(user, cache_attr, checks_cache)
|
||||
|
||||
if self.pk not in checks_cache:
|
||||
checks_cache[self.pk] = self.groups.filter(
|
||||
id__in=user.groups.all()
|
||||
).exists()
|
||||
|
||||
return checks_cache[self.pk]
|
||||
|
||||
def user_can_access_editor(self, obj, user):
|
||||
return user.is_superuser or self._user_in_groups(user)
|
||||
|
||||
def locked_for_user(self, obj, user):
|
||||
return not (user.is_superuser or self._user_in_groups(user))
|
||||
|
||||
def user_can_lock(self, obj, user):
|
||||
return self._user_in_groups(user)
|
||||
|
||||
def user_can_unlock(self, obj, user):
|
||||
return False
|
||||
|
||||
def get_actions(self, obj, user):
|
||||
if user.is_superuser or self._user_in_groups(user):
|
||||
return [
|
||||
("reject", _("Request changes"), True),
|
||||
("approve", _("Approve"), False),
|
||||
("approve", _("Approve with comment"), True),
|
||||
]
|
||||
|
||||
return []
|
||||
|
||||
def get_task_states_user_can_moderate(self, user, **kwargs):
|
||||
if user.is_superuser or self._user_in_groups(user):
|
||||
return self.task_states.filter(status=TaskState.STATUS_IN_PROGRESS)
|
||||
else:
|
||||
return TaskState.objects.none()
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return _("Members of the chosen Wagtail Groups can approve this task")
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Group approval task")
|
||||
verbose_name_plural = _("Group approval tasks")
|
||||
|
||||
|
||||
class GroupApprovalTask(AbstractGroupApprovalTask):
|
||||
pass
|
||||
|
||||
|
||||
class BaseTaskStateManager(models.Manager):
|
||||
def reviewable_by(self, user):
|
||||
tasks = Task.objects.filter(active=True).specific()
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import PermissionDenied, ValidationError
|
||||
|
@ -816,3 +818,96 @@ class Task(SpecificMixin, models.Model):
|
|||
class Meta:
|
||||
verbose_name = _("task")
|
||||
verbose_name_plural = _("tasks")
|
||||
|
||||
|
||||
class AbstractGroupApprovalTask(Task):
|
||||
groups = models.ManyToManyField(
|
||||
Group,
|
||||
verbose_name=_("groups"),
|
||||
help_text=_(
|
||||
"Pages/snippets at this step in a workflow will be moderated or approved by these groups of users"
|
||||
),
|
||||
)
|
||||
|
||||
admin_form_fields = Task.admin_form_fields + ["groups"]
|
||||
admin_form_widgets = {
|
||||
"groups": forms.CheckboxSelectMultiple,
|
||||
}
|
||||
|
||||
def start(self, workflow_state, user=None):
|
||||
if (
|
||||
isinstance(workflow_state.content_object, LockableMixin)
|
||||
and workflow_state.content_object.locked_by
|
||||
):
|
||||
# If the person who locked the object isn't in one of the groups, unlock the object
|
||||
if not workflow_state.content_object.locked_by.groups.filter(
|
||||
id__in=self.groups.all()
|
||||
).exists():
|
||||
workflow_state.content_object.locked = False
|
||||
workflow_state.content_object.locked_by = None
|
||||
workflow_state.content_object.locked_at = None
|
||||
workflow_state.content_object.save(
|
||||
update_fields=["locked", "locked_by", "locked_at"]
|
||||
)
|
||||
|
||||
return super().start(workflow_state, user=user)
|
||||
|
||||
def _user_in_groups(self, user):
|
||||
# Cache the check whether "this user is in any of this
|
||||
# GroupApprovalTask's groups" on the user object, in case we do it
|
||||
# against the same user and task multiple times in a request.
|
||||
# Use a dict to map the task id to the check result, in case we also
|
||||
# check against different GroupApprovalTasks for the same user.
|
||||
cache_attr = "_group_approval_task_checks"
|
||||
if not (checks_cache := getattr(user, cache_attr, {})):
|
||||
setattr(user, cache_attr, checks_cache)
|
||||
|
||||
if self.pk not in checks_cache:
|
||||
checks_cache[self.pk] = self.groups.filter(
|
||||
id__in=user.groups.all()
|
||||
).exists()
|
||||
|
||||
return checks_cache[self.pk]
|
||||
|
||||
def user_can_access_editor(self, obj, user):
|
||||
return user.is_superuser or self._user_in_groups(user)
|
||||
|
||||
def locked_for_user(self, obj, user):
|
||||
return not (user.is_superuser or self._user_in_groups(user))
|
||||
|
||||
def user_can_lock(self, obj, user):
|
||||
return self._user_in_groups(user)
|
||||
|
||||
def user_can_unlock(self, obj, user):
|
||||
return False
|
||||
|
||||
def get_actions(self, obj, user):
|
||||
if user.is_superuser or self._user_in_groups(user):
|
||||
return [
|
||||
("reject", _("Request changes"), True),
|
||||
("approve", _("Approve"), False),
|
||||
("approve", _("Approve with comment"), True),
|
||||
]
|
||||
|
||||
return []
|
||||
|
||||
def get_task_states_user_can_moderate(self, user, **kwargs):
|
||||
from wagtail.models import TaskState
|
||||
|
||||
if user.is_superuser or self._user_in_groups(user):
|
||||
return self.task_states.filter(status=TaskState.STATUS_IN_PROGRESS)
|
||||
else:
|
||||
return TaskState.objects.none()
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
return _("Members of the chosen Wagtail Groups can approve this task")
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
verbose_name = _("Group approval task")
|
||||
verbose_name_plural = _("Group approval tasks")
|
||||
|
||||
|
||||
class GroupApprovalTask(AbstractGroupApprovalTask):
|
||||
pass
|
||||
|
|
Ładowanie…
Reference in New Issue