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

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
hawkowl committed May 21, 2019
2 parents c99c105 + 4a30e4a commit 8fe26db
Show file tree
Hide file tree
Showing 39 changed files with 1,601 additions and 61 deletions.
1 change: 1 addition & 0 deletions changelog.d/4338.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Synapse now more efficiently collates room statistics.
1 change: 1 addition & 0 deletions changelog.d/5146.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Exclude soft-failed events from forward-extremity candidates: fixes "No forward extremities left!" error.
1 change: 1 addition & 0 deletions changelog.d/5203.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add experimental support for relations (aka reactions and edits).
1 change: 1 addition & 0 deletions changelog.d/5204.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Stick an expiration date to any registered user missing one at startup if account validity is enabled.
2 changes: 1 addition & 1 deletion changelog.d/5210.feature
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Add a new room version which uses a new event ID format.
Add a room version 4 which uses a new event ID format, as per [MSC2002](https://github.com/matrix-org/matrix-doc/pull/2002).
1 change: 1 addition & 0 deletions changelog.d/5212.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add experimental support for relations (aka reactions and edits).
1 change: 1 addition & 0 deletions changelog.d/5217.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a room version 4 which uses a new event ID format, as per [MSC2002](https://github.com/matrix-org/matrix-doc/pull/2002).
1 change: 1 addition & 0 deletions changelog.d/5218.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix incompatibility between ACME support and Python 3.5.2.
1 change: 1 addition & 0 deletions changelog.d/5219.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix error handling for rooms whose versions are unknown.
24 changes: 24 additions & 0 deletions docs/sample_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,14 @@ uploads_path: "DATADIR/uploads"
# link. ``%(app)s`` can be used as a placeholder for the ``app_name`` parameter
# from the ``email`` section.
#
# Once this feature is enabled, Synapse will look for registered users without an
# expiration date at startup and will add one to every account it found using the
# current settings at that time.
# This means that, if a validity period is set, and Synapse is restarted (it will
# then derive an expiration date from the current validity period), and some time
# after that the validity period changes and Synapse is restarted, the users'
# expiration dates won't be updated unless their account is manually renewed.
#
#account_validity:
# enabled: True
# period: 6w
Expand Down Expand Up @@ -1156,6 +1164,22 @@ password_config:
#



# Local statistics collection. Used in populating the room directory.
#
# 'bucket_size' controls how large each statistics timeslice is. It can
# be defined in a human readable short form -- e.g. "1d", "1y".
#
# 'retention' controls how long historical statistics will be kept for.
# It can be defined in a human readable short form -- e.g. "1d", "1y".
#
#
#stats:
# enabled: true
# bucket_size: 1d
# retention: 1y


# Server Notices room configuration
#
# Uncomment this section to enable a room which can be used to send notices
Expand Down
1 change: 1 addition & 0 deletions synapse/api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class EventTypes(object):

RoomHistoryVisibility = "m.room.history_visibility"
CanonicalAlias = "m.room.canonical_alias"
Encryption = "m.room.encryption"
RoomAvatar = "m.room.avatar"
RoomEncryption = "m.room.encryption"
GuestAccess = "m.room.guest_access"
Expand Down
16 changes: 15 additions & 1 deletion synapse/api/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,23 @@ def __init__(self, current_version):
self.current_version = current_version


class UnsupportedRoomVersionError(SynapseError):
"""The client's request to create a room used a room version that the server does
not support."""
def __init__(self):
super(UnsupportedRoomVersionError, self).__init__(
code=400,
msg="Homeserver does not support this room version",
errcode=Codes.UNSUPPORTED_ROOM_VERSION,
)


class IncompatibleRoomVersionError(SynapseError):
"""A server is trying to join a room whose version it does not support."""
"""A server is trying to join a room whose version it does not support.
Unlike UnsupportedRoomVersionError, it is specific to the case of the make_join
failing.
"""
def __init__(self, room_version):
super(IncompatibleRoomVersionError, self).__init__(
code=400,
Expand Down
8 changes: 4 additions & 4 deletions synapse/api/room_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ class RoomVersions(object):
EventFormatVersions.V2,
StateResolutionVersions.V2,
)
EVENTID_NOSLASH_TEST = RoomVersion(
"eventid-noslash-test",
RoomDisposition.UNSTABLE,
V4 = RoomVersion(
"4",
RoomDisposition.STABLE,
EventFormatVersions.V3,
StateResolutionVersions.V2,
)
Expand All @@ -95,6 +95,6 @@ class RoomVersions(object):
RoomVersions.V2,
RoomVersions.V3,
RoomVersions.STATE_V2_TEST,
RoomVersions.EVENTID_NOSLASH_TEST,
RoomVersions.V4,
)
} # type: dict[str, RoomVersion]
42 changes: 32 additions & 10 deletions synapse/config/homeserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# 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.

from .api import ApiConfig
from .appservice import AppServiceConfig
from .captcha import CaptchaConfig
Expand All @@ -36,20 +37,41 @@
from .server import ServerConfig
from .server_notices_config import ServerNoticesConfig
from .spam_checker import SpamCheckerConfig
from .stats import StatsConfig
from .tls import TlsConfig
from .user_directory import UserDirectoryConfig
from .voip import VoipConfig
from .workers import WorkerConfig


class HomeServerConfig(ServerConfig, TlsConfig, DatabaseConfig, LoggingConfig,
RatelimitConfig, ContentRepositoryConfig, CaptchaConfig,
VoipConfig, RegistrationConfig, MetricsConfig, ApiConfig,
AppServiceConfig, KeyConfig, SAML2Config, CasConfig,
JWTConfig, PasswordConfig, EmailConfig,
WorkerConfig, PasswordAuthProviderConfig, PushConfig,
SpamCheckerConfig, GroupsConfig, UserDirectoryConfig,
ConsentConfig,
ServerNoticesConfig, RoomDirectoryConfig,
):
class HomeServerConfig(
ServerConfig,
TlsConfig,
DatabaseConfig,
LoggingConfig,
RatelimitConfig,
ContentRepositoryConfig,
CaptchaConfig,
VoipConfig,
RegistrationConfig,
MetricsConfig,
ApiConfig,
AppServiceConfig,
KeyConfig,
SAML2Config,
CasConfig,
JWTConfig,
PasswordConfig,
EmailConfig,
WorkerConfig,
PasswordAuthProviderConfig,
PushConfig,
SpamCheckerConfig,
GroupsConfig,
UserDirectoryConfig,
ConsentConfig,
StatsConfig,
ServerNoticesConfig,
RoomDirectoryConfig,
):
pass
8 changes: 8 additions & 0 deletions synapse/config/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ def default_config(self, generate_secrets=False, **kwargs):
# link. ``%%(app)s`` can be used as a placeholder for the ``app_name`` parameter
# from the ``email`` section.
#
# Once this feature is enabled, Synapse will look for registered users without an
# expiration date at startup and will add one to every account it found using the
# current settings at that time.
# This means that, if a validity period is set, and Synapse is restarted (it will
# then derive an expiration date from the current validity period), and some time
# after that the validity period changes and Synapse is restarted, the users'
# expiration dates won't be updated unless their account is manually renewed.
#
#account_validity:
# enabled: True
# period: 6w
Expand Down
60 changes: 60 additions & 0 deletions synapse/config/stats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Copyright 2018 New Vector 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.

from __future__ import division

import sys

from ._base import Config


class StatsConfig(Config):
"""Stats Configuration
Configuration for the behaviour of synapse's stats engine
"""

def read_config(self, config):
self.stats_enabled = True
self.stats_bucket_size = 86400
self.stats_retention = sys.maxsize
stats_config = config.get("stats", None)
if stats_config:
self.stats_enabled = stats_config.get("enabled", self.stats_enabled)
self.stats_bucket_size = (
self.parse_duration(stats_config.get("bucket_size", "1d")) / 1000
)
self.stats_retention = (
self.parse_duration(
stats_config.get("retention", "%ds" % (sys.maxsize,))
)
/ 1000
)

def default_config(self, config_dir_path, server_name, **kwargs):
return """
# Local statistics collection. Used in populating the room directory.
#
# 'bucket_size' controls how large each statistics timeslice is. It can
# be defined in a human readable short form -- e.g. "1d", "1y".
#
# 'retention' controls how long historical statistics will be kept for.
# It can be defined in a human readable short form -- e.g. "1d", "1y".
#
#
#stats:
# enabled: true
# bucket_size: 1d
# retention: 1y
"""
8 changes: 6 additions & 2 deletions synapse/events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from unpaddedbase64 import encode_base64

from synapse.api.errors import UnsupportedRoomVersionError
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS, EventFormatVersions
from synapse.util.caches import intern_dict
from synapse.util.frozenutils import freeze
Expand Down Expand Up @@ -369,12 +370,15 @@ def room_version_to_event_format(room_version):
Returns:
int
Raises:
UnsupportedRoomVersionError if the room version is unknown
"""
v = KNOWN_ROOM_VERSIONS.get(room_version)

if not v:
# We should have already checked version, so this should not happen
raise RuntimeError("Unrecognized room version %s" % (room_version,))
# this can happen if support is withdrawn for a room version
raise UnsupportedRoomVersionError()

return v.event_format

Expand Down
6 changes: 3 additions & 3 deletions synapse/events/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from twisted.internet import defer

from synapse.api.constants import MAX_DEPTH
from synapse.api.errors import UnsupportedRoomVersionError
from synapse.api.room_versions import (
KNOWN_EVENT_FORMAT_VERSIONS,
KNOWN_ROOM_VERSIONS,
Expand Down Expand Up @@ -178,9 +179,8 @@ def new(self, room_version, key_values):
"""
v = KNOWN_ROOM_VERSIONS.get(room_version)
if not v:
raise Exception(
"No event format defined for version %r" % (room_version,)
)
# this can happen if support is withdrawn for a room version
raise UnsupportedRoomVersionError()
return self.for_room_version(v, key_values)

def for_room_version(self, room_version, key_values):
Expand Down
14 changes: 13 additions & 1 deletion synapse/federation/federation_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
IncompatibleRoomVersionError,
NotFoundError,
SynapseError,
UnsupportedRoomVersionError,
)
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
from synapse.crypto.event_signing import compute_event_signature
Expand Down Expand Up @@ -198,11 +199,22 @@ def _handle_incoming_transaction(self, origin, transaction, request_time):

try:
room_version = yield self.store.get_room_version(room_id)
format_ver = room_version_to_event_format(room_version)
except NotFoundError:
logger.info("Ignoring PDU for unknown room_id: %s", room_id)
continue

try:
format_ver = room_version_to_event_format(room_version)
except UnsupportedRoomVersionError:
# this can happen if support for a given room version is withdrawn,
# so that we still get events for said room.
logger.info(
"Ignoring PDU for room %s with unknown version %s",
room_id,
room_version,
)
continue

event = event_from_pdu_json(p, format_ver)
pdus_by_room.setdefault(room_id, []).append(event)

Expand Down
7 changes: 6 additions & 1 deletion synapse/handlers/federation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1916,6 +1916,11 @@ def _check_for_soft_fail(self, event, state, backfilled):
event.room_id, latest_event_ids=extrem_ids,
)

logger.debug(
"Doing soft-fail check for %s: state %s",
event.event_id, current_state_ids,
)

# Now check if event pass auth against said current state
auth_types = auth_types_for_event(event)
current_state_ids = [
Expand All @@ -1932,7 +1937,7 @@ def _check_for_soft_fail(self, event, state, backfilled):
self.auth.check(room_version, event, auth_events=current_auth_events)
except AuthError as e:
logger.warn(
"Failed current state auth resolution for %r because %s",
"Soft-failing %r because %s",
event, e,
)
event.internal_metadata.soft_failed = True
Expand Down
16 changes: 15 additions & 1 deletion synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from twisted.internet import defer
from twisted.internet.defer import succeed

from synapse.api.constants import EventTypes, Membership
from synapse.api.constants import EventTypes, Membership, RelationTypes
from synapse.api.errors import (
AuthError,
Codes,
Expand Down Expand Up @@ -601,6 +601,20 @@ def create_new_client_event(self, builder, requester=None,

self.validator.validate_new(event)

# If this event is an annotation then we check that that the sender
# can't annotate the same way twice (e.g. stops users from liking an
# event multiple times).
relation = event.content.get("m.relates_to", {})
if relation.get("rel_type") == RelationTypes.ANNOTATION:
relates_to = relation["event_id"]
aggregation_key = relation["key"]

already_exists = yield self.store.has_user_annotated_event(
relates_to, event.type, aggregation_key, event.sender,
)
if already_exists:
raise SynapseError(400, "Can't send same reaction twice")

logger.debug(
"Created event %s",
event.event_id,
Expand Down
Loading

0 comments on commit 8fe26db

Please sign in to comment.