Add all the necessary checks to make banning work.
This commit is contained in:
parent
3faa2ae78c
commit
b8ab9f1c0a
|
@ -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):
|
||||||
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):
|
||||||
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):
|
||||||
)
|
)
|
||||||
|
|
||||||
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):
|
||||||
"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):
|
||||||
"destinations",
|
"destinations",
|
||||||
"origin",
|
"origin",
|
||||||
"outlier",
|
"outlier",
|
||||||
|
"power_level",
|
||||||
]
|
]
|
||||||
|
|
||||||
required_keys = [
|
required_keys = [
|
||||||
|
|
|
@ -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):
|
||||||
|
|
||||||
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):
|
||||||
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):
|
||||||
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(
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue