diff --git a/aleksis/apps/matrix/models.py b/aleksis/apps/matrix/models.py index 71dcf1c8552dfe6c2c4f4e226df2a55eb7714bc1..af52611d849caa16172e4874125de503640303be 100644 --- a/aleksis/apps/matrix/models.py +++ b/aleksis/apps/matrix/models.py @@ -191,7 +191,7 @@ class MatrixRoom(ExtensiblePolymorphicModel): all_profiles = MatrixProfile.objects.filter( Q(person__in=group.members.all()) | Q(person__in=group.owners.all()) - ) + ).distinct() return all_profiles @@ -211,14 +211,19 @@ class MatrixRoom(ExtensiblePolymorphicModel): self._invite(profile) # Set power levels for all users - # Mod = 50 = Owners - # User = 0 = Members user_levels = self.power_levels for profile in all_profiles: if profile.person in self.group.owners.all(): - user_levels[profile.matrix_id] = 50 - elif profile.person in self.group.members.all(): - user_levels[profile.matrix_id] = 0 + power_level = get_site_preferences()["matrix__power_level_for_owners"] + else: + power_level = get_site_preferences()["matrix__power_level_for_members"] + + if ( + profile.matrix_id not in user_levels + or user_levels[profile.matrix_id] < power_level + or get_site_preferences()["matrix__reduce_power_levels"] + ): + user_levels[profile.matrix_id] = power_level self._set_power_levels(user_levels) def sync_space(self): diff --git a/aleksis/apps/matrix/preferences.py b/aleksis/apps/matrix/preferences.py index 123be1cd23f9a48050e96fed8083f2f4ae7f1142..67226337cb160f4b5896b9ecf00e6389f806e265 100644 --- a/aleksis/apps/matrix/preferences.py +++ b/aleksis/apps/matrix/preferences.py @@ -1,7 +1,7 @@ from django.utils.translation import gettext as _ from dynamic_preferences.preferences import Section -from dynamic_preferences.types import BooleanPreference, StringPreference +from dynamic_preferences.types import BooleanPreference, IntegerPreference, StringPreference from aleksis.core.registries import site_preferences_registry @@ -47,3 +47,29 @@ class UseSpaces(BooleanPreference): name = "use_spaces" verbose_name = _("Use Matrix spaces") default = True + + +@site_preferences_registry.register +class ReducePowerLevels(BooleanPreference): + section = matrix + name = "reduce_power_levels" + verbose_name = _("Reduce existing power levels") + default = False + + +@site_preferences_registry.register +class PowerLevelForOwners(IntegerPreference): + section = matrix + name = "power_level_for_owners" + verbose_name = _("Power level for owners") + default = 50 + required = True + + +@site_preferences_registry.register +class PowerLevelForMembers(IntegerPreference): + section = matrix + name = "power_level_for_members" + verbose_name = _("Power level for members") + default = 0 + required = True diff --git a/aleksis/apps/matrix/tests/test_matrix.py b/aleksis/apps/matrix/tests/test_matrix.py index 71530bb15601b1f220580511167bd71a9f0b9d14..cd05c507dbfba91d72e31441b5399b94bbe7b491 100644 --- a/aleksis/apps/matrix/tests/test_matrix.py +++ b/aleksis/apps/matrix/tests/test_matrix.py @@ -121,6 +121,9 @@ def test_room_alias_collision_school_term(matrix_bot_user): def test_sync_room_members(matrix_bot_user): get_site_preferences()["matrix__homeserver_ids"] = "matrix.aleksis.example.org" + get_site_preferences()["matrix__reduce_power_levels"] = False + get_site_preferences()["matrix__power_level_for_owners"] = 50 + get_site_preferences()["matrix__power_level_for_members"] = 0 g = Group.objects.create(name="Test Room") u1 = User.objects.create_user("test1", "test1@example.org", "test1") @@ -183,6 +186,71 @@ def test_sync_room_members(matrix_bot_user): break +def test_power_levels(matrix_bot_user): + get_site_preferences()["matrix__homeserver_ids"] = "matrix.aleksis.example.org" + get_site_preferences()["matrix__power_level_for_owners"] = 55 + get_site_preferences()["matrix__power_level_for_members"] = 11 + get_site_preferences()["matrix__reduce_power_levels"] = False + + g = Group.objects.create(name="Test Room") + u1 = User.objects.create_user("test1", "test1@example.org", "test1") + u2 = User.objects.create_user("test2", "test2@example.org", "test2") + + p1 = Person.objects.create(first_name="Test", last_name="Person", user=u1) + p2 = Person.objects.create(first_name="Test 2", last_name="Person", user=u2) + + g.members.set([p1]) + g.owners.set([p2]) + + room = MatrixRoom.from_group(g) + room.sync_profiles() + + # Get power levels + r = do_matrix_request("GET", f"rooms/{room.room_id}/state") + for event in r: + if not event["type"] == "m.room.power_levels": + continue + current_power_levels = event["content"]["users"] + + assert current_power_levels[p1.matrix_profile.matrix_id] == 11 + assert current_power_levels[p2.matrix_profile.matrix_id] == 55 + + break + + # Test reducing of power levels + g.owners.set([]) + g.members.set([p1, p2]) + + room.sync_profiles() + + # Not reduced here + r = do_matrix_request("GET", f"rooms/{room.room_id}/state") + for event in r: + if not event["type"] == "m.room.power_levels": + continue + current_power_levels = event["content"]["users"] + + assert current_power_levels[p1.matrix_profile.matrix_id] == 11 + assert current_power_levels[p2.matrix_profile.matrix_id] == 55 + + break + + get_site_preferences()["matrix__reduce_power_levels"] = True + room.sync_profiles() + + # Reduced here + r = do_matrix_request("GET", f"rooms/{room.room_id}/state") + for event in r: + if not event["type"] == "m.room.power_levels": + continue + current_power_levels = event["content"]["users"] + + assert current_power_levels[p1.matrix_profile.matrix_id] == 11 + assert current_power_levels[p2.matrix_profile.matrix_id] == 11 + + break + + def test_sync_room_members_without_user(matrix_bot_user): get_site_preferences()["matrix__homeserver_ids"] = "matrix.aleksis.example.org"