SYN-12: Implement auth for deletion by adding a 'delete_level' on the ops levels event

SYN-12 # comment Auth has been added.
This commit is contained in:
Erik Johnston 2014-09-23 17:36:17 +01:00
parent 932b376b4e
commit bc250a6afa
4 changed files with 43 additions and 6 deletions

View File

@ -19,7 +19,9 @@ from twisted.internet import defer
from synapse.api.constants import Membership, JoinRules from synapse.api.constants import Membership, JoinRules
from synapse.api.errors import AuthError, StoreError, Codes, SynapseError from synapse.api.errors import AuthError, StoreError, Codes, SynapseError
from synapse.api.events.room import RoomMemberEvent, RoomPowerLevelsEvent from synapse.api.events.room import (
RoomMemberEvent, RoomPowerLevelsEvent, RoomDeletionEvent,
)
from synapse.util.logutils import log_function from synapse.util.logutils import log_function
import logging import logging
@ -70,6 +72,9 @@ class Auth(object):
if event.type == RoomPowerLevelsEvent.TYPE: if event.type == RoomPowerLevelsEvent.TYPE:
yield self._check_power_levels(event) yield self._check_power_levels(event)
if event.type == RoomDeletionEvent.TYPE:
yield self._check_deletion(event)
defer.returnValue(True) defer.returnValue(True)
else: else:
raise AuthError(500, "Unknown event: %s" % event) raise AuthError(500, "Unknown event: %s" % event)
@ -170,7 +175,7 @@ class Auth(object):
event.room_id, event.room_id,
event.user_id, event.user_id,
) )
_, kick_level = yield self.store.get_ops_levels(event.room_id) _, kick_level, _ = yield self.store.get_ops_levels(event.room_id)
if kick_level: if kick_level:
kick_level = int(kick_level) kick_level = int(kick_level)
@ -187,7 +192,7 @@ class Auth(object):
event.user_id, event.user_id,
) )
ban_level, _ = yield self.store.get_ops_levels(event.room_id) ban_level, _, _ = yield self.store.get_ops_levels(event.room_id)
if ban_level: if ban_level:
ban_level = int(ban_level) ban_level = int(ban_level)
@ -321,6 +326,29 @@ class Auth(object):
"You don't have permission to change that state" "You don't have permission to change that state"
) )
@defer.inlineCallbacks
def _check_deletion(self, event):
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
_, _, delete_level = yield self.store.get_ops_levels(event.room_id)
if not delete_level:
delete_level = 50
if user_level < delete_level:
raise AuthError(
403,
"You don't have permission to delete events"
)
@defer.inlineCallbacks @defer.inlineCallbacks
def _check_power_levels(self, event): def _check_power_levels(self, event):
for k, v in event.content.items(): for k, v in event.content.items():

View File

@ -255,6 +255,7 @@ class RoomCreationHandler(BaseHandler):
etype=RoomOpsPowerLevelsEvent.TYPE, etype=RoomOpsPowerLevelsEvent.TYPE,
ban_level=50, ban_level=50,
kick_level=50, kick_level=50,
delete_level=50,
) )
return [ return [

View File

@ -27,7 +27,7 @@ import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
OpsLevel = collections.namedtuple("OpsLevel", ("ban_level", "kick_level")) OpsLevel = collections.namedtuple("OpsLevel", ("ban_level", "kick_level", "delete_level"))
class RoomStore(SQLBaseStore): class RoomStore(SQLBaseStore):
@ -189,7 +189,8 @@ class RoomStore(SQLBaseStore):
def _get_ops_levels(self, txn, room_id): def _get_ops_levels(self, txn, room_id):
sql = ( sql = (
"SELECT ban_level, kick_level FROM room_ops_levels as r " "SELECT ban_level, kick_level, delete_level "
"FROM room_ops_levels as r "
"INNER JOIN current_state_events as c " "INNER JOIN current_state_events as c "
"ON r.event_id = c.event_id " "ON r.event_id = c.event_id "
"WHERE c.room_id = ? " "WHERE c.room_id = ? "
@ -198,7 +199,7 @@ class RoomStore(SQLBaseStore):
rows = txn.execute(sql, (room_id,)).fetchall() rows = txn.execute(sql, (room_id,)).fetchall()
if len(rows) == 1: if len(rows) == 1:
return OpsLevel(rows[0][0], rows[0][1]) return OpsLevel(rows[0][0], rows[0][1], rows[0][2])
else: else:
return OpsLevel(None, None) return OpsLevel(None, None)
@ -326,6 +327,9 @@ class RoomStore(SQLBaseStore):
if "ban_level" in event.content: if "ban_level" in event.content:
content["ban_level"] = event.content["ban_level"] content["ban_level"] = event.content["ban_level"]
if "delete_level" in event.content:
content["delete_level"] = event.content["delete_level"]
self._simple_insert_txn( self._simple_insert_txn(
txn, txn,
"room_ops_levels", "room_ops_levels",

View File

@ -5,3 +5,7 @@ CREATE TABLE IF NOT EXISTS deletions (
CREATE INDEX IF NOT EXISTS deletions_event_id ON deletions (event_id); CREATE INDEX IF NOT EXISTS deletions_event_id ON deletions (event_id);
CREATE INDEX IF NOT EXISTS deletions_deletes ON deletions (deletes); CREATE INDEX IF NOT EXISTS deletions_deletes ON deletions (deletes);
ALTER TABLE room_ops_levels ADD COLUMN delete_level INTEGER;
PRAGMA user_version = 4;