diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 755c39238..13b1782de 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -34,6 +34,8 @@ Motions: follow recommendation, manage submitters and supporters, change motion category, motion block and origin and manage motion polls [#3913]. - Added new permission to create amendments [#4128]. + - Allowed submitters to set state of new motions in complex and customized + workflow [#4236]. - Added multi select action to manage submitters, tags, states and recommendations [#4037, #4132]. - Added timestampes for motions [#4134]. diff --git a/client/src/app/site/motions/components/motion-detail/motion-detail.component.html b/client/src/app/site/motions/components/motion-detail/motion-detail.component.html index 1cf555806..7331a681a 100644 --- a/client/src/app/site/motions/components/motion-detail/motion-detail.component.html +++ b/client/src/app/site/motions/components/motion-detail/motion-detail.component.html @@ -222,12 +222,14 @@ - - +
+ + +
-
+
{{ stateLabel }} @@ -238,7 +240,7 @@
-
+
{{ stateLabel }}
diff --git a/client/src/app/site/motions/services/local-permissions.service.ts b/client/src/app/site/motions/services/local-permissions.service.ts index 078c10381..e6d1cbacb 100644 --- a/client/src/app/site/motions/services/local-permissions.service.ts +++ b/client/src/app/site/motions/services/local-permissions.service.ts @@ -108,6 +108,20 @@ export class LocalPermissionsService { motion.state.allow_submitter_edit && motion.submitters.some(submitter => submitter.id === this.operator.user.id) ); + case 'change_state': + // check also for empty ViewMotion object (e.g. if motion.id is null) + // important for creating new motion as normal user + if (!motion || !motion.id) { + return false; + } + return ( + this.operator.hasPerms('motions.can_manage') || + this.operator.hasPerms('motions.can_manage_metadata') || + (motion.state && + motion.state.allow_submitter_edit && + motion.submitters && + motion.submitters.some(submitter => submitter.id === this.operator.user.id)) + ); case 'change_metadata': return ( this.operator.hasPerms('motions.can_manage') || diff --git a/openslides/motions/views.py b/openslides/motions/views.py index 554bee02b..18c1a7b12 100644 --- a/openslides/motions/views.py +++ b/openslides/motions/views.py @@ -75,11 +75,10 @@ class MotionViewSet(ModelViewSet): result = has_perm(self.request.user, "motions.can_see") # For partial_update, update and destroy requests the rest of the check is # done in the update method. See below. - elif self.action == "create": + elif self.action in ("create", "set_state"): result = has_perm(self.request.user, "motions.can_see") - # For create the rest of the check is done in the create method. See below. + # For create the rest of the check is done in the respective method. See below. elif self.action in ( - "set_state", "manage_multiple_state", "set_recommendation", "manage_multiple_recommendation", @@ -561,6 +560,10 @@ class MotionViewSet(ModelViewSet): # Set or reset state. if state is not None: # Check data and set state. + if not has_perm(request.user, "motions.can_manage_metadata") and not ( + motion.is_submitter(request.user) and motion.state.allow_submitter_edit + ): + self.permission_denied(request) try: state_id = int(state) except ValueError: @@ -574,6 +577,8 @@ class MotionViewSet(ModelViewSet): motion.set_state(state_id) else: # Reset state. + if not has_perm(self.request.user, "motions.can_manage_metadata"): + self.permission_denied(request) motion.reset_state() # Save motion.