Merge pull request #2118 from famedly/krille/matrix-security-predisclosure
Krille/matrix security predisclosure
This commit is contained in:
commit
026fd74352
|
|
@ -1930,13 +1930,41 @@ class Room {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the room version if specified in the `m.room.create` state event.
|
||||||
|
String? get roomVersion =>
|
||||||
|
getState(EventTypes.RoomCreate)?.content.tryGet<String>('room_version');
|
||||||
|
|
||||||
|
/// Returns the creator's user ID of the room by fetching the sender of the
|
||||||
|
/// `m.room.create` event.
|
||||||
|
Set<String> get creatorUserIds {
|
||||||
|
final creationEvent = getState(EventTypes.RoomCreate);
|
||||||
|
if (creationEvent == null) return {};
|
||||||
|
final additionalCreators =
|
||||||
|
creationEvent.content.tryGetList<String>('additional_creators') ?? [];
|
||||||
|
return {
|
||||||
|
creationEvent.senderId,
|
||||||
|
...additionalCreators,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the power level of the given user ID.
|
/// Returns the power level of the given user ID.
|
||||||
/// If a user_id is in the users list, then that user_id has the associated
|
/// If a user_id is in the users list, then that user_id has the associated
|
||||||
/// power level. Otherwise they have the default level users_default.
|
/// power level. Otherwise they have the default level users_default.
|
||||||
/// If users_default is not supplied, it is assumed to be 0. If the room
|
/// If users_default is not supplied, it is assumed to be 0. If the room
|
||||||
/// contains no m.room.power_levels event, the room’s creator has a power
|
/// contains no m.room.power_levels event, the room’s creator has a power
|
||||||
/// level of 100, and all other users have a power level of 0.
|
/// level of 100, and all other users have a power level of 0.
|
||||||
|
/// For room version 12 and above the room creator always has maximum
|
||||||
|
/// power level.
|
||||||
int getPowerLevelByUserId(String userId) {
|
int getPowerLevelByUserId(String userId) {
|
||||||
|
// Room creator has maximum power level:
|
||||||
|
if (creatorUserIds.contains(userId) &&
|
||||||
|
!((int.tryParse(roomVersion ?? '') ?? 0) < 12)) {
|
||||||
|
// 2^53 - 1 from https://spec.matrix.org/v1.15/appendices/#canonical-json
|
||||||
|
const maxInteger = 9007199254740991;
|
||||||
|
|
||||||
|
return maxInteger;
|
||||||
|
}
|
||||||
|
|
||||||
final powerLevelMap = getState(EventTypes.RoomPowerLevels)?.content;
|
final powerLevelMap = getState(EventTypes.RoomPowerLevels)?.content;
|
||||||
|
|
||||||
final userSpecificPowerLevel =
|
final userSpecificPowerLevel =
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,12 @@ extension MatrixIdExtension on String {
|
||||||
bool get isValidMatrixId {
|
bool get isValidMatrixId {
|
||||||
if (isEmpty) return false;
|
if (isEmpty) return false;
|
||||||
if (length > maxLength) return false;
|
if (length > maxLength) return false;
|
||||||
if (!validSigils.contains(substring(0, 1))) {
|
final sigil = substring(0, 1);
|
||||||
|
if (!validSigils.contains(sigil)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// event IDs do not have to have a domain
|
// event IDs and room IDs do not have to have a domain
|
||||||
if (substring(0, 1) == '\$') {
|
if ({'\$', '!'}.contains(sigil)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// all other matrix IDs have to have a domain
|
// all other matrix IDs have to have a domain
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,18 @@ void main() {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
room.setState(
|
||||||
|
Event(
|
||||||
|
content: {'room_version': '11'},
|
||||||
|
eventId: '\$143273582443PhrSn:example.org',
|
||||||
|
originServerTs: DateTime.fromMillisecondsSinceEpoch(1432735824653),
|
||||||
|
senderId: '@example:example.org',
|
||||||
|
type: 'm.room.create',
|
||||||
|
unsigned: {'age': 1234},
|
||||||
|
stateKey: '',
|
||||||
|
room: room,
|
||||||
|
),
|
||||||
|
);
|
||||||
room.setState(
|
room.setState(
|
||||||
Event(
|
Event(
|
||||||
room: room,
|
room: room,
|
||||||
|
|
@ -809,6 +821,17 @@ void main() {
|
||||||
expect(room.canSendEvent('m.room.message'), true);
|
expect(room.canSendEvent('m.room.message'), true);
|
||||||
final resp = await room.setPower('@test:fakeServer.notExisting', 0);
|
final resp = await room.setPower('@test:fakeServer.notExisting', 0);
|
||||||
expect(resp, '42');
|
expect(resp, '42');
|
||||||
|
|
||||||
|
// Creator has max power level from room version 12 on:
|
||||||
|
expect(room.creatorUserIds.contains('@example:example.org'), true);
|
||||||
|
expect(room.getPowerLevelByUserId('@example:example.org'), 0);
|
||||||
|
expect(room.roomVersion, '11');
|
||||||
|
room.states[EventTypes.RoomCreate]!['']!.content['room_version'] = '12';
|
||||||
|
expect(room.roomVersion, '12');
|
||||||
|
expect(
|
||||||
|
room.getPowerLevelByUserId('@example:example.org'),
|
||||||
|
9007199254740991,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('invite', () async {
|
test('invite', () async {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue