Modified /join/$identifier to support $identifier being a room ID in addition to a room alias.

paul/schema_breaking_changes
Kegan Dougal 2014-08-27 09:43:42 +01:00
parent f84ddc75cb
commit dfa0cd1d90
3 changed files with 61 additions and 14 deletions

View File

@ -162,6 +162,8 @@ class Auth(object):
""" """
try: try:
user_id = yield self.store.get_user_by_token(token=token) user_id = yield self.store.get_user_by_token(token=token)
if not user_id:
raise StoreError()
defer.returnValue(self.hs.parse_userid(user_id)) defer.returnValue(self.hs.parse_userid(user_id))
except StoreError: except StoreError:
raise AuthError(403, "Unrecognised access token.", raise AuthError(403, "Unrecognised access token.",

View File

@ -18,10 +18,8 @@ from twisted.internet import defer
from base import RestServlet, client_path_pattern from base import RestServlet, client_path_pattern
from synapse.api.errors import SynapseError, Codes from synapse.api.errors import SynapseError, Codes
from synapse.api.events.room import ( from synapse.api.events.room import RoomMemberEvent
MessageEvent, RoomMemberEvent, FeedbackEvent from synapse.api.constants import Membership
)
from synapse.api.constants import Feedback
from synapse.api.streams import PaginationConfig from synapse.api.streams import PaginationConfig
import json import json
@ -210,24 +208,63 @@ class RoomSendEventRestServlet(RestServlet):
defer.returnValue(response) defer.returnValue(response)
# TODO: Needs unit testing for room ID + alias joins
class JoinRoomAliasServlet(RestServlet): class JoinRoomAliasServlet(RestServlet):
PATTERN = client_path_pattern("/join/(?P<room_alias>[^/]+)$")
def register(self, http_server):
# /join/$room_identifier[/$txn_id]
PATTERN = ("/join/(?P<room_identifier>[^/]*)")
register_txn_path(self, PATTERN, http_server)
@defer.inlineCallbacks @defer.inlineCallbacks
def on_PUT(self, request, room_alias): def on_POST(self, request, room_identifier):
user = yield self.auth.get_user_by_req(request) user = yield self.auth.get_user_by_req(request)
if not user: # the identifier could be a room alias or a room id. Try one then the
defer.returnValue((403, "Unrecognized user")) # other if it fails to parse, without swallowing other valid
# SynapseErrors.
logger.debug("room_alias: %s", room_alias) identifier = None
is_room_alias = False
try:
identifier = self.hs.parse_roomalias(
urllib.unquote(room_identifier)
)
is_room_alias = True
except SynapseError:
identifier = self.hs.parse_roomid(
urllib.unquote(room_identifier)
)
room_alias = self.hs.parse_roomalias(urllib.unquote(room_alias)) # TODO: Support for specifying the home server to join with?
handler = self.handlers.room_member_handler if is_room_alias:
ret_dict = yield handler.join_room_alias(user, room_alias) handler = self.handlers.room_member_handler
ret_dict = yield handler.join_room_alias(user, identifier)
defer.returnValue((200, ret_dict))
else: # room id
event = self.event_factory.create_event(
etype=RoomMemberEvent.TYPE,
content={"membership": Membership.JOIN},
room_id=urllib.unquote(identifier.to_string()),
user_id=user.to_string(),
state_key=user.to_string()
)
handler = self.handlers.room_member_handler
yield handler.change_membership(event)
defer.returnValue((200, ""))
defer.returnValue((200, ret_dict)) @defer.inlineCallbacks
def on_PUT(self, request, room_identifier, txn_id):
try:
defer.returnValue(self.txns.get_client_transaction(request, txn_id))
except KeyError:
pass
response = yield self.on_POST(request, room_identifier)
self.txns.store_client_transaction(request, txn_id, response)
defer.returnValue(response)
# TODO: Needs unit testing # TODO: Needs unit testing

View File

@ -28,7 +28,7 @@ from synapse.handlers import Handlers
from synapse.rest import RestServletFactory from synapse.rest import RestServletFactory
from synapse.state import StateHandler from synapse.state import StateHandler
from synapse.storage import DataStore from synapse.storage import DataStore
from synapse.types import UserID, RoomAlias from synapse.types import UserID, RoomAlias, RoomID
from synapse.util import Clock from synapse.util import Clock
from synapse.util.distributor import Distributor from synapse.util.distributor import Distributor
from synapse.util.lockutils import LockManager from synapse.util.lockutils import LockManager
@ -117,6 +117,9 @@ class BaseHomeServer(object):
setattr(BaseHomeServer, "get_%s" % (depname), _get) setattr(BaseHomeServer, "get_%s" % (depname), _get)
# TODO: Why are these parse_ methods so high up along with other globals?
# Surely these should be in a util package or in the api package?
# Other utility methods # Other utility methods
def parse_userid(self, s): def parse_userid(self, s):
"""Parse the string given by 's' as a User ID and return a UserID """Parse the string given by 's' as a User ID and return a UserID
@ -128,6 +131,11 @@ class BaseHomeServer(object):
object.""" object."""
return RoomAlias.from_string(s, hs=self) return RoomAlias.from_string(s, hs=self)
def parse_roomid(self, s):
"""Parse the string given by 's' as a Room ID and return a RoomID
object."""
return RoomID.from_string(s, hs=self)
# Build magic accessors for every dependency # Build magic accessors for every dependency
for depname in BaseHomeServer.DEPENDENCIES: for depname in BaseHomeServer.DEPENDENCIES:
BaseHomeServer._make_dependency_method(depname) BaseHomeServer._make_dependency_method(depname)