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
|