-
Notifications
You must be signed in to change notification settings - Fork 385
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
MSC3667: Enforce integer power levels #3667
Changes from all commits
cd85016
fb65ed0
feb6b92
9c5ae82
2087c4d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,42 @@ | ||||||||||||||||||||||||||
# MSC3667: Enforce integer power levels | ||||||||||||||||||||||||||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
The spec defines power levels in `m.room.power_levels` events as integers, but due to legacy | ||||||||||||||||||||||||||
behaviour in Synapse, string power levels are also accepted and parsed. The string parsing itself | ||||||||||||||||||||||||||
Comment on lines
+3
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This first sentence is a little confusing. String power levels are not accepted by the spec - but in practice are often accepted by homeserver implementations as not doing so would break existing rooms. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spec PR #3688 will formally allow today's behaviour into the spec for all room versions up to and including version 9, since this issue was still not yet fixed in Synapse. That will allow us and future implementations to preserve compatibility with existing rooms. This MSC, on the other hand, will fix the problem in future room versions (hopefully from room version 10). |
||||||||||||||||||||||||||
is problematic because it is done using Python's [int()](https://docs.python.org/3/library/functions.html#int) | ||||||||||||||||||||||||||
function, which has all sorts of associated behaviours: | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
> If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance | ||||||||||||||||||||||||||
> representing an integer literal in radix base. Optionally, the literal can be preceded by + or - | ||||||||||||||||||||||||||
> (with no space in between) and surrounded by whitespace. A base-n literal consists of the digits 0 | ||||||||||||||||||||||||||
> to n-1, with a to z (or A to Z) having values 10 to 35. The default base is 10. The allowed values | ||||||||||||||||||||||||||
> are 0 and 2–36. Base-2, -8, and -16 literals can be optionally prefixed with 0b/0B, 0o/0O, or 0x/0X, | ||||||||||||||||||||||||||
> as with integer literals in code. Base 0 means to interpret exactly as a code literal, so that the | ||||||||||||||||||||||||||
> actual base is 2, 8, 10, or 16, and so that int('010', 0) is not legal, while int('010') is, as | ||||||||||||||||||||||||||
> well as int('010', 8). | ||||||||||||||||||||||||||
Comment on lines
+8
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. most of this isn't relevant as it requires an explicit base.
Suggested change
(notably, all the prefixes here are not valid) |
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
All of this behaviour is exceptionally difficult for non-Python implementations to reproduce | ||||||||||||||||||||||||||
accurately. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
## Proposal | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
In a future room version, we should enforce the letter of the spec and only allow power levels | ||||||||||||||||||||||||||
as integers within the range defined by canonical JSON and reject events which try to define them as any other type. This removes all of the | ||||||||||||||||||||||||||
associated headaches with string parsing. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
## Potential issues | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
We can't avoid the string parsing behaviour altogether because we need to continue to do so for | ||||||||||||||||||||||||||
existing room versions so that we do not break existing rooms. However, there are already documented | ||||||||||||||||||||||||||
cases of this causing problems across implementations. For example, Synapse will accept `" +2 "` as | ||||||||||||||||||||||||||
a power level but Dendrite will outright fail to parse it. | ||||||||||||||||||||||||||
Comment on lines
+28
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be good to have a line here explicitly stating that: as a result, homeserver implementations may need to update their existing room version implementations to remain compatible with the spec. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is my hope that the wording in #3688 will be sufficient to cover what implementations should do today and then this MSC can focus on what we do to plug the hole going forward. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (directionally, I think it's best to work on this MSC and that spec PR almost concurrently: the MSC can make reference to what the spec intended to say, as we know we'd accept a clarification about how stringy power levels work, and the spec PR can either continue working on inclusion or wait for this MSC to land and be assigned a room version) |
||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
## Alternatives | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
Event schema enforcement for all event types used in event auth could solve this problem and | ||||||||||||||||||||||||||
more but is a significantly bigger task. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
## Unstable prefix | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
An implementation exists in Dendrite using the `org.matrix.msc3667` room version identifier. The | ||||||||||||||||||||||||||
experimental room version is based on room version 7, with the additional requirement that power | ||||||||||||||||||||||||||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||
levels must be integers or the power level content will fail to unmarshal altogether. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to pre-empt some potential discussion: other event types, like join rules, aren't really subject to the same nuances that integer-based power levels are. As a power event itself in state res v2, the power levels are critical for determining whether or not a user can do something - the same issue can theoretically arise from incorrect membership or join rule, however the handling of those two events is targeted at the specific enum values whereas power levels are a range.