mirror of
https://mau.dev/maunium/synapse.git
synced 2024-10-01 01:36:05 -04:00
Merge branch 'develop' of github.com:matrix-org/synapse into erikj/media_storage_refactor
This commit is contained in:
commit
81391fa162
43
CHANGES.rst
43
CHANGES.rst
@ -1,3 +1,46 @@
|
|||||||
|
Changes in synapse v0.26.0 (2018-01-05)
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
No changes since v0.26.0-rc1
|
||||||
|
|
||||||
|
|
||||||
|
Changes in synapse v0.26.0-rc1 (2017-12-13)
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
* Add ability for ASes to publicise groups for their users (PR #2686)
|
||||||
|
* Add all local users to the user_directory and optionally search them (PR
|
||||||
|
#2723)
|
||||||
|
* Add support for custom login types for validating users (PR #2729)
|
||||||
|
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
* Update example Prometheus config to new format (PR #2648) Thanks to
|
||||||
|
@krombel!
|
||||||
|
* Rename redact_content option to include_content in Push API (PR #2650)
|
||||||
|
* Declare support for r0.3.0 (PR #2677)
|
||||||
|
* Improve upserts (PR #2684, #2688, #2689, #2713)
|
||||||
|
* Improve documentation of workers (PR #2700)
|
||||||
|
* Improve tracebacks on exceptions (PR #2705)
|
||||||
|
* Allow guest access to group APIs for reading (PR #2715)
|
||||||
|
* Support for posting content in federation_client script (PR #2716)
|
||||||
|
* Delete devices and pushers on logouts etc (PR #2722)
|
||||||
|
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Fix database port script (PR #2673)
|
||||||
|
* Fix internal server error on login with ldap_auth_provider (PR #2678) Thanks
|
||||||
|
to @jkolo!
|
||||||
|
* Fix error on sqlite 3.7 (PR #2697)
|
||||||
|
* Fix OPTIONS on preview_url (PR #2707)
|
||||||
|
* Fix error handling on dns lookup (PR #2711)
|
||||||
|
* Fix wrong avatars when inviting multiple users when creating room (PR #2717)
|
||||||
|
* Fix 500 when joining matrix-dev (PR #2719)
|
||||||
|
|
||||||
|
|
||||||
Changes in synapse v0.25.1 (2017-11-17)
|
Changes in synapse v0.25.1 (2017-11-17)
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
|
@ -632,6 +632,11 @@ largest boxes pause for thought.)
|
|||||||
|
|
||||||
Troubleshooting
|
Troubleshooting
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
You can use the federation tester to check if your homeserver is all set:
|
||||||
|
``https://matrix.org/federationtester/api/report?server_name=<your_server_name>``
|
||||||
|
If any of the attributes under "checks" is false, federation won't work.
|
||||||
|
|
||||||
The typical failure mode with federation is that when you try to join a room,
|
The typical failure mode with federation is that when you try to join a room,
|
||||||
it is rejected with "401: Unauthorized". Generally this means that other
|
it is rejected with "401: Unauthorized". Generally this means that other
|
||||||
servers in the room couldn't access yours. (Joining a room over federation is a
|
servers in the room couldn't access yours. (Joining a room over federation is a
|
||||||
|
@ -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.25.1"
|
__version__ = "0.26.0"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
from twisted.internet import defer
|
from twisted.internet import defer, threads
|
||||||
|
|
||||||
from ._base import BaseHandler
|
from ._base import BaseHandler
|
||||||
from synapse.api.constants import LoginType
|
from synapse.api.constants import LoginType
|
||||||
@ -25,6 +25,7 @@ from synapse.module_api import ModuleApi
|
|||||||
from synapse.types import UserID
|
from synapse.types import UserID
|
||||||
from synapse.util.async import run_on_reactor
|
from synapse.util.async import run_on_reactor
|
||||||
from synapse.util.caches.expiringcache import ExpiringCache
|
from synapse.util.caches.expiringcache import ExpiringCache
|
||||||
|
from synapse.util.logcontext import make_deferred_yieldable
|
||||||
|
|
||||||
from twisted.web.client import PartialDownloadError
|
from twisted.web.client import PartialDownloadError
|
||||||
|
|
||||||
@ -714,7 +715,7 @@ class AuthHandler(BaseHandler):
|
|||||||
if not lookupres:
|
if not lookupres:
|
||||||
defer.returnValue(None)
|
defer.returnValue(None)
|
||||||
(user_id, password_hash) = lookupres
|
(user_id, password_hash) = lookupres
|
||||||
result = self.validate_hash(password, password_hash)
|
result = yield self.validate_hash(password, password_hash)
|
||||||
if not result:
|
if not result:
|
||||||
logger.warn("Failed password login for user %s", user_id)
|
logger.warn("Failed password login for user %s", user_id)
|
||||||
defer.returnValue(None)
|
defer.returnValue(None)
|
||||||
@ -842,11 +843,14 @@ class AuthHandler(BaseHandler):
|
|||||||
password (str): Password to hash.
|
password (str): Password to hash.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Hashed password (str).
|
Deferred(str): Hashed password.
|
||||||
"""
|
"""
|
||||||
|
def _do_hash():
|
||||||
return bcrypt.hashpw(password.encode('utf8') + self.hs.config.password_pepper,
|
return bcrypt.hashpw(password.encode('utf8') + self.hs.config.password_pepper,
|
||||||
bcrypt.gensalt(self.bcrypt_rounds))
|
bcrypt.gensalt(self.bcrypt_rounds))
|
||||||
|
|
||||||
|
return make_deferred_yieldable(threads.deferToThread(_do_hash))
|
||||||
|
|
||||||
def validate_hash(self, password, stored_hash):
|
def validate_hash(self, password, stored_hash):
|
||||||
"""Validates that self.hash(password) == stored_hash.
|
"""Validates that self.hash(password) == stored_hash.
|
||||||
|
|
||||||
@ -855,13 +859,17 @@ class AuthHandler(BaseHandler):
|
|||||||
stored_hash (str): Expected hash value.
|
stored_hash (str): Expected hash value.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Whether self.hash(password) == stored_hash (bool).
|
Deferred(bool): Whether self.hash(password) == stored_hash.
|
||||||
"""
|
"""
|
||||||
if stored_hash:
|
|
||||||
|
def _do_validate_hash():
|
||||||
return bcrypt.hashpw(password.encode('utf8') + self.hs.config.password_pepper,
|
return bcrypt.hashpw(password.encode('utf8') + self.hs.config.password_pepper,
|
||||||
stored_hash.encode('utf8')) == stored_hash
|
stored_hash.encode('utf8')) == stored_hash
|
||||||
|
|
||||||
|
if stored_hash:
|
||||||
|
return make_deferred_yieldable(threads.deferToThread(_do_validate_hash))
|
||||||
else:
|
else:
|
||||||
return False
|
return defer.succeed(False)
|
||||||
|
|
||||||
|
|
||||||
class MacaroonGeneartor(object):
|
class MacaroonGeneartor(object):
|
||||||
|
@ -383,11 +383,12 @@ class GroupsLocalHandler(object):
|
|||||||
|
|
||||||
defer.returnValue({"groups": result})
|
defer.returnValue({"groups": result})
|
||||||
else:
|
else:
|
||||||
result = yield self.transport_client.get_publicised_groups_for_user(
|
bulk_result = yield self.transport_client.bulk_get_publicised_groups(
|
||||||
get_domain_from_id(user_id), user_id
|
get_domain_from_id(user_id), [user_id],
|
||||||
)
|
)
|
||||||
|
result = bulk_result.get("users", {}).get(user_id)
|
||||||
# TODO: Verify attestations
|
# TODO: Verify attestations
|
||||||
defer.returnValue(result)
|
defer.returnValue({"groups": result})
|
||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def bulk_get_publicised_groups(self, user_ids, proxy=True):
|
def bulk_get_publicised_groups(self, user_ids, proxy=True):
|
||||||
|
@ -131,7 +131,7 @@ class RegistrationHandler(BaseHandler):
|
|||||||
yield run_on_reactor()
|
yield run_on_reactor()
|
||||||
password_hash = None
|
password_hash = None
|
||||||
if password:
|
if password:
|
||||||
password_hash = self.auth_handler().hash(password)
|
password_hash = yield self.auth_handler().hash(password)
|
||||||
|
|
||||||
if localpart:
|
if localpart:
|
||||||
yield self.check_username(localpart, guest_access_token=guest_access_token)
|
yield self.check_username(localpart, guest_access_token=guest_access_token)
|
||||||
|
@ -31,7 +31,7 @@ class SetPasswordHandler(BaseHandler):
|
|||||||
|
|
||||||
@defer.inlineCallbacks
|
@defer.inlineCallbacks
|
||||||
def set_password(self, user_id, newpassword, requester=None):
|
def set_password(self, user_id, newpassword, requester=None):
|
||||||
password_hash = self._auth_handler.hash(newpassword)
|
password_hash = yield self._auth_handler.hash(newpassword)
|
||||||
|
|
||||||
except_device_id = requester.device_id if requester else None
|
except_device_id = requester.device_id if requester else None
|
||||||
except_access_token_id = requester.access_token_id if requester else None
|
except_access_token_id = requester.access_token_id if requester else None
|
||||||
|
@ -107,6 +107,10 @@ def wrap_request_handler(request_handler, include_metrics=False):
|
|||||||
with LoggingContext(request_id) as request_context:
|
with LoggingContext(request_id) as request_context:
|
||||||
with Measure(self.clock, "wrapped_request_handler"):
|
with Measure(self.clock, "wrapped_request_handler"):
|
||||||
request_metrics = RequestMetrics()
|
request_metrics = RequestMetrics()
|
||||||
|
# we start the request metrics timer here with an initial stab
|
||||||
|
# at the servlet name. For most requests that name will be
|
||||||
|
# JsonResource (or a subclass), and JsonResource._async_render
|
||||||
|
# will update it once it picks a servlet.
|
||||||
request_metrics.start(self.clock, name=self.__class__.__name__)
|
request_metrics.start(self.clock, name=self.__class__.__name__)
|
||||||
|
|
||||||
request_context.request = request_id
|
request_context.request = request_id
|
||||||
@ -249,12 +253,23 @@ class JsonResource(HttpServer, resource.Resource):
|
|||||||
if not m:
|
if not m:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# We found a match! Trigger callback and then return the
|
# We found a match! First update the metrics object to indicate
|
||||||
# returned response. We pass both the request and any
|
# which servlet is handling the request.
|
||||||
# matched groups from the regex to the callback.
|
|
||||||
|
|
||||||
callback = path_entry.callback
|
callback = path_entry.callback
|
||||||
|
|
||||||
|
servlet_instance = getattr(callback, "__self__", None)
|
||||||
|
if servlet_instance is not None:
|
||||||
|
servlet_classname = servlet_instance.__class__.__name__
|
||||||
|
else:
|
||||||
|
servlet_classname = "%r" % callback
|
||||||
|
|
||||||
|
request_metrics.name = servlet_classname
|
||||||
|
|
||||||
|
# Now trigger the callback. If it returns a response, we send it
|
||||||
|
# here. If it throws an exception, that is handled by the wrapper
|
||||||
|
# installed by @request_handler.
|
||||||
|
|
||||||
kwargs = intern_dict({
|
kwargs = intern_dict({
|
||||||
name: urllib.unquote(value).decode("UTF-8") if value else value
|
name: urllib.unquote(value).decode("UTF-8") if value else value
|
||||||
for name, value in m.groupdict().items()
|
for name, value in m.groupdict().items()
|
||||||
@ -265,17 +280,10 @@ class JsonResource(HttpServer, resource.Resource):
|
|||||||
code, response = callback_return
|
code, response = callback_return
|
||||||
self._send_response(request, code, response)
|
self._send_response(request, code, response)
|
||||||
|
|
||||||
servlet_instance = getattr(callback, "__self__", None)
|
|
||||||
if servlet_instance is not None:
|
|
||||||
servlet_classname = servlet_instance.__class__.__name__
|
|
||||||
else:
|
|
||||||
servlet_classname = "%r" % callback
|
|
||||||
|
|
||||||
request_metrics.name = servlet_classname
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Huh. No one wanted to handle that? Fiiiiiine. Send 400.
|
# Huh. No one wanted to handle that? Fiiiiiine. Send 400.
|
||||||
|
request_metrics.name = self.__class__.__name__ + ".UnrecognizedRequest"
|
||||||
raise UnrecognizedRequestError()
|
raise UnrecognizedRequestError()
|
||||||
|
|
||||||
def _send_response(self, request, code, response_json_object,
|
def _send_response(self, request, code, response_json_object,
|
||||||
|
@ -487,13 +487,35 @@ class RoomInitialSyncRestServlet(ClientV1RestServlet):
|
|||||||
defer.returnValue((200, content))
|
defer.returnValue((200, content))
|
||||||
|
|
||||||
|
|
||||||
class RoomEventContext(ClientV1RestServlet):
|
class RoomEventServlet(ClientV1RestServlet):
|
||||||
|
PATTERNS = client_path_patterns(
|
||||||
|
"/rooms/(?P<room_id>[^/]*)/event/(?P<event_id>[^/]*)$"
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, hs):
|
||||||
|
super(RoomEventServlet, self).__init__(hs)
|
||||||
|
self.clock = hs.get_clock()
|
||||||
|
self.event_handler = hs.get_event_handler()
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def on_GET(self, request, room_id, event_id):
|
||||||
|
requester = yield self.auth.get_user_by_req(request)
|
||||||
|
event = yield self.event_handler.get_event(requester.user, event_id)
|
||||||
|
|
||||||
|
time_now = self.clock.time_msec()
|
||||||
|
if event:
|
||||||
|
defer.returnValue((200, serialize_event(event, time_now)))
|
||||||
|
else:
|
||||||
|
defer.returnValue((404, "Event not found."))
|
||||||
|
|
||||||
|
|
||||||
|
class RoomEventContextServlet(ClientV1RestServlet):
|
||||||
PATTERNS = client_path_patterns(
|
PATTERNS = client_path_patterns(
|
||||||
"/rooms/(?P<room_id>[^/]*)/context/(?P<event_id>[^/]*)$"
|
"/rooms/(?P<room_id>[^/]*)/context/(?P<event_id>[^/]*)$"
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, hs):
|
def __init__(self, hs):
|
||||||
super(RoomEventContext, self).__init__(hs)
|
super(RoomEventContextServlet, self).__init__(hs)
|
||||||
self.clock = hs.get_clock()
|
self.clock = hs.get_clock()
|
||||||
self.handlers = hs.get_handlers()
|
self.handlers = hs.get_handlers()
|
||||||
|
|
||||||
@ -803,4 +825,5 @@ def register_servlets(hs, http_server):
|
|||||||
RoomTypingRestServlet(hs).register(http_server)
|
RoomTypingRestServlet(hs).register(http_server)
|
||||||
SearchRestServlet(hs).register(http_server)
|
SearchRestServlet(hs).register(http_server)
|
||||||
JoinedRoomsRestServlet(hs).register(http_server)
|
JoinedRoomsRestServlet(hs).register(http_server)
|
||||||
RoomEventContext(hs).register(http_server)
|
RoomEventServlet(hs).register(http_server)
|
||||||
|
RoomEventContextServlet(hs).register(http_server)
|
||||||
|
Loading…
Reference in New Issue
Block a user