summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
Diffstat (limited to 'synapse')
-rw-r--r--synapse/api/auth.py25
-rwxr-xr-xsynapse/app/homeserver.py61
-rwxr-xr-xsynapse/app/synctl.py2
-rw-r--r--synapse/handlers/directory.py20
-rw-r--r--synapse/handlers/room.py67
-rw-r--r--synapse/rest/directory.py4
-rw-r--r--synapse/storage/directory.py24
7 files changed, 122 insertions, 81 deletions
diff --git a/synapse/api/auth.py b/synapse/api/auth.py
index 87f19a96d6..1a8785e890 100644
--- a/synapse/api/auth.py
+++ b/synapse/api/auth.py
@@ -21,7 +21,7 @@ from synapse.api.constants import Membership, JoinRules
 from synapse.api.errors import AuthError, StoreError, Codes, SynapseError
 from synapse.api.events.room import (
     RoomMemberEvent, RoomPowerLevelsEvent, RoomRedactionEvent,
-    RoomJoinRulesEvent, RoomCreateEvent,
+    RoomJoinRulesEvent, RoomCreateEvent, RoomAliasesEvent,
 )
 from synapse.util.logutils import log_function
 from syutil.base64util import encode_base64
@@ -63,6 +63,10 @@ class Auth(object):
                     # FIXME
                     return True
 
+                # FIXME: Temp hack
+                if event.type == RoomAliasesEvent.TYPE:
+                    return True
+
                 if event.type == RoomMemberEvent.TYPE:
                     allowed = self.is_membership_change_allowed(event)
                     if allowed:
@@ -144,6 +148,17 @@ class Auth(object):
 
     @log_function
     def is_membership_change_allowed(self, event):
+        membership = event.content["membership"]
+
+        # Check if this is the room creator joining:
+        if len(event.prev_events) == 1 and Membership.JOIN == membership:
+            # Get room creation event:
+            key = (RoomCreateEvent.TYPE, "", )
+            create = event.old_state_events.get(key)
+            if event.prev_events[0][0] == create.event_id:
+                if create.content["creator"] == event.state_key:
+                    return True
+
         target_user_id = event.state_key
 
         # get info about the caller
@@ -159,8 +174,6 @@ class Auth(object):
 
         target_in_room = target and target.membership == Membership.JOIN
 
-        membership = event.content["membership"]
-
         key = (RoomJoinRulesEvent.TYPE, "", )
         join_rule_event = event.old_state_events.get(key)
         if join_rule_event:
@@ -255,6 +268,12 @@ class Auth(object):
             level = power_level_event.content.get("users", {}).get(user_id)
             if not level:
                 level = power_level_event.content.get("users_default", 0)
+        else:
+            key = (RoomCreateEvent.TYPE, "", )
+            create_event = event.old_state_events.get(key)
+            if (create_event is not None and
+                create_event.content["creator"] == user_id):
+                return 100
 
         return level
 
diff --git a/synapse/app/homeserver.py b/synapse/app/homeserver.py
index 85284a4919..53ca1f8f51 100755
--- a/synapse/app/homeserver.py
+++ b/synapse/app/homeserver.py
@@ -184,15 +184,7 @@ class SynapseHomeServer(HomeServer):
             logger.info("Synapse now listening on port %d", unsecure_port)
 
 
-def setup():
-    config = HomeServerConfig.load_config(
-        "Synapse Homeserver",
-        sys.argv[1:],
-        generate_section="Homeserver"
-    )
-
-    config.setup_logging()
-
+def setup(config, run_http=True):
     logger.info("Server hostname: %s", config.server_name)
 
     if re.search(":[0-9]+$", config.server_name):
@@ -212,12 +204,13 @@ def setup():
         content_addr=config.content_addr,
     )
 
-    hs.register_servlets()
+    if run_http:
+        hs.register_servlets()
 
-    hs.create_resource_tree(
-        web_client=config.webclient,
-        redirect_root_to_web_client=True,
-    )
+        hs.create_resource_tree(
+            web_client=config.webclient,
+            redirect_root_to_web_client=True,
+        )
 
     db_name = hs.get_db_name()
 
@@ -237,11 +230,18 @@ def setup():
         f.namespace['hs'] = hs
         reactor.listenTCP(config.manhole, f, interface='127.0.0.1')
 
