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

Commit d028207

Browse files
committed
Merge branch 'release-v0.8.1' of github.com:matrix-org/synapse
2 parents d517406 + 0a55a2b commit d028207

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1542
-425
lines changed

CHANGES.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
Changes in synapse v0.8.1 (2015-03-18)
2+
======================================
3+
4+
* Disable registration by default. New users can be added using the command
5+
``register_new_matrix_user`` or by enabling registration in the config.
6+
* Add metrics to synapse. To enable metrics use config options
7+
``enable_metrics`` and ``metrics_port``.
8+
* Fix bug where banning only kicked the user.
9+
110
Changes in synapse v0.8.0 (2015-03-06)
211
======================================
312

README.rst

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. contents::
2+
13
Introduction
24
============
35

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

127129
Substituting your host and domain name as appropriate.
128130

131+
By default, registration of new users is disabled. You can either enable
132+
registration in the config (it is then recommended to also set up CAPTCHA), or
133+
you can use the command line to register new users::
134+
135+
$ source ~/.synapse/bin/activate
136+
$ register_new_matrix_user -c homeserver.yaml https://localhost:8448
137+
New user localpart: erikj
138+
Password:
139+
Confirm password:
140+
Success!
141+
129142
For reliable VoIP calls to be routed via this homeserver, you MUST configure
130143
a TURN server. See docs/turn-howto.rst for details.
131144

@@ -250,7 +263,8 @@ fix try re-installing from PyPI or directly from
250263
ArchLinux
251264
---------
252265

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

255269
$ python2.7 -m synapse.app.homeserver --daemonize -c homeserver.yaml --pid-file homeserver.pid
256270

contrib/vertobot/bot.pl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,12 @@ sub on_room_message
175175
my $verto_connecting = $loop->new_future;
176176
$bot_verto->connect(
177177
%{ $CONFIG{"verto-bot"} },
178-
on_connected => sub {
179-
warn("[Verto] connected to websocket");
180-
$verto_connecting->done($bot_verto) if not $verto_connecting->is_done;
181-
},
182178
on_connect_error => sub { die "Cannot connect to verto - $_[-1]" },
183179
on_resolve_error => sub { die "Cannot resolve to verto - $_[-1]" },
184-
);
180+
)->then( sub {
181+
warn("[Verto] connected to websocket");
182+
$verto_connecting->done($bot_verto) if not $verto_connecting->is_done;
183+
});
185184

186185
Future->needs_all(
187186
$bot_matrix->login( %{ $CONFIG{"matrix-bot"} } )->then( sub {

contrib/vertobot/bridge.pl

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ sub create_virtual_user
8686
"user": "$localpart"
8787
}
8888
EOT
89-
)->get;
89+
)->get;
9090
warn $response->as_string if ($response->code != 200);
9191
}
9292

@@ -266,17 +266,21 @@ sub create_virtual_user
266266

267267
Future->needs_all(
268268
$http->do_request(
269-
method => "POST",
270-
uri => URI->new( $CONFIG{"matrix"}->{server}."/_matrix/appservice/v1/register" ),
271-
content_type => "application/json",
272-
content => <<EOT
269+
method => "POST",
270+
uri => URI->new( $CONFIG{"matrix"}->{server}."/_matrix/appservice/v1/register" ),
271+
content_type => "application/json",
272+
content => <<EOT
273273
{
274274
"as_token": "$as_token",
275275
"url": "$as_url",
276-
"namespaces": { "users": ["\@\\\\+.*"] }
276+
"namespaces": { "users": [ { "regex": "\@\\\\+.*", "exclusive": false } ] }
277277
}
278278
EOT
279-
),
279+
)->then( sub{
280+
my ($response) = (@_);
281+
warn $response->as_string if ($response->code != 200);
282+
return Future->done;
283+
}),
280284
$verto_connecting,
281285
)->get;
282286

register_new_matrix_user

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
# Copyright 2015 OpenMarket Ltd
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
18+
import argparse
19+
import getpass
20+
import hashlib
21+
import hmac
22+
import json
23+
import sys
24+
import urllib2
25+
import yaml
26+
27+
28+
def request_registration(user, password, server_location, shared_secret):
29+
mac = hmac.new(
30+
key=shared_secret,
31+
msg=user,
32+
digestmod=hashlib.sha1,
33+
).hexdigest()
34+
35+
data = {
36+
"user": user,
37+
"password": password,
38+
"mac": mac,
39+
"type": "org.matrix.login.shared_secret",
40+
}
41+
42+
server_location = server_location.rstrip("/")
43+
44+
print "Sending registration request..."
45+
46+
req = urllib2.Request(
47+
"%s/_matrix/client/api/v1/register" % (server_location,),
48+
data=json.dumps(data),
49+
headers={'Content-Type': 'application/json'}
50+
)
51+
try:
52+
f = urllib2.urlopen(req)
53+
f.read()
54+
f.close()
55+
print "Success."
56+
except urllib2.HTTPError as e:
57+
print "ERROR! Received %d %s" % (e.code, e.reason,)
58+
if 400 <= e.code < 500:
59+
if e.info().type == "application/json":
60+
resp = json.load(e)
61+
if "error" in resp:
62+
print resp["error"]
63+
sys.exit(1)
64+
65+
66+
def register_new_user(user, password, server_location, shared_secret):
67+
if not user:
68+
try:
69+
default_user = getpass.getuser()
70+
except:
71+
default_user = None
72+
73+
if default_user:
74+
user = raw_input("New user localpart [%s]: " % (default_user,))
75+
if not user:
76+
user = default_user
77+
else:
78+
user = raw_input("New user localpart: ")
79+
80+
if not user:
81+
print "Invalid user name"
82+
sys.exit(1)
83+
84+
if not password:
85+
password = getpass.getpass("Password: ")
86+
87+
if not password:
88+
print "Password cannot be blank."
89+
sys.exit(1)
90+
91+
confirm_password = getpass.getpass("Confirm password: ")
92+
93+
if password != confirm_password:
94+
print "Passwords do not match"
95+
sys.exit(1)
96+
97+
request_registration(user, password, server_location, shared_secret)
98+
99+
100+
if __name__ == "__main__":
101+
parser = argparse.ArgumentParser(
102+
description="Used to register new users with a given home server when"
103+
" registration has been disabled. The home server must be"
104+
" configured with the 'registration_shared_secret' option"
105+
" set.",
106+
)
107+
parser.add_argument(
108+
"-u", "--user",
109+
default=None,
110+
help="Local part of the new user. Will prompt if omitted.",
111+
)
112+
parser.add_argument(
113+
"-p", "--password",
114+
default=None,
115+
help="New password for user. Will prompt if omitted.",
116+
)
117+
118+
group = parser.add_mutually_exclusive_group(required=True)
119+
group.add_argument(
120+
"-c", "--config",
121+
type=argparse.FileType('r'),
122+
help="Path to server config file. Used to read in shared secret.",
123+
)
124+
125+
group.add_argument(
126+
"-k", "--shared-secret",
127+
help="Shared secret as defined in server config file.",
128+
)
129+
130+
parser.add_argument(
131+
"server_url",
132+
default="https://localhost:8448",
133+
nargs='?',
134+
help="URL to use to talk to the home server. Defaults to "
135+
" 'https://localhost:8448'.",
136+
)
137+
138+
args = parser.parse_args()
139+
140+
if "config" in args and args.config:
141+
config = yaml.safe_load(args.config)
142+
secret = config.get("registration_shared_secret", None)
143+
if not secret:
144+
print "No 'registration_shared_secret' defined in config."
145+
sys.exit(1)
146+
else:
147+
secret = args.shared_secret
148+
149+
register_new_user(args.user, args.password, args.server_url, secret)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,5 @@ def exec_file(path_segments):
5555
include_package_data=True,
5656
zip_safe=False,
5757
long_description=long_description,
58-
scripts=["synctl"],
58+
scripts=["synctl", "register_new_matrix_user"],
5959
)

synapse/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
""" This is a reference implementation of a Matrix home server.
1717
"""
1818

19-
__version__ = "0.8.0"
19+
__version__ = "0.8.1"

synapse/api/auth.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
logger = logging.getLogger(__name__)
2929

3030

31+
AuthEventTypes = (
32+
EventTypes.Create, EventTypes.Member, EventTypes.PowerLevels,
33+
EventTypes.JoinRules,
34+
)
35+
36+
3137
class Auth(object):
3238

