Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

matrix-org / synapse / 4532

23 Sep 2019 - 19:39 coverage decreased (-49.7%) to 17.596%
4532

Pull #6079

buildkite

Richard van der Hoff
update changelog
Pull Request #6079: Add submit_url response parameter to msisdn /requestToken

359 of 12986 branches covered (2.76%)

Branch coverage included in aggregate %.

0 of 7 new or added lines in 1 file covered. (0.0%)

18869 existing lines in 281 files now uncovered.

8809 of 39116 relevant lines covered (22.52%)

0.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

36.28
/synapse/events/builder.py
1
# -*- coding: utf-8 -*-
2
# Copyright 2014-2016 OpenMarket Ltd
3
#
4
# Licensed under the Apache License, Version 2.0 (the "License");
5
# you may not use this file except in compliance with the License.
6
# You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15

16
import attr
1×
17

18
from twisted.internet import defer
1×
19

20
from synapse.api.constants import MAX_DEPTH
1×
21
from synapse.api.errors import UnsupportedRoomVersionError
1×
22
from synapse.api.room_versions import (
1×
23
    KNOWN_EVENT_FORMAT_VERSIONS,
24
    KNOWN_ROOM_VERSIONS,
25
    EventFormatVersions,
26
)
27
from synapse.crypto.event_signing import add_hashes_and_signatures
1×
28
from synapse.types import EventID
1×
29
from synapse.util.stringutils import random_string
1×
30

31
from . import _EventInternalMetadata, event_type_from_format_version
1×
32

33

34
@attr.s(slots=True, cmp=False, frozen=True)
1×
35
class EventBuilder(object):
1×
36
    """A format independent event builder used to build up the event content
37
    before signing the event.
38

39
    (Note that while objects of this class are frozen, the
40
    content/unsigned/internal_metadata fields are still mutable)
41

42
    Attributes:
43
        format_version (int): Event format version
44
        room_id (str)
45
        type (str)
46
        sender (str)
47
        content (dict)
48
        unsigned (dict)
49
        internal_metadata (_EventInternalMetadata)
50

51
        _state (StateHandler)
52
        _auth (synapse.api.Auth)
53
        _store (DataStore)
54
        _clock (Clock)
55
        _hostname (str): The hostname of the server creating the event
56
        _signing_key: The signing key to use to sign the event as the server
57
    """
58

59
    _state = attr.ib()
1×
60
    _auth = attr.ib()
1×
61
    _store = attr.ib()
1×
62
    _clock = attr.ib()
1×
63
    _hostname = attr.ib()
1×
64
    _signing_key = attr.ib()
1×
65

66
    format_version = attr.ib()
1×
67

68
    room_id = attr.ib()
1×
69
    type = attr.ib()
1×
70
    sender = attr.ib()
1×
71

72
    content = attr.ib(default=attr.Factory(dict))
1×
73
    unsigned = attr.ib(default=attr.Factory(dict))
1×
74

75
    # These only exist on a subset of events, so they raise AttributeError if
76
    # someone tries to get them when they don't exist.
77
    _state_key = attr.ib(default=None)
1×
78
    _redacts = attr.ib(default=None)
1×
79
    _origin_server_ts = attr.ib(default=None)
1×
80

81
    internal_metadata = attr.ib(
Branches [[0, 82]] missed. 1×
82
        default=attr.Factory(lambda: _EventInternalMetadata({}))
83
    )
84

85
    @property
1×
86
    def state_key(self):
UNCOV
87
        if self._state_key is not None:
Branches [[0, 88], [0, 90]] missed. !
UNCOV
88
            return self._state_key
!
89

UNCOV
90
        raise AttributeError("state_key")
!
91

92
    def is_state(self):
1×
UNCOV
93
        return self._state_key is not None
!
94

95
    @defer.inlineCallbacks
1×
96
    def build(self, prev_event_ids):
97
        """Transform into a fully signed and hashed event
98

99
        Args:
100
            prev_event_ids (list[str]): The event IDs to use as the prev events
101

102
        Returns:
103
            Deferred[FrozenEvent]
104
        """
105

UNCOV
106
        state_ids = yield self._state.get_current_state_ids(
!
107
            self.room_id, prev_event_ids
108
        )
UNCOV
109
        auth_ids = yield self._auth.compute_auth_events(self, state_ids)
!
110

UNCOV
111
        if self.format_version == EventFormatVersions.V1:
Branches [[0, 112], [0, 115]] missed. !
UNCOV
112
            auth_events = yield self._store.add_event_hashes(auth_ids)
!
UNCOV
113
            prev_events = yield self._store.add_event_hashes(prev_event_ids)
!
114
        else:
UNCOV
115
            auth_events = auth_ids
!
UNCOV
116
            prev_events = prev_event_ids
!
117

UNCOV
118
        old_depth = yield self._store.get_max_depth_of(prev_event_ids)
!
UNCOV
119
        depth = old_depth + 1
!
120

121
        # we cap depth of generated events, to ensure that they are not
122
        # rejected by other servers (and so that they can be persisted in
123
        # the db)
UNCOV
124
        depth = min(depth, MAX_DEPTH)
!
125

UNCOV
126
        event_dict = {
!
127
            "auth_events": auth_events,
128
            "prev_events": prev_events,
129
            "type": self.type,
130
            "room_id": self.room_id,
131
            "sender": self.sender,
132
            "content": self.content,
133
            "unsigned": self.unsigned,
134
            "depth": depth,
135
            "prev_state": [],
136
        }
137

UNCOV
138
        if self.is_state():
Branches [[0, 139], [0, 141]] missed. !
UNCOV
139
            event_dict["state_key"] = self._state_key
!
140

UNCOV
141
        if self._redacts is not None:
