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