-    bind_port = config.bind_port
-    if config.no_tls:
-        bind_port = None
-    hs.start_listening(bind_port, config.unsecure_port)
+    if run_http:
+        bind_port = config.bind_port
+        if config.no_tls:
+            bind_port = None
+        hs.start_listening(bind_port, config.unsecure_port)
+
+    hs.config = config
+
+    return hs
+
 
+def run(config):
     if config.daemonize:
         print config.pid_file
         daemon = Daemonize(
@@ -257,13 +257,26 @@ def setup():
     else:
         reactor.run()
 
-def run():
-    with LoggingContext("run"):
-        reactor.run()
 
-def main():
+def main(args, run_http=True):
     with LoggingContext("main"):
-        setup()
+        config = HomeServerConfig.load_config(
+            "Synapse Homeserver",
+            args,
+            generate_section="Homeserver"
+        )
+
+        config.setup_logging()
+
+        hs = setup(config, run_http=run_http)
+
+        def r():
+            run(config)
+        hs.run = r
+
+        return hs
+
 
 if __name__ == '__main__':
-    main()
+    hs = main(sys.argv[1:])
+    hs.run()
diff --git a/synapse/app/synctl.py b/synapse/app/synctl.py
index e85073b06b..abe055a64c 100755
--- a/synapse/app/synctl.py
+++ b/synapse/app/synctl.py
@@ -56,8 +56,8 @@ def main():
     elif action == "stop":
         stop()
     elif action == "restart":
-        start()
         stop()
+        start()
     else:
         sys.stderr.write("Usage: %s [start|stop|restart]\n" % (sys.argv[0],))
         sys.exit(1)
diff --git a/synapse/handlers/directory.py b/synapse/handlers/directory.py
index 164363cdc5..98ac0684fc 100644
--- a/synapse/handlers/directory.py
+++ b/synapse/handlers/directory.py
@@ -21,8 +21,6 @@ from synapse.api.errors import SynapseError
 from synapse.api.events.room import RoomAliasesEvent
 
 import logging
-import sqlite3
-
 
 logger = logging.getLogger(__name__)
 
@@ -56,17 +54,11 @@ class DirectoryHandler(BaseHandler):
         if not servers:
             raise SynapseError(400, "Failed to get server list")
 
-        try:
-            yield self.store.create_room_alias_association(
-                room_alias,
-                room_id,
-                servers
-            )
-        except sqlite3.IntegrityError:
-            defer.returnValue("Already exists")
-
-        # TODO: Send the room event.
-        yield self._update_room_alias_events(user_id, room_id)
+        yield self.store.create_room_alias_association(
+            room_alias,
+            room_id,
+            servers
+        )
 
     @defer.inlineCallbacks
     def delete_association(self, user_id, room_alias):
@@ -136,7 +128,7 @@ class DirectoryHandler(BaseHandler):
         })
 
     @defer.inlineCallbacks
