Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #657 from matrix-org/erikj/roomlist
Browse files Browse the repository at this point in the history
Add published room list edit API
  • Loading branch information
erikjohnston committed Mar 22, 2016
2 parents 63137bb + 97785bf commit d6ac752
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 4 deletions.
54 changes: 50 additions & 4 deletions synapse/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,17 +814,16 @@ def compute_auth_events(self, event, current_state):

return auth_ids

@log_function
def _can_send_event(self, event, auth_events):
def _get_send_level(self, etype, state_key, auth_events):
key = (EventTypes.PowerLevels, "", )
send_level_event = auth_events.get(key)
send_level = None
if send_level_event:
send_level = send_level_event.content.get("events", {}).get(
event.type
etype
)
if send_level is None:
if hasattr(event, "state_key"):
if state_key is not None:
send_level = send_level_event.content.get(
"state_default", 50
)
Expand All @@ -838,6 +837,13 @@ def _can_send_event(self, event, auth_events):
else:
send_level = 0

return send_level

@log_function
def _can_send_event(self, event, auth_events):
send_level = self._get_send_level(
event.type, event.get("state_key", None), auth_events
)
user_level = self._get_user_power_level(event.user_id, auth_events)

if user_level < send_level:
Expand Down Expand Up @@ -982,3 +988,43 @@ def _check_power_levels(self, event, auth_events):
"You don't have permission to add ops level greater "
"than your own"
)

@defer.inlineCallbacks
def check_can_change_room_list(self, room_id, user):
"""Check if the user is allowed to edit the room's entry in the
published room list.
Args:
room_id (str)
user (UserID)
"""

is_admin = yield self.is_server_admin(user)
if is_admin:
defer.returnValue(True)

user_id = user.to_string()
yield self.check_joined_room(room_id, user_id)

# We currently require the user is a "moderator" in the room. We do this
# by checking if they would (theoretically) be able to change the
# m.room.aliases events
power_level_event = yield self.state.get_current_state(
room_id, EventTypes.PowerLevels, ""
)

auth_events = {}
if power_level_event:
auth_events[(EventTypes.PowerLevels, "")] = power_level_event

send_level = self._get_send_level(
EventTypes.Aliases, "", auth_events
)
user_level = self._get_user_power_level(user_id, auth_events)

if user_level < send_level:
raise AuthError(
403,
"This server requires you to be a moderator in the room to"
" edit its room list entry"
)
22 changes: 22 additions & 0 deletions synapse/handlers/directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,25 @@ def _user_can_delete_alias(self, alias, user_id):

is_admin = yield self.auth.is_server_admin(UserID.from_string(user_id))
defer.returnValue(is_admin)

@defer.inlineCallbacks
def edit_published_room_list(self, requester, room_id, visibility):
"""Edit the entry of the room in the published room list.
requester
room_id (str)
visibility (str): "public" or "private"
"""
if requester.is_guest:
raise AuthError(403, "Guests cannot edit the published room list")

if visibility not in ["public", "private"]:
raise SynapseError(400, "Invalid visibility setting")

room = yield self.store.get_room(room_id)
if room is None:
raise SynapseError(400, "Unknown room")

yield self.auth.check_can_change_room_list(room_id, requester.user)

yield self.store.set_room_is_public(room_id, visibility == "public")
42 changes: 42 additions & 0 deletions synapse/rest/client/v1/directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

def register_servlets(hs, http_server):
ClientDirectoryServer(hs).register(http_server)
ClientDirectoryListServer(hs).register(http_server)


class ClientDirectoryServer(ClientV1RestServlet):
Expand Down Expand Up @@ -137,3 +138,44 @@ def on_DELETE(self, request, room_alias):
)

defer.returnValue((200, {}))


class ClientDirectoryListServer(ClientV1RestServlet):
PATTERNS = client_path_patterns("/directory/list/room/(?P<room_id>[^/]*)$")

def __init__(self, hs):
super(ClientDirectoryListServer, self).__init__(hs)
self.store = hs.get_datastore()

@defer.inlineCallbacks
def on_GET(self, request, room_id):
room = yield self.store.get_room(room_id)
if room is None:
raise SynapseError(400, "Unknown room")

defer.returnValue((200, {
"visibility": "public" if room["is_public"] else "private"
}))

@defer.inlineCallbacks
def on_PUT(self, request, room_id):
requester = yield self.auth.get_user_by_req(request)

content = parse_json_object_from_request(request)
visibility = content.get("visibility", "public")

yield self.handlers.directory_handler.edit_published_room_list(
requester, room_id, visibility,
)

defer.returnValue((200, {}))

@defer.inlineCallbacks
def on_DELETE(self, request, room_id):
requester = yield self.auth.get_user_by_req(request)

yield self.handlers.directory_handler.edit_published_room_list(
requester, room_id, "private",
)

defer.returnValue((200, {}))
8 changes: 8 additions & 0 deletions synapse/storage/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ def get_room(self, room_id):
allow_none=True,
)

def set_room_is_public(self, room_id, is_public):
return self._simple_update_one(
table="rooms",
keyvalues={"room_id": room_id},
updatevalues={"is_public": is_public},
desc="set_room_is_public",
)

def get_public_room_ids(self):
return self._simple_select_onecol(
table="rooms",
Expand Down

0 comments on commit d6ac752

Please sign in to comment.