Skip to content
Snippets Groups Projects
Commit b8ab9f1c authored by Erik Johnston's avatar Erik Johnston
Browse files

Add all the necessary checks to make banning work.

parent 3faa2ae7
No related branches found
No related tags found
No related merge requests found
...@@ -45,7 +45,10 @@ class Auth(object): ...@@ -45,7 +45,10 @@ class Auth(object):
""" """
try: try:
if hasattr(event, "room_id"): if hasattr(event, "room_id"):
is_state = hasattr(event, "state_key")
if event.type == RoomMemberEvent.TYPE: if event.type == RoomMemberEvent.TYPE:
yield self._can_replace_state(event)
allowed = yield self.is_membership_change_allowed(event) allowed = yield self.is_membership_change_allowed(event)
defer.returnValue(allowed) defer.returnValue(allowed)
return return
...@@ -56,10 +59,11 @@ class Auth(object): ...@@ -56,10 +59,11 @@ class Auth(object):
room_id=snapshot.room_id, room_id=snapshot.room_id,
) )
if hasattr(event, "state_key"): if is_state:
# TODO (erikj): This really only should be called for *new* # TODO (erikj): This really only should be called for *new*
# state # state
yield self._can_add_state(event) yield self._can_add_state(event)
yield self._can_replace_state(event)
else: else:
yield self._can_send_event(event) yield self._can_send_event(event)
...@@ -175,7 +179,7 @@ class Auth(object): ...@@ -175,7 +179,7 @@ class Auth(object):
else: else:
ban_level = 5 # FIXME (erikj): What should we do here? ban_level = 5 # FIXME (erikj): What should we do here?
if ban_level < user_level: if user_level < ban_level:
raise AuthError(403, "You don't have permission to ban") raise AuthError(403, "You don't have permission to ban")
else: else:
raise AuthError(500, "Unknown membership %s" % membership) raise AuthError(500, "Unknown membership %s" % membership)
...@@ -267,3 +271,35 @@ class Auth(object): ...@@ -267,3 +271,35 @@ class Auth(object):
) )
defer.returnValue(True) defer.returnValue(True)
@defer.inlineCallbacks
def _can_replace_state(self, event):
current_state = yield self.store.get_current_state(
event.room_id,
event.type,
event.state_key,
)
if current_state:
current_state = current_state[0]
user_level = yield self.store.get_power_level(
event.room_id,
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)
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"
)
...@@ -42,6 +42,7 @@ class SynapseEvent(JsonEncodedObject): ...@@ -42,6 +42,7 @@ class SynapseEvent(JsonEncodedObject):
"user_id", # sender/initiator "user_id", # sender/initiator
"content", # HTTP body, JSON "content", # HTTP body, JSON
"state_key", "state_key",
"required_power_level",
] ]
internal_keys = [ internal_keys = [
...@@ -52,6 +53,7 @@ class SynapseEvent(JsonEncodedObject): ...@@ -52,6 +53,7 @@ class SynapseEvent(JsonEncodedObject):
"destinations", "destinations",
"origin", "origin",
"outlier", "outlier",
"power_level",
] ]
required_keys = [ required_keys = [
......
...@@ -68,6 +68,7 @@ class Pdu(JsonEncodedObject): ...@@ -68,6 +68,7 @@ class Pdu(JsonEncodedObject):
"power_level", "power_level",
"prev_state_id", "prev_state_id",
"prev_state_origin", "prev_state_origin",
"required_power_level",
] ]
internal_keys = [ internal_keys = [
......
...@@ -166,7 +166,7 @@ class RoomCreationHandler(BaseRoomHandler): ...@@ -166,7 +166,7 @@ class RoomCreationHandler(BaseRoomHandler):
power_levels_event = create( power_levels_event = create(
etype=RoomPowerLevelsEvent.TYPE, etype=RoomPowerLevelsEvent.TYPE,
**{creator.to_string(): 10} **{creator.to_string(): 10, "default": 0}
) )
join_rule = JoinRules.PUBLIC if is_public else JoinRules.INVITE join_rule = JoinRules.PUBLIC if is_public else JoinRules.INVITE
...@@ -343,6 +343,16 @@ class RoomMemberHandler(BaseRoomHandler): ...@@ -343,6 +343,16 @@ class RoomMemberHandler(BaseRoomHandler):
if do_auth: if do_auth:
yield self.auth.check(event, snapshot, raises=True) yield self.auth.check(event, snapshot, raises=True)
# If we're banning someone, set a req power level
if event.membership == Membership.BAN:
if not hasattr(event, "required_power_level") or event.required_power_level is None:
# Add some default required_power_level
user_level = yield self.store.get_power_level(
event.room_id,
event.user_id,
)
event.required_power_level = user_level
if prev_state and prev_state.membership == event.membership: if prev_state and prev_state.membership == event.membership:
# double same action, treat this event as a NOOP. # double same action, treat this event as a NOOP.
defer.returnValue({}) defer.returnValue({})
......
...@@ -165,8 +165,7 @@ class RoomStore(SQLBaseStore): ...@@ -165,8 +165,7 @@ class RoomStore(SQLBaseStore):
rows = txn.execute(sql, (room_id, user_id,)).fetchall() rows = txn.execute(sql, (room_id, user_id,)).fetchall()
if len(rows) == 1: if len(rows) == 1:
defer.returnValue(rows[0][0]) return rows[0][0]
return
sql = ( sql = (
"SELECT level FROM room_default_levels as r " "SELECT level FROM room_default_levels as r "
......
...@@ -150,7 +150,7 @@ CREATE TABLE IF NOT EXISTS room_ops_levels( ...@@ -150,7 +150,7 @@ CREATE TABLE IF NOT EXISTS room_ops_levels(
event_id TEXT NOT NULL, event_id TEXT NOT NULL,
room_id TEXT NOT NULL, room_id TEXT NOT NULL,
ban_level INTEGER, ban_level INTEGER,
kick_level INTEGER, kick_level INTEGER
); );
CREATE INDEX IF NOT EXISTS room_ops_levels_event_id ON room_ops_levels(event_id); CREATE INDEX IF NOT EXISTS room_ops_levels_event_id ON room_ops_levels(event_id);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment