Merge branch 'develop' of github.com:matrix-org/synapse into erikj/check_alias

This commit is contained in:
Erik Johnston 2015-09-14 18:04:36 +01:00
commit 228465b0ec
15 changed files with 119 additions and 35 deletions

3
.gitignore vendored
View File

@ -43,3 +43,6 @@ build/
localhost-800*/ localhost-800*/
static/client/register/register_config.js static/client/register/register_config.js
.tox .tox
env/
*.config

View File

@ -1,3 +1,14 @@
Changes in synapse v0.10.0 (2015-09-03)
=======================================
No change from release candidate.
Changes in synapse v0.10.0-rc6 (2015-09-02)
===========================================
* Remove some of the old database upgrade scripts.
* Fix database port script to work with newly created sqlite databases.
Changes in synapse v0.10.0-rc5 (2015-08-27) Changes in synapse v0.10.0-rc5 (2015-08-27)
=========================================== ===========================================

View File

@ -94,6 +94,7 @@ Synapse is the reference python/twisted Matrix homeserver implementation.
System requirements: System requirements:
- POSIX-compliant system (tested on Linux & OS X) - POSIX-compliant system (tested on Linux & OS X)
- Python 2.7 - Python 2.7
- At least 512 MB RAM.
Synapse is written in python but some of the libraries is uses are written in Synapse is written in python but some of the libraries is uses are written in
C. So before we can install synapse itself we need a working C compiler and the C. So before we can install synapse itself we need a working C compiler and the
@ -120,6 +121,7 @@ To install the synapse homeserver run::
virtualenv -p python2.7 ~/.synapse virtualenv -p python2.7 ~/.synapse
source ~/.synapse/bin/activate source ~/.synapse/bin/activate
pip install --upgrade setuptools
pip install --process-dependency-links https://github.com/matrix-org/synapse/tarball/master pip install --process-dependency-links https://github.com/matrix-org/synapse/tarball/master
This installs synapse, along with the libraries it uses, into a virtual This installs synapse, along with the libraries it uses, into a virtual
@ -284,6 +286,11 @@ may need to manually upgrade it::
sudo pip install --upgrade pip sudo pip install --upgrade pip
Installing may fail with ``mock requires setuptools>=17.1. Aborting installation``.
You can fix this by upgrading setuptools::
pip install --upgrade setuptools
If pip crashes mid-installation for reason (e.g. lost terminal), pip may If pip crashes mid-installation for reason (e.g. lost terminal), pip may
refuse to run until you remove the temporary installation directory it refuse to run until you remove the temporary installation directory it
created. To reset the installation:: created. To reset the installation::

View File

@ -56,10 +56,9 @@ if __name__ == '__main__':
js = json.load(args.json) js = json.load(args.json)
auth = Auth(Mock()) auth = Auth(Mock())
check_auth( check_auth(
auth, auth,
[FrozenEvent(d) for d in js["auth_chain"]], [FrozenEvent(d) for d in js["auth_chain"]],
[FrozenEvent(d) for d in js["pdus"]], [FrozenEvent(d) for d in js.get("pdus", [])],
) )

View File

@ -29,7 +29,7 @@ import traceback
import yaml import yaml
logger = logging.getLogger("port_from_sqlite_to_postgres") logger = logging.getLogger("synapse_port_db")
BOOLEAN_COLUMNS = { BOOLEAN_COLUMNS = {
@ -412,6 +412,7 @@ class Porter(object):
self._convert_rows("sent_transactions", headers, rows) self._convert_rows("sent_transactions", headers, rows)
inserted_rows = len(rows) inserted_rows = len(rows)
if inserted_rows:
max_inserted_rowid = max(r[0] for r in rows) max_inserted_rowid = max(r[0] for r in rows)
def insert(txn): def insert(txn):
@ -420,6 +421,8 @@ class Porter(object):
) )
yield self.postgres_store.execute(insert) yield self.postgres_store.execute(insert)
else:
max_inserted_rowid = 0
def get_start_id(txn): def get_start_id(txn):
txn.execute( txn.execute(

View File

@ -81,7 +81,7 @@ setup(
packages=find_packages(exclude=["tests", "tests.*"]), packages=find_packages(exclude=["tests", "tests.*"]),
description="Reference Synapse Home Server", description="Reference Synapse Home Server",
install_requires=dependencies['requirements'](include_conditional=True).keys(), install_requires=dependencies['requirements'](include_conditional=True).keys(),
dependency_links=dependencies["DEPENDENCY_LINKS"], dependency_links=dependencies["DEPENDENCY_LINKS"].values(),
include_package_data=True, include_package_data=True,
zip_safe=False, zip_safe=False,
long_description=long_description, long_description=long_description,

View File

@ -16,4 +16,4 @@
""" This is a reference implementation of a Matrix home server. """ This is a reference implementation of a Matrix home server.
""" """
__version__ = "0.10.0-rc5" __version__ = "0.10.0"

View File

@ -112,7 +112,7 @@ class Auth(object):
self._check_power_levels(event, auth_events) self._check_power_levels(event, auth_events)
if event.type == EventTypes.Redaction: if event.type == EventTypes.Redaction:
self._check_redaction(event, auth_events) self.check_redaction(event, auth_events)
logger.debug("Allowing! %s", event) logger.debug("Allowing! %s", event)
except AuthError as e: except AuthError as e:
@ -567,12 +567,31 @@ class Auth(object):
return True return True
def _check_redaction(self, event, auth_events): def check_redaction(self, event, auth_events):
"""Check whether the event sender is allowed to redact the target event.
Returns:
True if the the sender is allowed to redact the target event if the
target event was created by them.
False if the sender is allowed to redact the target event with no
further checks.
Raises:
AuthError if the event sender is definitely not allowed to redact
the target event.
"""
user_level = self._get_user_power_level(event.user_id, auth_events) user_level = self._get_user_power_level(event.user_id, auth_events)
redact_level = self._get_named_level(auth_events, "redact", 50) redact_level = self._get_named_level(auth_events, "redact", 50)
if user_level < redact_level: if user_level > redact_level:
return False
redacter_domain = EventID.from_string(event.event_id).domain
redactee_domain = EventID.from_string(event.redacts).domain
if redacter_domain == redactee_domain:
return True
raise AuthError( raise AuthError(
403, 403,
"You don't have permission to redact events" "You don't have permission to redact events"

View File

@ -341,7 +341,7 @@ def get_version_string():
) )
).encode("ascii") ).encode("ascii")
except Exception as e: except Exception as e:
logger.warn("Failed to check for git repository: %s", e) logger.info("Failed to check for git repository: %s", e)
return ("Synapse/%s" % (synapse.__version__,)).encode("ascii") return ("Synapse/%s" % (synapse.__version__,)).encode("ascii")

View File

@ -182,7 +182,7 @@ class Config(object):
) % (entry_path, ) ) % (entry_path, )
continue continue
files.add(config_path) files.append(entry_path)
config_files.extend(sorted(files)) config_files.extend(sorted(files))
else: else:

View File

@ -162,7 +162,9 @@ class Keyring(object):
def remove_deferreds(res, server_name, group_id): def remove_deferreds(res, server_name, group_id):
server_to_gids[server_name].discard(group_id) server_to_gids[server_name].discard(group_id)
if not server_to_gids[server_name]: if not server_to_gids[server_name]:
server_to_deferred.pop(server_name).callback(None) d = server_to_deferred.pop(server_name, None)
if d:
d.callback(None)
return res return res
for g_id, deferred in deferreds.items(): for g_id, deferred in deferreds.items():
@ -200,8 +202,15 @@ class Keyring(object):
else: else:
break break
for server_name, deferred in server_to_deferred: for server_name, deferred in server_to_deferred.items():
self.key_downloads[server_name] = ObservableDeferred(deferred) d = ObservableDeferred(deferred)
self.key_downloads[server_name] = d
def rm(r, server_name):
self.key_downloads.pop(server_name, None)
return r
d.addBoth(rm, server_name)
def get_server_verify_keys(self, group_id_to_group, group_id_to_deferred): def get_server_verify_keys(self, group_id_to_group, group_id_to_deferred):
"""Takes a dict of KeyGroups and tries to find at least one key for """Takes a dict of KeyGroups and tries to find at least one key for
@ -220,9 +229,8 @@ class Keyring(object):
merged_results = {} merged_results = {}
missing_keys = { missing_keys = {
group.server_name: key_id group.server_name: set(group.key_ids)
for group in group_id_to_group.values() for group in group_id_to_group.values()
for key_id in group.key_ids
} }
for fn in key_fetch_fns: for fn in key_fetch_fns:
@ -279,16 +287,15 @@ class Keyring(object):
def get_keys_from_store(self, server_name_and_key_ids): def get_keys_from_store(self, server_name_and_key_ids):
res = yield defer.gatherResults( res = yield defer.gatherResults(
[ [
self.store.get_server_verify_keys(server_name, key_ids) self.store.get_server_verify_keys(
server_name, key_ids
).addCallback(lambda ks, server: (server, ks), server_name)
for server_name, key_ids in server_name_and_key_ids for server_name, key_ids in server_name_and_key_ids
], ],
consumeErrors=True, consumeErrors=True,
).addErrback(unwrapFirstError) ).addErrback(unwrapFirstError)
defer.returnValue(dict(zip( defer.returnValue(dict(res))
[server_name for server_name, _ in server_name_and_key_ids],
res
)))
@defer.inlineCallbacks @defer.inlineCallbacks
def get_keys_from_perspectives(self, server_name_and_key_ids): def get_keys_from_perspectives(self, server_name_and_key_ids):