3339
def __init__(self, hs):
@@ -166,6 +172,7 @@ def is_membership_change_allowed(self, event, auth_events):
166172
target = auth_events.get(key)
167173

168174
target_in_room = target and target.membership == Membership.JOIN
175+
target_banned = target and target.membership == Membership.BAN
169176

170177
key = (EventTypes.JoinRules, "", )
171178
join_rule_event = auth_events.get(key)
@@ -194,6 +201,7 @@ def is_membership_change_allowed(self, event, auth_events):
194201
{
195202
"caller_in_room": caller_in_room,
196203
"caller_invited": caller_invited,
204+
"target_banned": target_banned,
197205
"target_in_room": target_in_room,
198206
"membership": membership,
199207
"join_rule": join_rule,
@@ -202,6 +210,11 @@ def is_membership_change_allowed(self, event, auth_events):
202210
}
203211
)
204212

213+
if ban_level:
214+
ban_level = int(ban_level)
215+
else:
216+
ban_level = 50 # FIXME (erikj): What should we do here?
217+
205218
if Membership.INVITE == membership:
206219
# TODO (erikj): We should probably handle this more intelligently
207220
# PRIVATE join rules.
@@ -212,6 +225,10 @@ def is_membership_change_allowed(self, event, auth_events):
212225
403,
213226
"%s not in room %s." % (event.user_id, event.room_id,)
214227
)
228+
elif target_banned:
229+
raise AuthError(
230+
403, "%s is banned from the room" % (target_user_id,)
231+
)
215232
elif target_in_room: # the target is already in the room.
216233
raise AuthError(403, "%s is already in the room." %
217234
target_user_id)
@@ -221,6 +238,8 @@ def is_membership_change_allowed(self, event, auth_events):
221238
# joined: It's a NOOP
222239
if event.user_id != target_user_id:
223240
raise AuthError(403, "Cannot force another user to join.")
241+
elif target_banned:
242+
raise AuthError(403, "You are banned from this room")
224243
elif join_rule == JoinRules.PUBLIC:
225244
pass
226245
elif join_rule == JoinRules.INVITE:
@@ -238,6 +257,10 @@ def is_membership_change_allowed(self, event, auth_events):
238257
403,
239258
"%s not in room %s." % (target_user_id, event.room_id,)
240259
)
260+
elif target_banned and user_level < ban_level:
261+
raise AuthError(
262+
403, "You cannot unban user &s." % (target_user_id,)
263+
)
241264
elif target_user_id != event.user_id:
242265
if kick_level:
243266
kick_level = int(kick_level)
@@ -249,11 +272,6 @@ def is_membership_change_allowed(self, event, auth_events):
249272
403, "You cannot kick user %s." % target_user_id
250273
)
251274
elif Membership.BAN == membership:
252-
if ban_level:
253-
ban_level = int(ban_level)
254-
else:
255-
ban_level = 50 # FIXME (erikj): What should we do here?
256-
257275
if user_level < ban_level:
258276
raise AuthError(403, "You don't have permission to ban")
259277
else:
@@ -370,7 +388,7 @@ def get_user_by_token(self, token):
370388
AuthError if no user by that token exists or the token is invalid.
371389
"""
372390
try:
373-
ret = yield self.store.get_user_by_token(token=token)
391+
ret = yield self.store.get_user_by_token(token)
374392
if not ret:
375393
raise StoreError(400, "Unknown token")
376394
user_info = {
@@ -412,12 +430,6 @@ def add_auth_events(self, builder, context):
412430

413431
builder.auth_events = auth_events_entries
414432

415-
context.auth_events = {
416-
k: v
417-
for k, v in context.current_state.items()
418-
if v.event_id in auth_ids
419-
}
420-
421433
def compute_auth_events(self, event, current_state):
422434
if event.type == EventTypes.Create:
423435
return []

synapse/api/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class LoginType(object):
6060
EMAIL_IDENTITY = u"m.login.email.identity"
6161
RECAPTCHA = u"m.login.recaptcha"
6262
APPLICATION_SERVICE = u"m.login.application_service"
63+
SHARED_SECRET = u"org.matrix.login.shared_secret"
6364

6465

6566
class EventTypes(object):

0 commit comments

Comments
 (0)