-    def _update_room_alias_events(self, user_id, room_id):
+    def send_room_alias_update_event(self, user_id, room_id):
         aliases = yield self.store.get_aliases_for_room(room_id)
 
         event = self.event_factory.create_event(
diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py
index cfe1061ed3..d09743ed1b 100644
--- a/synapse/handlers/room.py
+++ b/synapse/handlers/room.py
@@ -106,20 +106,37 @@ class RoomCreationHandler(BaseHandler):
             if not room_id:
                 raise StoreError(500, "Couldn't generate a room ID.")
 
+        if room_alias:
+            directory_handler = self.hs.get_handlers().directory_handler
+            yield directory_handler.create_association(
+                user_id=user_id,
+                room_id=room_id,
+                room_alias=room_alias,
+                servers=[self.hs.hostname],
+            )
+
         user = self.hs.parse_userid(user_id)
         creation_events = self._create_events_for_new_room(
             user, room_id, is_public=is_public
         )
 
+        room_member_handler = self.hs.get_handlers().room_member_handler
+
         @defer.inlineCallbacks
         def handle_event(event):
             snapshot = yield self.store.snapshot_room(event)
 
             logger.debug("Event: %s", event)
 
-            yield self._on_new_room_event(
-                event, snapshot, extra_users=[user], suppress_auth=True
-            )
+            if event.type == RoomMemberEvent.TYPE:
+                yield room_member_handler.change_membership(
+                    event,
+                    do_auth=True
+                )
+            else:
+                yield self._on_new_room_event(
+                    event, snapshot, extra_users=[user], suppress_auth=True
+                )
 
         for event in creation_events:
             yield handle_event(event)
@@ -146,16 +163,6 @@ class RoomCreationHandler(BaseHandler):
 
             yield handle_event(topic_event)
 
-        content = {"membership": Membership.JOIN}
-        join_event = self.event_factory.create_event(
-            etype=RoomMemberEvent.TYPE,
-            state_key=user_id,
-            room_id=room_id,
-            user_id=user_id,
-            membership=Membership.JOIN,
-            content=content
-        )
-
         content = {"membership": Membership.INVITE}
         for invitee in invite_list:
             invite_event = self.event_factory.create_event(
@@ -165,35 +172,22 @@ class RoomCreationHandler(BaseHandler):
                 user_id=user_id,
                 content=content
             )
-
-            yield self.hs.get_handlers().room_member_handler.change_membership(
-                invite_event,
-                do_auth=False
-            )
-
-        yield self.hs.get_handlers().room_member_handler.change_membership(
-            join_event,
-            do_auth=False
-        )
+            yield handle_event(invite_event)
 
         result = {"room_id": room_id}
 
         if room_alias:
             result["room_alias"] = room_alias.to_string()
-            directory_handler = self.hs.get_handlers().directory_handler
-            yield directory_handler.create_association(
-                user_id=user_id,
-                room_id=room_id,
-                room_alias=room_alias,
-                servers=[self.hs.hostname],
-            )
+            directory_handler.send_room_alias_update_event(user_id, room_id)
 
         defer.returnValue(result)
 
     def _create_events_for_new_room(self, creator, room_id, is_public=False):
+        creator_id = creator.to_string()
+
         event_keys = {
             "room_id": room_id,
-            "user_id": creator.to_string(),
+            "user_id": creator_id,
         }
 
         def create(etype, **content):
@@ -208,6 +202,16 @@ class RoomCreationHandler(BaseHandler):
             creator=creator.to_string(),
         )
 
+        join_event = self.event_factory.create_event(
+            etype=RoomMemberEvent.TYPE,
+            state_key=creator_id,
+            content={
+                "membership": Membership.JOIN,
+            },
+            **event_keys
+        )
+
+
         power_levels_event = self.event_factory.create_event(
             etype=RoomPowerLevelsEvent.TYPE,
             content={
@@ -236,6 +240,7 @@ class RoomCreationHandler(BaseHandler):
 
         return [
             creation_event,
+            join_event,
             power_levels_event,
             join_rules_event,
         ]
diff --git a/synapse/rest/directory.py b/synapse/rest/directory.py
index 6c260e7102..5aaac05e28 100644
--- a/synapse/rest/directory.py
+++ b/synapse/rest/directory.py
@@ -70,9 +70,11 @@ class ClientDirectoryServer(RestServlet):
         dir_handler = self.handlers.directory_handler
 
         try:
+            user_id = user.to_string()
             yield dir_handler.create_association(
-                user.to_string(), room_alias, room_id, servers
+                user_id, room_alias, room_id, servers
             )
+            yield dir_handler.send_room_alias_update_event(user_id, room_id)
         except SynapseError as e:
             raise e
         except:
diff --git a/synapse/storage/directory.py b/synapse/storage/directory.py
index d6a7113b9c..2be9c41374 100644
--- a/synapse/storage/directory.py
+++ b/synapse/storage/directory.py
@@ -14,10 +14,15 @@
 # limitations under the License.
 
 from ._base import SQLBaseStore
+
+from synapse.api.errors import SynapseError
+
 from twisted.internet import defer
 
 from collections import namedtuple
 
+import sqlite3
+
 
 RoomAliasMapping = namedtuple(
     "RoomAliasMapping",
@@ -75,13 +80,18 @@ class DirectoryStore(SQLBaseStore):
         Returns:
             Deferred
         """
-        yield self._simple_insert(
-            "room_aliases",
-            {
-                "room_alias": room_alias.to_string(),
-                "room_id": room_id,
-            },
-        )
+        try:
+            yield self._simple_insert(
+                "room_aliases",
+                {
+                    "room_alias": room_alias.to_string(),
+                    "room_id": room_id,
+                },
+            )
+        except sqlite3.IntegrityError:
+            raise SynapseError(
+                409, "Room alias %s already exists" % room_alias.to_string()
+            )
 
         for server in servers:
             # TODO(erikj): Fix this to bulk insert