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

Add published room list edit API #657

Merged
merged 3 commits into from
Mar 22, 2016
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
)
16 changes: 16 additions & 0 deletions synapse/handlers/directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,3 +317,19 @@ 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):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add some doc string

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