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

Commit

Permalink
Merge branch 'release-v0.8.1' of github.com:matrix-org/synapse
Browse files Browse the repository at this point in the history
  • Loading branch information
erikjohnston committed Mar 19, 2015
2 parents d517406 + 0a55a2b commit d028207
Show file tree
Hide file tree
Showing 61 changed files with 1,542 additions and 425 deletions.
9 changes: 9 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
Changes in synapse v0.8.1 (2015-03-18)
======================================

* Disable registration by default. New users can be added using the command
``register_new_matrix_user`` or by enabling registration in the config.
* Add metrics to synapse. To enable metrics use config options
``enable_metrics`` and ``metrics_port``.
* Fix bug where banning only kicked the user.

Changes in synapse v0.8.0 (2015-03-06)
======================================

Expand Down
16 changes: 15 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. contents::

Introduction
============

Expand Down Expand Up @@ -126,6 +128,17 @@ To set up your homeserver, run (in your virtualenv, as before)::

Substituting your host and domain name as appropriate.

By default, registration of new users is disabled. You can either enable
registration in the config (it is then recommended to also set up CAPTCHA), or
you can use the command line to register new users::

$ source ~/.synapse/bin/activate
$ register_new_matrix_user -c homeserver.yaml https://localhost:8448
New user localpart: erikj
Password:
Confirm password:
Success!

For reliable VoIP calls to be routed via this homeserver, you MUST configure
a TURN server. See docs/turn-howto.rst for details.

Expand Down Expand Up @@ -250,7 +263,8 @@ fix try re-installing from PyPI or directly from
ArchLinux
---------

If running `$ synctl start` fails wit 'returned non-zero exit status 1', you will need to explicitly call Python2.7 - either running as::
If running `$ synctl start` fails with 'returned non-zero exit status 1',
you will need to explicitly call Python2.7 - either running as::

$ python2.7 -m synapse.app.homeserver --daemonize -c homeserver.yaml --pid-file homeserver.pid
Expand Down
9 changes: 4 additions & 5 deletions contrib/vertobot/bot.pl
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,12 @@ sub on_room_message
my $verto_connecting = $loop->new_future;
$bot_verto->connect(
%{ $CONFIG{"verto-bot"} },
on_connected => sub {
warn("[Verto] connected to websocket");
$verto_connecting->done($bot_verto) if not $verto_connecting->is_done;
},
on_connect_error => sub { die "Cannot connect to verto - $_[-1]" },
on_resolve_error => sub { die "Cannot resolve to verto - $_[-1]" },
);
)->then( sub {
warn("[Verto] connected to websocket");
$verto_connecting->done($bot_verto) if not $verto_connecting->is_done;
});

Future->needs_all(
$bot_matrix->login( %{ $CONFIG{"matrix-bot"} } )->then( sub {
Expand Down
18 changes: 11 additions & 7 deletions contrib/vertobot/bridge.pl
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ sub create_virtual_user
"user": "$localpart"
}
EOT
)->get;
)->get;
warn $response->as_string if ($response->code != 200);
}

Expand Down Expand Up @@ -266,17 +266,21 @@ sub create_virtual_user

Future->needs_all(
$http->do_request(
method => "POST",
uri => URI->new( $CONFIG{"matrix"}->{server}."/_matrix/appservice/v1/register" ),
content_type => "application/json",
content => <<EOT
method => "POST",
uri => URI->new( $CONFIG{"matrix"}->{server}."/_matrix/appservice/v1/register" ),
content_type => "application/json",
content => <<EOT
{
"as_token": "$as_token",
"url": "$as_url",
"namespaces": { "users": ["\@\\\\+.*"] }
"namespaces": { "users": [ { "regex": "\@\\\\+.*", "exclusive": false } ] }
}
EOT
),
)->then( sub{
my ($response) = (@_);
warn $response->as_string if ($response->code != 200);
return Future->done;
}),
$verto_connecting,
)->get;

Expand Down
149 changes: 149 additions & 0 deletions register_new_matrix_user
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright 2015 OpenMarket Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import argparse
import getpass
import hashlib
import hmac
import json
import sys
import urllib2
import yaml


def request_registration(user, password, server_location, shared_secret):
mac = hmac.new(
key=shared_secret,
msg=user,
digestmod=hashlib.sha1,
).hexdigest()

data = {
"user": user,
"password": password,
"mac": mac,
"type": "org.matrix.login.shared_secret",
}

server_location = server_location.rstrip("/")

print "Sending registration request..."

req = urllib2.Request(
"%s/_matrix/client/api/v1/register" % (server_location,),
data=json.dumps(data),
headers={'Content-Type': 'application/json'}
)
try:
f = urllib2.urlopen(req)
f.read()
f.close()
print "Success."
except urllib2.HTTPError as e:
print "ERROR! Received %d %s" % (e.code, e.reason,)
if 400 <= e.code < 500:
if e.info().type == "application/json":
resp = json.load(e)
if "error" in resp:
print resp["error"]
sys.exit(1)


def register_new_user(user, password, server_location, shared_secret):
if not user:
try:
default_user = getpass.getuser()
except:
default_user = None

if default_user:
user = raw_input("New user localpart [%s]: " % (default_user,))
if not user:
user = default_user
else:
user = raw_input("New user localpart: ")

if not user:
print "Invalid user name"
sys.exit(1)

if not password:
password = getpass.getpass("Password: ")

if not password:
print "Password cannot be blank."
sys.exit(1)

confirm_password = getpass.getpass("Confirm password: ")

if password != confirm_password:
print "Passwords do not match"
sys.exit(1)

