diff --git a/lib/src/Event.dart b/lib/src/Event.dart index de3eaf9..f5251ab 100644 --- a/lib/src/Event.dart +++ b/lib/src/Event.dart @@ -138,4 +138,7 @@ class Event extends RoomState { final String eventID = await room.sendTextEvent(text, txid: txid); return eventID; } + + /// Whether the client is allowed to redact this event. + bool get canRedact => senderId == room.client.userID || room.canRedact; } diff --git a/lib/src/Room.dart b/lib/src/Room.dart index 284bb3c..f16c5db 100644 --- a/lib/src/Room.dart +++ b/lib/src/Room.dart @@ -465,7 +465,7 @@ class Room { /// Set the power level of the user with the [userID] to the value [power]. Future setPower(String userID, int power) async { if (states["m.room.power_levels"] == null) return null; - Map powerMap = states["m.room.power_levels"].content["users"]; + Map powerMap = states["m.room.power_levels"].content["users"]; powerMap[userID] = power; dynamic res = await client.connection.jsonRequest( @@ -819,4 +819,41 @@ class Room { if (setAvatarResp is ErrorResponse) return setAvatarResp; return setAvatarResp["event_id"]; } + + bool _hasPermissionFor(String action) { + if (getState("m.room.power_levels") == null || + getState("m.room.power_levels").content[action] == null) return false; + return ownPowerLevel >= getState("m.room.power_levels").content[action]; + } + + /// The level required to ban a user. + bool get canBan => _hasPermissionFor("ban"); + + /// The default level required to send message events. Can be overridden by the events key. + bool get canSendDefaultMessages => _hasPermissionFor("events_default"); + + /// The level required to invite a user. + bool get canInvite => _hasPermissionFor("invite"); + + /// The level required to kick a user. + bool get canKick => _hasPermissionFor("kick"); + + /// The level required to redact an event. + bool get canRedact => _hasPermissionFor("redact"); + + /// The default level required to send state events. Can be overridden by the events key. + bool get canSendDefaultStates => _hasPermissionFor("state_default"); + + bool get canChangePowerLevel => canSendEvent("m.room.power_levels"); + + bool canSendEvent(String eventType) { + if (getState("m.room.power_levels") == null || + getState("m.room.power_levels").content["events"] == null) return false; + if (getState("m.room.power_levels").content["events"][eventType] == null) + return eventType == "m.room.message" + ? canSendDefaultMessages + : canSendDefaultStates; + return ownPowerLevel >= + getState("m.room.power_levels").content["events"][eventType]; + } } diff --git a/lib/src/User.dart b/lib/src/User.dart index 40ac24c..bf8b6c1 100644 --- a/lib/src/User.dart +++ b/lib/src/User.dart @@ -165,4 +165,15 @@ class User extends RoomState { return newRoomID; } + + /// Whether the client is allowed to ban/unban this user. + bool get canBan => room.canBan && powerLevel < room.ownPowerLevel; + + /// Whether the client is allowed to kick this user. + bool get canKick => room.canKick && powerLevel < room.ownPowerLevel; + + /// Whether the client is allowed to change the power level of this user. + /// Please be aware that you can only set the power level to at least your own! + bool get canChangePowerLevel => + room.canChangePowerLevel && powerLevel < room.ownPowerLevel; } diff --git a/test/Room_test.dart b/test/Room_test.dart index f78f196..7c55d29 100644 --- a/test/Room_test.dart +++ b/test/Room_test.dart @@ -214,8 +214,51 @@ void main() { expect(room.ownPowerLevel, 100); expect(room.getPowerLevelByUserId(matrix.userID), room.ownPowerLevel); expect(room.getPowerLevelByUserId("@nouser:example.com"), 10); + expect(room.ownPowerLevel, 100); + expect(room.canBan, true); + expect(room.canInvite, true); + expect(room.canKick, true); + expect(room.canRedact, true); + expect(room.canSendDefaultMessages, true); + expect(room.canSendDefaultStates, true); + expect(room.canChangePowerLevel, true); + expect(room.canSendEvent("m.room.name"), true); + expect(room.canSendEvent("m.room.power_levels"), true); + expect(room.canSendEvent("m.room.member"), true); expect(room.powerLevels, room.states["m.room.power_levels"].content["users"]); + + room.states["m.room.power_levels"] = RoomState( + senderId: "@test:example.com", + typeKey: "m.room.power_levels", + roomId: room.id, + room: room, + eventId: "123abc", + content: { + "ban": 50, + "events": {"m.room.name": 0, "m.room.power_levels": 100}, + "events_default": 0, + "invite": 50, + "kick": 50, + "notifications": {"room": 20}, + "redact": 50, + "state_default": 50, + "users": {}, + "users_default": 0 + }, + stateKey: ""); + expect(room.ownPowerLevel, 0); + expect(room.canBan, false); + expect(room.canInvite, false); + expect(room.canKick, false); + expect(room.canRedact, false); + expect(room.canSendDefaultMessages, true); + expect(room.canSendDefaultStates, false); + expect(room.canChangePowerLevel, false); + expect(room.canSendEvent("m.room.name"), true); + expect(room.canSendEvent("m.room.power_levels"), false); + expect(room.canSendEvent("m.room.member"), false); + expect(room.canSendEvent("m.room.message"), true); final dynamic resp = await room.setPower("@test:fakeServer.notExisting", 90); expect(resp["event_id"], "42");