1/* Copyright 2016-2017 Vector Creations Ltd
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16package gomatrixserverlib
17
18import (
19	"bytes"
20	"encoding/json"
21	"errors"
22	"fmt"
23	"reflect"
24	"strings"
25	"time"
26
27	"github.com/matrix-org/util"
28	"github.com/tidwall/gjson"
29	"github.com/tidwall/sjson"
30	"golang.org/x/crypto/ed25519"
31)
32
33// A StateKeyTuple is the combination of an event type and an event state key.
34// It is often used as a key in maps.
35type StateKeyTuple struct {
36	// The "type" key of a matrix event.
37	EventType string
38	// The "state_key" of a matrix event.
39	// The empty string is a legitimate value for the "state_key" in matrix
40	// so take care to initialise this field lest you accidentally request a
41	// "state_key" with the go default of the empty string.
42	StateKey string
43}
44
45// An EventReference is a reference to a matrix event.
46type EventReference struct {
47	// The event ID of the event.
48	EventID string
49	// The sha256 of the redacted event.
50	EventSHA256 Base64Bytes
51}
52
53// Event validation errors
54const (
55	EventValidationTooLarge int = 1
56)
57
58// EventValidationError is returned if there is a problem validating an event
59type EventValidationError struct {
60	Message string
61	Code    int
62}
63
64func (e EventValidationError) Error() string {
65	return e.Message
66}
67
68// An EventBuilder is used to build a new event.
69// These can be exchanged between matrix servers in the federation APIs when
70// joining or leaving a room.
71type EventBuilder struct {
72	// The user ID of the user sending the event.
73	Sender string `json:"sender"`
74	// The room ID of the room this event is in.
75	RoomID string `json:"room_id"`
76	// The type of the event.
77	Type string `json:"type"`
78	// The state_key of the event if the event is a state event or nil if the event is not a state event.
79	StateKey *string `json:"state_key,omitempty"`
80	// The events that immediately preceded this event in the room history. This can be
81	// either []EventReference for room v1/v2, and []string for room v3 onwards.
82	PrevEvents interface{} `json:"prev_events"`
83	// The events needed to authenticate this event. This can be
84	// either []EventReference for room v1/v2, and []string for room v3 onwards.
85	AuthEvents interface{} `json:"auth_events"`
86	// The event ID of the event being redacted if this event is a "m.room.redaction".
87	Redacts string `json:"redacts,omitempty"`
88	// The depth of the event, This should be one greater than the maximum depth of the previous events.
89	// The create event has a depth of 1.
90	Depth int64 `json:"depth"`
91	// The JSON object for "signatures" key of the event.
92	Signature RawJSON `json:"signatures,omitempty"`
93	// The JSON object for "content" key of the event.
94	Content RawJSON `json:"content"`
95	// The JSON object for the "unsigned" key
96	Unsigned RawJSON `json:"unsigned,omitempty"`
97}
98
99// SetContent sets the JSON content key of the event.
100func (eb *EventBuilder) SetContent(content interface{}) (err error) {
101	eb.Content, err = json.Marshal(content)
102	return
103}
104
105// SetUnsigned sets the JSON unsigned key of the event.
106func (eb *EventBuilder) SetUnsigned(unsigned interface{}) (err error) {
107	eb.Unsigned, err = json.Marshal(unsigned)
108	return
109}
110
111// An Event is a matrix event.
112// The event should always contain valid JSON.
113// If the event content hash is invalid then the event is redacted.
114// Redacted events contain only the fields covered by the event signature.
115// The fields have different formats depending on the room version - see
116// eventFormatV1Fields, eventFormatV2Fields.
117type Event struct {
118	redacted    bool
119	eventJSON   []byte
120	fields      interface{}
121	roomVersion RoomVersion
122}
123
124type eventFields struct {
125	EventID        string     `json:"event_id,omitempty"`
126	RoomID         string     `json:"room_id"`
127	Sender         string     `json:"sender"`
128	Type           string     `json:"type"`
129	StateKey       *string    `json:"state_key"`
130	Content        RawJSON    `json:"content"`
131	Redacts        string     `json:"redacts"`
132	Depth          int64      `json:"depth"`
133	Unsigned       RawJSON    `json:"unsigned"`
134	OriginServerTS Timestamp  `json:"origin_server_ts"`
135	Origin         ServerName `json:"origin"`
136}
137
138// Fields for room versions 1, 2.
139type eventFormatV1Fields struct {
140	eventFields
141	PrevEvents []EventReference `json:"prev_events"`
142	AuthEvents []EventReference `json:"auth_events"`
143}
144
145// Fields for room versions 3, 4, 5.
146type eventFormatV2Fields struct {
147	eventFields
148	PrevEvents []string `json:"prev_events"`
149	AuthEvents []string `json:"auth_events"`
150}
151
152var emptyEventReferenceList = []EventReference{}
153
154// Build a new Event.
155// This is used when a local event is created on this server.
156// Call this after filling out the necessary fields.
157// This can be called multiple times on the same builder.
158// A different event ID must be supplied each time this is called.
159func (eb *EventBuilder) Build(
160	now time.Time, origin ServerName, keyID KeyID,
161	privateKey ed25519.PrivateKey, roomVersion RoomVersion,
162) (result *Event, err error) {
163	if ver, ok := SupportedRoomVersions()[roomVersion]; !ok || !ver.Supported {
164		return nil, UnsupportedRoomVersionError{
165			Version: roomVersion,
166		}
167	}
168
169	eventFormat, err := roomVersion.EventFormat()
170	if err != nil {
171		return result, err
172	}
173	eventIDFormat, err := roomVersion.EventIDFormat()
174	if err != nil {
175		return result, err
176	}
177	var event struct {
178		EventBuilder
179		EventID        string     `json:"event_id"`
180		OriginServerTS Timestamp  `json:"origin_server_ts"`
181		Origin         ServerName `json:"origin"`
182		// This key is either absent or an empty list.
183		// If it is absent then the pointer is nil and omitempty removes it.
184		// Otherwise it points to an empty list and omitempty keeps it.
185		PrevState *[]EventReference `json:"prev_state,omitempty"`
186	}
187	event.EventBuilder = *eb
188	if eventIDFormat == EventIDFormatV1 {
189		event.EventID = fmt.Sprintf("$%s:%s", util.RandomString(16), origin)
190	}
191	event.OriginServerTS = AsTimestamp(now)
192	event.Origin = origin
193	switch eventFormat {
194	case EventFormatV1:
195		// If either prev_events or auth_events are nil slices then Go will
196		// marshal them into 'null' instead of '[]', which is bad. Since the
197		// EventBuilder struct is instantiated outside of gomatrixserverlib
198		// let's just make sure that they haven't been left as nil slices.
199		if event.PrevEvents == nil {
200			event.PrevEvents = []EventReference{}
201		}
202		if event.AuthEvents == nil {
203			event.AuthEvents = []EventReference{}
204		}
205	case EventFormatV2:
206		// In this event format, prev_events and auth_events are lists of
207		// event IDs as a []string, rather than full-blown []EventReference.
208		// Since gomatrixserverlib otherwise deals with EventReferences,
209		// take the event IDs out of these and replace the prev_events and
210		// auth_events with those new arrays.
211		switch prevEvents := event.PrevEvents.(type) {
212		case []string:
213			event.PrevEvents = prevEvents
214		case []EventReference:
215			resPrevEvents := []string{}
216			for _, prevEvent := range prevEvents {
217				resPrevEvents = append(resPrevEvents, prevEvent.EventID)
218			}
219			event.PrevEvents = resPrevEvents
220		case nil:
221			event.PrevEvents = []string{}
222		}
223		switch authEvents := event.AuthEvents.(type) {
224		case []string:
225			event.AuthEvents = authEvents
226		case []EventReference:
227			resAuthEvents := []string{}
228			for _, authEvent := range authEvents {
229				resAuthEvents = append(resAuthEvents, authEvent.EventID)
230			}
231			event.AuthEvents = resAuthEvents
232		case nil:
233			event.AuthEvents = []string{}
234		}
235	}
236
237	if event.StateKey != nil {
238		// In early versions of the matrix protocol state events
239		// had a "prev_state" key that listed the state events with
240		// the same type and state key that this event replaced.
241		// This was later dropped from the protocol.
242		// Synapse ignores the contents of the key but still expects
243		// the key to be present in state events.
244		event.PrevState = &emptyEventReferenceList
245	}
246
247	var eventJSON []byte
248	if eventJSON, err = json.Marshal(&event); err != nil {
249		return
250	}
251
252	if eventFormat == EventFormatV2 {
253		if eventJSON, err = sjson.DeleteBytes(eventJSON, "event_id"); err != nil {
254			return
255		}
256	}
257
258	if eventJSON, err = addContentHashesToEvent(eventJSON); err != nil {
259		return
260	}
261
262	if eventJSON, err = signEvent(string(origin), keyID, privateKey, eventJSON, roomVersion); err != nil {
263		return
264	}
265
266	if eventJSON, err = EnforcedCanonicalJSON(eventJSON, roomVersion); err != nil {
267		return
268	}
269
270	result = &Event{}
271	result.roomVersion = roomVersion
272
273	if err = result.populateFieldsFromJSON("", eventJSON); err != nil {
274		return
275	}
276
277	if err = result.CheckFields(); err != nil {
278		return
279	}
280
281	return
282}
283
284// NewEventFromUntrustedJSON loads a new event from some JSON that may be invalid.
285// This checks that the event is valid JSON.
286// It also checks the content hashes to ensure the event has not been tampered with.
287// This should be used when receiving new events from remote servers.
288func NewEventFromUntrustedJSON(eventJSON []byte, roomVersion RoomVersion) (result *Event, err error) {
289	if ver, ok := SupportedRoomVersions()[roomVersion]; !ok || !ver.Supported {
290		return nil, UnsupportedRoomVersionError{
291			Version: roomVersion,
292		}
293	}
294
295	if r := gjson.GetBytes(eventJSON, "_*"); r.Exists() {
296		err = fmt.Errorf("gomatrixserverlib NewEventFromUntrustedJSON: %w", UnexpectedHeaderedEvent{})
297		return
298	}
299
300	var enforceCanonicalJSON bool
301	if enforceCanonicalJSON, err = roomVersion.EnforceCanonicalJSON(); err != nil {
302		return
303	}
304	if enforceCanonicalJSON {
305		if err = verifyEnforcedCanonicalJSON(eventJSON); err != nil {
306			err = BadJSONError{err}
307			return
308		}
309	}
310
311	result = &Event{}
312	result.roomVersion = roomVersion
313
314	var eventFormat EventFormat
315	eventFormat, err = result.roomVersion.EventFormat()
316	if err != nil {
317		return
318	}
319
320	if eventFormat == EventFormatV2 {
321		if eventJSON, err = sjson.DeleteBytes(eventJSON, "event_id"); err != nil {
322			return
323		}
324	}
325
326	if err = result.populateFieldsFromJSON("", eventJSON); err != nil {
327		return
328	}
329
330	// Synapse removes these keys from events in case a server accidentally added them.
331	// https://github.com/matrix-org/synapse/blob/v0.18.5/synapse/crypto/event_signing.py#L57-L62
332	for _, key := range []string{"outlier", "destinations", "age_ts"} {
333		if eventJSON, err = sjson.DeleteBytes(eventJSON, key); err != nil {
334			return
335		}
336	}
337
338	// We know the JSON must be valid here.
339	eventJSON = CanonicalJSONAssumeValid(eventJSON)
340
341	if err = checkEventContentHash(eventJSON); err != nil {
342		result.redacted = true
343
344		// If the content hash doesn't match then we have to discard all non-essential fields
345		// because they've been tampered with.
346		var redactedJSON []byte
347		if redactedJSON, err = redactEvent(eventJSON, roomVersion); err != nil {
348			return
349		}
350
351		redactedJSON = CanonicalJSONAssumeValid(redactedJSON)
352
353		// We need to ensure that `result` is the redacted event.
354		// If redactedJSON is the same as eventJSON then `result` is already
355		// correct. If not then we need to reparse.
356		//
357		// Yes, this means that for some events we parse twice (which is slow),
358		// but means that parsing unredacted events is fast.
359		if !bytes.Equal(redactedJSON, eventJSON) {
360			if result, err = NewEventFromTrustedJSON(redactedJSON, true, roomVersion); err != nil {
361				return
362			}
363		}
364	}
365
366	err = result.CheckFields()
367	return
368}
369
370// NewEventFromTrustedJSON loads a new event from some JSON that must be valid.
371// This will be more efficient than NewEventFromUntrustedJSON since it can skip cryptographic checks.
372// This can be used when loading matrix events from a local database.
373func NewEventFromTrustedJSON(eventJSON []byte, redacted bool, roomVersion RoomVersion) (result *Event, err error) {
374	if ver, ok := SupportedRoomVersions()[roomVersion]; !ok || !ver.Supported {
375		return nil, UnsupportedRoomVersionError{
376			Version: roomVersion,
377		}
378	}
379
380	result = &Event{}
381	result.roomVersion = roomVersion
382	result.redacted = redacted
383	err = result.populateFieldsFromJSON("", eventJSON) // "" -> event ID not known
384	return
385}
386
387// NewEventFromTrustedJSONWithEventID loads a new event from some JSON that must be valid
388// and that the event ID is already known. This must ONLY be used when retrieving
389// an event from the database and NEVER when accepting an event over federation.
390// This will be more efficient than NewEventFromTrustedJSON since, if the event
391// ID is known, we skip all the reference hash and canonicalisation work.
392func NewEventFromTrustedJSONWithEventID(eventID string, eventJSON []byte, redacted bool, roomVersion RoomVersion) (result *Event, err error) {
393	if ver, ok := SupportedRoomVersions()[roomVersion]; !ok || !ver.Supported {
394		return nil, UnsupportedRoomVersionError{
395			Version: roomVersion,
396		}
397	}
398
399	result = &Event{}
400	result.roomVersion = roomVersion
401	result.redacted = redacted
402	err = result.populateFieldsFromJSON(eventID, eventJSON)
403	return
404}
405
406// populateFieldsFromJSON takes the JSON and populates the event
407// fields with it. If the event ID is already known, because the
408// event came from storage, then we pass it in here as a means of
409// avoiding all of the canonicalisation and reference hash
410// calculations etc as they are expensive operations. If the event
411// ID isn't known, pass an empty string and we'll work it out.
412func (e *Event) populateFieldsFromJSON(eventIDIfKnown string, eventJSON []byte) error {
413	// Work out the format of the event from the room version.
414	var eventFormat EventFormat
415	eventFormat, err := e.roomVersion.EventFormat()
416	if err != nil {
417		return err
418	}
419
420	switch eventFormat {
421	case EventFormatV1:
422		e.eventJSON = eventJSON
423		// Unmarshal the event fields.
424		fields := eventFormatV1Fields{}
425		if err := json.Unmarshal(eventJSON, &fields); err != nil {
426			return err
427		}
428		// Populate the fields of the received object.
429		fields.fixNilSlices()
430		e.fields = fields
431	case EventFormatV2:
432		// Later room versions don't have the event_id field so if it is
433		// present, remove it.
434		if eventJSON, err = sjson.DeleteBytes(eventJSON, "event_id"); err != nil {
435			return err
436		}
437		e.eventJSON = eventJSON
438		// Unmarshal the event fields.
439		fields := eventFormatV2Fields{}
440		if err := json.Unmarshal(eventJSON, &fields); err != nil {
441			return err
442		}
443		// Generate a hash of the event which forms the event ID.
444		if eventIDIfKnown != "" {
445			fields.EventID = eventIDIfKnown
446		} else {
447			fields.EventID, err = e.generateEventID()
448			if err != nil {
449				return err
450			}
451		}
452		// Populate the fields of the received object.
453		fields.fixNilSlices()
454		e.fields = fields
455	default:
456		return errors.New("gomatrixserverlib: room version not supported")
457	}
458
459	return nil
460}
461
462// Redacted returns whether the event is redacted.
463func (e *Event) Redacted() bool { return e.redacted }
464
465// Version returns the version of this event
466func (e *Event) Version() RoomVersion { return e.roomVersion }
467
468// JSON returns the JSON bytes for the event.
469func (e *Event) JSON() []byte { return e.eventJSON }
470
471// Redact returns a redacted copy of the event.
472func (e *Event) Redact() *Event {
473	if e.redacted {
474		return e
475	}
476	eventJSON, err := redactEvent(e.eventJSON, e.roomVersion)
477	if err != nil {
478		// This is unreachable for events created with EventBuilder.Build or NewEventFromUntrustedJSON
479		panic(fmt.Errorf("gomatrixserverlib: invalid event %v", err))
480	}
481	if eventJSON, err = EnforcedCanonicalJSON(eventJSON, e.roomVersion); err != nil {
482		// This is unreachable for events created with EventBuilder.Build or NewEventFromUntrustedJSON
483		panic(fmt.Errorf("gomatrixserverlib: invalid event %v", err))
484	}
485	result := Event{
486		redacted:    true,
487		roomVersion: e.roomVersion,
488		eventJSON:   eventJSON,
489	}
490	err = result.populateFieldsFromJSON(e.EventID(), eventJSON)
491	if err != nil {
492		panic(fmt.Errorf("gomatrixserverlib: populateFieldsFromJSON failed %v", err))
493	}
494	return &result
495}
496
497// SetUnsigned sets the unsigned key of the event.
498// Returns a copy of the event with the "unsigned" key set.
499func (e *Event) SetUnsigned(unsigned interface{}) (*Event, error) {
500	var eventAsMap map[string]RawJSON
501	var err error
502	if err = json.Unmarshal(e.eventJSON, &eventAsMap); err != nil {
503		return nil, err
504	}
505	unsignedJSON, err := json.Marshal(unsigned)
506	if err != nil {
507		return nil, err
508	}
509	eventAsMap["unsigned"] = unsignedJSON
510	eventJSON, err := json.Marshal(eventAsMap)
511	if err != nil {
512		return nil, err
513	}
514	if eventJSON, err = EnforcedCanonicalJSON(eventJSON, e.roomVersion); err != nil {
515		return nil, err
516	}
517	if err = e.updateUnsignedFields(unsignedJSON); err != nil {
518		return nil, err
519	}
520	result := *e
521	result.eventJSON = eventJSON
522	return &result, nil
523}
524
525// SetUnsignedField takes a path and value to insert into the unsigned dict of
526// the event.
527// path is a dot separated path into the unsigned dict (see gjson package
528// for details on format). In particular some characters like '.' and '*' must
529// be escaped.
530func (e *Event) SetUnsignedField(path string, value interface{}) error {
531	// The safest way is to change the unsigned json and then reparse the
532	// event fully. But since we are only changing the unsigned section,
533	// which doesn't affect the signatures or hashes, we can cheat and
534	// just fiddle those bits directly.
535
536	path = "unsigned." + path
537	eventJSON, err := sjson.SetBytes(e.eventJSON, path, value)
538	if err != nil {
539		return err
540	}
541	eventJSON = CanonicalJSONAssumeValid(eventJSON)
542
543	res := gjson.GetBytes(eventJSON, "unsigned")
544	unsigned := RawJSONFromResult(res, eventJSON)
545	if err = e.updateUnsignedFields(unsigned); err != nil {
546		return err
547	}
548
549	e.eventJSON = eventJSON
550
551	return nil
552}
553
554// updateUnsignedFields sets the value of the unsigned field and then
555// fixes nil slices if needed.
556func (e *Event) updateUnsignedFields(unsigned []byte) error {
557	switch fields := e.fields.(type) {
558	case eventFormatV1Fields:
559		fields.Unsigned = unsigned
560		fields.fixNilSlices()
561		e.fields = fields
562	case eventFormatV2Fields:
563		fields.Unsigned = unsigned
564		fields.fixNilSlices()
565		e.fields = fields
566	default:
567		return UnsupportedRoomVersionError{Version: e.roomVersion}
568	}
569	return nil
570}
571
572// EventReference returns an EventReference for the event.
573// The reference can be used to refer to this event from other events.
574func (e *Event) EventReference() EventReference {
575	reference, err := referenceOfEvent(e.eventJSON, e.roomVersion)
576	if err != nil {
577		// This is unreachable for events created with EventBuilder.Build or NewEventFromUntrustedJSON
578		// This can be reached if NewEventFromTrustedJSON is given JSON from an untrusted source.
579		panic(fmt.Errorf("gomatrixserverlib: invalid event %v (%q)", err, string(e.eventJSON)))
580	}
581	return reference
582}
583
584// Sign returns a copy of the event with an additional signature.
585func (e *Event) Sign(signingName string, keyID KeyID, privateKey ed25519.PrivateKey) Event {
586	eventJSON, err := signEvent(signingName, keyID, privateKey, e.eventJSON, e.roomVersion)
587	if err != nil {
588		// This is unreachable for events created with EventBuilder.Build or NewEventFromUntrustedJSON
589		panic(fmt.Errorf("gomatrixserverlib: invalid event %v (%q)", err, string(e.eventJSON)))
590	}
591	if eventJSON, err = EnforcedCanonicalJSON(eventJSON, e.roomVersion); err != nil {
592		// This is unreachable for events created with EventBuilder.Build or NewEventFromUntrustedJSON
593		panic(fmt.Errorf("gomatrixserverlib: invalid event %v (%q)", err, string(e.eventJSON)))
594	}
595	return Event{
596		redacted:    e.redacted,
597		eventJSON:   eventJSON,
598		fields:      e.fields,
599		roomVersion: e.roomVersion,
600	}
601}
602
603// KeyIDs returns a list of key IDs that the named entity has signed the event with.
604func (e *Event) KeyIDs(signingName string) []KeyID {
605	keyIDs, err := ListKeyIDs(signingName, e.eventJSON)
606	if err != nil {
607		// This should unreachable for events created with EventBuilder.Build or NewEventFromUntrustedJSON
608		panic(fmt.Errorf("gomatrixserverlib: invalid event %v", err))
609	}
610	return keyIDs
611}
612
613// StateKey returns the "state_key" of the event, or the nil if the event is not a state event.
614func (e *Event) StateKey() *string {
615	switch fields := e.fields.(type) {
616	case eventFormatV1Fields:
617		return fields.StateKey
618	case eventFormatV2Fields:
619		return fields.StateKey
620	default:
621		panic(e.invalidFieldType())
622	}
623}
624
625// StateKeyEquals returns true if the event is a state event and the "state_key" matches.
626func (e *Event) StateKeyEquals(stateKey string) bool {
627	var sk *string
628	switch fields := e.fields.(type) {
629	case eventFormatV1Fields:
630		sk = fields.StateKey
631	case eventFormatV2Fields:
632		sk = fields.StateKey
633	default:
634		panic(e.invalidFieldType())
635	}
636	if sk == nil {
637		return false
638	}
639	return *sk == stateKey
640}
641
642const (
643	// The event ID, room ID, sender, event type and state key fields cannot be
644	// bigger than this.
645	// https://github.com/matrix-org/synapse/blob/v0.21.0/synapse/event_auth.py#L173-L182
646	maxIDLength = 255
647	// The entire event JSON, including signatures cannot be bigger than this.
648	// https://github.com/matrix-org/synapse/blob/v0.21.0/synapse/event_auth.py#L183-184
649	maxEventLength = 65536
650)
651
652// CheckFields checks that the event fields are valid.
653// Returns an error if the IDs have the wrong format or too long.
654// Returns an error if the total length of the event JSON is too long.
655// Returns an error if the event ID doesn't match the origin of the event.
656// https://matrix.org/docs/spec/client_server/r0.2.0.html#size-limits
657func (e *Event) CheckFields() error { // nolint: gocyclo
658	var fields eventFields
659	switch f := e.fields.(type) {
660	case eventFormatV1Fields:
661		if f.AuthEvents == nil || f.PrevEvents == nil {
662			return errors.New("gomatrixserverlib: auth events and prev events must not be nil")
663		}
664		fields = f.eventFields
665	case eventFormatV2Fields:
666		if f.AuthEvents == nil || f.PrevEvents == nil {
667			return errors.New("gomatrixserverlib: auth events and prev events must not be nil")
668		}
669		fields = f.eventFields
670	default:
671		panic(e.invalidFieldType())
672	}
673
674	if len(e.eventJSON) > maxEventLength {
675		return EventValidationError{
676			Code:    EventValidationTooLarge,
677			Message: fmt.Sprintf("gomatrixserverlib: event is too long, length %d > maximum %d", len(e.eventJSON), maxEventLength),
678		}
679	}
680
681	if len(fields.Type) > maxIDLength {
682		return EventValidationError{
683			Code:    EventValidationTooLarge,
684			Message: fmt.Sprintf("gomatrixserverlib: event type is too long, length %d > maximum %d", len(fields.Type), maxIDLength),
685		}
686	}
687
688	if fields.StateKey != nil && len(*fields.StateKey) > maxIDLength {
689		return EventValidationError{
690			Code:    EventValidationTooLarge,
691			Message: fmt.Sprintf("gomatrixserverlib: state key is too long, length %d > maximum %d", len(*fields.StateKey), maxIDLength),
692		}
693	}
694
695	_, err := checkID(fields.RoomID, "room", '!')
696	if err != nil {
697		return err
698	}
699
700	origin := fields.Origin
701
702	senderDomain, err := checkID(fields.Sender, "user", '@')
703	if err != nil {
704		return err
705	}
706
707	if origin != ServerName(senderDomain) {
708		// For the most part all events should be sent by a user on the
709		// originating server.
710		//
711		// However "m.room.member" events created from third-party invites
712		// are allowed to have a different sender because they have the same
713		// sender as the "m.room.third_party_invite" event they derived from.
714		// https://github.com/matrix-org/synapse/blob/v0.21.0/synapse/event_auth.py#L58-L64
715		//
716		// Also, some old versions of synapse had a bug wherein some
717		// joins/leaves used the origin and event id supplied by the helping
718		// server instead of the joining/leaving server.
719		//
720		// So in general we allow the sender to be different from the
721		// origin for m.room.member events. In any case, we check it was
722		// signed by both servers later.
723		if fields.Type != MRoomMember {
724			return fmt.Errorf(
725				"gomatrixserverlib: sender domain doesn't match origin: %q != %q",
726				senderDomain, origin,
727			)
728		}
729	}
730
731	return nil
732}
733
734func checkID(id, kind string, sigil byte) (domain string, err error) {
735	domain, err = domainFromID(id)
736	if err != nil {
737		return
738	}
739	if id[0] != sigil {
740		err = fmt.Errorf(
741			"gomatrixserverlib: invalid %s ID, wanted first byte to be '%c' got '%c'",
742			kind, sigil, id[0],
743		)
744		return
745	}
746	if len(id) > maxIDLength {
747		err = fmt.Errorf(
748			"gomatrixserverlib: %s ID is too long, length %d > maximum %d",
749			kind, len(id), maxIDLength,
750		)
751		return
752	}
753	return
754}
755
756// Origin returns the name of the server that sent the event
757func (e *Event) Origin() ServerName {
758	switch fields := e.fields.(type) {
759	case eventFormatV1Fields:
760		return fields.Origin
761	case eventFormatV2Fields:
762		return fields.Origin
763	default:
764		panic(e.invalidFieldType())
765	}
766}
767
768func (e *Event) generateEventID() (eventID string, err error) {
769	var eventFormat EventFormat
770	eventFormat, err = e.roomVersion.EventFormat()
771	if err != nil {
772		return
773	}
774	switch eventFormat {
775	case EventFormatV1:
776		eventID = e.fields.(eventFormatV1Fields).EventID
777	case EventFormatV2:
778		eventJSON := e.eventJSON
779		var reference EventReference
780		reference, err = referenceOfEvent(eventJSON, e.roomVersion)
781		if err != nil {
782			return
783		}
784		eventID = reference.EventID
785	default:
786		err = errors.New("gomatrixserverlib: unknown room version")
787	}
788	return
789}
790
791// EventID returns the event ID of the event.
792func (e *Event) EventID() string {
793	switch fields := e.fields.(type) {
794	case eventFormatV1Fields:
795		return fields.EventID
796	case eventFormatV2Fields:
797		return fields.EventID
798	default:
799		panic(e.invalidFieldType())
800	}
801}
802
803// Sender returns the user ID of the sender of the event.
804func (e *Event) Sender() string {
805	switch fields := e.fields.(type) {
806	case eventFormatV1Fields:
807		return fields.Sender
808	case eventFormatV2Fields:
809		return fields.Sender
810	default:
811		panic(e.invalidFieldType())
812	}
813}
814
815// Type returns the type of the event.
816func (e *Event) Type() string {
817	switch fields := e.fields.(type) {
818	case eventFormatV1Fields:
819		return fields.Type
820	case eventFormatV2Fields:
821		return fields.Type
822	default:
823		panic(e.invalidFieldType())
824	}
825}
826
827// OriginServerTS returns the unix timestamp when this event was created on the origin server, with millisecond resolution.
828func (e *Event) OriginServerTS() Timestamp {
829	switch fields := e.fields.(type) {
830	case eventFormatV1Fields:
831		return fields.OriginServerTS
832	case eventFormatV2Fields:
833		return fields.OriginServerTS
834	default:
835		panic(e.invalidFieldType())
836	}
837}
838
839// Unsigned returns the object under the 'unsigned' key of the event.
840func (e *Event) Unsigned() []byte {
841	switch fields := e.fields.(type) {
842	case eventFormatV1Fields:
843		return fields.Unsigned
844	case eventFormatV2Fields:
845		return fields.Unsigned
846	default:
847		panic(e.invalidFieldType())
848	}
849}
850
851// Content returns the content JSON of the event.
852func (e *Event) Content() []byte {
853	switch fields := e.fields.(type) {
854	case eventFormatV1Fields:
855		return []byte(fields.Content)
856	case eventFormatV2Fields:
857		return []byte(fields.Content)
858	default:
859		panic(e.invalidFieldType())
860	}
861}
862
863// PrevEvents returns references to the direct ancestors of the event.
864func (e *Event) PrevEvents() []EventReference {
865	switch fields := e.fields.(type) {
866	case eventFormatV1Fields:
867		return fields.PrevEvents
868	case eventFormatV2Fields:
869		result := make([]EventReference, 0, len(fields.PrevEvents))
870		for _, id := range fields.PrevEvents {
871			// In the new event format, the event ID is already the hash of
872			// the event. Since we will have generated the event ID before
873			// now, we can just knock the sigil $ off the front and use that
874			// as the event SHA256.
875			var sha Base64Bytes
876			if err := sha.Decode(id[1:]); err != nil {
877				panic("gomatrixserverlib: event ID is malformed: " + err.Error())
878			}
879			result = append(result, EventReference{
880				EventID:     id,
881				EventSHA256: sha,
882			})
883		}
884		return result
885	default:
886		panic(e.invalidFieldType())
887	}
888}
889
890// PrevEventIDs returns the event IDs of the direct ancestors of the event.
891func (e *Event) PrevEventIDs() []string {
892	switch fields := e.fields.(type) {
893	case eventFormatV1Fields:
894		result := make([]string, 0, len(fields.PrevEvents))
895		for _, id := range fields.PrevEvents {
896			result = append(result, id.EventID)
897		}
898		return result
899	case eventFormatV2Fields:
900		return fields.PrevEvents
901	default:
902		panic(e.invalidFieldType())
903	}
904}
905
906func (e *Event) extractContent(eventType string, content interface{}) error {
907	eventFormat, err := e.roomVersion.EventFormat()
908	if err != nil {
909		panic(err)
910	}
911	var fields eventFields
912	switch eventFormat {
913	case EventFormatV1:
914		fields = e.fields.(eventFormatV1Fields).eventFields
915	case EventFormatV2:
916		fields = e.fields.(eventFormatV2Fields).eventFields
917	default:
918		panic(e.invalidFieldType())
919	}
920	if fields.Type != eventType {
921		return fmt.Errorf("gomatrixserverlib: not a %s event", eventType)
922	}
923	return json.Unmarshal(fields.Content, &content)
924}
925
926// Membership returns the value of the content.membership field if this event
927// is an "m.room.member" event.
928// Returns an error if the event is not a m.room.member event or if the content
929// is not valid m.room.member content.
930func (e *Event) Membership() (string, error) {
931	var content struct {
932		Membership string `json:"membership"`
933	}
934	if err := e.extractContent(MRoomMember, &content); err != nil {
935		return "", err
936	}
937	if e.StateKey() == nil {
938		return "", fmt.Errorf("gomatrixserverlib: Membersip() event is not a m.room.member event, missing state key")
939	}
940	return content.Membership, nil
941}
942
943// JoinRule returns the value of the content.join_rule field if this event
944// is an "m.room.join_rules" event.
945// Returns an error if the event is not a m.room.join_rules event or if the content
946// is not valid m.room.join_rules content.
947func (e *Event) JoinRule() (string, error) {
948	if !e.StateKeyEquals("") {
949		return "", fmt.Errorf("gomatrixserverlib: JoinRule() event is not a m.room.join_rules event, bad state key")
950	}
951	var content JoinRuleContent
952	if err := e.extractContent(MRoomJoinRules, &content); err != nil {
953		return "", err
954	}
955	return content.JoinRule, nil
956}
957
958// HistoryVisibility returns the value of the content.history_visibility field if this event
959// is an "m.room.history_visibility" event.
960// Returns an error if the event is not a m.room.history_visibility event or if the content
961// is not valid m.room.history_visibility content.
962func (e *Event) HistoryVisibility() (string, error) {
963	if !e.StateKeyEquals("") {
964		return "", fmt.Errorf("gomatrixserverlib: HistoryVisibility() event is not a m.room.history_visibility event, bad state key")
965	}
966	var content HistoryVisibilityContent
967	if err := e.extractContent(MRoomHistoryVisibility, &content); err != nil {
968		return "", err
969	}
970	return content.HistoryVisibility, nil
971}
972
973// PowerLevels returns the power levels content if this event
974// is an "m.room.power_levels" event.
975// Returns an error if the event is not a m.room.power_levels event or if the content
976// is not valid m.room.power_levels content.
977func (e *Event) PowerLevels() (*PowerLevelContent, error) {
978	if !e.StateKeyEquals("") {
979		return nil, fmt.Errorf("gomatrixserverlib: PowerLevels() event is not a m.room.power_levels event, bad state key")
980	}
981	var content PowerLevelContent
982	if err := e.extractContent(MRoomPowerLevels, &content); err != nil {
983		return nil, err
984	}
985	return &content, nil
986}
987
988// AuthEvents returns references to the events needed to auth the event.
989func (e *Event) AuthEvents() []EventReference {
990	switch fields := e.fields.(type) {
991	case eventFormatV1Fields:
992		return fields.AuthEvents
993	case eventFormatV2Fields:
994		result := make([]EventReference, 0, len(fields.AuthEvents))
995		for _, id := range fields.AuthEvents {
996			var sha Base64Bytes
997			if err := sha.Decode(id[1:]); err != nil {
998				panic("gomatrixserverlib: event ID is malformed: " + err.Error())
999			}
1000			result = append(result, EventReference{
1001				EventID:     id,
1002				EventSHA256: sha,
1003			})
1004		}
1005		return result
1006	default:
1007		panic(e.invalidFieldType())
1008	}
1009}
1010
1011// AuthEventIDs returns the event IDs of the events needed to auth the event.
1012func (e *Event) AuthEventIDs() []string {
1013	switch fields := e.fields.(type) {
1014	case eventFormatV1Fields:
1015		result := make([]string, 0, len(fields.AuthEvents))
1016		for _, id := range fields.AuthEvents {
1017			result = append(result, id.EventID)
1018		}
1019		return result
1020	case eventFormatV2Fields:
1021		return fields.AuthEvents
1022	default:
1023		panic(e.invalidFieldType())
1024	}
1025}
1026
1027// Redacts returns the event ID of the event this event redacts.
1028func (e *Event) Redacts() string {
1029	switch fields := e.fields.(type) {
1030	case eventFormatV1Fields:
1031		return fields.Redacts
1032	case eventFormatV2Fields:
1033		return fields.Redacts
1034	default:
1035		panic(e.invalidFieldType())
1036	}
1037}
1038
1039// RoomID returns the room ID of the room the event is in.
1040func (e *Event) RoomID() string {
1041	switch fields := e.fields.(type) {
1042	case eventFormatV1Fields:
1043		return fields.RoomID
1044	case eventFormatV2Fields:
1045		return fields.RoomID
1046	default:
1047		panic(e.invalidFieldType())
1048	}
1049}
1050
1051// Depth returns the depth of the event.
1052func (e *Event) Depth() int64 {
1053	switch fields := e.fields.(type) {
1054	case eventFormatV1Fields:
1055		return fields.Depth
1056	case eventFormatV2Fields:
1057		return fields.Depth
1058	default:
1059		panic(e.invalidFieldType())
1060	}
1061}
1062
1063// MarshalJSON implements json.Marshaller
1064func (e Event) MarshalJSON() ([]byte, error) {
1065	if e.eventJSON == nil {
1066		return nil, fmt.Errorf("gomatrixserverlib: cannot serialise uninitialised Event")
1067	}
1068	return e.eventJSON, nil
1069}
1070
1071// Headered returns a HeaderedEvent encapsulating the original event, with the
1072// supplied headers.
1073func (e *Event) Headered(roomVersion RoomVersion) *HeaderedEvent {
1074	return &HeaderedEvent{
1075		EventHeader: EventHeader{
1076			RoomVersion: roomVersion,
1077		},
1078		Event: e,
1079	}
1080}
1081
1082// UnmarshalJSON implements json.Unmarshaller
1083func (er *EventReference) UnmarshalJSON(data []byte) error {
1084	var tuple []RawJSON
1085	if err := json.Unmarshal(data, &tuple); err != nil {
1086		return err
1087	}
1088	if len(tuple) != 2 {
1089		return fmt.Errorf("gomatrixserverlib: invalid event reference, invalid length: %d != 2", len(tuple))
1090	}
1091	if err := json.Unmarshal(tuple[0], &er.EventID); err != nil {
1092		return fmt.Errorf("gomatrixserverlib: invalid event reference, first element is invalid: %q %v", string(tuple[0]), err)
1093	}
1094	var hashes struct {
1095		SHA256 Base64Bytes `json:"sha256"`
1096	}
1097	if err := json.Unmarshal(tuple[1], &hashes); err != nil {
1098		return fmt.Errorf("gomatrixserverlib: invalid event reference, second element is invalid: %q %v", string(tuple[1]), err)
1099	}
1100	er.EventSHA256 = hashes.SHA256
1101	return nil
1102}
1103
1104// MarshalJSON implements json.Marshaller
1105func (er EventReference) MarshalJSON() ([]byte, error) {
1106	hashes := struct {
1107		SHA256 Base64Bytes `json:"sha256"`
1108	}{er.EventSHA256}
1109
1110	tuple := []interface{}{er.EventID, hashes}
1111
1112	return json.Marshal(&tuple)
1113}
1114
1115// SplitID splits a matrix ID into a local part and a server name.
1116func SplitID(sigil byte, id string) (local string, domain ServerName, err error) {
1117	// IDs have the format: SIGIL LOCALPART ":" DOMAIN
1118	// Split on the first ":" character since the domain can contain ":"
1119	// characters.
1120	if len(id) == 0 || id[0] != sigil {
1121		return "", "", fmt.Errorf("gomatrixserverlib: invalid ID %q doesn't start with %q", id, sigil)
1122	}
1123	parts := strings.SplitN(id, ":", 2)
1124	if len(parts) != 2 {
1125		// The ID must have a ":" character.
1126		return "", "", fmt.Errorf("gomatrixserverlib: invalid ID %q missing ':'", id)
1127	}
1128	return parts[0][1:], ServerName(parts[1]), nil
1129}
1130
1131// fixNilSlices corrects cases where nil slices end up with "null" in the
1132// marshalled JSON because Go stupidly doesn't care about the type in this
1133// situation.
1134func (f *eventFormatV1Fields) fixNilSlices() {
1135	if f.AuthEvents == nil {
1136		f.AuthEvents = []EventReference{}
1137	}
1138	if f.PrevEvents == nil {
1139		f.PrevEvents = []EventReference{}
1140	}
1141}
1142
1143// fixNilSlices corrects cases where nil slices end up with "null" in the
1144// marshalled JSON because Go stupidly doesn't care about the type in this
1145// situation.
1146func (f *eventFormatV2Fields) fixNilSlices() {
1147	if f.AuthEvents == nil {
1148		f.AuthEvents = []string{}
1149	}
1150	if f.PrevEvents == nil {
1151		f.PrevEvents = []string{}
1152	}
1153}
1154
1155// invalidFieldType is used to generate something semi-helpful when panicing.
1156func (e *Event) invalidFieldType() string {
1157	if e == nil {
1158		return "gomatrixserverlib: attempt to call function on nil event"
1159	}
1160	if e.fields == nil {
1161		return fmt.Sprintf("gomatrixserverlib: event has no fields (room version %q)", e.roomVersion)
1162	}
1163	return fmt.Sprintf("gomatrixserverlib: field type %q invalid", reflect.TypeOf(e.fields).Name())
1164}
1165