View File

@ -15,7 +15,7 @@
from twisted.internet import defer from twisted.internet import defer
from synapse.api.errors import LimitExceededError, SynapseError from synapse.api.errors import LimitExceededError, SynapseError, AuthError
from synapse.crypto.event_signing import add_hashes_and_signatures from synapse.crypto.event_signing import add_hashes_and_signatures
from synapse.api.constants import Membership, EventTypes from synapse.api.constants import Membership, EventTypes
from synapse.types import UserID, RoomAlias from synapse.types import UserID, RoomAlias
@ -146,6 +146,21 @@ class BaseHandler(object):
returned_invite.signatures returned_invite.signatures
) )
if event.type == EventTypes.Redaction:
if self.auth.check_redaction(event, auth_events=context.current_state):
original_event = yield self.store.get_event(
event.redacts,
check_redacted=False,
get_prev_content=False,
allow_rejected=False,
allow_none=False
)
if event.user_id != original_event.user_id:
raise AuthError(
403,
"You don't have permission to redact events"
)
destinations = set(extra_destinations) destinations = set(extra_destinations)
for k, s in context.current_state.items(): for k, s in context.current_state.items():
try: try:

View File

@ -17,7 +17,7 @@
from __future__ import absolute_import from __future__ import absolute_import
import logging import logging
from resource import getrusage, getpagesize, RUSAGE_SELF from resource import getrusage, RUSAGE_SELF
import functools import functools
import os import os
import stat import stat
@ -100,7 +100,6 @@ def render_all():
# process resource usage # process resource usage
rusage = None rusage = None
PAGE_SIZE = getpagesize()
def update_resource_metrics(): def update_resource_metrics():
@ -113,8 +112,8 @@ resource_metrics = get_metrics_for("process.resource")
resource_metrics.register_callback("utime", lambda: rusage.ru_utime * 1000) resource_metrics.register_callback("utime", lambda: rusage.ru_utime * 1000)
resource_metrics.register_callback("stime", lambda: rusage.ru_stime * 1000) resource_metrics.register_callback("stime", lambda: rusage.ru_stime * 1000)
# pages # kilobytes
resource_metrics.register_callback("maxrss", lambda: rusage.ru_maxrss * PAGE_SIZE) resource_metrics.register_callback("maxrss", lambda: rusage.ru_maxrss * 1024)
TYPES = { TYPES = {
stat.S_IFSOCK: "SOCK", stat.S_IFSOCK: "SOCK",
@ -131,6 +130,10 @@ def _process_fds():
counts = {(k,): 0 for k in TYPES.values()} counts = {(k,): 0 for k in TYPES.values()}
counts[("other",)] = 0 counts[("other",)] = 0
# Not every OS will have a /proc/self/fd directory
if not os.path.exists("/proc/self/fd"):
return counts
for fd in os.listdir("/proc/self/fd"): for fd in os.listdir("/proc/self/fd"):
try: try:
s = os.stat("/proc/self/fd/%s" % (fd)) s = os.stat("/proc/self/fd/%s" % (fd))

View File

@ -96,6 +96,7 @@ class ThreepidRestServlet(RestServlet):
self.hs = hs self.hs = hs
self.identity_handler = hs.get_handlers().identity_handler self.identity_handler = hs.get_handlers().identity_handler
self.auth = hs.get_auth() self.auth = hs.get_auth()
self.auth_handler = hs.get_handlers().auth_handler
@defer.inlineCallbacks @defer.inlineCallbacks
def on_GET(self, request): def on_GET(self, request):

View File

@ -0,0 +1,16 @@
/* 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.
*/
DROP INDEX IF EXISTS state_groups_state_tuple;