Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move moderator_note to LoS #2593

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions docs/actions/agenda_item.create.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
duration: number; // in seconds
weight: number;
tag_ids: Id[];
moderator_notes: HTML;
}
```

Expand All @@ -23,5 +22,4 @@ item or the content object cannot have an agenda item (see available collections
`models.yml`). `tag_ids` must be from the same meeting.

## Permissions
The request user needs `agenda_item.can_manage_moderator_notes` to set `moderator_notes` and
`agenda_item.can_manage` for all other fields.
The request user needs `agenda_item.can_manage`.
5 changes: 2 additions & 3 deletions docs/actions/agenda_item.update.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
duration: number; // in minutes
weight: number;
tag_ids: Id[];
moderator_notes: HTML;
}
```

Expand All @@ -21,5 +20,5 @@ Updates the agenda item. `tag_ids` must be from the same meeting.
The `type` attribute of one `agenda_item` must be one of [`common`, `internal`, `hidden`].

## Permissions
The request user needs `agenda_item.can_manage_moderator_notes` to set `moderator_notes` and
`agenda_item.can_manage` for all other fields.
The request user needs `agenda_item.can_manage`.

2 changes: 1 addition & 1 deletion docs/actions/group.update.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ Updates the group. Permissions are restricted to the following enum: https://git
If the group is the meetings anonymous group, the name may not be changed and the permissions have to be in the following whitelist:
- agenda_item.can_see,
- agenda_item.can_see_internal,
- agenda_item.can_see_moderator_notes,
- assignment.can_see,
- list_of_speakers.can_see,
- list_of_speakers.can_see_moderator_notes,
- mediafile.can_see,
- meeting.can_see_autopilot,
- meeting.can_see_frontpage,
Expand Down
4 changes: 3 additions & 1 deletion docs/actions/list_of_speakers.update.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

