diff --git a/synapse/api/auth.py b/synapse/api/auth.py
index 9eb0491c97..462e97bd90 100644
--- a/synapse/api/auth.py
+++ b/synapse/api/auth.py
@@ -21,8 +21,8 @@ from synapse.api.constants import Membership, JoinRules
from synapse.api.errors import AuthError, StoreError, Codes, SynapseError
from synapse.api.events.room import (
RoomMemberEvent, RoomPowerLevelsEvent, RoomRedactionEvent,
- RoomJoinRulesEvent, RoomOpsPowerLevelsEvent, InviteJoinEvent,
- RoomCreateEvent, RoomSendEventLevelEvent, RoomAddStateLevelEvent,
+ RoomJoinRulesEvent, InviteJoinEvent,
+ RoomCreateEvent,
)
from synapse.util.logutils import log_function
@@ -51,6 +51,7 @@ class Auth(object):
if event.old_state_events is None:
# Oh, we don't know what the state of the room was, so we
# are trusting that this is allowed (at least for now)
+ logger.warn("Trusting event: %s", event.event_id)
return True
if hasattr(event, "outlier") and event.outlier is True:
@@ -64,7 +65,7 @@ class Auth(object):
return True
if event.type == RoomMemberEvent.TYPE:
- self._can_replace_state(event)
+ self._can_send_event(event)
allowed = self.is_membership_change_allowed(event)
if allowed:
logger.debug("Allowing! %s", event)
@@ -72,16 +73,7 @@ class Auth(object):
logger.debug("Denying! %s", event)
return allowed
- if not event.type == InviteJoinEvent.TYPE:
- self.check_event_sender_in_room(event)
-
- if is_state:
- # TODO (erikj): This really only should be called for *new*
- # state
- self._can_add_state(event)
- self._can_replace_state(event)
- else:
- self._can_send_event(event)
+ self._can_send_event(event)
if event.type == RoomPowerLevelsEvent.TYPE:
self._check_power_levels(event)
@@ -239,21 +231,21 @@ class Auth(object):
power_level_event = event.old_state_events.get(key)
level = None
if power_level_event:
- level = power_level_event.content.get(user_id)
+ level = power_level_event.content.get("users", {}).get(user_id)
if not level:
- level = power_level_event.content.get("default", 0)
+ level = power_level_event.content.get("users_default", 0)
return level
def _get_ops_level_from_event_state(self, event):
- key = (RoomOpsPowerLevelsEvent.TYPE, "", )
- ops_event = event.old_state_events.get(key)
+ key = (RoomPowerLevelsEvent.TYPE, "", )
+ power_level_event = event.old_state_events.get(key)
- if ops_event:
+ if power_level_event:
return (
- ops_event.content.get("ban_level"),
- ops_event.content.get("kick_level"),
- ops_event.content.get("redact_level"),
+ power_level_event.content.get("ban", 50),
+ power_level_event.content.get("kick", 50),
+ power_level_event.content.get("redact", 50),
)
return None, None, None,
@@ -325,13 +317,22 @@ class Auth(object):
@log_function
def _can_send_event(self, event):
- key = (RoomSendEventLevelEvent.TYPE, "", )
+ key = (RoomPowerLevelsEvent.TYPE, "", )
send_level_event = event.old_state_events.get(key)
send_level = None
if send_level_event:
- send_level = send_level_event.content.get(event.user_id)
+ send_level = send_level_event.content.get("events", {}).get(
+ event.type
+ )
if not send_level:
- send_level = send_level_event.content.get("level", 0)
+ if hasattr(event, "state_key"):
+ send_level = send_level_event.content.get(
+ "state_default", 50
+ )
+ else:
+ send_level = send_level_event.content.get(
+ "events_default", 0
+ )
if send_level:
send_level = int(send_level)
@@ -350,85 +351,21 @@ class Auth(object):
if user_level < send_level:
raise AuthError(
- 403, "You don't have permission to post to the room"
- )
-
- return True
-
- def _can_add_state(self, event):
- key = (RoomAddStateLevelEvent.TYPE, "", )
- add_level_event = event.old_state_events.get(key)
- add_level = None
- if add_level_event:
- add_level = add_level_event.content.get(event.user_id)
- if not add_level:
- add_level = add_level_event.content.get("level", 0)
-
- if add_level:
- add_level = int(add_level)
- else:
- add_level = 0
-
- user_level = self._get_power_level_from_event_state(
- event,
- event.user_id,
- )
-
- user_level = int(user_level)
-
- if user_level < add_level:
- raise AuthError(
- 403, "You don't have permission to add state to the room"
+ 403, "You don't have permission to post that to the room"
)
return True
- def _can_replace_state(self, event):
- user_level = self._get_power_level_from_event_state(
- event,
- event.user_id,
- )
-
- if user_level:
- user_level = int(user_level)
- else:
- user_level = 0
-
- logger.debug(
- "Checking power level for %s, %s", event.user_id, user_level
- )
-
- key = (event.type, event.state_key, )
- current_state = event.old_state_events.get(key)
-
- if current_state and hasattr(current_state, "required_power_level"):
- req = current_state.required_power_level
-
- logger.debug("Checked power level for %s, %s", event.user_id, req)
- if user_level < req:
- raise AuthError(
- 403,
- "You don't have permission to change that state"
- )
-
def _check_redaction(self, event):
user_level = self._get_power_level_from_event_state(
event,
event.user_id,
)
- if user_level:
- user_level = int(user_level)
- else:
- user_level = 0
-
_, _, redact_level = self._get_ops_level_from_event_state(
event
)
- if not redact_level:
- redact_level = 50
-
if user_level < redact_level:
raise AuthError(
403,
@@ -436,14 +373,9 @@ class Auth(object):
)
def _check_power_levels(self, event):
- for k, v in event.content.items():
- if k == "default":
- continue
-
- # FIXME (erikj): We don't want hsob_Ts in content.
- if k == "hsob_ts":
- continue
-
+ user_list = event.content.get("users", {})
+ # Validate users
+ for k, v in user_list.items():
try:
self.hs.parse_userid(k)
except:
@@ -459,72 +391,63 @@ class Auth(object):
if not current_state:
return
- else:
- current_state = current_state[0]
user_level = self._get_power_level_from_event_state(
event,
event.user_id,
)
- if user_level:
- user_level = int(user_level)
- else:
- user_level = 0
+ # Check other levels:
+ levels_to_check = [
+ ("users_default", []),
+ ("events_default", []),
+ ("ban", []),
+ ("redact", []),
+ ("kick", []),
+ ]
+
+ old_list = current_state.content.get("users")
+ for user in set(old_list.keys() + user_list.keys()):
+ levels_to_check.append(
+ (user, ["users"])
+ )
- old_list = current_state.content
+ old_list = current_state.content.get("events")
+ new_list = event.content.get("events")
+ for ev_id in set(old_list.keys() + new_list.keys()):
+ levels_to_check.append(
+ (ev_id, ["events"])
+ )
- # FIXME (erikj)
- old_people = {k: v for k, v in old_list.items() if k.startswith("@")}
- new_people = {
- k: v for k, v in event.content.items()
- if k.startswith("@")
- }
+ old_state = current_state.content
+ new_state = event.content
- removed = set(old_people.keys()) - set(new_people.keys())
- added = set(new_people.keys()) - set(old_people.keys())
- same = set(old_people.keys()) & set(new_people.keys())
+ for level_to_check, dir in levels_to_check:
+ old_loc = old_state
+ for d in dir:
+ old_loc = old_loc.get(d, {})
- for r in removed:
- if int(old_list[r]) > user_level:
- raise AuthError(
- 403,
- "You don't have permission to remove user: %s" % (r, )
- )
+ new_loc = new_state
+ for d in dir:
+ new_loc = new_loc.get(d, {})
- for n in added:
- if int(event.content[n]) > user_level:
- raise AuthError(
- 403,
- "You don't have permission to add ops level greater "
- "than your own"
- )
+ if level_to_check in old_loc:
+ old_level = int(old_loc[level_to_check])
+ else:
+ old_level = None
- for s in same:
- if int(event.content[s]) != int(old_list[s]):
- if int(event.content[s]) > user_level:
- raise AuthError(
- 403,
- "You don't have permission to add ops level greater "
- "than your own"
- )
+ if level_to_check in new_loc:
+ new_level = int(new_loc[level_to_check])
+ else:
+ new_level = None
- if "default" in old_list:
- old_default = int(old_list["default"])
+ if new_level is not None and old_level is not None:
+ if new_level == old_level:
+ continue
- if old_default > user_level:
+ if old_level > user_level or new_level > user_level:
raise AuthError(
403,
- "You don't have permission to add ops level greater than "
- "your own"
+ "You don't have permission to add ops level greater "
+ "than your own"
)
-
- if "default" in event.content:
- new_default = int(event.content["default"])
-
- if new_default > user_level:
- raise AuthError(
- 403,
- "You don't have permission to add ops level greater "
- "than your own"
- )
diff --git a/synapse/api/events/__init__.py b/synapse/api/events/__init__.py
index 98a66144e7..84d3a98365 100644
--- a/synapse/api/events/__init__.py
+++ b/synapse/api/events/__init__.py
@@ -56,12 +56,12 @@ class SynapseEvent(JsonEncodedObject):
"user_id", # sender/initiator
"content", # HTTP body, JSON
"state_key",
- "required_power_level",
"age_ts",
"prev_content",
"replaces_state",
"redacted_because",
"origin_server_ts",
+ "auth_chains",
]
internal_keys = [
@@ -70,7 +70,6 @@ class SynapseEvent(JsonEncodedObject):
"destinations",
"origin",
"outlier",
- "power_level",
"redacted",
"prev_events",
"hashes",
diff --git a/synapse/api/events/factory.py b/synapse/api/events/factory.py
index 9134c82eff..a1ec708a81 100644
--- a/synapse/api/events/factory.py
+++ b/synapse/api/events/factory.py
@@ -16,8 +16,8 @@
from synapse.api.events.room import (
RoomTopicEvent, MessageEvent, RoomMemberEvent, FeedbackEvent,
InviteJoinEvent, RoomConfigEvent, RoomNameEvent, GenericEvent,
- RoomPowerLevelsEvent, RoomJoinRulesEvent, RoomOpsPowerLevelsEvent,
- RoomCreateEvent, RoomAddStateLevelEvent, RoomSendEventLevelEvent,
+ RoomPowerLevelsEvent, RoomJoinRulesEvent,
+ RoomCreateEvent,
RoomRedactionEvent,
)
@@ -39,9 +39,6 @@ class EventFactory(object):
RoomPowerLevelsEvent,
RoomJoinRulesEvent,
RoomCreateEvent,
- RoomAddStateLevelEvent,
- RoomSendEventLevelEvent,
- RoomOpsPowerLevelsEvent,
RoomRedactionEvent,
]
diff --git a/synapse/api/events/room.py b/synapse/api/events/room.py
index cd936074fc..25bc883706 100644
--- a/synapse/api/events/room.py
+++ b/synapse/api/events/room.py
@@ -153,28 +153,6 @@ class RoomPowerLevelsEvent(SynapseStateEvent):
def get_content_template(self):
return {}
-
-class RoomAddStateLevelEvent(SynapseStateEvent):
- TYPE = "m.room.add_state_level"
-
- def get_content_template(self):
- return {}
-
-
-class RoomSendEventLevelEvent(SynapseStateEvent):
- TYPE = "m.room.send_event_level"
-
- def get_content_template(self):
- return {}
-
-
-class RoomOpsPowerLevelsEvent(SynapseStateEvent):
- TYPE = "m.room.ops_levels"
-
- def get_content_template(self):
- return {}
-
-
class RoomAliasesEvent(SynapseStateEvent):
TYPE = "m.room.aliases"
diff --git a/synapse/api/events/utils.py b/synapse/api/events/utils.py
index 31601fd3a9..5fc79105b5 100644
--- a/synapse/api/events/utils.py
+++ b/synapse/api/events/utils.py
@@ -15,7 +15,6 @@
from .room import (
RoomMemberEvent, RoomJoinRulesEvent, RoomPowerLevelsEvent,
- RoomAddStateLevelEvent, RoomSendEventLevelEvent, RoomOpsPowerLevelsEvent,
RoomAliasesEvent, RoomCreateEvent,
)
@@ -52,17 +51,17 @@ def _prune_event_or_pdu(event_type, event):
elif event_type == RoomJoinRulesEvent.TYPE:
add_fields("join_rule")
elif event_type == RoomPowerLevelsEvent.TYPE:
- # TODO: Actually check these are valid user_ids etc.
- add_fields("default")
- for k, v in event.content.items():
- if k.startswith("@") and isinstance(v, (int, long)):
- new_content[k] = v
- elif event_type == RoomAddStateLevelEvent.TYPE:
- add_fields("level")
- elif event_type == RoomSendEventLevelEvent.TYPE:
- add_fields("level")
- elif event_type == RoomOpsPowerLevelsEvent.TYPE:
- add_fields("kick_level", "ban_level", "redact_level")
+ add_fields(
+ "users",
+ "users_default",
+ "events",
+ "events_default",
+ "events_default",
+ "state_default",
+ "ban",
+ "kick",
+ "redact",
+ )
elif event_type == RoomAliasesEvent.TYPE:
add_fields("aliases")
|