aboutsummaryrefslogtreecommitdiff
path: root/syncapi/synctypes/clientevent.go
diff options
context:
space:
mode:
Diffstat (limited to 'syncapi/synctypes/clientevent.go')
-rw-r--r--syncapi/synctypes/clientevent.go79
1 files changed, 71 insertions, 8 deletions
diff --git a/syncapi/synctypes/clientevent.go b/syncapi/synctypes/clientevent.go
index a78aea1c..7e5b1c1b 100644
--- a/syncapi/synctypes/clientevent.go
+++ b/syncapi/synctypes/clientevent.go
@@ -16,12 +16,21 @@
package synctypes
import (
+ "encoding/json"
"fmt"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/spec"
+ "github.com/sirupsen/logrus"
)
+// PrevEventRef represents a reference to a previous event in a state event upgrade
+type PrevEventRef struct {
+ PrevContent json.RawMessage `json:"prev_content"`
+ ReplacesState string `json:"replaces_state"`
+ PrevSenderID string `json:"prev_sender"`
+}
+
type ClientEventFormat int
const (
@@ -30,8 +39,21 @@ const (
// FormatSync will include only the event keys required by the /sync API. Notably, this
// means the 'room_id' will be missing from the events.
FormatSync
+ // FormatSyncFederation will include all event keys normally included in federated events.
+ // This allows clients to request federated formatted events via the /sync API.
+ FormatSyncFederation
)
+// ClientFederationFields extends a ClientEvent to contain the additional fields present in a
+// federation event. Used when the client requests `event_format` of type `federation`.
+type ClientFederationFields struct {
+ Depth int64 `json:"depth,omitempty"`
+ PrevEvents []string `json:"prev_events,omitempty"`
+ AuthEvents []string `json:"auth_events,omitempty"`
+ Signatures spec.RawJSON `json:"signatures,omitempty"`
+ Hashes spec.RawJSON `json:"hashes,omitempty"`
+}
+
// ClientEvent is an event which is fit for consumption by clients, in accordance with the specification.
type ClientEvent struct {
Content spec.RawJSON `json:"content"`
@@ -44,6 +66,9 @@ type ClientEvent struct {
Type string `json:"type"`
Unsigned spec.RawJSON `json:"unsigned,omitempty"`
Redacts string `json:"redacts,omitempty"`
+
+ // Only sent to clients when `event_format` == `federation`.
+ ClientFederationFields
}
// ToClientEvents converts server events to client events.
@@ -53,6 +78,11 @@ func ToClientEvents(serverEvs []gomatrixserverlib.PDU, format ClientEventFormat,
if se == nil {
continue // TODO: shouldn't happen?
}
+ if format == FormatSyncFederation {
+ evs = append(evs, ToClientEvent(se, format, string(se.SenderID()), se.StateKey(), spec.RawJSON(se.Unsigned())))
+ continue
+ }
+
sender := spec.UserID{}
validRoomID, err := spec.NewRoomID(se.RoomID())
if err != nil {
@@ -71,28 +101,61 @@ func ToClientEvents(serverEvs []gomatrixserverlib.PDU, format ClientEventFormat,
sk = &skString
}
}
- evs = append(evs, ToClientEvent(se, format, sender, sk))
+
+ unsigned := se.Unsigned()
+ var prev PrevEventRef
+ if err := json.Unmarshal(se.Unsigned(), &prev); err == nil && prev.PrevSenderID != "" {
+ prevUserID, err := userIDForSender(*validRoomID, spec.SenderID(prev.PrevSenderID))
+ if err == nil && userID != nil {
+ prev.PrevSenderID = prevUserID.String()
+ } else {
+ errString := "userID unknown"
+ if err != nil {
+ errString = err.Error()
+ }
+ logrus.Warnf("Failed to find userID for prev_sender in ClientEvent: %s", errString)
+ // NOTE: Not much can be done here, so leave the previous value in place.
+ }
+ unsigned, err = json.Marshal(prev)
+ if err != nil {
+ logrus.Errorf("Failed to marshal unsigned content for ClientEvent: %s", err.Error())
+ continue
+ }
+ }
+ evs = append(evs, ToClientEvent(se, format, sender.String(), sk, spec.RawJSON(unsigned)))
}
return evs
}
// ToClientEvent converts a single server event to a client event.
-func ToClientEvent(se gomatrixserverlib.PDU, format ClientEventFormat, sender spec.UserID, stateKey *string) ClientEvent {
+func ToClientEvent(se gomatrixserverlib.PDU, format ClientEventFormat, sender string, stateKey *string, unsigned spec.RawJSON) ClientEvent {
ce := ClientEvent{
Content: spec.RawJSON(se.Content()),
- Sender: sender.String(),
+ Sender: sender,
Type: se.Type(),
StateKey: stateKey,
- Unsigned: spec.RawJSON(se.Unsigned()),
+ Unsigned: unsigned,
OriginServerTS: se.OriginServerTS(),
EventID: se.EventID(),
Redacts: se.Redacts(),
}
- if format == FormatAll {
+
+ switch format {
+ case FormatAll:
+ ce.RoomID = se.RoomID()
+ case FormatSync:
+ case FormatSyncFederation:
ce.RoomID = se.RoomID()
+ ce.AuthEvents = se.AuthEventIDs()
+ ce.PrevEvents = se.PrevEventIDs()
+ ce.Depth = se.Depth()
+ // TODO: Set Signatures & Hashes fields
}
- if se.Version() == gomatrixserverlib.RoomVersionPseudoIDs {
- ce.SenderKey = se.SenderID()
+
+ if format != FormatSyncFederation {
+ if se.Version() == gomatrixserverlib.RoomVersionPseudoIDs {
+ ce.SenderKey = se.SenderID()
+ }
}
return ce
}
@@ -118,7 +181,7 @@ func ToClientEventDefault(userIDQuery spec.UserIDForSender, event gomatrixserver
sk = &skString
}
}
- return ToClientEvent(event, FormatAll, sender, sk)
+ return ToClientEvent(event, FormatAll, sender.String(), sk, event.Unsigned())
}
// If provided state key is a user ID (state keys beginning with @ are reserved for this purpose)