request_registration(user, password, server_location, shared_secret)


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Used to register new users with a given home server when"
" registration has been disabled. The home server must be"
" configured with the 'registration_shared_secret' option"
" set.",
)
parser.add_argument(
"-u", "--user",
default=None,
help="Local part of the new user. Will prompt if omitted.",
)
parser.add_argument(
"-p", "--password",
default=None,
help="New password for user. Will prompt if omitted.",
)

group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(
"-c", "--config",
type=argparse.FileType('r'),
help="Path to server config file. Used to read in shared secret.",
)

group.add_argument(
"-k", "--shared-secret",
help="Shared secret as defined in server config file.",
)

parser.add_argument(
"server_url",
default="https://localhost:8448",
nargs='?',
help="URL to use to talk to the home server. Defaults to "
" 'https://localhost:8448'.",
)

args = parser.parse_args()

if "config" in args and args.config:
config = yaml.safe_load(args.config)
secret = config.get("registration_shared_secret", None)
if not secret:
print "No 'registration_shared_secret' defined in config."
sys.exit(1)
else:
secret = args.shared_secret

register_new_user(args.user, args.password, args.server_url, secret)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ def exec_file(path_segments):
include_package_data=True,
zip_safe=False,
long_description=long_description,
scripts=["synctl"],
scripts=["synctl", "register_new_matrix_user"],
)
2 changes: 1 addition & 1 deletion synapse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
""" This is a reference implementation of a Matrix home server.
"""

__version__ = "0.8.0"
__version__ = "0.8.1"
36 changes: 24 additions & 12 deletions synapse/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
logger = logging.getLogger(__name__)


AuthEventTypes = (
EventTypes.Create, EventTypes.Member, EventTypes.PowerLevels,
EventTypes.JoinRules,
)


class Auth(object):

def __init__(self, hs):
Expand Down Expand Up @@ -166,6 +172,7 @@ def is_membership_change_allowed(self, event, auth_events):
target = auth_events.get(key)

target_in_room = target and target.membership == Membership.JOIN
target_banned = target and target.membership == Membership.BAN

key = (EventTypes.JoinRules, "", )
join_rule_event = auth_events.get(key)
Expand Down Expand Up @@ -194,6 +201,7 @@ def is_membership_change_allowed(self, event, auth_events):
{
"caller_in_room": caller_in_room,
"caller_invited": caller_invited,
"target_banned": target_banned,
"target_in_room": target_in_room,
"membership": membership,
"join_rule": join_rule,
Expand All @@ -202,6 +210,11 @@ def is_membership_change_allowed(self, event, auth_events):
}
)

if ban_level:
ban_level = int(ban_level)
else:
ban_level = 50 # FIXME (erikj): What should we do here?

if Membership.INVITE == membership:
# TODO (erikj): We should probably handle this more intelligently
# PRIVATE join rules.
Expand All @@ -212,6 +225,10 @@ def is_membership_change_allowed(self, event, auth_events):
403,
"%s not in room %s." % (event.user_id, event.room_id,)
)
elif target_banned:
raise AuthError(
403, "%s is banned from the room" % (target_user_id,)
)
elif target_in_room: # the target is already in the room.
raise AuthError(403, "%s is already in the room." %
target_user_id)
Expand All @@ -221,6 +238,8 @@ def is_membership_change_allowed(self, event, auth_events):
# joined: It's a NOOP
if event.user_id != target_user_id:
raise AuthError(403, "Cannot force another user to join.")
elif target_banned:
raise AuthError(403, "You are banned from this room")
elif join_rule == JoinRules.PUBLIC:
pass
elif join_rule == JoinRules.INVITE:
Expand All @@ -238,6 +257,10 @@ def is_membership_change_allowed(self, event, auth_events):
403,
"%s not in room %s." % (target_user_id, event.room_id,)
)
elif target_banned and user_level < ban_level:
raise AuthError(
403, "You cannot unban user &s." % (target_user_id,)
)
elif target_user_id != event.user_id:
if kick_level:
kick_level = int(kick_level)
Expand All @@ -249,11 +272,6 @@ def is_membership_change_allowed(self, event, auth_events):
403, "You cannot kick user %s." % target_user_id
)
elif Membership.BAN == membership:
if ban_level:
ban_level = int(ban_level)
else:
ban_level = 50 # FIXME (erikj): What should we do here?

if user_level < ban_level:
raise AuthError(403, "You don't have permission to ban")
else:
Expand Down Expand Up @@ -370,7 +388,7 @@ def get_user_by_token(self, token):
AuthError if no user by that token exists or the token is invalid.
"""
try:
ret = yield self.store.get_user_by_token(token=token)
ret = yield self.store.get_user_by_token(token)
if not ret:
raise StoreError(400, "Unknown token")
user_info = {
Expand Down Expand Up @@ -412,12 +430,6 @@ def add_auth_events(self, builder, context):

builder.auth_events = auth_events_entries

context.auth_events = {
k: v
for k, v in context.current_state.items()
if v.event_id in auth_ids
}

def compute_auth_events(self, event, current_state):
if event.type == EventTypes.Create:
return []
Expand Down
1 change: 1 addition & 0 deletions synapse/api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class LoginType(object):
EMAIL_IDENTITY = u"m.login.email.identity"
RECAPTCHA = u"m.login.recaptcha"
APPLICATION_SERVICE = u"m.login.application_service"
SHARED_SECRET = u"org.matrix.login.shared_secret"


class EventTypes(object):
Expand Down
Loading

0 comments on commit d028207

Please sign in to comment.