Branches [[0, 142], [0, 144]] missed. !
UNCOV
142
            event_dict["redacts"] = self._redacts
!
143

UNCOV
144
        if self._origin_server_ts is not None:
Branches [[0, 145], [0, 147]] missed. !
145
            event_dict["origin_server_ts"] = self._origin_server_ts
!
146

UNCOV
147
        return create_local_event_from_event_dict(
!
148
            clock=self._clock,
149
            hostname=self._hostname,
150
            signing_key=self._signing_key,
151
            format_version=self.format_version,
152
            event_dict=event_dict,
153
            internal_metadata_dict=self.internal_metadata.get_dict(),
154
        )
155

156

157
class EventBuilderFactory(object):
1×
158
    def __init__(self, hs):
1×
UNCOV
159
        self.clock = hs.get_clock()
!
UNCOV
160
        self.hostname = hs.hostname
!
UNCOV
161
        self.signing_key = hs.config.signing_key[0]
!
162

UNCOV
163
        self.store = hs.get_datastore()
!
UNCOV
164
        self.state = hs.get_state_handler()
!
UNCOV
165
        self.auth = hs.get_auth()
!
166

167
    def new(self, room_version, key_values):
1×
168
        """Generate an event builder appropriate for the given room version
169

170
        Deprecated: use for_room_version with a RoomVersion object instead
171

172
        Args:
173
            room_version (str): Version of the room that we're creating an event builder
174
                for
175
            key_values (dict): Fields used as the basis of the new event
176

177
        Returns:
178
            EventBuilder
179
        """
UNCOV
180
        v = KNOWN_ROOM_VERSIONS.get(room_version)
!
UNCOV
181
        if not v:
Branches [[0, 183], [0, 184]] missed. !
182
            # this can happen if support is withdrawn for a room version
183
            raise UnsupportedRoomVersionError()
!
UNCOV
184
        return self.for_room_version(v, key_values)
!
185

186
    def for_room_version(self, room_version, key_values):
1×
187
        """Generate an event builder appropriate for the given room version
188

189
        Args:
190
            room_version (synapse.api.room_versions.RoomVersion):
191
                Version of the room that we're creating an event builder for
192
            key_values (dict): Fields used as the basis of the new event
193

194
        Returns:
195
            EventBuilder
196
        """
UNCOV
197
        return EventBuilder(
!
198
            store=self.store,
199
            state=self.state,
200
            auth=self.auth,
201
            clock=self.clock,
202
            hostname=self.hostname,
203
            signing_key=self.signing_key,
204
            format_version=room_version.event_format,
205
            type=key_values["type"],
206
            state_key=key_values.get("state_key"),
207
            room_id=key_values["room_id"],
208
            sender=key_values["sender"],
209
            content=key_values.get("content", {}),
210
            unsigned=key_values.get("unsigned", {}),
211
            redacts=key_values.get("redacts", None),
212
            origin_server_ts=key_values.get("origin_server_ts", None),
213
        )
214

215

216
def create_local_event_from_event_dict(
1×
217
    clock,
218
    hostname,
219
    signing_key,
220
    format_version,
221
    event_dict,
222
    internal_metadata_dict=None,
223
):
224
    """Takes a fully formed event dict, ensuring that fields like `origin`
225
    and `origin_server_ts` have correct values for a locally produced event,
226
    then signs and hashes it.
227

228
    Args:
229
        clock (Clock)
230
        hostname (str)
231
        signing_key
232
        format_version (int)
233
        event_dict (dict)
234
        internal_metadata_dict (dict|None)
235

236
    Returns:
237
        FrozenEvent
238
    """
239

UNCOV
240
    if format_version not in KNOWN_EVENT_FORMAT_VERSIONS:
Branches [[0, 241], [0, 243]] missed. !
241
        raise Exception("No event format defined for version %r" % (format_version,))
!
242

UNCOV
243
    if internal_metadata_dict is None:
Branches [[0, 244], [0, 246]] missed. !
UNCOV
244
        internal_metadata_dict = {}
!
245

UNCOV
246
    time_now = int(clock.time_msec())
!
247

UNCOV
248
    if format_version == EventFormatVersions.V1:
Branches [[0, 249], [0, 251]] missed. !
UNCOV
249
        event_dict["event_id"] = _create_event_id(clock, hostname)
!
250

UNCOV
251
    event_dict["origin"] = hostname
!
UNCOV
252
    event_dict.setdefault("origin_server_ts", time_now)
!
253

UNCOV
254
    event_dict.setdefault("unsigned", {})
!
UNCOV
255
    age = event_dict["unsigned"].pop("age", 0)
!
UNCOV
256
    event_dict["unsigned"].setdefault("age_ts", time_now - age)
!
257

UNCOV
258
    event_dict.setdefault("signatures", {})
!
259

UNCOV
260
    add_hashes_and_signatures(event_dict, hostname, signing_key)
!
UNCOV
261
    return event_type_from_format_version(format_version)(
!
262
        event_dict, internal_metadata_dict=internal_metadata_dict
263
    )
264

265

266
# A counter used when generating new event IDs
267
_event_id_counter = 0
1×
268

269

270
def _create_event_id(clock, hostname):
1×
271
    """Create a new event ID
272

273
    Args:
274
        clock (Clock)
275
        hostname (str): The server name for the event ID
276

277
    Returns:
278
        str
279
    """
280

281
    global _event_id_counter
282

UNCOV
283
    i = str(_event_id_counter)
!
UNCOV
284
    _event_id_counter += 1
!
285

UNCOV
286
    local_part = str(int(clock.time())) + i + random_string(5)
!
287

UNCOV
288
    e_id = EventID(local_part, hostname)
!
289

UNCOV
290
    return e_id.to_string()
!
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2019 Coveralls, LLC