// Optional
closed: boolean;
moderator_notes: HTML;
}
```

## Action
Updates a list of speakers.

## Permissions
The request user needs `list_of_speakers.can_manage`.
The request user needs `list_of_speakers.can_manage_moderator_notes` to set `moderator_notes` and
`list_of_speakers.can_manage` for all other fields.
2 changes: 1 addition & 1 deletion global/data/example-data.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_migration_index": 60,
"_migration_index": 61,
"gender":{
"1":{
"id": 1,
Expand Down
2 changes: 1 addition & 1 deletion global/data/initial-data.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_migration_index": 60,
"_migration_index": 61,
"gender":{
"1":{
"id": 1,
Expand Down
2 changes: 1 addition & 1 deletion global/meta
Submodule meta updated 2 files
+5 −5 models.yml
+2 −3 permission.yml
4 changes: 1 addition & 3 deletions openslides_backend/action/actions/agenda_item/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
)
from ...util.default_schema import DefaultSchema
from ...util.register import register_action
from .permission_mixin import AgendaItemPermissionMixin


@register_action("agenda_item.create")
class AgendaItemCreate(AgendaItemPermissionMixin, CreateActionWithInferredMeeting):
class AgendaItemCreate(CreateActionWithInferredMeeting):
"""
Action to create agenda items.
"""
Expand All @@ -29,7 +28,6 @@ class AgendaItemCreate(AgendaItemPermissionMixin, CreateActionWithInferredMeetin
"duration",
"weight",
"tag_ids",
"moderator_notes",
],
)
permission = Permissions.AgendaItem.CAN_MANAGE
Expand Down
25 changes: 0 additions & 25 deletions openslides_backend/action/actions/agenda_item/permission_mixin.py

This file was deleted.

4 changes: 1 addition & 3 deletions openslides_backend/action/actions/agenda_item/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
from ...util.default_schema import DefaultSchema
from ...util.register import register_action
from ...util.typing import ActionData
from .permission_mixin import AgendaItemPermissionMixin


@register_action("agenda_item.update")
class AgendaItemUpdate(AgendaItemPermissionMixin, UpdateAction):
class AgendaItemUpdate(UpdateAction):
"""
Action to update agenda items.
"""
Expand All @@ -25,7 +24,6 @@ class AgendaItemUpdate(AgendaItemPermissionMixin, UpdateAction):
"weight",
"tag_ids",
"duration",
"moderator_notes",
]
)
permission = Permissions.AgendaItem.CAN_MANAGE
Expand Down
20 changes: 19 additions & 1 deletion openslides_backend/action/actions/list_of_speakers/update.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from typing import Any

from ....models.models import ListOfSpeakers
from ....permissions.permission_helper import has_perm
from ....permissions.permissions import Permissions
from ....shared.exceptions import MissingPermission
from ...generics.update import UpdateAction
from ...util.default_schema import DefaultSchema
from ...util.register import register_action
Expand All @@ -13,6 +17,20 @@ class ListOfSpeakersUpdateAction(UpdateAction):

model = ListOfSpeakers()
schema = DefaultSchema(ListOfSpeakers()).get_update_schema(
optional_properties=["closed"]
optional_properties=["closed", "moderator_notes"]
)
permission = Permissions.ListOfSpeakers.CAN_MANAGE

def check_permissions(self, instance: dict[str, Any]) -> None:
if "moderator_notes" in instance:
perm = Permissions.ListOfSpeakers.CAN_MANAGE_MODERATOR_NOTES
if not has_perm(
self.datastore,
self.user_id,
perm,
self.get_meeting_id(instance),
):
raise MissingPermission(perm)
if len(instance) == 2:
return
super().check_permissions(instance)
114 changes: 114 additions & 0 deletions openslides_backend/migrations/migrations/0060_move_moderator_notes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from collections import defaultdict

from datastore.migrations import BaseModelMigration
from datastore.reader.core import GetManyRequestPart
from datastore.writer.core import BaseRequestEvent, RequestUpdateEvent

from openslides_backend.shared.patterns import (
collection_and_id_from_fqid,
fqid_from_collection_and_id,
)


class Migration(BaseModelMigration):
"""
This migration moves all set moderator notes to the related models list_of_speakers.
It also gives any group which had the permissions agenda_item.can_see_moderator_notes or agenda_item.can_manage_moderator_notes
the permission list_of_speakers.can_see_moderator_notes or list_of_speakers.can_manage_moderator_notes instead.
"""

target_migration_index = 61

def migrate_models(self) -> list[BaseRequestEvent] | None:
agenda_items = self.reader.get_all(
"agenda_item", ["id", "content_object_id", "moderator_notes"]
)
events: list[BaseRequestEvent] = [
RequestUpdateEvent(
fqid_from_collection_and_id("agenda_item", agenda_item["id"]),
{"moderator_notes": None},
)
for agenda_item in agenda_items.values()
if (mod_note := agenda_item.get("moderator_notes"))
]
if len(events):
content_object_id_to_mod_note: dict[tuple[str, int], str] = {
collection_and_id_from_fqid(agenda_item["content_object_id"]): mod_note
for agenda_item in agenda_items.values()
if (mod_note := agenda_item.get("moderator_notes"))
}
content_object_collection_to_ids: dict[str, list[int]] = defaultdict(list)
for co_collection, co_id in content_object_id_to_mod_note.keys():
content_object_collection_to_ids[co_collection].append(co_id)
content_objects = self.reader.get_many(
[
GetManyRequestPart(co_collection, co_ids, ["list_of_speakers_id"])
for co_collection, co_ids in content_object_collection_to_ids.items()
]
)
events.extend(
[
RequestUpdateEvent(
fqid_from_collection_and_id(
"list_of_speakers",
content_objects[co_collection][co_id][
"list_of_speakers_id"
],
),
{"moderator_notes": mod_note},
)
for (
co_collection,
co_id,
), mod_note in content_object_id_to_mod_note.items()
]
)
groups = self.reader.get_all("group", ["id", "permissions"])
events.extend(
[
RequestUpdateEvent(
fqid_from_collection_and_id("group", group["id"]),
{},
{
"add": {
"permissions": [
*(
["agenda_item.can_see"]
if not any(
"agenda_item." + suffix
in group.get("permissions", [])
or []
for suffix in ["can_see_internal", "can_manage"]
)
else []
),
*[
"list_of_speakers" + substr
for substr in perm_substrings
],
]
},
"remove": {
"permissions": [
"agenda_item" + substr for substr in perm_substrings
]
},
},
)
for group in groups.values()
if (
perm_substrings := [
substr
for substr in [
".can_see_moderator_notes",
".can_manage_moderator_notes",
]
if any(
permission == "agenda_item" + substr
for permission in group.get("permissions", []) or []
)
]
)
]
)
return events
6 changes: 3 additions & 3 deletions openslides_backend/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -954,8 +954,6 @@ class Group(Model):
"agenda_item.can_manage",
"agenda_item.can_see",
"agenda_item.can_see_internal",
"agenda_item.can_manage_moderator_notes",
"agenda_item.can_see_moderator_notes",
"assignment.can_manage",
"assignment.can_nominate_other",
"assignment.can_nominate_self",
Expand All @@ -964,6 +962,8 @@ class Group(Model):
"list_of_speakers.can_be_speaker",
"list_of_speakers.can_manage",
"list_of_speakers.can_see",
"list_of_speakers.can_manage_moderator_notes",
"list_of_speakers.can_see_moderator_notes",
"mediafile.can_manage",
"mediafile.can_see",
"meeting.can_manage_logos_and_fonts",
Expand Down Expand Up @@ -1098,7 +1098,6 @@ class AgendaItem(Model, AgendaItemModelMixin):
duration = fields.IntegerField(
constraints={"description": "Given in seconds", "minimum": 0}
)
moderator_notes = fields.HTMLStrictField()
is_internal = fields.BooleanField(
read_only=True, constraints={"description": "Calculated by the server"}
)
Expand Down Expand Up @@ -1153,6 +1152,7 @@ class ListOfSpeakers(Model):
"description": "The (positive) serial number of this model in its meeting. This number is auto-generated and read-only."
},
)
moderator_notes = fields.HTMLStrictField()
content_object_id = fields.GenericRelationField(
to={
"motion": "list_of_speakers_id",
Expand Down
2 changes: 1 addition & 1 deletion openslides_backend/permissions/permission_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ def is_admin(datastore: DatastoreService, user_id: int, meeting_id: int) -> bool
anonymous_perms_whitelist: set[Permission] = {
Permissions.AgendaItem.CAN_SEE,
Permissions.AgendaItem.CAN_SEE_INTERNAL,
Permissions.AgendaItem.CAN_SEE_MODERATOR_NOTES,
Permissions.Assignment.CAN_SEE,
Permissions.ListOfSpeakers.CAN_SEE,
Permissions.ListOfSpeakers.CAN_SEE_MODERATOR_NOTES,
Permissions.Mediafile.CAN_SEE,
Permissions.Meeting.CAN_SEE_AUTOPILOT,
Permissions.Meeting.CAN_SEE_FRONTPAGE,
Expand Down
15 changes: 7 additions & 8 deletions openslides_backend/permissions/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

class _AgendaItem(str, Permission, Enum):
CAN_MANAGE = "agenda_item.can_manage"
CAN_MANAGE_MODERATOR_NOTES = "agenda_item.can_manage_moderator_notes"
CAN_SEE = "agenda_item.can_see"
CAN_SEE_INTERNAL = "agenda_item.can_see_internal"
CAN_SEE_MODERATOR_NOTES = "agenda_item.can_see_moderator_notes"


class _Assignment(str, Permission, Enum):
Expand All @@ -27,7 +25,9 @@ class _Chat(str, Permission, Enum):
class _ListOfSpeakers(str, Permission, Enum):
CAN_BE_SPEAKER = "list_of_speakers.can_be_speaker"
CAN_MANAGE = "list_of_speakers.can_manage"
CAN_MANAGE_MODERATOR_NOTES = "list_of_speakers.can_manage_moderator_notes"
CAN_SEE = "list_of_speakers.can_see"
CAN_SEE_MODERATOR_NOTES = "list_of_speakers.can_see_moderator_notes"


class _Mediafile(str, Permission, Enum):
Expand Down Expand Up @@ -95,14 +95,9 @@ class Permissions:

# Holds the corresponding parent for each permission.
permission_parents: dict[Permission, list[Permission]] = {
_AgendaItem.CAN_SEE: [
_AgendaItem.CAN_SEE_INTERNAL,
_AgendaItem.CAN_SEE_MODERATOR_NOTES,
],
_AgendaItem.CAN_SEE: [_AgendaItem.CAN_SEE_INTERNAL],
_AgendaItem.CAN_SEE_INTERNAL: [_AgendaItem.CAN_MANAGE],
_AgendaItem.CAN_MANAGE: [],
_AgendaItem.CAN_SEE_MODERATOR_NOTES: [_AgendaItem.CAN_MANAGE_MODERATOR_NOTES],
_AgendaItem.CAN_MANAGE_MODERATOR_NOTES: [],
_Assignment.CAN_SEE: [
_Assignment.CAN_NOMINATE_OTHER,
_Assignment.CAN_NOMINATE_SELF,
Expand All @@ -114,6 +109,10 @@ class Permissions:
_ListOfSpeakers.CAN_SEE: [_ListOfSpeakers.CAN_MANAGE],
_ListOfSpeakers.CAN_MANAGE: [],
_ListOfSpeakers.CAN_BE_SPEAKER: [],
_ListOfSpeakers.CAN_SEE_MODERATOR_NOTES: [
_ListOfSpeakers.CAN_MANAGE_MODERATOR_NOTES
],
_ListOfSpeakers.CAN_MANAGE_MODERATOR_NOTES: [],
_Mediafile.CAN_SEE: [_Mediafile.CAN_MANAGE],
_Mediafile.CAN_MANAGE: [],
_Meeting.CAN_MANAGE_SETTINGS: [],
Expand Down
Loading