Merge branch 'master' of https://github.com/matrix-org/dendrite into reject-v6-invites

This commit is contained in:
Till Faelligen 2020-11-17 17:12:37 +01:00
commit 3e8c91ff8b
80 changed files with 492 additions and 348 deletions

View file

@ -1,5 +1,21 @@
# Changelog # Changelog
## Dendrite 0.3.0 (2020-11-16)
### Features
* Read receipts (both inbound and outbound) are now supported (contributed by [S7evinK](https://github.com/S7evinK))
* Forgetting rooms is now supported (contributed by [S7evinK](https://github.com/S7evinK))
* The `-version` command line flag has been added (contributed by [S7evinK](https://github.com/S7evinK))
### Fixes
* User accounts that contain the `=` character can now be registered
* Backfilling should now work properly on rooms with world-readable history visibility (contributed by [MayeulC](https://github.com/MayeulC))
* The `gjson` dependency has been updated for correct JSON integer ranges
* Some more client event fields have been marked as omit-when-empty (contributed by [S7evinK](https://github.com/S7evinK))
* The `build.sh` script has been updated to work properly on all POSIX platforms (contributed by [felix](https://github.com/felix))
## Dendrite 0.2.1 (2020-10-22) ## Dendrite 0.2.1 (2020-10-22)
### Fixes ### Fixes

View file

@ -18,7 +18,7 @@ As of October 2020, Dendrite has now entered **beta** which means:
This does not mean: This does not mean:
- Dendrite is bug-free. It has not yet been battle-tested in the real world and so will be error prone initially. - Dendrite is bug-free. It has not yet been battle-tested in the real world and so will be error prone initially.
- All of the CS/Federation APIs are implemented. We are tracking progress via a script called 'Are We Synapse Yet?'. In particular, - All of the CS/Federation APIs are implemented. We are tracking progress via a script called 'Are We Synapse Yet?'. In particular,
read receipts, presence and push notifications are entirely missing from Dendrite. See [CHANGES.md](CHANGES.md) for updates. presence and push notifications are entirely missing from Dendrite. See [CHANGES.md](CHANGES.md) for updates.
- Dendrite is ready for massive homeserver deployments. You cannot shard each microservice, only run each one on a different machine. - Dendrite is ready for massive homeserver deployments. You cannot shard each microservice, only run each one on a different machine.
Currently, we expect Dendrite to function well for small (10s/100s of users) homeserver deployments as well as P2P Matrix nodes in-browser or on mobile devices. Currently, we expect Dendrite to function well for small (10s/100s of users) homeserver deployments as well as P2P Matrix nodes in-browser or on mobile devices.
@ -77,10 +77,9 @@ Then point your favourite Matrix client at `http://localhost:8008` or `https://l
We use a script called Are We Synapse Yet which checks Sytest compliance rates. Sytest is a black-box homeserver We use a script called Are We Synapse Yet which checks Sytest compliance rates. Sytest is a black-box homeserver
test rig with around 900 tests. The script works out how many of these tests are passing on Dendrite and it test rig with around 900 tests. The script works out how many of these tests are passing on Dendrite and it
updates with CI. As of October 2020 we're at around 57% CS API coverage and 81% Federation coverage, though check updates with CI. As of November 2020 we're at around 58% CS API coverage and 83% Federation coverage, though check
CI for the latest numbers. In practice, this means you can communicate locally and via federation with Synapse CI for the latest numbers. In practice, this means you can communicate locally and via federation with Synapse
servers such as matrix.org reasonably well. There's a long list of features that are not implemented, notably: servers such as matrix.org reasonably well. There's a long list of features that are not implemented, notably:
- Receipts
- Push - Push
- Search and Context - Search and Context
- User Directory - User Directory
@ -100,6 +99,7 @@ This means Dendrite supports amongst others:
- Redaction - Redaction
- Tagging - Tagging
- E2E keys and device lists - E2E keys and device lists
- Receipts
## Contributing ## Contributing

View file

@ -88,7 +88,7 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
return nil return nil
} }
events := []gomatrixserverlib.HeaderedEvent{output.NewRoomEvent.Event} events := []*gomatrixserverlib.HeaderedEvent{output.NewRoomEvent.Event}
events = append(events, output.NewRoomEvent.AddStateEvents...) events = append(events, output.NewRoomEvent.AddStateEvents...)
// Send event to any relevant application services // Send event to any relevant application services
@ -102,14 +102,14 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
// application service. // application service.
func (s *OutputRoomEventConsumer) filterRoomserverEvents( func (s *OutputRoomEventConsumer) filterRoomserverEvents(
ctx context.Context, ctx context.Context,
events []gomatrixserverlib.HeaderedEvent, events []*gomatrixserverlib.HeaderedEvent,
) error { ) error {
for _, ws := range s.workerStates { for _, ws := range s.workerStates {
for _, event := range events { for _, event := range events {
// Check if this event is interesting to this application service // Check if this event is interesting to this application service
if s.appserviceIsInterestedInEvent(ctx, event, ws.AppService) { if s.appserviceIsInterestedInEvent(ctx, event, ws.AppService) {
// Queue this event to be sent off to the application service // Queue this event to be sent off to the application service
if err := s.asDB.StoreEvent(ctx, ws.AppService.ID, &event); err != nil { if err := s.asDB.StoreEvent(ctx, ws.AppService.ID, event); err != nil {
log.WithError(err).Warn("failed to insert incoming event into appservices database") log.WithError(err).Warn("failed to insert incoming event into appservices database")
} else { } else {
// Tell our worker to send out new messages by updating remaining message // Tell our worker to send out new messages by updating remaining message
@ -125,7 +125,7 @@ func (s *OutputRoomEventConsumer) filterRoomserverEvents(
// appserviceIsInterestedInEvent returns a boolean depending on whether a given // appserviceIsInterestedInEvent returns a boolean depending on whether a given
// event falls within one of a given application service's namespaces. // event falls within one of a given application service's namespaces.
func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(ctx context.Context, event gomatrixserverlib.HeaderedEvent, appservice config.ApplicationService) bool { func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(ctx context.Context, event *gomatrixserverlib.HeaderedEvent, appservice config.ApplicationService) bool {
// No reason to queue events if they'll never be sent to the application // No reason to queue events if they'll never be sent to the application
// service // service
if appservice.URL == "" { if appservice.URL == "" {

View file

@ -185,7 +185,7 @@ func createTransaction(
} }
} }
var ev []gomatrixserverlib.Event var ev []*gomatrixserverlib.Event
for _, e := range events { for _, e := range events {
ev = append(ev, e.Event) ev = append(ev, e.Event)
} }

View file

@ -1,4 +1,4 @@
#!/bin/bash -eu #!/bin/sh -eu
export GIT_COMMIT=$(git rev-list -1 HEAD) && \ export GIT_COMMIT=$(git rev-list -1 HEAD) && \
GOOS=js GOARCH=wasm go build -ldflags "-X main.GitCommit=$GIT_COMMIT" -o main.wasm ./cmd/dendritejs GOOS=js GOARCH=wasm go build -ldflags "-X main.GitCommit=$GIT_COMMIT" -o main.wasm ./cmd/dendritejs

View file

@ -1,4 +1,4 @@
#!/bin/bash -eu #!/bin/sh -eu
# Put installed packages into ./bin # Put installed packages into ./bin
export GOBIN=$PWD/`dirname $0`/bin export GOBIN=$PWD/`dirname $0`/bin
@ -7,7 +7,7 @@ if [ -d ".git" ]
then then
export BUILD=`git rev-parse --short HEAD || ""` export BUILD=`git rev-parse --short HEAD || ""`
export BRANCH=`(git symbolic-ref --short HEAD | tr -d \/ ) || ""` export BRANCH=`(git symbolic-ref --short HEAD | tr -d \/ ) || ""`
if [[ $BRANCH == "master" ]] if [ "$BRANCH" = master ]
then then
export BRANCH="" export BRANCH=""
fi fi

View file

@ -2,6 +2,11 @@
These are Docker images for Dendrite! These are Docker images for Dendrite!
They can be found on Docker Hub:
- [matrixdotorg/dendrite-monolith](https://hub.docker.com/repository/docker/matrixdotorg/dendrite-monolith) for monolith deployments
- [matrixdotorg/dendrite-polylith](https://hub.docker.com/repository/docker/matrixdotorg/dendrite-polylith) for polylith deployments
## Dockerfiles ## Dockerfiles
The `Dockerfile` builds the base image which contains all of the Dendrite The `Dockerfile` builds the base image which contains all of the Dendrite

View file

@ -0,0 +1,88 @@
// Copyright 2020 David Spenler
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package routing
import (
"net/http"
"github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/util"
)
type adminWhoisResponse struct {
UserID string `json:"user_id"`
Devices map[string]deviceInfo `json:"devices"`
}
type deviceInfo struct {
Sessions []sessionInfo `json:"sessions"`
}
type sessionInfo struct {
Connections []connectionInfo `json:"connections"`
}
type connectionInfo struct {
IP string `json:"ip"`
LastSeen int64 `json:"last_seen"`
UserAgent string `json:"user_agent"`
}
// GetAdminWhois implements GET /admin/whois/{userId}
func GetAdminWhois(
req *http.Request, userAPI api.UserInternalAPI, device *api.Device,
userID string,
) util.JSONResponse {
if userID != device.UserID {
// TODO: Still allow if user is admin
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden("userID does not match the current user"),
}
}
var queryRes api.QueryDevicesResponse
err := userAPI.QueryDevices(req.Context(), &api.QueryDevicesRequest{
UserID: userID,
}, &queryRes)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("GetAdminWhois failed to query user devices")
return jsonerror.InternalServerError()
}
devices := make(map[string]deviceInfo)
for _, device := range queryRes.Devices {
connInfo := connectionInfo{
IP: device.LastSeenIP,
LastSeen: device.LastSeenTS,
UserAgent: device.UserAgent,
}
dev, ok := devices[device.ID]
if !ok {
dev.Sessions = []sessionInfo{{}}
}
dev.Sessions[0].Connections = append(dev.Sessions[0].Connections, connInfo)
devices[device.ID] = dev
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: adminWhoisResponse{
UserID: userID,
Devices: devices,
},
}
}

View file

@ -255,7 +255,7 @@ func createRoom(
historyVisibility = historyVisibilityShared historyVisibility = historyVisibilityShared
} }
var builtEvents []gomatrixserverlib.HeaderedEvent var builtEvents []*gomatrixserverlib.HeaderedEvent
// send events into the room in order of: // send events into the room in order of:
// 1- m.room.create // 1- m.room.create
@ -327,13 +327,13 @@ func createRoom(
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }
if err = gomatrixserverlib.Allowed(*ev, &authEvents); err != nil { if err = gomatrixserverlib.Allowed(ev, &authEvents); err != nil {
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.Allowed failed") util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.Allowed failed")
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }
// Add the event to the list of auth events // Add the event to the list of auth events
builtEvents = append(builtEvents, (*ev).Headered(roomVersion)) builtEvents = append(builtEvents, ev.Headered(roomVersion))
err = authEvents.AddEvent(ev) err = authEvents.AddEvent(ev)
if err != nil { if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("authEvents.AddEvent failed") util.GetLogger(req.Context()).WithError(err).Error("authEvents.AddEvent failed")
@ -397,7 +397,7 @@ func createRoom(
ev := event.Event ev := event.Event
globalStrippedState = append( globalStrippedState = append(
globalStrippedState, globalStrippedState,
gomatrixserverlib.NewInviteV2StrippedState(&ev), gomatrixserverlib.NewInviteV2StrippedState(ev),
) )
} }
} }
@ -415,7 +415,7 @@ func createRoom(
} }
inviteStrippedState := append( inviteStrippedState := append(
globalStrippedState, globalStrippedState,
gomatrixserverlib.NewInviteV2StrippedState(&inviteEvent.Event), gomatrixserverlib.NewInviteV2StrippedState(inviteEvent.Event),
) )
// Send the invite event to the roomserver. // Send the invite event to the roomserver.
err = roomserverAPI.SendInvite( err = roomserverAPI.SendInvite(
@ -488,5 +488,5 @@ func buildEvent(
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot build event %s : Builder failed to build. %w", builder.Type, err) return nil, fmt.Errorf("cannot build event %s : Builder failed to build. %w", builder.Type, err)
} }
return &event, nil return event, nil
} }

View file

@ -32,7 +32,7 @@ type getEventRequest struct {
eventID string eventID string
cfg *config.ClientAPI cfg *config.ClientAPI
federation *gomatrixserverlib.FederationClient federation *gomatrixserverlib.FederationClient
requestedEvent gomatrixserverlib.Event requestedEvent *gomatrixserverlib.Event
} }
// GetEvent implements GET /_matrix/client/r0/rooms/{roomId}/event/{eventId} // GetEvent implements GET /_matrix/client/r0/rooms/{roomId}/event/{eventId}

View file

@ -77,7 +77,7 @@ func sendMembership(ctx context.Context, accountDB accounts.Database, device *us
if err = roomserverAPI.SendEvents( if err = roomserverAPI.SendEvents(
ctx, rsAPI, ctx, rsAPI,
api.KindNew, api.KindNew,
[]gomatrixserverlib.HeaderedEvent{event.Event.Headered(roomVer)}, []*gomatrixserverlib.HeaderedEvent{event.Event.Headered(roomVer)},
cfg.Matrix.ServerName, cfg.Matrix.ServerName,
nil, nil,
); err != nil { ); err != nil {
@ -214,7 +214,7 @@ func SendInvite(
err = roomserverAPI.SendInvite( err = roomserverAPI.SendInvite(
req.Context(), rsAPI, req.Context(), rsAPI,
*event, event,
nil, // ask the roomserver to draw up invite room state for us nil, // ask the roomserver to draw up invite room state for us
cfg.Matrix.ServerName, cfg.Matrix.ServerName,
nil, nil,

View file

@ -346,14 +346,14 @@ func buildMembershipEvents(
roomIDs []string, roomIDs []string,
newProfile authtypes.Profile, userID string, cfg *config.ClientAPI, newProfile authtypes.Profile, userID string, cfg *config.ClientAPI,
evTime time.Time, rsAPI api.RoomserverInternalAPI, evTime time.Time, rsAPI api.RoomserverInternalAPI,
) ([]gomatrixserverlib.HeaderedEvent, error) { ) ([]*gomatrixserverlib.HeaderedEvent, error) {
evs := []gomatrixserverlib.HeaderedEvent{} evs := []*gomatrixserverlib.HeaderedEvent{}
for _, roomID := range roomIDs { for _, roomID := range roomIDs {
verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID} verReq := api.QueryRoomVersionForRoomRequest{RoomID: roomID}
verRes := api.QueryRoomVersionForRoomResponse{} verRes := api.QueryRoomVersionForRoomResponse{}
if err := rsAPI.QueryRoomVersionForRoom(ctx, &verReq, &verRes); err != nil { if err := rsAPI.QueryRoomVersionForRoom(ctx, &verReq, &verRes); err != nil {
return []gomatrixserverlib.HeaderedEvent{}, err return nil, err
} }
builder := gomatrixserverlib.EventBuilder{ builder := gomatrixserverlib.EventBuilder{
@ -379,7 +379,7 @@ func buildMembershipEvents(
return nil, err return nil, err
} }
evs = append(evs, (*event).Headered(verRes.RoomVersion)) evs = append(evs, event.Headered(verRes.RoomVersion))
} }
return evs, nil return evs, nil

View file

@ -121,7 +121,7 @@ func SendRedaction(
JSON: jsonerror.NotFound("Room does not exist"), JSON: jsonerror.NotFound("Room does not exist"),
} }
} }
if err = roomserverAPI.SendEvents(context.Background(), rsAPI, api.KindNew, []gomatrixserverlib.HeaderedEvent{*e}, cfg.Matrix.ServerName, nil); err != nil { if err = roomserverAPI.SendEvents(context.Background(), rsAPI, api.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, cfg.Matrix.ServerName, nil); err != nil {
util.GetLogger(req.Context()).WithError(err).Errorf("failed to SendEvents") util.GetLogger(req.Context()).WithError(err).Errorf("failed to SendEvents")
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }

View file

@ -651,6 +651,16 @@ func Setup(
}), }),
).Methods(http.MethodGet) ).Methods(http.MethodGet)
r0mux.Handle("/admin/whois/{userID}",
httputil.MakeAuthAPI("admin_whois", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
if err != nil {
return util.ErrorResponse(err)
}
return GetAdminWhois(req, userAPI, device, vars["userID"])
}),
).Methods(http.MethodGet)
r0mux.Handle("/user_directory/search", r0mux.Handle("/user_directory/search",
httputil.MakeAuthAPI("userdirectory_search", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { httputil.MakeAuthAPI("userdirectory_search", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
if r := rateLimits.rateLimit(req); r != nil { if r := rateLimits.rateLimit(req); r != nil {

View file

@ -93,7 +93,7 @@ func SendEvent(
if err := api.SendEvents( if err := api.SendEvents(
req.Context(), rsAPI, req.Context(), rsAPI,
api.KindNew, api.KindNew,
[]gomatrixserverlib.HeaderedEvent{ []*gomatrixserverlib.HeaderedEvent{
e.Headered(verRes.RoomVersion), e.Headered(verRes.RoomVersion),
}, },
cfg.Matrix.ServerName, cfg.Matrix.ServerName,
@ -189,7 +189,7 @@ func generateSendEvent(
// check to see if this user can perform this operation // check to see if this user can perform this operation
stateEvents := make([]*gomatrixserverlib.Event, len(queryRes.StateEvents)) stateEvents := make([]*gomatrixserverlib.Event, len(queryRes.StateEvents))
for i := range queryRes.StateEvents { for i := range queryRes.StateEvents {
stateEvents[i] = &queryRes.StateEvents[i].Event stateEvents[i] = queryRes.StateEvents[i].Event
} }
provider := gomatrixserverlib.NewAuthEvents(stateEvents) provider := gomatrixserverlib.NewAuthEvents(stateEvents)
if err = gomatrixserverlib.Allowed(e.Event, &provider); err != nil { if err = gomatrixserverlib.Allowed(e.Event, &provider); err != nil {
@ -198,5 +198,5 @@ func generateSendEvent(
JSON: jsonerror.Forbidden(err.Error()), // TODO: Is this error string comprehensible to the client? JSON: jsonerror.Forbidden(err.Error()), // TODO: Is this error string comprehensible to the client?
} }
} }
return &e.Event, nil return e.Event, nil
} }

View file

@ -267,7 +267,7 @@ func OnIncomingStateTypeRequest(
// to find the state event, if provided. // to find the state event, if provided.
for _, ev := range stateRes.StateEvents { for _, ev := range stateRes.StateEvents {
if ev.Type() == evType && ev.StateKeyEquals(stateKey) { if ev.Type() == evType && ev.StateKeyEquals(stateKey) {
event = &ev event = ev
break break
} }
} }
@ -290,7 +290,7 @@ func OnIncomingStateTypeRequest(
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }
if len(stateAfterRes.StateEvents) > 0 { if len(stateAfterRes.StateEvents) > 0 {
event = &stateAfterRes.StateEvents[0] event = stateAfterRes.StateEvents[0]
} }
} }
@ -304,7 +304,7 @@ func OnIncomingStateTypeRequest(
} }
stateEvent := stateEventInStateResp{ stateEvent := stateEventInStateResp{
ClientEvent: gomatrixserverlib.HeaderedToClientEvent(*event, gomatrixserverlib.FormatAll), ClientEvent: gomatrixserverlib.HeaderedToClientEvent(event, gomatrixserverlib.FormatAll),
} }
var res interface{} var res interface{}

View file

@ -362,8 +362,8 @@ func emit3PIDInviteEvent(
return api.SendEvents( return api.SendEvents(
ctx, rsAPI, ctx, rsAPI,
api.KindNew, api.KindNew,
[]gomatrixserverlib.HeaderedEvent{ []*gomatrixserverlib.HeaderedEvent{
(*event).Headered(queryRes.RoomVersion), event.Headered(queryRes.RoomVersion),
}, },
cfg.Matrix.ServerName, cfg.Matrix.ServerName,
nil, nil,

View file

@ -123,7 +123,7 @@ func buildAndOutput() gomatrixserverlib.EventReference {
} }
// Write an event to the output. // Write an event to the output.
func writeEvent(event gomatrixserverlib.Event) { func writeEvent(event *gomatrixserverlib.Event) {
encoder := json.NewEncoder(os.Stdout) encoder := json.NewEncoder(os.Stdout)
if *format == "InputRoomEvent" { if *format == "InputRoomEvent" {
var ire api.InputRoomEvent var ire api.InputRoomEvent

View file

@ -80,9 +80,9 @@ func main() {
} }
authEventIDMap := make(map[string]struct{}) authEventIDMap := make(map[string]struct{})
eventPtrs := make([]*gomatrixserverlib.Event, len(eventEntries)) events := make([]*gomatrixserverlib.Event, len(eventEntries))
for i := range eventEntries { for i := range eventEntries {
eventPtrs[i] = &eventEntries[i].Event events[i] = eventEntries[i].Event
for _, authEventID := range eventEntries[i].AuthEventIDs() { for _, authEventID := range eventEntries[i].AuthEventIDs() {
authEventIDMap[authEventID] = struct{}{} authEventIDMap[authEventID] = struct{}{}
} }
@ -99,18 +99,9 @@ func main() {
panic(err) panic(err)
} }
authEventPtrs := make([]*gomatrixserverlib.Event, len(authEventEntries)) authEvents := make([]*gomatrixserverlib.Event, len(authEventEntries))
for i := range authEventEntries { for i := range authEventEntries {
authEventPtrs[i] = &authEventEntries[i].Event authEvents[i] = authEventEntries[i].Event
}
events := make([]gomatrixserverlib.Event, len(eventEntries))
authEvents := make([]gomatrixserverlib.Event, len(authEventEntries))
for i, ptr := range eventPtrs {
events[i] = *ptr
}
for i, ptr := range authEventPtrs {
authEvents[i] = *ptr
} }
fmt.Println("Resolving state") fmt.Println("Resolving state")

View file

@ -103,7 +103,7 @@ func clientEventJSONForOutputRoomEvent(outputRoomEvent string) string {
if err := json.Unmarshal([]byte(outputRoomEvent), &out); err != nil { if err := json.Unmarshal([]byte(outputRoomEvent), &out); err != nil {
panic("failed to unmarshal output room event: " + err.Error()) panic("failed to unmarshal output room event: " + err.Error())
} }
clientEvs := gomatrixserverlib.ToClientEvents([]gomatrixserverlib.Event{ clientEvs := gomatrixserverlib.ToClientEvents([]*gomatrixserverlib.Event{
out.NewRoomEvent.Event.Event, out.NewRoomEvent.Event.Event,
}, gomatrixserverlib.FormatSync) }, gomatrixserverlib.FormatSync)
b, err := json.Marshal(clientEvs[0]) b, err := json.Marshal(clientEvs[0])

View file

@ -72,7 +72,7 @@ func TestRoomsV3URLEscapeDoNot404(t *testing.T) {
t.Errorf("failed to parse event: %s", err) t.Errorf("failed to parse event: %s", err)
} }
he := ev.Headered(tc.roomVer) he := ev.Headered(tc.roomVer)
invReq, err := gomatrixserverlib.NewInviteV2Request(&he, nil) invReq, err := gomatrixserverlib.NewInviteV2Request(he, nil)
if err != nil { if err != nil {
t.Errorf("failed to create invite v2 request: %s", err) t.Errorf("failed to create invite v2 request: %s", err)
continue continue

View file

@ -93,9 +93,9 @@ func Backfill(
} }
// Filter any event that's not from the requested room out. // Filter any event that's not from the requested room out.
evs := make([]gomatrixserverlib.Event, 0) evs := make([]*gomatrixserverlib.Event, 0)
var ev gomatrixserverlib.HeaderedEvent var ev *gomatrixserverlib.HeaderedEvent
for _, ev = range res.Events { for _, ev = range res.Events {
if ev.RoomID() == roomID { if ev.RoomID() == roomID {
evs = append(evs, ev.Event) evs = append(evs, ev.Event)

View file

@ -98,5 +98,5 @@ func fetchEvent(ctx context.Context, rsAPI api.RoomserverInternalAPI, eventID st
return nil, &util.JSONResponse{Code: http.StatusNotFound, JSON: nil} return nil, &util.JSONResponse{Code: http.StatusNotFound, JSON: nil}
} }
return &eventsResponse.Events[0].Event, nil return eventsResponse.Events[0].Event, nil
} }

View file

@ -97,7 +97,7 @@ func InviteV1(
func processInvite( func processInvite(
ctx context.Context, ctx context.Context,
isInviteV2 bool, isInviteV2 bool,
event gomatrixserverlib.Event, event *gomatrixserverlib.Event,
roomVer gomatrixserverlib.RoomVersion, roomVer gomatrixserverlib.RoomVersion,
strippedState []gomatrixserverlib.InviteV2StrippedState, strippedState []gomatrixserverlib.InviteV2StrippedState,
roomID string, roomID string,
@ -171,12 +171,12 @@ func processInvite(
if isInviteV2 { if isInviteV2 {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: gomatrixserverlib.RespInviteV2{Event: signedEvent}, JSON: gomatrixserverlib.RespInviteV2{Event: &signedEvent},
} }
} else { } else {
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,
JSON: gomatrixserverlib.RespInvite{Event: signedEvent}, JSON: gomatrixserverlib.RespInvite{Event: &signedEvent},
} }
} }
default: default:

View file

@ -138,7 +138,7 @@ func MakeJoin(
// Check that the join is allowed or not // Check that the join is allowed or not
stateEvents := make([]*gomatrixserverlib.Event, len(queryRes.StateEvents)) stateEvents := make([]*gomatrixserverlib.Event, len(queryRes.StateEvents))
for i := range queryRes.StateEvents { for i := range queryRes.StateEvents {
stateEvents[i] = &queryRes.StateEvents[i].Event stateEvents[i] = queryRes.StateEvents[i].Event
} }
provider := gomatrixserverlib.NewAuthEvents(stateEvents) provider := gomatrixserverlib.NewAuthEvents(stateEvents)
@ -291,7 +291,7 @@ func SendJoin(
if err = api.SendEvents( if err = api.SendEvents(
httpReq.Context(), rsAPI, httpReq.Context(), rsAPI,
api.KindNew, api.KindNew,
[]gomatrixserverlib.HeaderedEvent{ []*gomatrixserverlib.HeaderedEvent{
event.Headered(stateAndAuthChainResponse.RoomVersion), event.Headered(stateAndAuthChainResponse.RoomVersion),
}, },
cfg.Matrix.ServerName, cfg.Matrix.ServerName,
@ -319,7 +319,7 @@ func SendJoin(
} }
} }
type eventsByDepth []gomatrixserverlib.HeaderedEvent type eventsByDepth []*gomatrixserverlib.HeaderedEvent
func (e eventsByDepth) Len() int { func (e eventsByDepth) Len() int {
return len(e) return len(e)

View file

@ -98,7 +98,7 @@ func MakeLeave(
// Check that the leave is allowed or not // Check that the leave is allowed or not
stateEvents := make([]*gomatrixserverlib.Event, len(queryRes.StateEvents)) stateEvents := make([]*gomatrixserverlib.Event, len(queryRes.StateEvents))
for i := range queryRes.StateEvents { for i := range queryRes.StateEvents {
stateEvents[i] = &queryRes.StateEvents[i].Event stateEvents[i] = queryRes.StateEvents[i].Event
} }
provider := gomatrixserverlib.NewAuthEvents(stateEvents) provider := gomatrixserverlib.NewAuthEvents(stateEvents)
if err = gomatrixserverlib.Allowed(event.Event, &provider); err != nil { if err = gomatrixserverlib.Allowed(event.Event, &provider); err != nil {
@ -257,7 +257,7 @@ func SendLeave(
if err = api.SendEvents( if err = api.SendEvents(
httpReq.Context(), rsAPI, httpReq.Context(), rsAPI,
api.KindNew, api.KindNew,
[]gomatrixserverlib.HeaderedEvent{ []*gomatrixserverlib.HeaderedEvent{
event.Headered(verRes.RoomVersion), event.Headered(verRes.RoomVersion),
}, },
cfg.Matrix.ServerName, cfg.Matrix.ServerName,

View file

@ -73,8 +73,8 @@ func GetMissingEvents(
// filterEvents returns only those events with matching roomID // filterEvents returns only those events with matching roomID
func filterEvents( func filterEvents(
events []gomatrixserverlib.HeaderedEvent, roomID string, events []*gomatrixserverlib.HeaderedEvent, roomID string,
) []gomatrixserverlib.HeaderedEvent { ) []*gomatrixserverlib.HeaderedEvent {
ref := events[:0] ref := events[:0]
for _, ev := range events { for _, ev := range events {
if ev.RoomID() == roomID { if ev.RoomID() == roomID {

View file

@ -128,7 +128,7 @@ type txnFederationClient interface {
func (t *txnReq) processTransaction(ctx context.Context) (*gomatrixserverlib.RespSend, *util.JSONResponse) { func (t *txnReq) processTransaction(ctx context.Context) (*gomatrixserverlib.RespSend, *util.JSONResponse) {
results := make(map[string]gomatrixserverlib.PDUResult) results := make(map[string]gomatrixserverlib.PDUResult)
pdus := []gomatrixserverlib.HeaderedEvent{} pdus := []*gomatrixserverlib.HeaderedEvent{}
for _, pdu := range t.PDUs { for _, pdu := range t.PDUs {
var header struct { var header struct {
RoomID string `json:"room_id"` RoomID string `json:"room_id"`
@ -171,7 +171,7 @@ func (t *txnReq) processTransaction(ctx context.Context) (*gomatrixserverlib.Res
} }
continue continue
} }
if err = gomatrixserverlib.VerifyAllEventSignatures(ctx, []gomatrixserverlib.Event{event}, t.keys); err != nil { if err = gomatrixserverlib.VerifyAllEventSignatures(ctx, []*gomatrixserverlib.Event{event}, t.keys); err != nil {
util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID()) util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID())
results[event.EventID()] = gomatrixserverlib.PDUResult{ results[event.EventID()] = gomatrixserverlib.PDUResult{
Error: err.Error(), Error: err.Error(),
@ -413,7 +413,7 @@ func (t *txnReq) getServers(ctx context.Context, roomID string) []gomatrixserver
return servers return servers
} }
func (t *txnReq) processEvent(ctx context.Context, e gomatrixserverlib.Event) error { func (t *txnReq) processEvent(ctx context.Context, e *gomatrixserverlib.Event) error {
logger := util.GetLogger(ctx).WithField("event_id", e.EventID()).WithField("room_id", e.RoomID()) logger := util.GetLogger(ctx).WithField("event_id", e.EventID()).WithField("room_id", e.RoomID())
// Work out if the roomserver knows everything it needs to know to auth // Work out if the roomserver knows everything it needs to know to auth
@ -461,7 +461,7 @@ func (t *txnReq) processEvent(ctx context.Context, e gomatrixserverlib.Event) er
context.Background(), context.Background(),
t.rsAPI, t.rsAPI,
api.KindNew, api.KindNew,
[]gomatrixserverlib.HeaderedEvent{ []*gomatrixserverlib.HeaderedEvent{
e.Headered(stateResp.RoomVersion), e.Headered(stateResp.RoomVersion),
}, },
api.DoNotSendToOtherServers, api.DoNotSendToOtherServers,
@ -470,7 +470,7 @@ func (t *txnReq) processEvent(ctx context.Context, e gomatrixserverlib.Event) er
} }
func (t *txnReq) retrieveMissingAuthEvents( func (t *txnReq) retrieveMissingAuthEvents(
ctx context.Context, e gomatrixserverlib.Event, stateResp *api.QueryMissingAuthPrevEventsResponse, ctx context.Context, e *gomatrixserverlib.Event, stateResp *api.QueryMissingAuthPrevEventsResponse,
) error { ) error {
logger := util.GetLogger(ctx).WithField("event_id", e.EventID()).WithField("room_id", e.RoomID()) logger := util.GetLogger(ctx).WithField("event_id", e.EventID()).WithField("room_id", e.RoomID())
@ -523,10 +523,10 @@ withNextEvent:
return nil return nil
} }
func checkAllowedByState(e gomatrixserverlib.Event, stateEvents []gomatrixserverlib.Event) error { func checkAllowedByState(e *gomatrixserverlib.Event, stateEvents []*gomatrixserverlib.Event) error {
authUsingState := gomatrixserverlib.NewAuthEvents(nil) authUsingState := gomatrixserverlib.NewAuthEvents(nil)
for i := range stateEvents { for i := range stateEvents {
err := authUsingState.AddEvent(&stateEvents[i]) err := authUsingState.AddEvent(stateEvents[i])
if err != nil { if err != nil {
return err return err
} }
@ -535,7 +535,7 @@ func checkAllowedByState(e gomatrixserverlib.Event, stateEvents []gomatrixserver
} }
// nolint:gocyclo // nolint:gocyclo
func (t *txnReq) processEventWithMissingState(ctx context.Context, e gomatrixserverlib.Event, roomVersion gomatrixserverlib.RoomVersion) error { func (t *txnReq) processEventWithMissingState(ctx context.Context, e *gomatrixserverlib.Event, roomVersion gomatrixserverlib.RoomVersion) error {
// Do this with a fresh context, so that we keep working even if the // Do this with a fresh context, so that we keep working even if the
// original request times out. With any luck, by the time the remote // original request times out. With any luck, by the time the remote
// side retries, we'll have fetched the missing state. // side retries, we'll have fetched the missing state.
@ -569,7 +569,7 @@ func (t *txnReq) processEventWithMissingState(ctx context.Context, e gomatrixser
return nil return nil
} }
backwardsExtremity := &newEvents[0] backwardsExtremity := newEvents[0]
newEvents = newEvents[1:] newEvents = newEvents[1:]
type respState struct { type respState struct {
@ -657,7 +657,7 @@ func (t *txnReq) processEventWithMissingState(ctx context.Context, e gomatrixser
// than the backward extremity, into the roomserver without state. This way // than the backward extremity, into the roomserver without state. This way
// they will automatically fast-forward based on the room state at the // they will automatically fast-forward based on the room state at the
// extremity in the last step. // extremity in the last step.
headeredNewEvents := make([]gomatrixserverlib.HeaderedEvent, len(newEvents)) headeredNewEvents := make([]*gomatrixserverlib.HeaderedEvent, len(newEvents))
for i, newEvent := range newEvents { for i, newEvent := range newEvents {
headeredNewEvents[i] = newEvent.Headered(roomVersion) headeredNewEvents[i] = newEvent.Headered(roomVersion)
} }
@ -734,9 +734,9 @@ func (t *txnReq) lookupStateAfterEventLocally(ctx context.Context, roomID, event
return nil return nil
} }
for i, ev := range res.StateEvents { for i, ev := range res.StateEvents {
t.haveEvents[ev.EventID()] = &res.StateEvents[i] t.haveEvents[ev.EventID()] = res.StateEvents[i]
} }
var authEvents []gomatrixserverlib.Event var authEvents []*gomatrixserverlib.Event
missingAuthEvents := make(map[string]bool) missingAuthEvents := make(map[string]bool)
for _, ev := range res.StateEvents { for _, ev := range res.StateEvents {
for _, ae := range ev.AuthEventIDs() { for _, ae := range ev.AuthEventIDs() {
@ -764,7 +764,7 @@ func (t *txnReq) lookupStateAfterEventLocally(ctx context.Context, roomID, event
} }
for i := range queryRes.Events { for i := range queryRes.Events {
evID := queryRes.Events[i].EventID() evID := queryRes.Events[i].EventID()
t.haveEvents[evID] = &queryRes.Events[i] t.haveEvents[evID] = queryRes.Events[i]
authEvents = append(authEvents, queryRes.Events[i].Unwrap()) authEvents = append(authEvents, queryRes.Events[i].Unwrap())
} }
@ -787,8 +787,8 @@ func (t *txnReq) lookupStateBeforeEvent(ctx context.Context, roomVersion gomatri
} }
func (t *txnReq) resolveStatesAndCheck(ctx context.Context, roomVersion gomatrixserverlib.RoomVersion, states []*gomatrixserverlib.RespState, backwardsExtremity *gomatrixserverlib.Event) (*gomatrixserverlib.RespState, error) { func (t *txnReq) resolveStatesAndCheck(ctx context.Context, roomVersion gomatrixserverlib.RoomVersion, states []*gomatrixserverlib.RespState, backwardsExtremity *gomatrixserverlib.Event) (*gomatrixserverlib.RespState, error) {
var authEventList []gomatrixserverlib.Event var authEventList []*gomatrixserverlib.Event
var stateEventList []gomatrixserverlib.Event var stateEventList []*gomatrixserverlib.Event
for _, state := range states { for _, state := range states {
authEventList = append(authEventList, state.AuthEvents...) authEventList = append(authEventList, state.AuthEvents...)
stateEventList = append(stateEventList, state.StateEvents...) stateEventList = append(stateEventList, state.StateEvents...)
@ -799,7 +799,7 @@ func (t *txnReq) resolveStatesAndCheck(ctx context.Context, roomVersion gomatrix
} }
// apply the current event // apply the current event
retryAllowedState: retryAllowedState:
if err = checkAllowedByState(*backwardsExtremity, resolvedStateEvents); err != nil { if err = checkAllowedByState(backwardsExtremity, resolvedStateEvents); err != nil {
switch missing := err.(type) { switch missing := err.(type) {
case gomatrixserverlib.MissingAuthEventError: case gomatrixserverlib.MissingAuthEventError:
servers := t.getServers(ctx, backwardsExtremity.RoomID()) servers := t.getServers(ctx, backwardsExtremity.RoomID())
@ -836,9 +836,9 @@ retryAllowedState:
// This function recursively calls txnReq.processEvent with the missing events, which will be processed before this function returns. // This function recursively calls txnReq.processEvent with the missing events, which will be processed before this function returns.
// This means that we may recursively call this function, as we spider back up prev_events. // This means that we may recursively call this function, as we spider back up prev_events.
// nolint:gocyclo // nolint:gocyclo
func (t *txnReq) getMissingEvents(ctx context.Context, e gomatrixserverlib.Event, roomVersion gomatrixserverlib.RoomVersion) (newEvents []gomatrixserverlib.Event, err error) { func (t *txnReq) getMissingEvents(ctx context.Context, e *gomatrixserverlib.Event, roomVersion gomatrixserverlib.RoomVersion) (newEvents []*gomatrixserverlib.Event, err error) {
logger := util.GetLogger(ctx).WithField("event_id", e.EventID()).WithField("room_id", e.RoomID()) logger := util.GetLogger(ctx).WithField("event_id", e.EventID()).WithField("room_id", e.RoomID())
needed := gomatrixserverlib.StateNeededForAuth([]gomatrixserverlib.Event{e}) needed := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{e})
// query latest events (our trusted forward extremities) // query latest events (our trusted forward extremities)
req := api.QueryLatestEventsAndStateRequest{ req := api.QueryLatestEventsAndStateRequest{
RoomID: e.RoomID(), RoomID: e.RoomID(),
@ -979,7 +979,7 @@ func (t *txnReq) lookupMissingStateViaStateIDs(ctx context.Context, roomID, even
} }
for i := range queryRes.Events { for i := range queryRes.Events {
evID := queryRes.Events[i].EventID() evID := queryRes.Events[i].EventID()
t.haveEvents[evID] = &queryRes.Events[i] t.haveEvents[evID] = queryRes.Events[i]
if missing[evID] { if missing[evID] {
delete(missing, evID) delete(missing, evID)
} }
@ -1116,10 +1116,10 @@ func (t *txnReq) lookupEvent(ctx context.Context, roomVersion gomatrixserverlib.
if err := t.rsAPI.QueryEventsByID(ctx, &queryReq, &queryRes); err != nil { if err := t.rsAPI.QueryEventsByID(ctx, &queryReq, &queryRes); err != nil {
util.GetLogger(ctx).Warnf("Failed to query roomserver for missing event %s: %s - falling back to remote", missingEventID, err) util.GetLogger(ctx).Warnf("Failed to query roomserver for missing event %s: %s - falling back to remote", missingEventID, err)
} else if len(queryRes.Events) == 1 { } else if len(queryRes.Events) == 1 {
return &queryRes.Events[0], nil return queryRes.Events[0], nil
} }
} }
var event gomatrixserverlib.Event var event *gomatrixserverlib.Event
found := false found := false
for _, serverName := range servers { for _, serverName := range servers {
txn, err := t.federation.GetEvent(ctx, serverName, missingEventID) txn, err := t.federation.GetEvent(ctx, serverName, missingEventID)
@ -1139,11 +1139,11 @@ func (t *txnReq) lookupEvent(ctx context.Context, roomVersion gomatrixserverlib.
util.GetLogger(ctx).WithField("event_id", missingEventID).Warnf("Failed to get missing /event for event ID from %d server(s)", len(servers)) util.GetLogger(ctx).WithField("event_id", missingEventID).Warnf("Failed to get missing /event for event ID from %d server(s)", len(servers))
return nil, fmt.Errorf("wasn't able to find event via %d server(s)", len(servers)) return nil, fmt.Errorf("wasn't able to find event via %d server(s)", len(servers))
} }
if err := gomatrixserverlib.VerifyAllEventSignatures(ctx, []gomatrixserverlib.Event{event}, t.keys); err != nil { if err := gomatrixserverlib.VerifyAllEventSignatures(ctx, []*gomatrixserverlib.Event{event}, t.keys); err != nil {
util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID()) util.GetLogger(ctx).WithError(err).Warnf("Transaction: Couldn't validate signature of event %q", event.EventID())
return nil, verifySigError{event.EventID(), err} return nil, verifySigError{event.EventID(), err}
} }
h := event.Headered(roomVersion) h := event.Headered(roomVersion)
t.newEvents[h.EventID()] = true t.newEvents[h.EventID()] = true
return &h, nil return h, nil
} }

View file

@ -33,8 +33,8 @@ var (
[]byte(`{"auth_events":[["$0ok8ynDp7kjc95e3:kaer.morhen",{"sha256":"sWCi6Ckp9rDimQON+MrUlNRkyfZ2tjbPbWfg2NMB18Q"}],["$LEwEu0kxrtu5fOiS:kaer.morhen",{"sha256":"1aKajq6DWHru1R1HJjvdWMEavkJJHGaTmPvfuERUXaA"}]],"content":{"body":"Test Message"},"depth":6,"event_id":"$MYSbs8m4rEbsCWXD:kaer.morhen","hashes":{"sha256":"kgbYM7v4Ud2YaBsjBTolM4ySg6rHcJNYI6nWhMSdFUA"},"origin":"kaer.morhen","origin_server_ts":0,"prev_events":[["$gl2T9l3qm0kUbiIJ:kaer.morhen",{"sha256":"C/rD04h9wGxRdN2G/IBfrgoE1UovzLZ+uskwaKZ37/Q"}]],"room_id":"!roomid:kaer.morhen","sender":"@userid:kaer.morhen","signatures":{"kaer.morhen":{"ed25519:auto":"x0UoKh968jj/F5l1/R7Ew0T6CTKuew3PLNHASNxqck/bkNe8yYQiDHXRr+kZxObeqPZZTpaF1+EI+bLU9W8GDQ"}},"type":"m.room.message"}`), []byte(`{"auth_events":[["$0ok8ynDp7kjc95e3:kaer.morhen",{"sha256":"sWCi6Ckp9rDimQON+MrUlNRkyfZ2tjbPbWfg2NMB18Q"}],["$LEwEu0kxrtu5fOiS:kaer.morhen",{"sha256":"1aKajq6DWHru1R1HJjvdWMEavkJJHGaTmPvfuERUXaA"}]],"content":{"body":"Test Message"},"depth":6,"event_id":"$MYSbs8m4rEbsCWXD:kaer.morhen","hashes":{"sha256":"kgbYM7v4Ud2YaBsjBTolM4ySg6rHcJNYI6nWhMSdFUA"},"origin":"kaer.morhen","origin_server_ts":0,"prev_events":[["$gl2T9l3qm0kUbiIJ:kaer.morhen",{"sha256":"C/rD04h9wGxRdN2G/IBfrgoE1UovzLZ+uskwaKZ37/Q"}]],"room_id":"!roomid:kaer.morhen","sender":"@userid:kaer.morhen","signatures":{"kaer.morhen":{"ed25519:auto":"x0UoKh968jj/F5l1/R7Ew0T6CTKuew3PLNHASNxqck/bkNe8yYQiDHXRr+kZxObeqPZZTpaF1+EI+bLU9W8GDQ"}},"type":"m.room.message"}`),
[]byte(`{"auth_events":[["$0ok8ynDp7kjc95e3:kaer.morhen",{"sha256":"sWCi6Ckp9rDimQON+MrUlNRkyfZ2tjbPbWfg2NMB18Q"}],["$LEwEu0kxrtu5fOiS:kaer.morhen",{"sha256":"1aKajq6DWHru1R1HJjvdWMEavkJJHGaTmPvfuERUXaA"}]],"content":{"body":"Test Message"},"depth":7,"event_id":"$N5x9WJkl9ClPrAEg:kaer.morhen","hashes":{"sha256":"FWM8oz4yquTunRZ67qlW2gzPDzdWfBP6RPHXhK1I/x8"},"origin":"kaer.morhen","origin_server_ts":0,"prev_events":[["$MYSbs8m4rEbsCWXD:kaer.morhen",{"sha256":"fatqgW+SE8mb2wFn3UN+drmluoD4UJ/EcSrL6Ur9q1M"}]],"room_id":"!roomid:kaer.morhen","sender":"@userid:kaer.morhen","signatures":{"kaer.morhen":{"ed25519:auto":"Y+LX/xcyufoXMOIoqQBNOzy6lZfUGB1ffgXIrSugk6obMiyAsiRejHQN/pciZXsHKxMJLYRFAz4zSJoS/LGPAA"}},"type":"m.room.message"}`), []byte(`{"auth_events":[["$0ok8ynDp7kjc95e3:kaer.morhen",{"sha256":"sWCi6Ckp9rDimQON+MrUlNRkyfZ2tjbPbWfg2NMB18Q"}],["$LEwEu0kxrtu5fOiS:kaer.morhen",{"sha256":"1aKajq6DWHru1R1HJjvdWMEavkJJHGaTmPvfuERUXaA"}]],"content":{"body":"Test Message"},"depth":7,"event_id":"$N5x9WJkl9ClPrAEg:kaer.morhen","hashes":{"sha256":"FWM8oz4yquTunRZ67qlW2gzPDzdWfBP6RPHXhK1I/x8"},"origin":"kaer.morhen","origin_server_ts":0,"prev_events":[["$MYSbs8m4rEbsCWXD:kaer.morhen",{"sha256":"fatqgW+SE8mb2wFn3UN+drmluoD4UJ/EcSrL6Ur9q1M"}]],"room_id":"!roomid:kaer.morhen","sender":"@userid:kaer.morhen","signatures":{"kaer.morhen":{"ed25519:auto":"Y+LX/xcyufoXMOIoqQBNOzy6lZfUGB1ffgXIrSugk6obMiyAsiRejHQN/pciZXsHKxMJLYRFAz4zSJoS/LGPAA"}},"type":"m.room.message"}`),
} }
testEvents = []gomatrixserverlib.HeaderedEvent{} testEvents = []*gomatrixserverlib.HeaderedEvent{}
testStateEvents = make(map[gomatrixserverlib.StateKeyTuple]gomatrixserverlib.HeaderedEvent) testStateEvents = make(map[gomatrixserverlib.StateKeyTuple]*gomatrixserverlib.HeaderedEvent)
) )
func init() { func init() {
@ -445,7 +445,7 @@ NextPDU:
} }
} }
func fromStateTuples(tuples []gomatrixserverlib.StateKeyTuple, omitTuples []gomatrixserverlib.StateKeyTuple) (result []gomatrixserverlib.HeaderedEvent) { func fromStateTuples(tuples []gomatrixserverlib.StateKeyTuple, omitTuples []gomatrixserverlib.StateKeyTuple) (result []*gomatrixserverlib.HeaderedEvent) {
NextTuple: NextTuple:
for _, t := range tuples { for _, t := range tuples {
for _, o := range omitTuples { for _, o := range omitTuples {
@ -461,7 +461,7 @@ NextTuple:
return return
} }
func assertInputRoomEvents(t *testing.T, got []api.InputRoomEvent, want []gomatrixserverlib.HeaderedEvent) { func assertInputRoomEvents(t *testing.T, got []api.InputRoomEvent, want []*gomatrixserverlib.HeaderedEvent) {
for _, g := range got { for _, g := range got {
fmt.Println("GOT ", g.Event.EventID()) fmt.Println("GOT ", g.Event.EventID())
} }
@ -493,7 +493,7 @@ func TestBasicTransaction(t *testing.T) {
} }
txn := mustCreateTransaction(rsAPI, &txnFedClient{}, pdus) txn := mustCreateTransaction(rsAPI, &txnFedClient{}, pdus)
mustProcessTransaction(t, txn, nil) mustProcessTransaction(t, txn, nil)
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{testEvents[len(testEvents)-1]}) assertInputRoomEvents(t, rsAPI.inputRoomEvents, []*gomatrixserverlib.HeaderedEvent{testEvents[len(testEvents)-1]})
} }
// The purpose of this test is to check that if the event received fails auth checks the event is still sent to the roomserver // The purpose of this test is to check that if the event received fails auth checks the event is still sent to the roomserver
@ -514,7 +514,7 @@ func TestTransactionFailAuthChecks(t *testing.T) {
txn := mustCreateTransaction(rsAPI, &txnFedClient{}, pdus) txn := mustCreateTransaction(rsAPI, &txnFedClient{}, pdus)
mustProcessTransaction(t, txn, []string{}) mustProcessTransaction(t, txn, []string{})
// expect message to be sent to the roomserver // expect message to be sent to the roomserver
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{testEvents[len(testEvents)-1]}) assertInputRoomEvents(t, rsAPI.inputRoomEvents, []*gomatrixserverlib.HeaderedEvent{testEvents[len(testEvents)-1]})
} }
// The purpose of this test is to make sure that when an event is received for which we do not know the prev_events, // The purpose of this test is to make sure that when an event is received for which we do not know the prev_events,
@ -586,7 +586,7 @@ func TestTransactionFetchMissingPrevEvents(t *testing.T) {
t.Errorf("call to /get_missing_events wrong latest events: got %v want %v", missing.LatestEvents, inputEvent.EventID()) t.Errorf("call to /get_missing_events wrong latest events: got %v want %v", missing.LatestEvents, inputEvent.EventID())
} }
return gomatrixserverlib.RespMissingEvents{ return gomatrixserverlib.RespMissingEvents{
Events: []gomatrixserverlib.Event{ Events: []*gomatrixserverlib.Event{
prevEvent.Unwrap(), prevEvent.Unwrap(),
}, },
}, nil }, nil
@ -598,7 +598,7 @@ func TestTransactionFetchMissingPrevEvents(t *testing.T) {
} }
txn := mustCreateTransaction(rsAPI, cli, pdus) txn := mustCreateTransaction(rsAPI, cli, pdus)
mustProcessTransaction(t, txn, nil) mustProcessTransaction(t, txn, nil)
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{prevEvent, inputEvent}) assertInputRoomEvents(t, rsAPI.inputRoomEvents, []*gomatrixserverlib.HeaderedEvent{prevEvent, inputEvent})
} }
// The purpose of this test is to check that when there are missing prev_events and we still haven't been able to fill // The purpose of this test is to check that when there are missing prev_events and we still haven't been able to fill
@ -653,7 +653,7 @@ func TestTransactionFetchMissingStateByStateIDs(t *testing.T) {
} else if askingForEvent == eventB.EventID() { } else if askingForEvent == eventB.EventID() {
prevEventExists = haveEventB prevEventExists = haveEventB
} }
var stateEvents []gomatrixserverlib.HeaderedEvent var stateEvents []*gomatrixserverlib.HeaderedEvent
if prevEventExists { if prevEventExists {
stateEvents = fromStateTuples(req.StateToFetch, omitTuples) stateEvents = fromStateTuples(req.StateToFetch, omitTuples)
} }
@ -771,7 +771,7 @@ func TestTransactionFetchMissingStateByStateIDs(t *testing.T) {
} }
// just return event C, not event B so /state_ids logic kicks in as there will STILL be missing prev_events // just return event C, not event B so /state_ids logic kicks in as there will STILL be missing prev_events
return gomatrixserverlib.RespMissingEvents{ return gomatrixserverlib.RespMissingEvents{
Events: []gomatrixserverlib.Event{ Events: []*gomatrixserverlib.Event{
eventC.Unwrap(), eventC.Unwrap(),
}, },
}, nil }, nil
@ -783,5 +783,5 @@ func TestTransactionFetchMissingStateByStateIDs(t *testing.T) {
} }
txn := mustCreateTransaction(rsAPI, cli, pdus) txn := mustCreateTransaction(rsAPI, cli, pdus)
mustProcessTransaction(t, txn, nil) mustProcessTransaction(t, txn, nil)
assertInputRoomEvents(t, rsAPI.inputRoomEvents, []gomatrixserverlib.HeaderedEvent{eventB, eventC, eventD}) assertInputRoomEvents(t, rsAPI.inputRoomEvents, []*gomatrixserverlib.HeaderedEvent{eventB, eventC, eventD})
} }

View file

@ -136,7 +136,7 @@ func getState(
}, nil }, nil
} }
func getIDsFromEvent(events []gomatrixserverlib.Event) []string { func getIDsFromEvent(events []*gomatrixserverlib.Event) []string {
IDs := make([]string, len(events)) IDs := make([]string, len(events))
for i := range events { for i := range events {
IDs[i] = events[i].EventID() IDs[i] = events[i].EventID()

View file

@ -65,7 +65,7 @@ func CreateInvitesFrom3PIDInvites(
return *reqErr return *reqErr
} }
evs := []gomatrixserverlib.HeaderedEvent{} evs := []*gomatrixserverlib.HeaderedEvent{}
for _, inv := range body.Invites { for _, inv := range body.Invites {
verReq := api.QueryRoomVersionForRoomRequest{RoomID: inv.RoomID} verReq := api.QueryRoomVersionForRoomRequest{RoomID: inv.RoomID}
verRes := api.QueryRoomVersionForRoomResponse{} verRes := api.QueryRoomVersionForRoomResponse{}
@ -84,7 +84,7 @@ func CreateInvitesFrom3PIDInvites(
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
} }
if event != nil { if event != nil {
evs = append(evs, (*event).Headered(verRes.RoomVersion)) evs = append(evs, event.Headered(verRes.RoomVersion))
} }
} }
@ -165,7 +165,7 @@ func ExchangeThirdPartyInvite(
// Ask the requesting server to sign the newly created event so we know it // Ask the requesting server to sign the newly created event so we know it
// acknowledged it // acknowledged it
signedEvent, err := federation.SendInvite(httpReq.Context(), request.Origin(), *event) signedEvent, err := federation.SendInvite(httpReq.Context(), request.Origin(), event)
if err != nil { if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("federation.SendInvite failed") util.GetLogger(httpReq.Context()).WithError(err).Error("federation.SendInvite failed")
return jsonerror.InternalServerError() return jsonerror.InternalServerError()
@ -175,7 +175,7 @@ func ExchangeThirdPartyInvite(
if err = api.SendEvents( if err = api.SendEvents(
httpReq.Context(), rsAPI, httpReq.Context(), rsAPI,
api.KindNew, api.KindNew,
[]gomatrixserverlib.HeaderedEvent{ []*gomatrixserverlib.HeaderedEvent{
signedEvent.Event.Headered(verRes.RoomVersion), signedEvent.Event.Headered(verRes.RoomVersion),
}, },
cfg.Matrix.ServerName, cfg.Matrix.ServerName,
@ -297,7 +297,7 @@ func buildMembershipEvent(
authEvents := gomatrixserverlib.NewAuthEvents(nil) authEvents := gomatrixserverlib.NewAuthEvents(nil)
for i := range queryRes.StateEvents { for i := range queryRes.StateEvents {
err = authEvents.AddEvent(&queryRes.StateEvents[i].Event) err = authEvents.AddEvent(queryRes.StateEvents[i].Event)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -318,7 +318,7 @@ func buildMembershipEvent(
cfg.Matrix.PrivateKey, queryRes.RoomVersion, cfg.Matrix.PrivateKey, queryRes.RoomVersion,
) )
return &event, err return event, err
} }
// sendToRemoteServer uses federation to send an invite provided by an identity // sendToRemoteServer uses federation to send an invite provided by an identity

View file

@ -118,12 +118,12 @@ type PerformLeaveResponse struct {
type PerformInviteRequest struct { type PerformInviteRequest struct {
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
Event gomatrixserverlib.HeaderedEvent `json:"event"` Event *gomatrixserverlib.HeaderedEvent `json:"event"`
InviteRoomState []gomatrixserverlib.InviteV2StrippedState `json:"invite_room_state"` InviteRoomState []gomatrixserverlib.InviteV2StrippedState `json:"invite_room_state"`
} }
type PerformInviteResponse struct { type PerformInviteResponse struct {
Event gomatrixserverlib.HeaderedEvent `json:"event"` Event *gomatrixserverlib.HeaderedEvent `json:"event"`
} }
type PerformServersAliveRequest struct { type PerformServersAliveRequest struct {

View file

@ -85,7 +85,7 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
switch output.Type { switch output.Type {
case api.OutputTypeNewRoomEvent: case api.OutputTypeNewRoomEvent:
ev := &output.NewRoomEvent.Event ev := output.NewRoomEvent.Event
if output.NewRoomEvent.RewritesState { if output.NewRoomEvent.RewritesState {
if err := s.db.PurgeRoomState(context.TODO(), ev.RoomID()); err != nil { if err := s.db.PurgeRoomState(context.TODO(), ev.RoomID()); err != nil {
@ -158,7 +158,7 @@ func (s *OutputRoomEventConsumer) processMessage(ore api.OutputNewRoomEvent) err
// Send the event. // Send the event.
return s.queues.SendEvent( return s.queues.SendEvent(
&ore.Event, gomatrixserverlib.ServerName(ore.SendAsServer), joinedHostsAtEvent, ore.Event, gomatrixserverlib.ServerName(ore.SendAsServer), joinedHostsAtEvent,
) )
} }
@ -226,7 +226,7 @@ func (s *OutputRoomEventConsumer) joinedHostsAtEvent(
// joinedHostsFromEvents turns a list of state events into a list of joined hosts. // joinedHostsFromEvents turns a list of state events into a list of joined hosts.
// This errors if one of the events was invalid. // This errors if one of the events was invalid.
// It should be impossible for an invalid event to get this far in the pipeline. // It should be impossible for an invalid event to get this far in the pipeline.
func joinedHostsFromEvents(evs []gomatrixserverlib.Event) ([]types.JoinedHost, error) { func joinedHostsFromEvents(evs []*gomatrixserverlib.Event) ([]types.JoinedHost, error) {
var joinedHosts []types.JoinedHost var joinedHosts []types.JoinedHost
for _, ev := range evs { for _, ev := range evs {
if ev.Type() != "m.room.member" || ev.StateKey() == nil { if ev.Type() != "m.room.member" || ev.StateKey() == nil {
@ -291,8 +291,8 @@ func combineDeltas(adds1, removes1, adds2, removes2 []string) (adds, removes []s
// lookupStateEvents looks up the state events that are added by a new event. // lookupStateEvents looks up the state events that are added by a new event.
func (s *OutputRoomEventConsumer) lookupStateEvents( func (s *OutputRoomEventConsumer) lookupStateEvents(
addsStateEventIDs []string, event gomatrixserverlib.Event, addsStateEventIDs []string, event *gomatrixserverlib.Event,
) ([]gomatrixserverlib.Event, error) { ) ([]*gomatrixserverlib.Event, error) {
// Fast path if there aren't any new state events. // Fast path if there aren't any new state events.
if len(addsStateEventIDs) == 0 { if len(addsStateEventIDs) == 0 {
return nil, nil return nil, nil
@ -300,11 +300,11 @@ func (s *OutputRoomEventConsumer) lookupStateEvents(
// Fast path if the only state event added is the event itself. // Fast path if the only state event added is the event itself.
if len(addsStateEventIDs) == 1 && addsStateEventIDs[0] == event.EventID() { if len(addsStateEventIDs) == 1 && addsStateEventIDs[0] == event.EventID() {
return []gomatrixserverlib.Event{event}, nil return []*gomatrixserverlib.Event{event}, nil
} }
missing := addsStateEventIDs missing := addsStateEventIDs
var result []gomatrixserverlib.Event var result []*gomatrixserverlib.Event
// Check if event itself is being added. // Check if event itself is being added.
for _, eventID := range missing { for _, eventID := range missing {
@ -343,7 +343,7 @@ func (s *OutputRoomEventConsumer) lookupStateEvents(
return result, nil return result, nil
} }
func missingEventsFrom(events []gomatrixserverlib.Event, required []string) []string { func missingEventsFrom(events []*gomatrixserverlib.Event, required []string) []string {
have := map[string]bool{} have := map[string]bool{}
for _, event := range events { for _, event := range events {
have[event.EventID()] = true have[event.EventID()] = true

View file

@ -378,7 +378,7 @@ func (r *FederationSenderInternalAPI) PerformInvite(
"destination": destination, "destination": destination,
}).Info("Sending invite") }).Info("Sending invite")
inviteReq, err := gomatrixserverlib.NewInviteV2Request(&request.Event, request.InviteRoomState) inviteReq, err := gomatrixserverlib.NewInviteV2Request(request.Event, request.InviteRoomState)
if err != nil { if err != nil {
return fmt.Errorf("gomatrixserverlib.NewInviteV2Request: %w", err) return fmt.Errorf("gomatrixserverlib.NewInviteV2Request: %w", err)
} }

View file

@ -26,20 +26,20 @@ func JoinContext(f *gomatrixserverlib.FederationClient, k *gomatrixserverlib.Key
// and that the join is allowed by the supplied state. // and that the join is allowed by the supplied state.
func (r joinContext) CheckSendJoinResponse( func (r joinContext) CheckSendJoinResponse(
ctx context.Context, ctx context.Context,
event gomatrixserverlib.Event, event *gomatrixserverlib.Event,
server gomatrixserverlib.ServerName, server gomatrixserverlib.ServerName,
respMakeJoin gomatrixserverlib.RespMakeJoin, respMakeJoin gomatrixserverlib.RespMakeJoin,
respSendJoin gomatrixserverlib.RespSendJoin, respSendJoin gomatrixserverlib.RespSendJoin,
) (*gomatrixserverlib.RespState, error) { ) (*gomatrixserverlib.RespState, error) {
// A list of events that we have retried, if they were not included in // A list of events that we have retried, if they were not included in
// the auth events supplied in the send_join. // the auth events supplied in the send_join.
retries := map[string][]gomatrixserverlib.Event{} retries := map[string][]*gomatrixserverlib.Event{}
// Define a function which we can pass to Check to retrieve missing // Define a function which we can pass to Check to retrieve missing
// auth events inline. This greatly increases our chances of not having // auth events inline. This greatly increases our chances of not having
// to repeat the entire set of checks just for a missing event or two. // to repeat the entire set of checks just for a missing event or two.
missingAuth := func(roomVersion gomatrixserverlib.RoomVersion, eventIDs []string) ([]gomatrixserverlib.Event, error) { missingAuth := func(roomVersion gomatrixserverlib.RoomVersion, eventIDs []string) ([]*gomatrixserverlib.Event, error) {
returning := []gomatrixserverlib.Event{} returning := []*gomatrixserverlib.Event{}
// See if we have retry entries for each of the supplied event IDs. // See if we have retry entries for each of the supplied event IDs.
for _, eventID := range eventIDs { for _, eventID := range eventIDs {
@ -75,7 +75,7 @@ func (r joinContext) CheckSendJoinResponse(
} }
// Check the signatures of the event. // Check the signatures of the event.
if res, err := gomatrixserverlib.VerifyEventSignatures(ctx, []gomatrixserverlib.Event{ev}, r.keyRing); err != nil { if res, err := gomatrixserverlib.VerifyEventSignatures(ctx, []*gomatrixserverlib.Event{ev}, r.keyRing); err != nil {
return nil, fmt.Errorf("missingAuth VerifyEventSignatures: %w", err) return nil, fmt.Errorf("missingAuth VerifyEventSignatures: %w", err)
} else { } else {
for _, err := range res { for _, err := range res {

2
go.mod
View file

@ -22,7 +22,7 @@ require (
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4 github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3 github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd
github.com/matrix-org/gomatrixserverlib v0.0.0-20201020162226-22169fe9cda7 github.com/matrix-org/gomatrixserverlib v0.0.0-20201116151724-6e7b24e4956c
github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91 github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
github.com/mattn/go-sqlite3 v1.14.2 github.com/mattn/go-sqlite3 v1.14.2

4
go.sum
View file

@ -569,8 +569,8 @@ github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bh
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0= github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd h1:xVrqJK3xHREMNjwjljkAUaadalWc0rRbmVuQatzmgwg= github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd h1:xVrqJK3xHREMNjwjljkAUaadalWc0rRbmVuQatzmgwg=
github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= github.com/matrix-org/gomatrix v0.0.0-20200827122206-7dd5e2a05bcd/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
github.com/matrix-org/gomatrixserverlib v0.0.0-20201020162226-22169fe9cda7 h1:YPuewGCKaJh08NslYAhyGiLw2tg6ew9LtkW7Xr+4uTU= github.com/matrix-org/gomatrixserverlib v0.0.0-20201116151724-6e7b24e4956c h1:iiloytJig9EmlKwuSulIbNvoPz1BFZ1QdyPWpuy85XM=
github.com/matrix-org/gomatrixserverlib v0.0.0-20201020162226-22169fe9cda7/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU= github.com/matrix-org/gomatrixserverlib v0.0.0-20201116151724-6e7b24e4956c/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91 h1:HJ6U3S3ljJqNffYMcIeAncp5qT/i+ZMiJ2JC2F0aXP4= github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91 h1:HJ6U3S3ljJqNffYMcIeAncp5qT/i+ZMiJ2JC2F0aXP4=
github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE= github.com/matrix-org/naffka v0.0.0-20200901083833-bcdd62999a91/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE=
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo= github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=

View file

@ -73,8 +73,7 @@ func BuildEvent(
return nil, err return nil, err
} }
h := event.Headered(queryRes.RoomVersion) return event.Headered(queryRes.RoomVersion), nil
return &h, nil
} }
// queryRequiredEventsForBuilder queries the roomserver for auth/prev events needed for this builder. // queryRequiredEventsForBuilder queries the roomserver for auth/prev events needed for this builder.
@ -120,7 +119,7 @@ func addPrevEventsToEvent(
authEvents := gomatrixserverlib.NewAuthEvents(nil) authEvents := gomatrixserverlib.NewAuthEvents(nil)
for i := range queryRes.StateEvents { for i := range queryRes.StateEvents {
err = authEvents.AddEvent(&queryRes.StateEvents[i].Event) err = authEvents.AddEvent(queryRes.StateEvents[i].Event)
if err != nil { if err != nil {
return fmt.Errorf("authEvents.AddEvent: %w", err) return fmt.Errorf("authEvents.AddEvent: %w", err)
} }
@ -186,5 +185,5 @@ func RedactEvent(redactionEvent, redactedEvent *gomatrixserverlib.Event) (*gomat
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &r, nil return r, nil
} }

View file

@ -16,18 +16,28 @@ package setup
import ( import (
"flag" "flag"
"fmt"
"os"
"github.com/matrix-org/dendrite/internal"
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
var configPath = flag.String("config", "dendrite.yaml", "The path to the config file. For more information, see the config file in this repository.") var (
configPath = flag.String("config", "dendrite.yaml", "The path to the config file. For more information, see the config file in this repository.")
version = flag.Bool("version", false, "Shows the current version and exits immediately.")
)
// ParseFlags parses the commandline flags and uses them to create a config. // ParseFlags parses the commandline flags and uses them to create a config.
func ParseFlags(monolith bool) *config.Dendrite { func ParseFlags(monolith bool) *config.Dendrite {
flag.Parse() flag.Parse()
if *version {
fmt.Println(internal.VersionString())
os.Exit(0)
}
if *configPath == "" { if *configPath == "" {
logrus.Fatal("--config must be supplied") logrus.Fatal("--config must be supplied")
} }

View file

@ -16,8 +16,8 @@ var build string
const ( const (
VersionMajor = 0 VersionMajor = 0
VersionMinor = 2 VersionMinor = 3
VersionPatch = 1 VersionPatch = 0
VersionTag = "" // example: "rc1" VersionTag = "" // example: "rc1"
) )

View file

@ -61,7 +61,7 @@ func NewServerACLs(db ServerACLDatabase) *ServerACLs {
continue continue
} }
if state != nil { if state != nil {
acls.OnServerACLUpdate(&state.Event) acls.OnServerACLUpdate(state.Event)
} }
} }
return acls return acls

View file

@ -53,7 +53,7 @@ type InputRoomEvent struct {
// This controls how the event is processed. // This controls how the event is processed.
Kind Kind `json:"kind"` Kind Kind `json:"kind"`
// The event JSON for the event to add. // The event JSON for the event to add.
Event gomatrixserverlib.HeaderedEvent `json:"event"` Event *gomatrixserverlib.HeaderedEvent `json:"event"`
// List of state event IDs that authenticate this event. // List of state event IDs that authenticate this event.
// These are likely derived from the "auth_events" JSON key of the event. // These are likely derived from the "auth_events" JSON key of the event.
// But can be different because the "auth_events" key can be incomplete or wrong. // But can be different because the "auth_events" key can be incomplete or wrong.

View file

@ -94,7 +94,7 @@ const (
// prev_events. // prev_events.
type OutputNewRoomEvent struct { type OutputNewRoomEvent struct {
// The Event. // The Event.
Event gomatrixserverlib.HeaderedEvent `json:"event"` Event *gomatrixserverlib.HeaderedEvent `json:"event"`
// Does the event completely rewrite the room state? If so, then AddsStateEventIDs // Does the event completely rewrite the room state? If so, then AddsStateEventIDs
// will contain the entire room state. // will contain the entire room state.
RewritesState bool `json:"rewrites_state"` RewritesState bool `json:"rewrites_state"`
@ -111,7 +111,7 @@ type OutputNewRoomEvent struct {
// may decide a bunch of state events on one branch are now valid, so they will be // may decide a bunch of state events on one branch are now valid, so they will be
// present in this list. This is useful when trying to maintain the current state of a room // present in this list. This is useful when trying to maintain the current state of a room
// as to do so you need to include both these events and `Event`. // as to do so you need to include both these events and `Event`.
AddStateEvents []gomatrixserverlib.HeaderedEvent `json:"adds_state_events"` AddStateEvents []*gomatrixserverlib.HeaderedEvent `json:"adds_state_events"`
// The state event IDs that were removed from the state of the room by this event. // The state event IDs that were removed from the state of the room by this event.
RemovesStateEventIDs []string `json:"removes_state_event_ids"` RemovesStateEventIDs []string `json:"removes_state_event_ids"`
@ -168,7 +168,7 @@ type OutputNewRoomEvent struct {
// the original event to save space, so you cannot use that slice alone. // the original event to save space, so you cannot use that slice alone.
// Instead, use this function which will add the original event if it is present // Instead, use this function which will add the original event if it is present
// in `AddsStateEventIDs`. // in `AddsStateEventIDs`.
func (ore *OutputNewRoomEvent) AddsState() []gomatrixserverlib.HeaderedEvent { func (ore *OutputNewRoomEvent) AddsState() []*gomatrixserverlib.HeaderedEvent {
includeOutputEvent := false includeOutputEvent := false
for _, id := range ore.AddsStateEventIDs { for _, id := range ore.AddsStateEventIDs {
if id == ore.Event.EventID() { if id == ore.Event.EventID() {
@ -193,7 +193,7 @@ func (ore *OutputNewRoomEvent) AddsState() []gomatrixserverlib.HeaderedEvent {
// should build their current room state up from OutputNewRoomEvents only. // should build their current room state up from OutputNewRoomEvents only.
type OutputOldRoomEvent struct { type OutputOldRoomEvent struct {
// The Event. // The Event.
Event gomatrixserverlib.HeaderedEvent `json:"event"` Event *gomatrixserverlib.HeaderedEvent `json:"event"`
} }
// An OutputNewInviteEvent is written whenever an invite becomes active. // An OutputNewInviteEvent is written whenever an invite becomes active.
@ -203,7 +203,7 @@ type OutputNewInviteEvent struct {
// The room version of the invited room. // The room version of the invited room.
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
// The "m.room.member" invite event. // The "m.room.member" invite event.
Event gomatrixserverlib.HeaderedEvent `json:"event"` Event *gomatrixserverlib.HeaderedEvent `json:"event"`
} }
// An OutputRetireInviteEvent is written whenever an existing invite is no longer // An OutputRetireInviteEvent is written whenever an existing invite is no longer
@ -230,7 +230,7 @@ type OutputRedactedEvent struct {
// The event ID that was redacted // The event ID that was redacted
RedactedEventID string RedactedEventID string
// The value of `unsigned.redacted_because` - the redaction event itself // The value of `unsigned.redacted_because` - the redaction event itself
RedactedBecause gomatrixserverlib.HeaderedEvent RedactedBecause *gomatrixserverlib.HeaderedEvent
} }
// An OutputNewPeek is written whenever a user starts peeking into a room // An OutputNewPeek is written whenever a user starts peeking into a room

View file

@ -105,7 +105,7 @@ type PerformLeaveResponse struct {
type PerformInviteRequest struct { type PerformInviteRequest struct {
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"` RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
Event gomatrixserverlib.HeaderedEvent `json:"event"` Event *gomatrixserverlib.HeaderedEvent `json:"event"`
InviteRoomState []gomatrixserverlib.InviteV2StrippedState `json:"invite_room_state"` InviteRoomState []gomatrixserverlib.InviteV2StrippedState `json:"invite_room_state"`
SendAsServer string `json:"send_as_server"` SendAsServer string `json:"send_as_server"`
TransactionID *TransactionID `json:"transaction_id"` TransactionID *TransactionID `json:"transaction_id"`
@ -154,7 +154,7 @@ func (r *PerformBackfillRequest) PrevEventIDs() []string {
// PerformBackfillResponse is a response to PerformBackfill. // PerformBackfillResponse is a response to PerformBackfill.
type PerformBackfillResponse struct { type PerformBackfillResponse struct {
// Missing events, arbritrary order. // Missing events, arbritrary order.
Events []gomatrixserverlib.HeaderedEvent `json:"events"` Events []*gomatrixserverlib.HeaderedEvent `json:"events"`
} }
type PerformPublishRequest struct { type PerformPublishRequest struct {

View file

@ -50,7 +50,7 @@ type QueryLatestEventsAndStateResponse struct {
// This list will be in an arbitrary order. // This list will be in an arbitrary order.
// These are used to set the auth_events when sending an event. // These are used to set the auth_events when sending an event.
// These are used to check whether the event is allowed. // These are used to check whether the event is allowed.
StateEvents []gomatrixserverlib.HeaderedEvent `json:"state_events"` StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"`
// The depth of the latest events. // The depth of the latest events.
// This is one greater than the maximum depth of the latest events. // This is one greater than the maximum depth of the latest events.
// This is used to set the depth when sending an event. // This is used to set the depth when sending an event.
@ -80,7 +80,7 @@ type QueryStateAfterEventsResponse struct {
PrevEventsExist bool `json:"prev_events_exist"` PrevEventsExist bool `json:"prev_events_exist"`
// The state events requested. // The state events requested.
// This list will be in an arbitrary order. // This list will be in an arbitrary order.
StateEvents []gomatrixserverlib.HeaderedEvent `json:"state_events"` StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"`
} }
type QueryMissingAuthPrevEventsRequest struct { type QueryMissingAuthPrevEventsRequest struct {
@ -119,7 +119,7 @@ type QueryEventsByIDResponse struct {
// fails to read it from the database then it will fail // fails to read it from the database then it will fail
// the entire request. // the entire request.
// This list will be in an arbitrary order. // This list will be in an arbitrary order.
Events []gomatrixserverlib.HeaderedEvent `json:"events"` Events []*gomatrixserverlib.HeaderedEvent `json:"events"`
} }
// QueryMembershipForUserRequest is a request to QueryMembership // QueryMembershipForUserRequest is a request to QueryMembership
@ -213,7 +213,7 @@ type QueryMissingEventsRequest struct {
// QueryMissingEventsResponse is a response to QueryMissingEvents // QueryMissingEventsResponse is a response to QueryMissingEvents
type QueryMissingEventsResponse struct { type QueryMissingEventsResponse struct {
// Missing events, arbritrary order. // Missing events, arbritrary order.
Events []gomatrixserverlib.HeaderedEvent `json:"events"` Events []*gomatrixserverlib.HeaderedEvent `json:"events"`
} }
// QueryStateAndAuthChainRequest is a request to QueryStateAndAuthChain // QueryStateAndAuthChainRequest is a request to QueryStateAndAuthChain
@ -242,8 +242,8 @@ type QueryStateAndAuthChainResponse struct {
PrevEventsExist bool `json:"prev_events_exist"` PrevEventsExist bool `json:"prev_events_exist"`
// The state and auth chain events that were requested. // The state and auth chain events that were requested.
// The lists will be in an arbitrary order. // The lists will be in an arbitrary order.
StateEvents []gomatrixserverlib.HeaderedEvent `json:"state_events"` StateEvents []*gomatrixserverlib.HeaderedEvent `json:"state_events"`
AuthChainEvents []gomatrixserverlib.HeaderedEvent `json:"auth_chain_events"` AuthChainEvents []*gomatrixserverlib.HeaderedEvent `json:"auth_chain_events"`
} }
// QueryRoomVersionCapabilitiesRequest asks for the default room version // QueryRoomVersionCapabilitiesRequest asks for the default room version

View file

@ -25,7 +25,7 @@ import (
// SendEvents to the roomserver The events are written with KindNew. // SendEvents to the roomserver The events are written with KindNew.
func SendEvents( func SendEvents(
ctx context.Context, rsAPI RoomserverInternalAPI, ctx context.Context, rsAPI RoomserverInternalAPI,
kind Kind, events []gomatrixserverlib.HeaderedEvent, kind Kind, events []*gomatrixserverlib.HeaderedEvent,
sendAsServer gomatrixserverlib.ServerName, txnID *TransactionID, sendAsServer gomatrixserverlib.ServerName, txnID *TransactionID,
) error { ) error {
ires := make([]InputRoomEvent, len(events)) ires := make([]InputRoomEvent, len(events))
@ -46,7 +46,7 @@ func SendEvents(
// marked as `true` in haveEventIDs // marked as `true` in haveEventIDs
func SendEventWithState( func SendEventWithState(
ctx context.Context, rsAPI RoomserverInternalAPI, kind Kind, ctx context.Context, rsAPI RoomserverInternalAPI, kind Kind,
state *gomatrixserverlib.RespState, event gomatrixserverlib.HeaderedEvent, state *gomatrixserverlib.RespState, event *gomatrixserverlib.HeaderedEvent,
haveEventIDs map[string]bool, haveEventIDs map[string]bool,
) error { ) error {
outliers, err := state.Events() outliers, err := state.Events()
@ -97,7 +97,7 @@ func SendInputRoomEvents(
// If we are in the room then the event should be sent using the SendEvents method. // If we are in the room then the event should be sent using the SendEvents method.
func SendInvite( func SendInvite(
ctx context.Context, ctx context.Context,
rsAPI RoomserverInternalAPI, inviteEvent gomatrixserverlib.HeaderedEvent, rsAPI RoomserverInternalAPI, inviteEvent *gomatrixserverlib.HeaderedEvent,
inviteRoomState []gomatrixserverlib.InviteV2StrippedState, inviteRoomState []gomatrixserverlib.InviteV2StrippedState,
sendAsServer gomatrixserverlib.ServerName, txnID *TransactionID, sendAsServer gomatrixserverlib.ServerName, txnID *TransactionID,
) error { ) error {
@ -134,7 +134,7 @@ func GetEvent(ctx context.Context, rsAPI RoomserverInternalAPI, eventID string)
if len(res.Events) != 1 { if len(res.Events) != 1 {
return nil return nil
} }
return &res.Events[0] return res.Events[0]
} }
// GetStateEvent returns the current state event in the room or nil. // GetStateEvent returns the current state event in the room or nil.

View file

@ -25,7 +25,7 @@ import (
func IsServerAllowed( func IsServerAllowed(
serverName gomatrixserverlib.ServerName, serverName gomatrixserverlib.ServerName,
serverCurrentlyInRoom bool, serverCurrentlyInRoom bool,
authEvents []gomatrixserverlib.Event, authEvents []*gomatrixserverlib.Event,
) bool { ) bool {
historyVisibility := HistoryVisibilityForRoom(authEvents) historyVisibility := HistoryVisibilityForRoom(authEvents)
@ -52,7 +52,7 @@ func IsServerAllowed(
return false return false
} }
func HistoryVisibilityForRoom(authEvents []gomatrixserverlib.Event) string { func HistoryVisibilityForRoom(authEvents []*gomatrixserverlib.Event) string {
// https://matrix.org/docs/spec/client_server/r0.6.0#id87 // https://matrix.org/docs/spec/client_server/r0.6.0#id87
// By default if no history_visibility is set, or if the value is not understood, the visibility is assumed to be shared. // By default if no history_visibility is set, or if the value is not understood, the visibility is assumed to be shared.
visibility := "shared" visibility := "shared"
@ -78,7 +78,7 @@ func HistoryVisibilityForRoom(authEvents []gomatrixserverlib.Event) string {
return visibility return visibility
} }
func IsAnyUserOnServerWithMembership(serverName gomatrixserverlib.ServerName, authEvents []gomatrixserverlib.Event, wantMembership string) bool { func IsAnyUserOnServerWithMembership(serverName gomatrixserverlib.ServerName, authEvents []*gomatrixserverlib.Event, wantMembership string) bool {
for _, ev := range authEvents { for _, ev := range authEvents {
membership, err := ev.Membership() membership, err := ev.Membership()
if err != nil || membership != wantMembership { if err != nil || membership != wantMembership {

View file

@ -229,7 +229,7 @@ func (r *RoomserverInternalAPI) sendUpdatedAliasesEvent(
// Add auth events // Add auth events
authEvents := gomatrixserverlib.NewAuthEvents(nil) authEvents := gomatrixserverlib.NewAuthEvents(nil)
for i := range res.StateEvents { for i := range res.StateEvents {
err = authEvents.AddEvent(&res.StateEvents[i].Event) err = authEvents.AddEvent(res.StateEvents[i].Event)
if err != nil { if err != nil {
return err return err
} }

View file

@ -31,7 +31,7 @@ import (
func CheckForSoftFail( func CheckForSoftFail(
ctx context.Context, ctx context.Context,
db storage.Database, db storage.Database,
event gomatrixserverlib.HeaderedEvent, event *gomatrixserverlib.HeaderedEvent,
stateEventIDs []string, stateEventIDs []string,
) (bool, error) { ) (bool, error) {
rewritesState := len(stateEventIDs) > 1 rewritesState := len(stateEventIDs) > 1
@ -72,7 +72,7 @@ func CheckForSoftFail(
} }
// Work out which of the state events we actually need. // Work out which of the state events we actually need.
stateNeeded := gomatrixserverlib.StateNeededForAuth([]gomatrixserverlib.Event{event.Unwrap()}) stateNeeded := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{event.Unwrap()})
// Load the actual auth events from the database. // Load the actual auth events from the database.
authEvents, err := loadAuthEvents(ctx, db, stateNeeded, authStateEntries) authEvents, err := loadAuthEvents(ctx, db, stateNeeded, authStateEntries)
@ -93,7 +93,7 @@ func CheckForSoftFail(
func CheckAuthEvents( func CheckAuthEvents(
ctx context.Context, ctx context.Context,
db storage.Database, db storage.Database,
event gomatrixserverlib.HeaderedEvent, event *gomatrixserverlib.HeaderedEvent,
authEventIDs []string, authEventIDs []string,
) ([]types.EventNID, error) { ) ([]types.EventNID, error) {
// Grab the numeric IDs for the supplied auth state events from the database. // Grab the numeric IDs for the supplied auth state events from the database.
@ -104,7 +104,7 @@ func CheckAuthEvents(
authStateEntries = types.DeduplicateStateEntries(authStateEntries) authStateEntries = types.DeduplicateStateEntries(authStateEntries)
// Work out which of the state events we actually need. // Work out which of the state events we actually need.
stateNeeded := gomatrixserverlib.StateNeededForAuth([]gomatrixserverlib.Event{event.Unwrap()}) stateNeeded := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{event.Unwrap()})
// Load the actual auth events from the database. // Load the actual auth events from the database.
authEvents, err := loadAuthEvents(ctx, db, stateNeeded, authStateEntries) authEvents, err := loadAuthEvents(ctx, db, stateNeeded, authStateEntries)
@ -168,7 +168,7 @@ func (ae *authEvents) lookupEventWithEmptyStateKey(typeNID types.EventTypeNID) *
if !ok { if !ok {
return nil return nil
} }
return &event.Event return event.Event
} }
func (ae *authEvents) lookupEvent(typeNID types.EventTypeNID, stateKey string) *gomatrixserverlib.Event { func (ae *authEvents) lookupEvent(typeNID types.EventTypeNID, stateKey string) *gomatrixserverlib.Event {
@ -187,7 +187,7 @@ func (ae *authEvents) lookupEvent(typeNID types.EventTypeNID, stateKey string) *
if !ok { if !ok {
return nil return nil
} }
return &event.Event return event.Event
} }
// loadAuthEvents loads the events needed for authentication from the supplied room state. // loadAuthEvents loads the events needed for authentication from the supplied room state.

View file

@ -67,7 +67,7 @@ func IsServerCurrentlyInRoom(ctx context.Context, db storage.Database, serverNam
if err != nil { if err != nil {
return false, err return false, err
} }
gmslEvents := make([]gomatrixserverlib.Event, len(events)) gmslEvents := make([]*gomatrixserverlib.Event, len(events))
for i := range events { for i := range events {
gmslEvents[i] = events[i].Event gmslEvents[i] = events[i].Event
} }
@ -190,13 +190,13 @@ func StateBeforeEvent(ctx context.Context, db storage.Database, info types.RoomI
func LoadEvents( func LoadEvents(
ctx context.Context, db storage.Database, eventNIDs []types.EventNID, ctx context.Context, db storage.Database, eventNIDs []types.EventNID,
) ([]gomatrixserverlib.Event, error) { ) ([]*gomatrixserverlib.Event, error) {
stateEvents, err := db.Events(ctx, eventNIDs) stateEvents, err := db.Events(ctx, eventNIDs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := make([]gomatrixserverlib.Event, len(stateEvents)) result := make([]*gomatrixserverlib.Event, len(stateEvents))
for i := range stateEvents { for i := range stateEvents {
result[i] = stateEvents[i].Event result[i] = stateEvents[i].Event
} }
@ -205,7 +205,7 @@ func LoadEvents(
func LoadStateEvents( func LoadStateEvents(
ctx context.Context, db storage.Database, stateEntries []types.StateEntry, ctx context.Context, db storage.Database, stateEntries []types.StateEntry,
) ([]gomatrixserverlib.Event, error) { ) ([]*gomatrixserverlib.Event, error) {
eventNIDs := make([]types.EventNID, len(stateEntries)) eventNIDs := make([]types.EventNID, len(stateEntries))
for i := range stateEntries { for i := range stateEntries {
eventNIDs[i] = stateEntries[i].EventNID eventNIDs[i] = stateEntries[i].EventNID

View file

@ -92,7 +92,7 @@ func (r *Inputer) WriteOutputEvents(roomID string, updates []api.OutputEvent) er
}) })
if updates[i].NewRoomEvent.Event.Type() == "m.room.server_acl" && updates[i].NewRoomEvent.Event.StateKeyEquals("") { if updates[i].NewRoomEvent.Event.Type() == "m.room.server_acl" && updates[i].NewRoomEvent.Event.StateKeyEquals("") {
ev := updates[i].NewRoomEvent.Event.Unwrap() ev := updates[i].NewRoomEvent.Event.Unwrap()
defer r.ACLs.OnServerACLUpdate(&ev) defer r.ACLs.OnServerACLUpdate(ev)
} }
} }
logger.Infof("Producing to topic '%s'", r.OutputRoomEventTopic) logger.Infof("Producing to topic '%s'", r.OutputRoomEventTopic)

View file

@ -111,11 +111,11 @@ func (r *Inputer) processRoomEvent(
// if storing this event results in it being redacted then do so. // if storing this event results in it being redacted then do so.
if !isRejected && redactedEventID == event.EventID() { if !isRejected && redactedEventID == event.EventID() {
r, rerr := eventutil.RedactEvent(redactionEvent, &event) r, rerr := eventutil.RedactEvent(redactionEvent, event)
if rerr != nil { if rerr != nil {
return "", fmt.Errorf("eventutil.RedactEvent: %w", rerr) return "", fmt.Errorf("eventutil.RedactEvent: %w", rerr)
} }
event = *r event = r
} }
// For outliers we can stop after we've stored the event itself as it // For outliers we can stop after we've stored the event itself as it
@ -215,7 +215,7 @@ func (r *Inputer) calculateAndSetState(
input *api.InputRoomEvent, input *api.InputRoomEvent,
roomInfo types.RoomInfo, roomInfo types.RoomInfo,
stateAtEvent *types.StateAtEvent, stateAtEvent *types.StateAtEvent,
event gomatrixserverlib.Event, event *gomatrixserverlib.Event,
isRejected bool, isRejected bool,
) error { ) error {
var err error var err error

View file

@ -50,7 +50,7 @@ func (r *Inputer) updateLatestEvents(
ctx context.Context, ctx context.Context,
roomInfo *types.RoomInfo, roomInfo *types.RoomInfo,
stateAtEvent types.StateAtEvent, stateAtEvent types.StateAtEvent,
event gomatrixserverlib.Event, event *gomatrixserverlib.Event,
sendAsServer string, sendAsServer string,
transactionID *api.TransactionID, transactionID *api.TransactionID,
rewritesState bool, rewritesState bool,
@ -92,7 +92,7 @@ type latestEventsUpdater struct {
updater *shared.LatestEventsUpdater updater *shared.LatestEventsUpdater
roomInfo *types.RoomInfo roomInfo *types.RoomInfo
stateAtEvent types.StateAtEvent stateAtEvent types.StateAtEvent
event gomatrixserverlib.Event event *gomatrixserverlib.Event
transactionID *api.TransactionID transactionID *api.TransactionID
rewritesState bool rewritesState bool
// Which server to send this event as. // Which server to send this event as.
@ -140,7 +140,7 @@ func (u *latestEventsUpdater) doUpdateLatestEvents() error {
// Work out what the latest events are. This will include the new // Work out what the latest events are. This will include the new
// event if it is not already referenced. // event if it is not already referenced.
extremitiesChanged, err := u.calculateLatest( extremitiesChanged, err := u.calculateLatest(
oldLatest, &u.event, oldLatest, u.event,
types.StateAtEventAndReference{ types.StateAtEventAndReference{
EventReference: u.event.EventReference(), EventReference: u.event.EventReference(),
StateAtEvent: u.stateAtEvent, StateAtEvent: u.stateAtEvent,
@ -373,7 +373,7 @@ func (u *latestEventsUpdater) makeOutputNewRoomEvent() (*api.OutputEvent, error)
// extraEventsForIDs returns the full events for the event IDs given, but does not include the current event being // extraEventsForIDs returns the full events for the event IDs given, but does not include the current event being
// updated. // updated.
func (u *latestEventsUpdater) extraEventsForIDs(roomVersion gomatrixserverlib.RoomVersion, eventIDs []string) ([]gomatrixserverlib.HeaderedEvent, error) { func (u *latestEventsUpdater) extraEventsForIDs(roomVersion gomatrixserverlib.RoomVersion, eventIDs []string) ([]*gomatrixserverlib.HeaderedEvent, error) {
var extraEventIDs []string var extraEventIDs []string
for _, e := range eventIDs { for _, e := range eventIDs {
if e == u.event.EventID() { if e == u.event.EventID() {
@ -388,7 +388,7 @@ func (u *latestEventsUpdater) extraEventsForIDs(roomVersion gomatrixserverlib.Ro
if err != nil { if err != nil {
return nil, err return nil, err
} }
var h []gomatrixserverlib.HeaderedEvent var h []*gomatrixserverlib.HeaderedEvent
for _, e := range extraEvents { for _, e := range extraEvents {
h = append(h, e.Headered(roomVersion)) h = append(h, e.Headered(roomVersion))
} }

View file

@ -62,13 +62,13 @@ func (r *Inputer) updateMemberships(
if change.removedEventNID != 0 { if change.removedEventNID != 0 {
ev, _ := helpers.EventMap(events).Lookup(change.removedEventNID) ev, _ := helpers.EventMap(events).Lookup(change.removedEventNID)
if ev != nil { if ev != nil {
re = &ev.Event re = ev.Event
} }
} }
if change.addedEventNID != 0 { if change.addedEventNID != 0 {
ev, _ := helpers.EventMap(events).Lookup(change.addedEventNID) ev, _ := helpers.EventMap(events).Lookup(change.addedEventNID)
if ev != nil { if ev != nil {
ae = &ev.Event ae = ev.Event
} }
} }
if updates, err = r.updateMembership(updater, targetUserNID, re, ae, updates); err != nil { if updates, err = r.updateMembership(updater, targetUserNID, re, ae, updates); err != nil {

View file

@ -83,7 +83,7 @@ func (r *Backfiller) PerformBackfill(
} }
// Retrieve events from the list that was filled previously. // Retrieve events from the list that was filled previously.
var loadedEvents []gomatrixserverlib.Event var loadedEvents []*gomatrixserverlib.Event
loadedEvents, err = helpers.LoadEvents(ctx, r.DB, resultNIDs) loadedEvents, err = helpers.LoadEvents(ctx, r.DB, resultNIDs)
if err != nil { if err != nil {
return err return err
@ -211,10 +211,10 @@ func (r *Backfiller) fetchAndStoreMissingEvents(ctx context.Context, roomVer gom
} }
} }
var newEvents []gomatrixserverlib.HeaderedEvent var newEvents []*gomatrixserverlib.HeaderedEvent
for _, ev := range missingMap { for _, ev := range missingMap {
if ev != nil { if ev != nil {
newEvents = append(newEvents, *ev) newEvents = append(newEvents, ev)
} }
} }
util.GetLogger(ctx).Infof("Persisting %d new events", len(newEvents)) util.GetLogger(ctx).Infof("Persisting %d new events", len(newEvents))
@ -232,7 +232,7 @@ type backfillRequester struct {
// per-request state // per-request state
servers []gomatrixserverlib.ServerName servers []gomatrixserverlib.ServerName
eventIDToBeforeStateIDs map[string][]string eventIDToBeforeStateIDs map[string][]string
eventIDMap map[string]gomatrixserverlib.Event eventIDMap map[string]*gomatrixserverlib.Event
} }
func newBackfillRequester( func newBackfillRequester(
@ -248,13 +248,13 @@ func newBackfillRequester(
fsAPI: fsAPI, fsAPI: fsAPI,
thisServer: thisServer, thisServer: thisServer,
eventIDToBeforeStateIDs: make(map[string][]string), eventIDToBeforeStateIDs: make(map[string][]string),
eventIDMap: make(map[string]gomatrixserverlib.Event), eventIDMap: make(map[string]*gomatrixserverlib.Event),
bwExtrems: bwExtrems, bwExtrems: bwExtrems,
preferServer: preferServer, preferServer: preferServer,
} }
} }
func (b *backfillRequester) StateIDsBeforeEvent(ctx context.Context, targetEvent gomatrixserverlib.HeaderedEvent) ([]string, error) { func (b *backfillRequester) StateIDsBeforeEvent(ctx context.Context, targetEvent *gomatrixserverlib.HeaderedEvent) ([]string, error) {
b.eventIDMap[targetEvent.EventID()] = targetEvent.Unwrap() b.eventIDMap[targetEvent.EventID()] = targetEvent.Unwrap()
if ids, ok := b.eventIDToBeforeStateIDs[targetEvent.EventID()]; ok { if ids, ok := b.eventIDToBeforeStateIDs[targetEvent.EventID()]; ok {
return ids, nil return ids, nil
@ -305,7 +305,7 @@ FederationHit:
return nil, lastErr return nil, lastErr
} }
func (b *backfillRequester) calculateNewStateIDs(targetEvent, prevEvent gomatrixserverlib.Event, prevEventStateIDs []string) []string { func (b *backfillRequester) calculateNewStateIDs(targetEvent, prevEvent *gomatrixserverlib.Event, prevEventStateIDs []string) []string {
newStateIDs := prevEventStateIDs[:] newStateIDs := prevEventStateIDs[:]
if prevEvent.StateKey() == nil { if prevEvent.StateKey() == nil {
// state is the same as the previous event // state is the same as the previous event
@ -343,7 +343,7 @@ func (b *backfillRequester) calculateNewStateIDs(targetEvent, prevEvent gomatrix
} }
func (b *backfillRequester) StateBeforeEvent(ctx context.Context, roomVer gomatrixserverlib.RoomVersion, func (b *backfillRequester) StateBeforeEvent(ctx context.Context, roomVer gomatrixserverlib.RoomVersion,
event gomatrixserverlib.HeaderedEvent, eventIDs []string) (map[string]*gomatrixserverlib.Event, error) { event *gomatrixserverlib.HeaderedEvent, eventIDs []string) (map[string]*gomatrixserverlib.Event, error) {
// try to fetch the events from the database first // try to fetch the events from the database first
events, err := b.ProvideEvents(roomVer, eventIDs) events, err := b.ProvideEvents(roomVer, eventIDs)
@ -355,7 +355,7 @@ func (b *backfillRequester) StateBeforeEvent(ctx context.Context, roomVer gomatr
if len(events) == len(eventIDs) { if len(events) == len(eventIDs) {
result := make(map[string]*gomatrixserverlib.Event) result := make(map[string]*gomatrixserverlib.Event)
for i := range events { for i := range events {
result[events[i].EventID()] = &events[i] result[events[i].EventID()] = events[i]
b.eventIDMap[events[i].EventID()] = events[i] b.eventIDMap[events[i].EventID()] = events[i]
} }
return result, nil return result, nil
@ -372,7 +372,7 @@ func (b *backfillRequester) StateBeforeEvent(ctx context.Context, roomVer gomatr
return nil, err return nil, err
} }
for eventID, ev := range result { for eventID, ev := range result {
b.eventIDMap[eventID] = *ev b.eventIDMap[eventID] = ev
} }
return result, nil return result, nil
} }
@ -426,7 +426,7 @@ FindSuccessor:
} }
// possibly return all joined servers depending on history visiblity // possibly return all joined servers depending on history visiblity
memberEventsFromVis, err := joinEventsFromHistoryVisibility(ctx, b.db, roomID, stateEntries) memberEventsFromVis, err := joinEventsFromHistoryVisibility(ctx, b.db, roomID, stateEntries, b.thisServer)
if err != nil { if err != nil {
logrus.WithError(err).Error("ServersAtEvent: failed calculate servers from history visibility rules") logrus.WithError(err).Error("ServersAtEvent: failed calculate servers from history visibility rules")
return nil return nil
@ -476,7 +476,7 @@ func (b *backfillRequester) Backfill(ctx context.Context, server gomatrixserverl
return tx, err return tx, err
} }
func (b *backfillRequester) ProvideEvents(roomVer gomatrixserverlib.RoomVersion, eventIDs []string) ([]gomatrixserverlib.Event, error) { func (b *backfillRequester) ProvideEvents(roomVer gomatrixserverlib.RoomVersion, eventIDs []string) ([]*gomatrixserverlib.Event, error) {
ctx := context.Background() ctx := context.Background()
nidMap, err := b.db.EventNIDs(ctx, eventIDs) nidMap, err := b.db.EventNIDs(ctx, eventIDs)
if err != nil { if err != nil {
@ -494,18 +494,19 @@ func (b *backfillRequester) ProvideEvents(roomVer gomatrixserverlib.RoomVersion,
logrus.WithError(err).WithField("event_nids", eventNIDs).Error("Failed to load events") logrus.WithError(err).WithField("event_nids", eventNIDs).Error("Failed to load events")
return nil, err return nil, err
} }
events := make([]gomatrixserverlib.Event, len(eventsWithNids)) events := make([]*gomatrixserverlib.Event, len(eventsWithNids))
for i := range eventsWithNids { for i := range eventsWithNids {
events[i] = eventsWithNids[i].Event events[i] = eventsWithNids[i].Event
} }
return events, nil return events, nil
} }
// joinEventsFromHistoryVisibility returns all CURRENTLY joined members if the provided state indicated a 'shared' history visibility. // joinEventsFromHistoryVisibility returns all CURRENTLY joined members if our server can read the room history
// TODO: Long term we probably want a history_visibility table which stores eventNID | visibility_enum so we can just // TODO: Long term we probably want a history_visibility table which stores eventNID | visibility_enum so we can just
// pull all events and then filter by that table. // pull all events and then filter by that table.
func joinEventsFromHistoryVisibility( func joinEventsFromHistoryVisibility(
ctx context.Context, db storage.Database, roomID string, stateEntries []types.StateEntry) ([]types.Event, error) { ctx context.Context, db storage.Database, roomID string, stateEntries []types.StateEntry,
thisServer gomatrixserverlib.ServerName) ([]types.Event, error) {
var eventNIDs []types.EventNID var eventNIDs []types.EventNID
for _, entry := range stateEntries { for _, entry := range stateEntries {
@ -521,13 +522,15 @@ func joinEventsFromHistoryVisibility(
if err != nil { if err != nil {
return nil, err return nil, err
} }
events := make([]gomatrixserverlib.Event, len(stateEvents)) events := make([]*gomatrixserverlib.Event, len(stateEvents))
for i := range stateEvents { for i := range stateEvents {
events[i] = stateEvents[i].Event events[i] = stateEvents[i].Event
} }
visibility := auth.HistoryVisibilityForRoom(events)
if visibility != "shared" { // Can we see events in the room?
logrus.Infof("ServersAtEvent history visibility not shared: %s", visibility) canSeeEvents := auth.IsServerAllowed(thisServer, true, events)
if !canSeeEvents {
logrus.Infof("ServersAtEvent history not visible to us: %s", auth.HistoryVisibilityForRoom(events))
return nil, nil return nil, nil
} }
// get joined members // get joined members
@ -542,7 +545,7 @@ func joinEventsFromHistoryVisibility(
return db.Events(ctx, joinEventNIDs) return db.Events(ctx, joinEventNIDs)
} }
func persistEvents(ctx context.Context, db storage.Database, events []gomatrixserverlib.HeaderedEvent) (types.RoomNID, map[string]types.Event) { func persistEvents(ctx context.Context, db storage.Database, events []*gomatrixserverlib.HeaderedEvent) (types.RoomNID, map[string]types.Event) {
var roomNID types.RoomNID var roomNID types.RoomNID
backfilledEventMap := make(map[string]types.Event) backfilledEventMap := make(map[string]types.Event)
for j, ev := range events { for j, ev := range events {
@ -570,7 +573,7 @@ func persistEvents(ctx context.Context, db storage.Database, events []gomatrixse
// redacted, which we don't care about since we aren't returning it in this backfill. // redacted, which we don't care about since we aren't returning it in this backfill.
if redactedEventID == ev.EventID() { if redactedEventID == ev.EventID() {
eventToRedact := ev.Unwrap() eventToRedact := ev.Unwrap()
redactedEvent, err := eventutil.RedactEvent(redactionEvent, &eventToRedact) redactedEvent, err := eventutil.RedactEvent(redactionEvent, eventToRedact)
if err != nil { if err != nil {
logrus.WithError(err).WithField("event_id", ev.EventID()).Error("Failed to redact event") logrus.WithError(err).WithField("event_id", ev.EventID()).Error("Failed to redact event")
continue continue

View file

@ -205,7 +205,7 @@ func (r *Inviter) PerformInvite(
} }
unwrapped := event.Unwrap() unwrapped := event.Unwrap()
outputUpdates, err := helpers.UpdateToInviteMembership(updater, &unwrapped, nil, req.Event.RoomVersion) outputUpdates, err := helpers.UpdateToInviteMembership(updater, unwrapped, nil, req.Event.RoomVersion)
if err != nil { if err != nil {
return nil, fmt.Errorf("updateToInviteMembership: %w", err) return nil, fmt.Errorf("updateToInviteMembership: %w", err)
} }
@ -255,11 +255,11 @@ func buildInviteStrippedState(
return nil, err return nil, err
} }
inviteState := []gomatrixserverlib.InviteV2StrippedState{ inviteState := []gomatrixserverlib.InviteV2StrippedState{
gomatrixserverlib.NewInviteV2StrippedState(&input.Event.Event), gomatrixserverlib.NewInviteV2StrippedState(input.Event.Event),
} }
stateEvents = append(stateEvents, types.Event{Event: input.Event.Unwrap()}) stateEvents = append(stateEvents, types.Event{Event: input.Event.Unwrap()})
for _, event := range stateEvents { for _, event := range stateEvents {
inviteState = append(inviteState, gomatrixserverlib.NewInviteV2StrippedState(&event.Event)) inviteState = append(inviteState, gomatrixserverlib.NewInviteV2StrippedState(event.Event))
} }
return inviteState, nil return inviteState, nil
} }

View file

@ -416,7 +416,7 @@ func (r *Queryer) QueryMissingEvents(
return err return err
} }
response.Events = make([]gomatrixserverlib.HeaderedEvent, 0, len(loadedEvents)-len(eventsToFilter)) response.Events = make([]*gomatrixserverlib.HeaderedEvent, 0, len(loadedEvents)-len(eventsToFilter))
for _, event := range loadedEvents { for _, event := range loadedEvents {
if !eventsToFilter[event.EventID()] { if !eventsToFilter[event.EventID()] {
roomVersion, verr := r.roomVersion(event.RoomID()) roomVersion, verr := r.roomVersion(event.RoomID())
@ -485,7 +485,7 @@ func (r *Queryer) QueryStateAndAuthChain(
return err return err
} }
func (r *Queryer) loadStateAtEventIDs(ctx context.Context, roomInfo types.RoomInfo, eventIDs []string) ([]gomatrixserverlib.Event, error) { func (r *Queryer) loadStateAtEventIDs(ctx context.Context, roomInfo types.RoomInfo, eventIDs []string) ([]*gomatrixserverlib.Event, error) {
roomState := state.NewStateResolution(r.DB, roomInfo) roomState := state.NewStateResolution(r.DB, roomInfo)
prevStates, err := r.DB.StateAtEventIDs(ctx, eventIDs) prevStates, err := r.DB.StateAtEventIDs(ctx, eventIDs)
if err != nil { if err != nil {
@ -516,13 +516,13 @@ type eventsFromIDs func(context.Context, []string) ([]types.Event, error)
// given events. Will *not* error if we don't have all auth events. // given events. Will *not* error if we don't have all auth events.
func getAuthChain( func getAuthChain(
ctx context.Context, fn eventsFromIDs, authEventIDs []string, ctx context.Context, fn eventsFromIDs, authEventIDs []string,
) ([]gomatrixserverlib.Event, error) { ) ([]*gomatrixserverlib.Event, error) {
// List of event IDs to fetch. On each pass, these events will be requested // List of event IDs to fetch. On each pass, these events will be requested
// from the database and the `eventsToFetch` will be updated with any new // from the database and the `eventsToFetch` will be updated with any new
// events that we have learned about and need to find. When `eventsToFetch` // events that we have learned about and need to find. When `eventsToFetch`
// is eventually empty, we should have reached the end of the chain. // is eventually empty, we should have reached the end of the chain.
eventsToFetch := authEventIDs eventsToFetch := authEventIDs
authEventsMap := make(map[string]gomatrixserverlib.Event) authEventsMap := make(map[string]*gomatrixserverlib.Event)
for len(eventsToFetch) > 0 { for len(eventsToFetch) > 0 {
// Try to retrieve the events from the database. // Try to retrieve the events from the database.
@ -553,7 +553,7 @@ func getAuthChain(
// We've now retrieved all of the events we can. Flatten them down into an // We've now retrieved all of the events we can. Flatten them down into an
// array and return them. // array and return them.
var authEvents []gomatrixserverlib.Event var authEvents []*gomatrixserverlib.Event
for _, event := range authEventsMap { for _, event := range authEventsMap {
authEvents = append(authEvents, event) authEvents = append(authEvents, event)
} }

View file

@ -26,12 +26,12 @@ import (
// used to implement RoomserverInternalAPIEventDB to test getAuthChain // used to implement RoomserverInternalAPIEventDB to test getAuthChain
type getEventDB struct { type getEventDB struct {
eventMap map[string]gomatrixserverlib.Event eventMap map[string]*gomatrixserverlib.Event
} }
func createEventDB() *getEventDB { func createEventDB() *getEventDB {
return &getEventDB{ return &getEventDB{
eventMap: make(map[string]gomatrixserverlib.Event), eventMap: make(map[string]*gomatrixserverlib.Event),
} }
} }

View file

@ -94,7 +94,7 @@ type fledglingEvent struct {
RoomID string RoomID string
} }
func mustCreateEvents(t *testing.T, roomVer gomatrixserverlib.RoomVersion, events []fledglingEvent) (result []gomatrixserverlib.HeaderedEvent) { func mustCreateEvents(t *testing.T, roomVer gomatrixserverlib.RoomVersion, events []fledglingEvent) (result []*gomatrixserverlib.HeaderedEvent) {
t.Helper() t.Helper()
depth := int64(1) depth := int64(1)
seed := make([]byte, ed25519.SeedSize) // zero seed seed := make([]byte, ed25519.SeedSize) // zero seed
@ -143,16 +143,15 @@ func mustCreateEvents(t *testing.T, roomVer gomatrixserverlib.RoomVersion, event
return return
} }
func mustLoadRawEvents(t *testing.T, ver gomatrixserverlib.RoomVersion, events []json.RawMessage) []gomatrixserverlib.HeaderedEvent { func mustLoadRawEvents(t *testing.T, ver gomatrixserverlib.RoomVersion, events []json.RawMessage) []*gomatrixserverlib.HeaderedEvent {
t.Helper() t.Helper()
hs := make([]gomatrixserverlib.HeaderedEvent, len(events)) hs := make([]*gomatrixserverlib.HeaderedEvent, len(events))
for i := range events { for i := range events {
e, err := gomatrixserverlib.NewEventFromTrustedJSON(events[i], false, ver) e, err := gomatrixserverlib.NewEventFromTrustedJSON(events[i], false, ver)
if err != nil { if err != nil {
t.Fatalf("cannot load test data: " + err.Error()) t.Fatalf("cannot load test data: " + err.Error())
} }
h := e.Headered(ver) hs[i] = e.Headered(ver)
hs[i] = h
} }
return hs return hs
} }
@ -187,7 +186,7 @@ func mustCreateRoomserverAPI(t *testing.T) (api.RoomserverInternalAPI, *dummyPro
), dp ), dp
} }
func mustSendEvents(t *testing.T, ver gomatrixserverlib.RoomVersion, events []json.RawMessage) (api.RoomserverInternalAPI, *dummyProducer, []gomatrixserverlib.HeaderedEvent) { func mustSendEvents(t *testing.T, ver gomatrixserverlib.RoomVersion, events []json.RawMessage) (api.RoomserverInternalAPI, *dummyProducer, []*gomatrixserverlib.HeaderedEvent) {
t.Helper() t.Helper()
rsAPI, dp := mustCreateRoomserverAPI(t) rsAPI, dp := mustCreateRoomserverAPI(t)
hevents := mustLoadRawEvents(t, ver, events) hevents := mustLoadRawEvents(t, ver, events)

View file

@ -522,7 +522,7 @@ func init() {
// Returns a numeric ID for the snapshot of the state before the event. // Returns a numeric ID for the snapshot of the state before the event.
func (v StateResolution) CalculateAndStoreStateBeforeEvent( func (v StateResolution) CalculateAndStoreStateBeforeEvent(
ctx context.Context, ctx context.Context,
event gomatrixserverlib.Event, event *gomatrixserverlib.Event,
isRejected bool, isRejected bool,
) (types.StateSnapshotNID, error) { ) (types.StateSnapshotNID, error) {
// Load the state at the prev events. // Load the state at the prev events.
@ -689,17 +689,17 @@ func (v StateResolution) calculateStateAfterManyEvents(
// TODO: Some of this can possibly be deduplicated // TODO: Some of this can possibly be deduplicated
func ResolveConflictsAdhoc( func ResolveConflictsAdhoc(
version gomatrixserverlib.RoomVersion, version gomatrixserverlib.RoomVersion,
events []gomatrixserverlib.Event, events []*gomatrixserverlib.Event,
authEvents []gomatrixserverlib.Event, authEvents []*gomatrixserverlib.Event,
) ([]gomatrixserverlib.Event, error) { ) ([]*gomatrixserverlib.Event, error) {
type stateKeyTuple struct { type stateKeyTuple struct {
Type string Type string
StateKey string StateKey string
} }
// Prepare our data structures. // Prepare our data structures.
eventMap := make(map[stateKeyTuple][]gomatrixserverlib.Event) eventMap := make(map[stateKeyTuple][]*gomatrixserverlib.Event)
var conflicted, notConflicted, resolved []gomatrixserverlib.Event var conflicted, notConflicted, resolved []*gomatrixserverlib.Event
// Run through all of the events that we were given and sort them // Run through all of the events that we were given and sort them
// into a map, sorted by (event_type, state_key) tuple. This means // into a map, sorted by (event_type, state_key) tuple. This means
@ -868,15 +868,15 @@ func (v StateResolution) resolveConflictsV2(
// For each conflicted event, we will add a new set of auth events. Auth // For each conflicted event, we will add a new set of auth events. Auth
// events may be duplicated across these sets but that's OK. // events may be duplicated across these sets but that's OK.
authSets := make(map[string][]gomatrixserverlib.Event) authSets := make(map[string][]*gomatrixserverlib.Event)
var authEvents []gomatrixserverlib.Event var authEvents []*gomatrixserverlib.Event
var authDifference []gomatrixserverlib.Event var authDifference []*gomatrixserverlib.Event
// For each conflicted event, let's try and get the needed auth events. // For each conflicted event, let's try and get the needed auth events.
for _, conflictedEvent := range conflictedEvents { for _, conflictedEvent := range conflictedEvents {
// Work out which auth events we need to load. // Work out which auth events we need to load.
key := conflictedEvent.EventID() key := conflictedEvent.EventID()
needed := gomatrixserverlib.StateNeededForAuth([]gomatrixserverlib.Event{conflictedEvent}) needed := gomatrixserverlib.StateNeededForAuth([]*gomatrixserverlib.Event{conflictedEvent})
// Find the numeric IDs for the necessary state keys. // Find the numeric IDs for the necessary state keys.
var neededStateKeys []string var neededStateKeys []string
@ -909,7 +909,7 @@ func (v StateResolution) resolveConflictsV2(
// This function helps us to work out whether an event exists in one of the // This function helps us to work out whether an event exists in one of the
// auth sets. // auth sets.
isInAuthList := func(k string, event gomatrixserverlib.Event) bool { isInAuthList := func(k string, event *gomatrixserverlib.Event) bool {
for _, e := range authSets[k] { for _, e := range authSets[k] {
if e.EventID() == event.EventID() { if e.EventID() == event.EventID() {
return true return true
@ -919,7 +919,7 @@ func (v StateResolution) resolveConflictsV2(
} }
// This function works out if an event exists in all of the auth sets. // This function works out if an event exists in all of the auth sets.
isInAllAuthLists := func(event gomatrixserverlib.Event) bool { isInAllAuthLists := func(event *gomatrixserverlib.Event) bool {
found := true found := true
for k := range authSets { for k := range authSets {
found = found && isInAuthList(k, event) found = found && isInAuthList(k, event)
@ -1006,7 +1006,7 @@ func (v StateResolution) stateKeyTuplesNeeded(stateKeyNIDMap map[string]types.Ev
// Returns an error if there was a problem talking to the database. // Returns an error if there was a problem talking to the database.
func (v StateResolution) loadStateEvents( func (v StateResolution) loadStateEvents(
ctx context.Context, entries []types.StateEntry, ctx context.Context, entries []types.StateEntry,
) ([]gomatrixserverlib.Event, map[string]types.StateEntry, error) { ) ([]*gomatrixserverlib.Event, map[string]types.StateEntry, error) {
eventNIDs := make([]types.EventNID, len(entries)) eventNIDs := make([]types.EventNID, len(entries))
for i := range entries { for i := range entries {
eventNIDs[i] = entries[i].EventNID eventNIDs[i] = entries[i].EventNID
@ -1016,7 +1016,7 @@ func (v StateResolution) loadStateEvents(
return nil, nil, err return nil, nil, err
} }
eventIDMap := map[string]types.StateEntry{} eventIDMap := map[string]types.StateEntry{}
result := make([]gomatrixserverlib.Event, len(entries)) result := make([]*gomatrixserverlib.Event, len(entries))
for i := range entries { for i := range entries {
event, ok := eventMap(events).lookup(entries[i].EventNID) event, ok := eventMap(events).lookup(entries[i].EventNID)
if !ok { if !ok {

View file

@ -69,7 +69,7 @@ type Database interface {
SnapshotNIDFromEventID(ctx context.Context, eventID string) (types.StateSnapshotNID, error) SnapshotNIDFromEventID(ctx context.Context, eventID string) (types.StateSnapshotNID, error)
// Stores a matrix room event in the database. Returns the room NID, the state snapshot and the redacted event ID if any, or an error. // Stores a matrix room event in the database. Returns the room NID, the state snapshot and the redacted event ID if any, or an error.
StoreEvent( StoreEvent(
ctx context.Context, event gomatrixserverlib.Event, txnAndSessionID *api.TransactionID, authEventNIDs []types.EventNID, ctx context.Context, event *gomatrixserverlib.Event, txnAndSessionID *api.TransactionID, authEventNIDs []types.EventNID,
isRejected bool, isRejected bool,
) (types.RoomNID, types.StateAtEvent, *gomatrixserverlib.Event, string, error) ) (types.RoomNID, types.StateAtEvent, *gomatrixserverlib.Event, string, error)
// Look up the state entries for a list of string event IDs // Look up the state entries for a list of string event IDs

View file

@ -388,7 +388,7 @@ func (d *Database) GetLatestEventsForUpdate(
// nolint:gocyclo // nolint:gocyclo
func (d *Database) StoreEvent( func (d *Database) StoreEvent(
ctx context.Context, event gomatrixserverlib.Event, ctx context.Context, event *gomatrixserverlib.Event,
txnAndSessionID *api.TransactionID, authEventNIDs []types.EventNID, isRejected bool, txnAndSessionID *api.TransactionID, authEventNIDs []types.EventNID, isRejected bool,
) (types.RoomNID, types.StateAtEvent, *gomatrixserverlib.Event, string, error) { ) (types.RoomNID, types.StateAtEvent, *gomatrixserverlib.Event, string, error) {
var ( var (
@ -611,7 +611,7 @@ func (d *Database) assignStateKeyNID(
return eventStateKeyNID, err return eventStateKeyNID, err
} }
func extractRoomVersionFromCreateEvent(event gomatrixserverlib.Event) ( func extractRoomVersionFromCreateEvent(event *gomatrixserverlib.Event) (
gomatrixserverlib.RoomVersion, error, gomatrixserverlib.RoomVersion, error,
) { ) {
var err error var err error
@ -651,7 +651,7 @@ func extractRoomVersionFromCreateEvent(event gomatrixserverlib.Event) (
// Returns the redaction event and the event ID of the redacted event if this call resulted in a redaction. // Returns the redaction event and the event ID of the redacted event if this call resulted in a redaction.
// nolint:gocyclo // nolint:gocyclo
func (d *Database) handleRedactions( func (d *Database) handleRedactions(
ctx context.Context, txn *sql.Tx, eventNID types.EventNID, event gomatrixserverlib.Event, ctx context.Context, txn *sql.Tx, eventNID types.EventNID, event *gomatrixserverlib.Event,
) (*gomatrixserverlib.Event, string, error) { ) (*gomatrixserverlib.Event, string, error) {
var err error var err error
isRedactionEvent := event.Type() == gomatrixserverlib.MRoomRedaction && event.StateKey() == nil isRedactionEvent := event.Type() == gomatrixserverlib.MRoomRedaction && event.StateKey() == nil
@ -703,12 +703,12 @@ func (d *Database) handleRedactions(
err = fmt.Errorf("d.RedactionsTable.MarkRedactionValidated: %w", err) err = fmt.Errorf("d.RedactionsTable.MarkRedactionValidated: %w", err)
} }
return &redactionEvent.Event, redactedEvent.EventID(), err return redactionEvent.Event, redactedEvent.EventID(), err
} }
// loadRedactionPair returns both the redaction event and the redacted event, else nil. // loadRedactionPair returns both the redaction event and the redacted event, else nil.
func (d *Database) loadRedactionPair( func (d *Database) loadRedactionPair(
ctx context.Context, txn *sql.Tx, eventNID types.EventNID, event gomatrixserverlib.Event, ctx context.Context, txn *sql.Tx, eventNID types.EventNID, event *gomatrixserverlib.Event,
) (*types.Event, *types.Event, bool, error) { ) (*types.Event, *types.Event, bool, error) {
var redactionEvent, redactedEvent *types.Event var redactionEvent, redactedEvent *types.Event
var info *tables.RedactionInfo var info *tables.RedactionInfo
@ -814,8 +814,7 @@ func (d *Database) GetStateEvent(ctx context.Context, roomID, evType, stateKey s
if err != nil { if err != nil {
return nil, err return nil, err
} }
h := ev.Headered(roomInfo.RoomVersion) return ev.Headered(roomInfo.RoomVersion), nil
return &h, nil
} }
} }
@ -934,12 +933,11 @@ func (d *Database) GetBulkStateContent(ctx context.Context, roomIDs []string, tu
if err != nil { if err != nil {
return nil, fmt.Errorf("GetBulkStateContent: failed to load event JSON for event NID %v : %w", events[i].EventNID, err) return nil, fmt.Errorf("GetBulkStateContent: failed to load event JSON for event NID %v : %w", events[i].EventNID, err)
} }
hev := ev.Headered(roomVer)
result[i] = tables.StrippedEvent{ result[i] = tables.StrippedEvent{
EventType: ev.Type(), EventType: ev.Type(),
RoomID: ev.RoomID(), RoomID: ev.RoomID(),
StateKey: *ev.StateKey(), StateKey: *ev.StateKey(),
ContentValue: tables.ExtractContentValue(&hev), ContentValue: tables.ExtractContentValue(ev.Headered(roomVer)),
} }
} }

View file

@ -126,7 +126,7 @@ type StateAtEventAndReference struct {
// It is when performing bulk event lookup in the database. // It is when performing bulk event lookup in the database.
type Event struct { type Event struct {
EventNID EventNID EventNID EventNID
gomatrixserverlib.Event *gomatrixserverlib.Event
} }
const ( const (

View file

@ -118,7 +118,7 @@ func (s *OutputRoomEventConsumer) onMessage(msg *sarama.ConsumerMessage) error {
func (s *OutputRoomEventConsumer) onRedactEvent( func (s *OutputRoomEventConsumer) onRedactEvent(
ctx context.Context, msg api.OutputRedactedEvent, ctx context.Context, msg api.OutputRedactedEvent,
) error { ) error {
err := s.db.RedactEvent(ctx, msg.RedactedEventID, &msg.RedactedBecause) err := s.db.RedactEvent(ctx, msg.RedactedEventID, msg.RedactedBecause)
if err != nil { if err != nil {
log.WithError(err).Error("RedactEvent error'd") log.WithError(err).Error("RedactEvent error'd")
return err return err
@ -156,7 +156,7 @@ func (s *OutputRoomEventConsumer) onNewRoomEvent(
pduPos, err := s.db.WriteEvent( pduPos, err := s.db.WriteEvent(
ctx, ctx,
&ev, ev,
addsStateEvents, addsStateEvents,
msg.AddsStateEventIDs, msg.AddsStateEventIDs,
msg.RemovesStateEventIDs, msg.RemovesStateEventIDs,
@ -174,12 +174,12 @@ func (s *OutputRoomEventConsumer) onNewRoomEvent(
return nil return nil
} }
if pduPos, err = s.notifyJoinedPeeks(ctx, &ev, pduPos); err != nil { if pduPos, err = s.notifyJoinedPeeks(ctx, ev, pduPos); err != nil {
logrus.WithError(err).Errorf("Failed to notifyJoinedPeeks for PDU pos %d", pduPos) logrus.WithError(err).Errorf("Failed to notifyJoinedPeeks for PDU pos %d", pduPos)
return err return err
} }
s.notifier.OnNewEvent(&ev, "", nil, types.NewStreamToken(pduPos, 0, nil)) s.notifier.OnNewEvent(ev, "", nil, types.NewStreamToken(pduPos, 0, nil))
return nil return nil
} }
@ -197,8 +197,8 @@ func (s *OutputRoomEventConsumer) onOldRoomEvent(
// from confusing clients into thinking they've joined/left rooms. // from confusing clients into thinking they've joined/left rooms.
pduPos, err := s.db.WriteEvent( pduPos, err := s.db.WriteEvent(
ctx, ctx,
&ev, ev,
[]gomatrixserverlib.HeaderedEvent{}, []*gomatrixserverlib.HeaderedEvent{},
[]string{}, // adds no state []string{}, // adds no state
[]string{}, // removes no state []string{}, // removes no state
nil, // no transaction nil, // no transaction
@ -213,12 +213,12 @@ func (s *OutputRoomEventConsumer) onOldRoomEvent(
return nil return nil
} }
if pduPos, err = s.notifyJoinedPeeks(ctx, &ev, pduPos); err != nil { if pduPos, err = s.notifyJoinedPeeks(ctx, ev, pduPos); err != nil {
logrus.WithError(err).Errorf("Failed to notifyJoinedPeeks for PDU pos %d", pduPos) logrus.WithError(err).Errorf("Failed to notifyJoinedPeeks for PDU pos %d", pduPos)
return err return err
} }
s.notifier.OnNewEvent(&ev, "", nil, types.NewStreamToken(pduPos, 0, nil)) s.notifier.OnNewEvent(ev, "", nil, types.NewStreamToken(pduPos, 0, nil))
return nil return nil
} }
@ -267,7 +267,7 @@ func (s *OutputRoomEventConsumer) onNewInviteEvent(
}).Panicf("roomserver output log: write invite failure") }).Panicf("roomserver output log: write invite failure")
return nil return nil
} }
s.notifier.OnNewEvent(&msg.Event, "", nil, types.NewStreamToken(pduPos, 0, nil)) s.notifier.OnNewEvent(msg.Event, "", nil, types.NewStreamToken(pduPos, 0, nil))
return nil return nil
} }
@ -309,7 +309,7 @@ func (s *OutputRoomEventConsumer) onNewPeek(
return nil return nil
} }
func (s *OutputRoomEventConsumer) updateStateEvent(event gomatrixserverlib.HeaderedEvent) (gomatrixserverlib.HeaderedEvent, error) { func (s *OutputRoomEventConsumer) updateStateEvent(event *gomatrixserverlib.HeaderedEvent) (*gomatrixserverlib.HeaderedEvent, error) {
if event.StateKey() == nil { if event.StateKey() == nil {
return event, nil return event, nil
} }

View file

@ -235,7 +235,7 @@ func (r *messagesReq) retrieveEvents() (
return return
} }
var events []gomatrixserverlib.HeaderedEvent var events []*gomatrixserverlib.HeaderedEvent
util.GetLogger(r.ctx).WithField("start", start).WithField("end", end).Infof("Fetched %d events locally", len(streamEvents)) util.GetLogger(r.ctx).WithField("start", start).WithField("end", end).Infof("Fetched %d events locally", len(streamEvents))
// There can be two reasons for streamEvents to be empty: either we've // There can be two reasons for streamEvents to be empty: either we've
@ -259,8 +259,8 @@ func (r *messagesReq) retrieveEvents() (
// Sort the events to ensure we send them in the right order. // Sort the events to ensure we send them in the right order.
if r.backwardOrdering { if r.backwardOrdering {
// This reverses the array from old->new to new->old // This reverses the array from old->new to new->old
reversed := func(in []gomatrixserverlib.HeaderedEvent) []gomatrixserverlib.HeaderedEvent { reversed := func(in []*gomatrixserverlib.HeaderedEvent) []*gomatrixserverlib.HeaderedEvent {
out := make([]gomatrixserverlib.HeaderedEvent, len(in)) out := make([]*gomatrixserverlib.HeaderedEvent, len(in))
for i := 0; i < len(in); i++ { for i := 0; i < len(in); i++ {
out[i] = in[len(in)-i-1] out[i] = in[len(in)-i-1]
} }
@ -287,7 +287,7 @@ func (r *messagesReq) retrieveEvents() (
} }
// nolint:gocyclo // nolint:gocyclo
func (r *messagesReq) filterHistoryVisible(events []gomatrixserverlib.HeaderedEvent) []gomatrixserverlib.HeaderedEvent { func (r *messagesReq) filterHistoryVisible(events []*gomatrixserverlib.HeaderedEvent) []*gomatrixserverlib.HeaderedEvent {
// TODO FIXME: We don't fully implement history visibility yet. To avoid leaking events which the // TODO FIXME: We don't fully implement history visibility yet. To avoid leaking events which the
// user shouldn't see, we check the recent events and remove any prior to the join event of the user // user shouldn't see, we check the recent events and remove any prior to the join event of the user
// which is equiv to history_visibility: joined // which is equiv to history_visibility: joined
@ -302,8 +302,8 @@ func (r *messagesReq) filterHistoryVisible(events []gomatrixserverlib.HeaderedEv
} }
} }
var result []gomatrixserverlib.HeaderedEvent var result []*gomatrixserverlib.HeaderedEvent
var eventsToCheck []gomatrixserverlib.HeaderedEvent var eventsToCheck []*gomatrixserverlib.HeaderedEvent
if joinEventIndex != -1 { if joinEventIndex != -1 {
if r.backwardOrdering { if r.backwardOrdering {
result = events[:joinEventIndex+1] result = events[:joinEventIndex+1]
@ -313,7 +313,7 @@ func (r *messagesReq) filterHistoryVisible(events []gomatrixserverlib.HeaderedEv
eventsToCheck = append(eventsToCheck, result[len(result)-1]) eventsToCheck = append(eventsToCheck, result[len(result)-1])
} }
} else { } else {
eventsToCheck = []gomatrixserverlib.HeaderedEvent{events[0], events[len(events)-1]} eventsToCheck = []*gomatrixserverlib.HeaderedEvent{events[0], events[len(events)-1]}
result = events result = events
} }
// make sure the user was in the room for both the earliest and latest events, we need this because // make sure the user was in the room for both the earliest and latest events, we need this because
@ -337,9 +337,9 @@ func (r *messagesReq) filterHistoryVisible(events []gomatrixserverlib.HeaderedEv
for i := range queryRes.StateEvents { for i := range queryRes.StateEvents {
switch queryRes.StateEvents[i].Type() { switch queryRes.StateEvents[i].Type() {
case gomatrixserverlib.MRoomMember: case gomatrixserverlib.MRoomMember:
membershipEvent = &queryRes.StateEvents[i] membershipEvent = queryRes.StateEvents[i]
case gomatrixserverlib.MRoomHistoryVisibility: case gomatrixserverlib.MRoomHistoryVisibility:
hisVisEvent = &queryRes.StateEvents[i] hisVisEvent = queryRes.StateEvents[i]
} }
} }
if hisVisEvent == nil { if hisVisEvent == nil {
@ -365,12 +365,12 @@ func (r *messagesReq) filterHistoryVisible(events []gomatrixserverlib.HeaderedEv
} }
if !wasJoined { if !wasJoined {
util.GetLogger(r.ctx).WithField("num_events", len(events)).Warnf("%s was not joined to room during these events, omitting them", r.device.UserID) util.GetLogger(r.ctx).WithField("num_events", len(events)).Warnf("%s was not joined to room during these events, omitting them", r.device.UserID)
return []gomatrixserverlib.HeaderedEvent{} return []*gomatrixserverlib.HeaderedEvent{}
} }
return result return result
} }
func (r *messagesReq) getStartEnd(events []gomatrixserverlib.HeaderedEvent) (start, end types.TopologyToken, err error) { func (r *messagesReq) getStartEnd(events []*gomatrixserverlib.HeaderedEvent) (start, end types.TopologyToken, err error) {
start, err = r.db.EventPositionInTopology( start, err = r.db.EventPositionInTopology(
r.ctx, events[0].EventID(), r.ctx, events[0].EventID(),
) )
@ -410,7 +410,7 @@ func (r *messagesReq) getStartEnd(events []gomatrixserverlib.HeaderedEvent) (sta
// Returns an error if there was an issue talking with the database or // Returns an error if there was an issue talking with the database or
// backfilling. // backfilling.
func (r *messagesReq) handleEmptyEventsSlice() ( func (r *messagesReq) handleEmptyEventsSlice() (
events []gomatrixserverlib.HeaderedEvent, err error, events []*gomatrixserverlib.HeaderedEvent, err error,
) { ) {
backwardExtremities, err := r.db.BackwardExtremitiesForRoom(r.ctx, r.roomID) backwardExtremities, err := r.db.BackwardExtremitiesForRoom(r.ctx, r.roomID)
@ -424,7 +424,7 @@ func (r *messagesReq) handleEmptyEventsSlice() (
} else { } else {
// If not, it means the slice was empty because we reached the room's // If not, it means the slice was empty because we reached the room's
// creation, so return an empty slice. // creation, so return an empty slice.
events = []gomatrixserverlib.HeaderedEvent{} events = []*gomatrixserverlib.HeaderedEvent{}
} }
return return
@ -436,7 +436,7 @@ func (r *messagesReq) handleEmptyEventsSlice() (
// through backfilling if needed. // through backfilling if needed.
// Returns an error if there was an issue while backfilling. // Returns an error if there was an issue while backfilling.
func (r *messagesReq) handleNonEmptyEventsSlice(streamEvents []types.StreamEvent) ( func (r *messagesReq) handleNonEmptyEventsSlice(streamEvents []types.StreamEvent) (
events []gomatrixserverlib.HeaderedEvent, err error, events []*gomatrixserverlib.HeaderedEvent, err error,
) { ) {
// Check if we have enough events. // Check if we have enough events.
isSetLargeEnough := len(streamEvents) >= r.limit isSetLargeEnough := len(streamEvents) >= r.limit
@ -464,7 +464,7 @@ func (r *messagesReq) handleNonEmptyEventsSlice(streamEvents []types.StreamEvent
// Backfill is needed if we've reached a backward extremity and need more // Backfill is needed if we've reached a backward extremity and need more
// events. It's only needed if the direction is backward. // events. It's only needed if the direction is backward.
if len(backwardExtremities) > 0 && !isSetLargeEnough && r.backwardOrdering { if len(backwardExtremities) > 0 && !isSetLargeEnough && r.backwardOrdering {
var pdus []gomatrixserverlib.HeaderedEvent var pdus []*gomatrixserverlib.HeaderedEvent
// Only ask the remote server for enough events to reach the limit. // Only ask the remote server for enough events to reach the limit.
pdus, err = r.backfill(r.roomID, backwardExtremities, r.limit-len(streamEvents)) pdus, err = r.backfill(r.roomID, backwardExtremities, r.limit-len(streamEvents))
if err != nil { if err != nil {
@ -482,7 +482,7 @@ func (r *messagesReq) handleNonEmptyEventsSlice(streamEvents []types.StreamEvent
return return
} }
type eventsByDepth []gomatrixserverlib.HeaderedEvent type eventsByDepth []*gomatrixserverlib.HeaderedEvent
func (e eventsByDepth) Len() int { func (e eventsByDepth) Len() int {
return len(e) return len(e)
@ -503,7 +503,7 @@ func (e eventsByDepth) Less(i, j int) bool {
// event, or if there is no remote homeserver to contact. // event, or if there is no remote homeserver to contact.
// Returns an error if there was an issue with retrieving the list of servers in // Returns an error if there was an issue with retrieving the list of servers in
// the room or sending the request. // the room or sending the request.
func (r *messagesReq) backfill(roomID string, backwardsExtremities map[string][]string, limit int) ([]gomatrixserverlib.HeaderedEvent, error) { func (r *messagesReq) backfill(roomID string, backwardsExtremities map[string][]string, limit int) ([]*gomatrixserverlib.HeaderedEvent, error) {
var res api.PerformBackfillResponse var res api.PerformBackfillResponse
err := r.rsAPI.PerformBackfill(context.Background(), &api.PerformBackfillRequest{ err := r.rsAPI.PerformBackfill(context.Background(), &api.PerformBackfillRequest{
RoomID: roomID, RoomID: roomID,
@ -531,8 +531,8 @@ func (r *messagesReq) backfill(roomID string, backwardsExtremities map[string][]
for i := range res.Events { for i := range res.Events {
_, err = r.db.WriteEvent( _, err = r.db.WriteEvent(
context.Background(), context.Background(),
&res.Events[i], res.Events[i],
[]gomatrixserverlib.HeaderedEvent{}, []*gomatrixserverlib.HeaderedEvent{},
[]string{}, []string{},
[]string{}, []string{},
nil, true, nil, true,

View file

@ -39,11 +39,11 @@ type Database interface {
// If an event is not found in the database then it will be omitted from the list. // If an event is not found in the database then it will be omitted from the list.
// Returns an error if there was a problem talking with the database. // Returns an error if there was a problem talking with the database.
// Does not include any transaction IDs in the returned events. // Does not include any transaction IDs in the returned events.
Events(ctx context.Context, eventIDs []string) ([]gomatrixserverlib.HeaderedEvent, error) Events(ctx context.Context, eventIDs []string) ([]*gomatrixserverlib.HeaderedEvent, error)
// WriteEvent into the database. It is not safe to call this function from multiple goroutines, as it would create races // WriteEvent into the database. It is not safe to call this function from multiple goroutines, as it would create races
// when generating the sync stream position for this event. Returns the sync stream position for the inserted event. // when generating the sync stream position for this event. Returns the sync stream position for the inserted event.
// Returns an error if there was a problem inserting this event. // Returns an error if there was a problem inserting this event.
WriteEvent(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent, addStateEvents []gomatrixserverlib.HeaderedEvent, WriteEvent(ctx context.Context, ev *gomatrixserverlib.HeaderedEvent, addStateEvents []*gomatrixserverlib.HeaderedEvent,
addStateEventIDs []string, removeStateEventIDs []string, transactionID *api.TransactionID, excludeFromSync bool) (types.StreamPosition, error) addStateEventIDs []string, removeStateEventIDs []string, transactionID *api.TransactionID, excludeFromSync bool) (types.StreamPosition, error)
// PurgeRoomState completely purges room state from the sync API. This is done when // PurgeRoomState completely purges room state from the sync API. This is done when
// receiving an output event that completely resets the state. // receiving an output event that completely resets the state.
@ -55,7 +55,7 @@ type Database interface {
// GetStateEventsForRoom fetches the state events for a given room. // GetStateEventsForRoom fetches the state events for a given room.
// Returns an empty slice if no state events could be found for this room. // Returns an empty slice if no state events could be found for this room.
// Returns an error if there was an issue with the retrieval. // Returns an error if there was an issue with the retrieval.
GetStateEventsForRoom(ctx context.Context, roomID string, stateFilterPart *gomatrixserverlib.StateFilter) (stateEvents []gomatrixserverlib.HeaderedEvent, err error) GetStateEventsForRoom(ctx context.Context, roomID string, stateFilterPart *gomatrixserverlib.StateFilter) (stateEvents []*gomatrixserverlib.HeaderedEvent, err error)
// SyncPosition returns the latest positions for syncing. // SyncPosition returns the latest positions for syncing.
SyncPosition(ctx context.Context) (types.StreamingToken, error) SyncPosition(ctx context.Context) (types.StreamingToken, error)
// IncrementalSync returns all the data needed in order to create an incremental // IncrementalSync returns all the data needed in order to create an incremental
@ -84,7 +84,7 @@ type Database interface {
// AddInviteEvent stores a new invite event for a user. // AddInviteEvent stores a new invite event for a user.
// If the invite was successfully stored this returns the stream ID it was stored at. // If the invite was successfully stored this returns the stream ID it was stored at.
// Returns an error if there was a problem communicating with the database. // Returns an error if there was a problem communicating with the database.
AddInviteEvent(ctx context.Context, inviteEvent gomatrixserverlib.HeaderedEvent) (types.StreamPosition, error) AddInviteEvent(ctx context.Context, inviteEvent *gomatrixserverlib.HeaderedEvent) (types.StreamPosition, error)
// RetireInviteEvent removes an old invite event from the database. Returns the new position of the retired invite. // RetireInviteEvent removes an old invite event from the database. Returns the new position of the retired invite.
// Returns an error if there was a problem communicating with the database. // Returns an error if there was a problem communicating with the database.
RetireInviteEvent(ctx context.Context, inviteEventID string) (types.StreamPosition, error) RetireInviteEvent(ctx context.Context, inviteEventID string) (types.StreamPosition, error)
@ -116,7 +116,7 @@ type Database interface {
// StreamEventsToEvents converts streamEvent to Event. If device is non-nil and // StreamEventsToEvents converts streamEvent to Event. If device is non-nil and
// matches the streamevent.transactionID device then the transaction ID gets // matches the streamevent.transactionID device then the transaction ID gets
// added to the unsigned section of the output event. // added to the unsigned section of the output event.
StreamEventsToEvents(device *userapi.Device, in []types.StreamEvent) []gomatrixserverlib.HeaderedEvent StreamEventsToEvents(device *userapi.Device, in []types.StreamEvent) []*gomatrixserverlib.HeaderedEvent
// AddSendToDevice increases the EDU position in the cache and returns the stream position. // AddSendToDevice increases the EDU position in the cache and returns the stream position.
AddSendToDevice() types.StreamPosition AddSendToDevice() types.StreamPosition
// SendToDeviceUpdatesForSync returns a list of send-to-device updates. It returns three lists: // SendToDeviceUpdatesForSync returns a list of send-to-device updates. It returns three lists:

View file

@ -195,7 +195,7 @@ func (s *currentRoomStateStatements) SelectRoomIDsWithMembership(
func (s *currentRoomStateStatements) SelectCurrentState( func (s *currentRoomStateStatements) SelectCurrentState(
ctx context.Context, txn *sql.Tx, roomID string, ctx context.Context, txn *sql.Tx, roomID string,
stateFilter *gomatrixserverlib.StateFilter, stateFilter *gomatrixserverlib.StateFilter,
) ([]gomatrixserverlib.HeaderedEvent, error) { ) ([]*gomatrixserverlib.HeaderedEvent, error) {
stmt := sqlutil.TxStmt(txn, s.selectCurrentStateStmt) stmt := sqlutil.TxStmt(txn, s.selectCurrentStateStmt)
rows, err := stmt.QueryContext(ctx, roomID, rows, err := stmt.QueryContext(ctx, roomID,
pq.StringArray(stateFilter.Senders), pq.StringArray(stateFilter.Senders),
@ -231,7 +231,7 @@ func (s *currentRoomStateStatements) DeleteRoomStateForRoom(
func (s *currentRoomStateStatements) UpsertRoomState( func (s *currentRoomStateStatements) UpsertRoomState(
ctx context.Context, txn *sql.Tx, ctx context.Context, txn *sql.Tx,
event gomatrixserverlib.HeaderedEvent, membership *string, addedAt types.StreamPosition, event *gomatrixserverlib.HeaderedEvent, membership *string, addedAt types.StreamPosition,
) error { ) error {
// Parse content as JSON and search for an "url" key // Parse content as JSON and search for an "url" key
containsURL := false containsURL := false
@ -275,8 +275,8 @@ func (s *currentRoomStateStatements) SelectEventsWithEventIDs(
return rowsToStreamEvents(rows) return rowsToStreamEvents(rows)
} }
func rowsToEvents(rows *sql.Rows) ([]gomatrixserverlib.HeaderedEvent, error) { func rowsToEvents(rows *sql.Rows) ([]*gomatrixserverlib.HeaderedEvent, error) {
result := []gomatrixserverlib.HeaderedEvent{} result := []*gomatrixserverlib.HeaderedEvent{}
for rows.Next() { for rows.Next() {
var eventBytes []byte var eventBytes []byte
if err := rows.Scan(&eventBytes); err != nil { if err := rows.Scan(&eventBytes); err != nil {
@ -287,7 +287,7 @@ func rowsToEvents(rows *sql.Rows) ([]gomatrixserverlib.HeaderedEvent, error) {
if err := json.Unmarshal(eventBytes, &ev); err != nil { if err := json.Unmarshal(eventBytes, &ev); err != nil {
return nil, err return nil, err
} }
result = append(result, ev) result = append(result, &ev)
} }
return result, rows.Err() return result, rows.Err()
} }

View file

@ -91,7 +91,7 @@ func NewPostgresInvitesTable(db *sql.DB) (tables.Invites, error) {
} }
func (s *inviteEventsStatements) InsertInviteEvent( func (s *inviteEventsStatements) InsertInviteEvent(
ctx context.Context, txn *sql.Tx, inviteEvent gomatrixserverlib.HeaderedEvent, ctx context.Context, txn *sql.Tx, inviteEvent *gomatrixserverlib.HeaderedEvent,
) (streamPos types.StreamPosition, err error) { ) (streamPos types.StreamPosition, err error) {
var headeredJSON []byte var headeredJSON []byte
headeredJSON, err = json.Marshal(inviteEvent) headeredJSON, err = json.Marshal(inviteEvent)
@ -121,15 +121,15 @@ func (s *inviteEventsStatements) DeleteInviteEvent(
// active invites for the target user ID in the supplied range. // active invites for the target user ID in the supplied range.
func (s *inviteEventsStatements) SelectInviteEventsInRange( func (s *inviteEventsStatements) SelectInviteEventsInRange(
ctx context.Context, txn *sql.Tx, targetUserID string, r types.Range, ctx context.Context, txn *sql.Tx, targetUserID string, r types.Range,
) (map[string]gomatrixserverlib.HeaderedEvent, map[string]gomatrixserverlib.HeaderedEvent, error) { ) (map[string]*gomatrixserverlib.HeaderedEvent, map[string]*gomatrixserverlib.HeaderedEvent, error) {
stmt := sqlutil.TxStmt(txn, s.selectInviteEventsInRangeStmt) stmt := sqlutil.TxStmt(txn, s.selectInviteEventsInRangeStmt)
rows, err := stmt.QueryContext(ctx, targetUserID, r.Low(), r.High()) rows, err := stmt.QueryContext(ctx, targetUserID, r.Low(), r.High())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
defer internal.CloseAndLogIfError(ctx, rows, "selectInviteEventsInRange: rows.close() failed") defer internal.CloseAndLogIfError(ctx, rows, "selectInviteEventsInRange: rows.close() failed")
result := map[string]gomatrixserverlib.HeaderedEvent{} result := map[string]*gomatrixserverlib.HeaderedEvent{}
retired := map[string]gomatrixserverlib.HeaderedEvent{} retired := map[string]*gomatrixserverlib.HeaderedEvent{}
for rows.Next() { for rows.Next() {
var ( var (
roomID string roomID string
@ -148,7 +148,7 @@ func (s *inviteEventsStatements) SelectInviteEventsInRange(
continue continue
} }
var event gomatrixserverlib.HeaderedEvent var event *gomatrixserverlib.HeaderedEvent
if err := json.Unmarshal(eventJSON, &event); err != nil { if err := json.Unmarshal(eventJSON, &event); err != nil {
return nil, nil, err return nil, nil, err
} }

View file

@ -247,7 +247,7 @@ func (s *outputRoomEventsStatements) SelectStateInRange(
stateNeeded[ev.RoomID()] = needSet stateNeeded[ev.RoomID()] = needSet
eventIDToEvent[ev.EventID()] = types.StreamEvent{ eventIDToEvent[ev.EventID()] = types.StreamEvent{
HeaderedEvent: ev, HeaderedEvent: &ev,
StreamPosition: streamPos, StreamPosition: streamPos,
ExcludeFromSync: excludeFromSync, ExcludeFromSync: excludeFromSync,
} }
@ -437,7 +437,7 @@ func rowsToStreamEvents(rows *sql.Rows) ([]types.StreamEvent, error) {
} }
result = append(result, types.StreamEvent{ result = append(result, types.StreamEvent{
HeaderedEvent: ev, HeaderedEvent: &ev,
StreamPosition: streamPos, StreamPosition: streamPos,
TransactionID: transactionID, TransactionID: transactionID,
ExcludeFromSync: excludeFromSync, ExcludeFromSync: excludeFromSync,

View file

@ -57,7 +57,7 @@ type Database struct {
// If an event is not found in the database then it will be omitted from the list. // If an event is not found in the database then it will be omitted from the list.
// Returns an error if there was a problem talking with the database. // Returns an error if there was a problem talking with the database.
// Does not include any transaction IDs in the returned events. // Does not include any transaction IDs in the returned events.
func (d *Database) Events(ctx context.Context, eventIDs []string) ([]gomatrixserverlib.HeaderedEvent, error) { func (d *Database) Events(ctx context.Context, eventIDs []string) ([]*gomatrixserverlib.HeaderedEvent, error) {
streamEvents, err := d.OutputEvents.SelectEvents(ctx, nil, eventIDs) streamEvents, err := d.OutputEvents.SelectEvents(ctx, nil, eventIDs)
if err != nil { if err != nil {
return nil, err return nil, err
@ -135,7 +135,7 @@ func (d *Database) GetStateEvent(
func (d *Database) GetStateEventsForRoom( func (d *Database) GetStateEventsForRoom(
ctx context.Context, roomID string, stateFilter *gomatrixserverlib.StateFilter, ctx context.Context, roomID string, stateFilter *gomatrixserverlib.StateFilter,
) (stateEvents []gomatrixserverlib.HeaderedEvent, err error) { ) (stateEvents []*gomatrixserverlib.HeaderedEvent, err error) {
stateEvents, err = d.CurrentRoomState.SelectCurrentState(ctx, nil, roomID, stateFilter) stateEvents, err = d.CurrentRoomState.SelectCurrentState(ctx, nil, roomID, stateFilter)
return return
} }
@ -144,7 +144,7 @@ func (d *Database) GetStateEventsForRoom(
// If the invite was successfully stored this returns the stream ID it was stored at. // If the invite was successfully stored this returns the stream ID it was stored at.
// Returns an error if there was a problem communicating with the database. // Returns an error if there was a problem communicating with the database.
func (d *Database) AddInviteEvent( func (d *Database) AddInviteEvent(
ctx context.Context, inviteEvent gomatrixserverlib.HeaderedEvent, ctx context.Context, inviteEvent *gomatrixserverlib.HeaderedEvent,
) (sp types.StreamPosition, err error) { ) (sp types.StreamPosition, err error) {
_ = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error { _ = d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
sp, err = d.Invites.InsertInviteEvent(ctx, txn, inviteEvent) sp, err = d.Invites.InsertInviteEvent(ctx, txn, inviteEvent)
@ -223,8 +223,8 @@ func (d *Database) UpsertAccountData(
return return
} }
func (d *Database) StreamEventsToEvents(device *userapi.Device, in []types.StreamEvent) []gomatrixserverlib.HeaderedEvent { func (d *Database) StreamEventsToEvents(device *userapi.Device, in []types.StreamEvent) []*gomatrixserverlib.HeaderedEvent {
out := make([]gomatrixserverlib.HeaderedEvent, len(in)) out := make([]*gomatrixserverlib.HeaderedEvent, len(in))
for i := 0; i < len(in); i++ { for i := 0; i < len(in); i++ {
out[i] = in[i].HeaderedEvent out[i] = in[i].HeaderedEvent
if device != nil && in[i].TransactionID != nil { if device != nil && in[i].TransactionID != nil {
@ -295,7 +295,7 @@ func (d *Database) PurgeRoomState(
func (d *Database) WriteEvent( func (d *Database) WriteEvent(
ctx context.Context, ctx context.Context,
ev *gomatrixserverlib.HeaderedEvent, ev *gomatrixserverlib.HeaderedEvent,
addStateEvents []gomatrixserverlib.HeaderedEvent, addStateEvents []*gomatrixserverlib.HeaderedEvent,
addStateEventIDs, removeStateEventIDs []string, addStateEventIDs, removeStateEventIDs []string,
transactionID *api.TransactionID, excludeFromSync bool, transactionID *api.TransactionID, excludeFromSync bool,
) (pduPosition types.StreamPosition, returnErr error) { ) (pduPosition types.StreamPosition, returnErr error) {
@ -332,7 +332,7 @@ func (d *Database) WriteEvent(
func (d *Database) updateRoomState( func (d *Database) updateRoomState(
ctx context.Context, txn *sql.Tx, ctx context.Context, txn *sql.Tx,
removedEventIDs []string, removedEventIDs []string,
addedEvents []gomatrixserverlib.HeaderedEvent, addedEvents []*gomatrixserverlib.HeaderedEvent,
pduPosition types.StreamPosition, pduPosition types.StreamPosition,
) error { ) error {
// remove first, then add, as we do not ever delete state, but do replace state which is a remove followed by an add. // remove first, then add, as we do not ever delete state, but do replace state which is a remove followed by an add.
@ -709,14 +709,14 @@ func (d *Database) RedactEvent(ctx context.Context, redactedEventID string, reda
} }
eventToRedact := redactedEvents[0].Unwrap() eventToRedact := redactedEvents[0].Unwrap()
redactionEvent := redactedBecause.Unwrap() redactionEvent := redactedBecause.Unwrap()
ev, err := eventutil.RedactEvent(&redactionEvent, &eventToRedact) ev, err := eventutil.RedactEvent(redactionEvent, eventToRedact)
if err != nil { if err != nil {
return err return err
} }
newEvent := ev.Headered(redactedBecause.RoomVersion) newEvent := ev.Headered(redactedBecause.RoomVersion)
err = d.Writer.Do(nil, nil, func(txn *sql.Tx) error { err = d.Writer.Do(nil, nil, func(txn *sql.Tx) error {
return d.OutputEvents.UpdateEventJSON(ctx, &newEvent) return d.OutputEvents.UpdateEventJSON(ctx, newEvent)
}) })
return err return err
} }
@ -809,7 +809,7 @@ func (d *Database) getJoinResponseForCompleteSync(
stateFilter *gomatrixserverlib.StateFilter, stateFilter *gomatrixserverlib.StateFilter,
numRecentEventsPerRoom int, device userapi.Device, numRecentEventsPerRoom int, device userapi.Device,
) (jr *types.JoinResponse, err error) { ) (jr *types.JoinResponse, err error) {
var stateEvents []gomatrixserverlib.HeaderedEvent var stateEvents []*gomatrixserverlib.HeaderedEvent
stateEvents, err = d.CurrentRoomState.SelectCurrentState(ctx, txn, roomID, stateFilter) stateEvents, err = d.CurrentRoomState.SelectCurrentState(ctx, txn, roomID, stateFilter)
if err != nil { if err != nil {
return return
@ -1180,7 +1180,7 @@ func (d *Database) getStateDeltas(
// dupe join events will result in the entire room state coming down to the client again. This is added in // dupe join events will result in the entire room state coming down to the client again. This is added in
// the 'state' part of the response though, so is transparent modulo bandwidth concerns as it is not added to // the 'state' part of the response though, so is transparent modulo bandwidth concerns as it is not added to
// the timeline. // the timeline.
if membership := getMembershipFromEvent(&ev.Event, userID); membership != "" { if membership := getMembershipFromEvent(ev.Event, userID); membership != "" {
if membership == gomatrixserverlib.Join { if membership == gomatrixserverlib.Join {
// send full room state down instead of a delta // send full room state down instead of a delta
var s []types.StreamEvent var s []types.StreamEvent
@ -1264,7 +1264,7 @@ func (d *Database) getStateDeltasForFullStateSync(
for roomID, stateStreamEvents := range state { for roomID, stateStreamEvents := range state {
for _, ev := range stateStreamEvents { for _, ev := range stateStreamEvents {
if membership := getMembershipFromEvent(&ev.Event, userID); membership != "" { if membership := getMembershipFromEvent(ev.Event, userID); membership != "" {
if membership != gomatrixserverlib.Join { // We've already added full state for all joined rooms above. if membership != gomatrixserverlib.Join { // We've already added full state for all joined rooms above.
deltas[roomID] = stateDelta{ deltas[roomID] = stateDelta{
membership: membership, membership: membership,
@ -1426,7 +1426,7 @@ func (d *Database) CleanSendToDeviceUpdates(
// There may be some overlap where events in stateEvents are already in recentEvents, so filter // There may be some overlap where events in stateEvents are already in recentEvents, so filter
// them out so we don't include them twice in the /sync response. They should be in recentEvents // them out so we don't include them twice in the /sync response. They should be in recentEvents
// only, so clients get to the correct state once they have rolled forward. // only, so clients get to the correct state once they have rolled forward.
func removeDuplicates(stateEvents, recentEvents []gomatrixserverlib.HeaderedEvent) []gomatrixserverlib.HeaderedEvent { func removeDuplicates(stateEvents, recentEvents []*gomatrixserverlib.HeaderedEvent) []*gomatrixserverlib.HeaderedEvent {
for _, recentEv := range recentEvents { for _, recentEv := range recentEvents {
if recentEv.StateKey() == nil { if recentEv.StateKey() == nil {
continue // not a state event continue // not a state event
@ -1463,7 +1463,7 @@ func getMembershipFromEvent(ev *gomatrixserverlib.Event, userID string) string {
type stateDelta struct { type stateDelta struct {
roomID string roomID string
stateEvents []gomatrixserverlib.HeaderedEvent stateEvents []*gomatrixserverlib.HeaderedEvent
membership string membership string
// The PDU stream position of the latest membership event for this user, if applicable. // The PDU stream position of the latest membership event for this user, if applicable.
// Can be 0 if there is no membership event in this delta. // Can be 0 if there is no membership event in this delta.

View file

@ -184,7 +184,7 @@ func (s *currentRoomStateStatements) SelectRoomIDsWithMembership(
func (s *currentRoomStateStatements) SelectCurrentState( func (s *currentRoomStateStatements) SelectCurrentState(
ctx context.Context, txn *sql.Tx, roomID string, ctx context.Context, txn *sql.Tx, roomID string,
stateFilterPart *gomatrixserverlib.StateFilter, stateFilterPart *gomatrixserverlib.StateFilter,
) ([]gomatrixserverlib.HeaderedEvent, error) { ) ([]*gomatrixserverlib.HeaderedEvent, error) {
stmt := sqlutil.TxStmt(txn, s.selectCurrentStateStmt) stmt := sqlutil.TxStmt(txn, s.selectCurrentStateStmt)
rows, err := stmt.QueryContext(ctx, roomID, rows, err := stmt.QueryContext(ctx, roomID,
nil, // FIXME: pq.StringArray(stateFilterPart.Senders), nil, // FIXME: pq.StringArray(stateFilterPart.Senders),
@ -220,7 +220,7 @@ func (s *currentRoomStateStatements) DeleteRoomStateForRoom(
func (s *currentRoomStateStatements) UpsertRoomState( func (s *currentRoomStateStatements) UpsertRoomState(
ctx context.Context, txn *sql.Tx, ctx context.Context, txn *sql.Tx,
event gomatrixserverlib.HeaderedEvent, membership *string, addedAt types.StreamPosition, event *gomatrixserverlib.HeaderedEvent, membership *string, addedAt types.StreamPosition,
) error { ) error {
// Parse content as JSON and search for an "url" key // Parse content as JSON and search for an "url" key
containsURL := false containsURL := false
@ -286,8 +286,8 @@ func (s *currentRoomStateStatements) SelectEventsWithEventIDs(
return res, nil return res, nil
} }
func rowsToEvents(rows *sql.Rows) ([]gomatrixserverlib.HeaderedEvent, error) { func rowsToEvents(rows *sql.Rows) ([]*gomatrixserverlib.HeaderedEvent, error) {
result := []gomatrixserverlib.HeaderedEvent{} result := []*gomatrixserverlib.HeaderedEvent{}
for rows.Next() { for rows.Next() {
var eventBytes []byte var eventBytes []byte
if err := rows.Scan(&eventBytes); err != nil { if err := rows.Scan(&eventBytes); err != nil {
@ -298,7 +298,7 @@ func rowsToEvents(rows *sql.Rows) ([]gomatrixserverlib.HeaderedEvent, error) {
if err := json.Unmarshal(eventBytes, &ev); err != nil { if err := json.Unmarshal(eventBytes, &ev); err != nil {
return nil, err return nil, err
} }
result = append(result, ev) result = append(result, &ev)
} }
return result, nil return result, nil
} }

View file

@ -91,7 +91,7 @@ func NewSqliteInvitesTable(db *sql.DB, streamID *streamIDStatements) (tables.Inv
} }
func (s *inviteEventsStatements) InsertInviteEvent( func (s *inviteEventsStatements) InsertInviteEvent(
ctx context.Context, txn *sql.Tx, inviteEvent gomatrixserverlib.HeaderedEvent, ctx context.Context, txn *sql.Tx, inviteEvent *gomatrixserverlib.HeaderedEvent,
) (streamPos types.StreamPosition, err error) { ) (streamPos types.StreamPosition, err error) {
streamPos, err = s.streamIDStatements.nextStreamID(ctx, txn) streamPos, err = s.streamIDStatements.nextStreamID(ctx, txn)
if err != nil { if err != nil {
@ -132,15 +132,15 @@ func (s *inviteEventsStatements) DeleteInviteEvent(
// active invites for the target user ID in the supplied range. // active invites for the target user ID in the supplied range.
func (s *inviteEventsStatements) SelectInviteEventsInRange( func (s *inviteEventsStatements) SelectInviteEventsInRange(
ctx context.Context, txn *sql.Tx, targetUserID string, r types.Range, ctx context.Context, txn *sql.Tx, targetUserID string, r types.Range,
) (map[string]gomatrixserverlib.HeaderedEvent, map[string]gomatrixserverlib.HeaderedEvent, error) { ) (map[string]*gomatrixserverlib.HeaderedEvent, map[string]*gomatrixserverlib.HeaderedEvent, error) {
stmt := sqlutil.TxStmt(txn, s.selectInviteEventsInRangeStmt) stmt := sqlutil.TxStmt(txn, s.selectInviteEventsInRangeStmt)
rows, err := stmt.QueryContext(ctx, targetUserID, r.Low(), r.High()) rows, err := stmt.QueryContext(ctx, targetUserID, r.Low(), r.High())
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
defer internal.CloseAndLogIfError(ctx, rows, "selectInviteEventsInRange: rows.close() failed") defer internal.CloseAndLogIfError(ctx, rows, "selectInviteEventsInRange: rows.close() failed")
result := map[string]gomatrixserverlib.HeaderedEvent{} result := map[string]*gomatrixserverlib.HeaderedEvent{}
retired := map[string]gomatrixserverlib.HeaderedEvent{} retired := map[string]*gomatrixserverlib.HeaderedEvent{}
for rows.Next() { for rows.Next() {
var ( var (
roomID string roomID string
@ -159,7 +159,7 @@ func (s *inviteEventsStatements) SelectInviteEventsInRange(
continue continue
} }
var event gomatrixserverlib.HeaderedEvent var event *gomatrixserverlib.HeaderedEvent
if err := json.Unmarshal(eventJSON, &event); err != nil { if err := json.Unmarshal(eventJSON, &event); err != nil {
return nil, nil, err return nil, nil, err
} }

View file

@ -246,7 +246,7 @@ func (s *outputRoomEventsStatements) SelectStateInRange(
stateNeeded[ev.RoomID()] = needSet stateNeeded[ev.RoomID()] = needSet
eventIDToEvent[ev.EventID()] = types.StreamEvent{ eventIDToEvent[ev.EventID()] = types.StreamEvent{
HeaderedEvent: ev, HeaderedEvent: &ev,
StreamPosition: streamPos, StreamPosition: streamPos,
ExcludeFromSync: excludeFromSync, ExcludeFromSync: excludeFromSync,
} }
@ -452,7 +452,7 @@ func rowsToStreamEvents(rows *sql.Rows) ([]types.StreamEvent, error) {
} }
result = append(result, types.StreamEvent{ result = append(result, types.StreamEvent{
HeaderedEvent: ev, HeaderedEvent: &ev,
StreamPosition: streamPos, StreamPosition: streamPos,
TransactionID: transactionID, TransactionID: transactionID,
ExcludeFromSync: excludeFromSync, ExcludeFromSync: excludeFromSync,

View file

@ -37,7 +37,7 @@ var (
}) })
) )
func MustCreateEvent(t *testing.T, roomID string, prevs []gomatrixserverlib.HeaderedEvent, b *gomatrixserverlib.EventBuilder) gomatrixserverlib.HeaderedEvent { func MustCreateEvent(t *testing.T, roomID string, prevs []*gomatrixserverlib.HeaderedEvent, b *gomatrixserverlib.EventBuilder) *gomatrixserverlib.HeaderedEvent {
b.RoomID = roomID b.RoomID = roomID
if prevs != nil { if prevs != nil {
prevIDs := make([]string, len(prevs)) prevIDs := make([]string, len(prevs))
@ -70,8 +70,8 @@ func MustCreateDatabase(t *testing.T) storage.Database {
} }
// Create a list of events which include a create event, join event and some messages. // Create a list of events which include a create event, join event and some messages.
func SimpleRoom(t *testing.T, roomID, userA, userB string) (msgs []gomatrixserverlib.HeaderedEvent, state []gomatrixserverlib.HeaderedEvent) { func SimpleRoom(t *testing.T, roomID, userA, userB string) (msgs []*gomatrixserverlib.HeaderedEvent, state []*gomatrixserverlib.HeaderedEvent) {
var events []gomatrixserverlib.HeaderedEvent var events []*gomatrixserverlib.HeaderedEvent
events = append(events, MustCreateEvent(t, roomID, nil, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, roomID, nil, &gomatrixserverlib.EventBuilder{
Content: []byte(fmt.Sprintf(`{"room_version":"4","creator":"%s"}`, userA)), Content: []byte(fmt.Sprintf(`{"room_version":"4","creator":"%s"}`, userA)),
Type: "m.room.create", Type: "m.room.create",
@ -80,7 +80,7 @@ func SimpleRoom(t *testing.T, roomID, userA, userB string) (msgs []gomatrixserve
Depth: int64(len(events) + 1), Depth: int64(len(events) + 1),
})) }))
state = append(state, events[len(events)-1]) state = append(state, events[len(events)-1])
events = append(events, MustCreateEvent(t, roomID, []gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, roomID, []*gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{
Content: []byte(`{"membership":"join"}`), Content: []byte(`{"membership":"join"}`),
Type: "m.room.member", Type: "m.room.member",
StateKey: &userA, StateKey: &userA,
@ -89,14 +89,14 @@ func SimpleRoom(t *testing.T, roomID, userA, userB string) (msgs []gomatrixserve
})) }))
state = append(state, events[len(events)-1]) state = append(state, events[len(events)-1])
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
events = append(events, MustCreateEvent(t, roomID, []gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, roomID, []*gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{
Content: []byte(fmt.Sprintf(`{"body":"Message A %d"}`, i+1)), Content: []byte(fmt.Sprintf(`{"body":"Message A %d"}`, i+1)),
Type: "m.room.message", Type: "m.room.message",
Sender: userA, Sender: userA,
Depth: int64(len(events) + 1), Depth: int64(len(events) + 1),
})) }))
} }
events = append(events, MustCreateEvent(t, roomID, []gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, roomID, []*gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{
Content: []byte(`{"membership":"join"}`), Content: []byte(`{"membership":"join"}`),
Type: "m.room.member", Type: "m.room.member",
StateKey: &userB, StateKey: &userB,
@ -105,7 +105,7 @@ func SimpleRoom(t *testing.T, roomID, userA, userB string) (msgs []gomatrixserve
})) }))
state = append(state, events[len(events)-1]) state = append(state, events[len(events)-1])
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
events = append(events, MustCreateEvent(t, roomID, []gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, roomID, []*gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{
Content: []byte(fmt.Sprintf(`{"body":"Message B %d"}`, i+1)), Content: []byte(fmt.Sprintf(`{"body":"Message B %d"}`, i+1)),
Type: "m.room.message", Type: "m.room.message",
Sender: userB, Sender: userB,
@ -116,16 +116,16 @@ func SimpleRoom(t *testing.T, roomID, userA, userB string) (msgs []gomatrixserve
return events, state return events, state
} }
func MustWriteEvents(t *testing.T, db storage.Database, events []gomatrixserverlib.HeaderedEvent) (positions []types.StreamPosition) { func MustWriteEvents(t *testing.T, db storage.Database, events []*gomatrixserverlib.HeaderedEvent) (positions []types.StreamPosition) {
for _, ev := range events { for _, ev := range events {
var addStateEvents []gomatrixserverlib.HeaderedEvent var addStateEvents []*gomatrixserverlib.HeaderedEvent
var addStateEventIDs []string var addStateEventIDs []string
var removeStateEventIDs []string var removeStateEventIDs []string
if ev.StateKey() != nil { if ev.StateKey() != nil {
addStateEvents = append(addStateEvents, ev) addStateEvents = append(addStateEvents, ev)
addStateEventIDs = append(addStateEventIDs, ev.EventID()) addStateEventIDs = append(addStateEventIDs, ev.EventID())
} }
pos, err := db.WriteEvent(ctx, &ev, addStateEvents, addStateEventIDs, removeStateEventIDs, nil, false) pos, err := db.WriteEvent(ctx, ev, addStateEvents, addStateEventIDs, removeStateEventIDs, nil, false)
if err != nil { if err != nil {
t.Fatalf("WriteEvent failed: %s", err) t.Fatalf("WriteEvent failed: %s", err)
} }
@ -156,8 +156,8 @@ func TestSyncResponse(t *testing.T) {
testCases := []struct { testCases := []struct {
Name string Name string
DoSync func() (*types.Response, error) DoSync func() (*types.Response, error)
WantTimeline []gomatrixserverlib.HeaderedEvent WantTimeline []*gomatrixserverlib.HeaderedEvent
WantState []gomatrixserverlib.HeaderedEvent WantState []*gomatrixserverlib.HeaderedEvent
}{ }{
// The purpose of this test is to make sure that incremental syncs are including up to the latest events. // The purpose of this test is to make sure that incremental syncs are including up to the latest events.
// It's a basic sanity test that sync works. It creates a `since` token that is on the penultimate event. // It's a basic sanity test that sync works. It creates a `since` token that is on the penultimate event.
@ -339,7 +339,7 @@ func TestGetEventsInRangeWithEventsSameDepth(t *testing.T) {
t.Parallel() t.Parallel()
db := MustCreateDatabase(t) db := MustCreateDatabase(t)
var events []gomatrixserverlib.HeaderedEvent var events []*gomatrixserverlib.HeaderedEvent
events = append(events, MustCreateEvent(t, testRoomID, nil, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, testRoomID, nil, &gomatrixserverlib.EventBuilder{
Content: []byte(fmt.Sprintf(`{"room_version":"4","creator":"%s"}`, testUserIDA)), Content: []byte(fmt.Sprintf(`{"room_version":"4","creator":"%s"}`, testUserIDA)),
Type: "m.room.create", Type: "m.room.create",
@ -347,7 +347,7 @@ func TestGetEventsInRangeWithEventsSameDepth(t *testing.T) {
Sender: testUserIDA, Sender: testUserIDA,
Depth: int64(len(events) + 1), Depth: int64(len(events) + 1),
})) }))
events = append(events, MustCreateEvent(t, testRoomID, []gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, testRoomID, []*gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{
Content: []byte(`{"membership":"join"}`), Content: []byte(`{"membership":"join"}`),
Type: "m.room.member", Type: "m.room.member",
StateKey: &testUserIDA, StateKey: &testUserIDA,
@ -355,7 +355,7 @@ func TestGetEventsInRangeWithEventsSameDepth(t *testing.T) {
Depth: int64(len(events) + 1), Depth: int64(len(events) + 1),
})) }))
// fork the dag into three, same prev_events and depth // fork the dag into three, same prev_events and depth
parent := []gomatrixserverlib.HeaderedEvent{events[len(events)-1]} parent := []*gomatrixserverlib.HeaderedEvent{events[len(events)-1]}
depth := int64(len(events) + 1) depth := int64(len(events) + 1)
for i := 0; i < 3; i++ { for i := 0; i < 3; i++ {
events = append(events, MustCreateEvent(t, testRoomID, parent, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, testRoomID, parent, &gomatrixserverlib.EventBuilder{
@ -388,7 +388,7 @@ func TestGetEventsInRangeWithEventsSameDepth(t *testing.T) {
Name string Name string
From types.TopologyToken From types.TopologyToken
Limit int Limit int
Wants []gomatrixserverlib.HeaderedEvent Wants []*gomatrixserverlib.HeaderedEvent
}{ }{
{ {
Name: "Pagination over the whole fork", Name: "Pagination over the whole fork",
@ -429,7 +429,7 @@ func TestGetEventsInTopologicalRangeMultiRoom(t *testing.T) {
t.Parallel() t.Parallel()
db := MustCreateDatabase(t) db := MustCreateDatabase(t)
makeEvents := func(roomID string) (events []gomatrixserverlib.HeaderedEvent) { makeEvents := func(roomID string) (events []*gomatrixserverlib.HeaderedEvent) {
events = append(events, MustCreateEvent(t, roomID, nil, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, roomID, nil, &gomatrixserverlib.EventBuilder{
Content: []byte(fmt.Sprintf(`{"room_version":"4","creator":"%s"}`, testUserIDA)), Content: []byte(fmt.Sprintf(`{"room_version":"4","creator":"%s"}`, testUserIDA)),
Type: "m.room.create", Type: "m.room.create",
@ -437,7 +437,7 @@ func TestGetEventsInTopologicalRangeMultiRoom(t *testing.T) {
Sender: testUserIDA, Sender: testUserIDA,
Depth: int64(len(events) + 1), Depth: int64(len(events) + 1),
})) }))
events = append(events, MustCreateEvent(t, roomID, []gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{ events = append(events, MustCreateEvent(t, roomID, []*gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{
Content: []byte(`{"membership":"join"}`), Content: []byte(`{"membership":"join"}`),
Type: "m.room.member", Type: "m.room.member",
StateKey: &testUserIDA, StateKey: &testUserIDA,
@ -483,14 +483,14 @@ func TestGetEventsInRangeWithEventsInsertedLikeBackfill(t *testing.T) {
// "federation" join // "federation" join
userC := fmt.Sprintf("@radiance:%s", testOrigin) userC := fmt.Sprintf("@radiance:%s", testOrigin)
joinEvent := MustCreateEvent(t, testRoomID, []gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{ joinEvent := MustCreateEvent(t, testRoomID, []*gomatrixserverlib.HeaderedEvent{events[len(events)-1]}, &gomatrixserverlib.EventBuilder{
Content: []byte(`{"membership":"join"}`), Content: []byte(`{"membership":"join"}`),
Type: "m.room.member", Type: "m.room.member",
StateKey: &userC, StateKey: &userC,
Sender: userC, Sender: userC,
Depth: int64(len(events) + 1), Depth: int64(len(events) + 1),
}) })
MustWriteEvents(t, db, []gomatrixserverlib.HeaderedEvent{joinEvent}) MustWriteEvents(t, db, []*gomatrixserverlib.HeaderedEvent{joinEvent})
// Sync will return this for the prev_batch // Sync will return this for the prev_batch
from := topologyTokenBefore(t, db, joinEvent.EventID()) from := topologyTokenBefore(t, db, joinEvent.EventID())
@ -627,7 +627,7 @@ func TestInviteBehaviour(t *testing.T) {
StateKey: &testUserIDA, StateKey: &testUserIDA,
Sender: "@inviteUser2:somewhere", Sender: "@inviteUser2:somewhere",
}) })
for _, ev := range []gomatrixserverlib.HeaderedEvent{inviteEvent1, inviteEvent2} { for _, ev := range []*gomatrixserverlib.HeaderedEvent{inviteEvent1, inviteEvent2} {
_, err := db.AddInviteEvent(ctx, ev) _, err := db.AddInviteEvent(ctx, ev)
if err != nil { if err != nil {
t.Fatalf("Failed to AddInviteEvent: %s", err) t.Fatalf("Failed to AddInviteEvent: %s", err)
@ -688,7 +688,7 @@ func assertInvitedToRooms(t *testing.T, res *types.Response, roomIDs []string) {
} }
} }
func assertEventsEqual(t *testing.T, msg string, checkRoomID bool, gots []gomatrixserverlib.ClientEvent, wants []gomatrixserverlib.HeaderedEvent) { func assertEventsEqual(t *testing.T, msg string, checkRoomID bool, gots []gomatrixserverlib.ClientEvent, wants []*gomatrixserverlib.HeaderedEvent) {
t.Helper() t.Helper()
if len(gots) != len(wants) { if len(gots) != len(wants) {
t.Fatalf("%s response returned %d events, want %d", msg, len(gots), len(wants)) t.Fatalf("%s response returned %d events, want %d", msg, len(gots), len(wants))
@ -738,8 +738,8 @@ func topologyTokenBefore(t *testing.T, db storage.Database, eventID string) *typ
return &tok return &tok
} }
func reversed(in []gomatrixserverlib.HeaderedEvent) []gomatrixserverlib.HeaderedEvent { func reversed(in []*gomatrixserverlib.HeaderedEvent) []*gomatrixserverlib.HeaderedEvent {
out := make([]gomatrixserverlib.HeaderedEvent, len(in)) out := make([]*gomatrixserverlib.HeaderedEvent, len(in))
for i := 0; i < len(in); i++ { for i := 0; i < len(in); i++ {
out[i] = in[len(in)-i-1] out[i] = in[len(in)-i-1]
} }

View file

@ -32,11 +32,11 @@ type AccountData interface {
} }
type Invites interface { type Invites interface {
InsertInviteEvent(ctx context.Context, txn *sql.Tx, inviteEvent gomatrixserverlib.HeaderedEvent) (streamPos types.StreamPosition, err error) InsertInviteEvent(ctx context.Context, txn *sql.Tx, inviteEvent *gomatrixserverlib.HeaderedEvent) (streamPos types.StreamPosition, err error)
DeleteInviteEvent(ctx context.Context, txn *sql.Tx, inviteEventID string) (types.StreamPosition, error) DeleteInviteEvent(ctx context.Context, txn *sql.Tx, inviteEventID string) (types.StreamPosition, error)
// SelectInviteEventsInRange returns a map of room ID to invite events. If multiple invite/retired invites exist in the given range, return the latest value // SelectInviteEventsInRange returns a map of room ID to invite events. If multiple invite/retired invites exist in the given range, return the latest value
// for the room. // for the room.
SelectInviteEventsInRange(ctx context.Context, txn *sql.Tx, targetUserID string, r types.Range) (invites map[string]gomatrixserverlib.HeaderedEvent, retired map[string]gomatrixserverlib.HeaderedEvent, err error) SelectInviteEventsInRange(ctx context.Context, txn *sql.Tx, targetUserID string, r types.Range) (invites map[string]*gomatrixserverlib.HeaderedEvent, retired map[string]*gomatrixserverlib.HeaderedEvent, err error)
SelectMaxInviteID(ctx context.Context, txn *sql.Tx) (id int64, err error) SelectMaxInviteID(ctx context.Context, txn *sql.Tx) (id int64, err error)
} }
@ -87,11 +87,11 @@ type Topology interface {
type CurrentRoomState interface { type CurrentRoomState interface {
SelectStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error) SelectStateEvent(ctx context.Context, roomID, evType, stateKey string) (*gomatrixserverlib.HeaderedEvent, error)
SelectEventsWithEventIDs(ctx context.Context, txn *sql.Tx, eventIDs []string) ([]types.StreamEvent, error) SelectEventsWithEventIDs(ctx context.Context, txn *sql.Tx, eventIDs []string) ([]types.StreamEvent, error)
UpsertRoomState(ctx context.Context, txn *sql.Tx, event gomatrixserverlib.HeaderedEvent, membership *string, addedAt types.StreamPosition) error UpsertRoomState(ctx context.Context, txn *sql.Tx, event *gomatrixserverlib.HeaderedEvent, membership *string, addedAt types.StreamPosition) error
DeleteRoomStateByEventID(ctx context.Context, txn *sql.Tx, eventID string) error DeleteRoomStateByEventID(ctx context.Context, txn *sql.Tx, eventID string) error
DeleteRoomStateForRoom(ctx context.Context, txn *sql.Tx, roomID string) error DeleteRoomStateForRoom(ctx context.Context, txn *sql.Tx, roomID string) error
// SelectCurrentState returns all the current state events for the given room. // SelectCurrentState returns all the current state events for the given room.
SelectCurrentState(ctx context.Context, txn *sql.Tx, roomID string, stateFilter *gomatrixserverlib.StateFilter) ([]gomatrixserverlib.HeaderedEvent, error) SelectCurrentState(ctx context.Context, txn *sql.Tx, roomID string, stateFilter *gomatrixserverlib.StateFilter) ([]*gomatrixserverlib.HeaderedEvent, error)
// SelectRoomIDsWithMembership returns the list of room IDs which have the given user in the given membership state. // SelectRoomIDsWithMembership returns the list of room IDs which have the given user in the given membership state.
SelectRoomIDsWithMembership(ctx context.Context, txn *sql.Tx, userID string, membership string) ([]string, error) SelectRoomIDsWithMembership(ctx context.Context, txn *sql.Tx, userID string, membership string) ([]string, error)
// SelectJoinedUsers returns a map of room ID to a list of joined user IDs. // SelectJoinedUsers returns a map of room ID to a list of joined user IDs.

View file

@ -59,7 +59,7 @@ func (p *LogPosition) IsAfter(lp *LogPosition) bool {
// StreamEvent is the same as gomatrixserverlib.Event but also has the PDU stream position for this event. // StreamEvent is the same as gomatrixserverlib.Event but also has the PDU stream position for this event.
type StreamEvent struct { type StreamEvent struct {
gomatrixserverlib.HeaderedEvent *gomatrixserverlib.HeaderedEvent
StreamPosition StreamPosition StreamPosition StreamPosition
TransactionID *api.TransactionID TransactionID *api.TransactionID
ExcludeFromSync bool ExcludeFromSync bool
@ -471,7 +471,7 @@ type InviteResponse struct {
} }
// NewInviteResponse creates an empty response with initialised arrays. // NewInviteResponse creates an empty response with initialised arrays.
func NewInviteResponse(event gomatrixserverlib.HeaderedEvent) *InviteResponse { func NewInviteResponse(event *gomatrixserverlib.HeaderedEvent) *InviteResponse {
res := InviteResponse{} res := InviteResponse{}
res.InviteState.Events = []json.RawMessage{} res.InviteState.Events = []json.RawMessage{}

View file

@ -61,3 +61,6 @@ If user leaves room, remote user changes device and rejoins we see update in /sy
# Blacklisted due to flakiness # Blacklisted due to flakiness
A prev_batch token from incremental sync can be used in the v1 messages API A prev_batch token from incremental sync can be used in the v1 messages API
# Blacklisted due to flakiness
Forgotten room messages cannot be paginated

View file

@ -492,7 +492,7 @@ Inbound federation rejects receipts from wrong remote
Should not be able to take over the room by pretending there is no PL event Should not be able to take over the room by pretending there is no PL event
Can get rooms/{roomId}/state for a departed room (SPEC-216) Can get rooms/{roomId}/state for a departed room (SPEC-216)
Users cannot set notifications powerlevel higher than their own Users cannot set notifications powerlevel higher than their own
Forgotten room messages cannot be paginated
Forgetting room does not show up in v2 /sync Forgetting room does not show up in v2 /sync
Can forget room you've been kicked from Can forget room you've been kicked from
Can re-join room if re-invited Can re-join room if re-invited
/whois

View file

@ -77,7 +77,7 @@ const selectDeviceByIDSQL = "" +
"SELECT display_name FROM device_devices WHERE localpart = $1 and device_id = $2" "SELECT display_name FROM device_devices WHERE localpart = $1 and device_id = $2"
const selectDevicesByLocalpartSQL = "" + const selectDevicesByLocalpartSQL = "" +
"SELECT device_id, display_name FROM device_devices WHERE localpart = $1 AND device_id != $2" "SELECT device_id, display_name, last_seen_ts, ip, user_agent FROM device_devices WHERE localpart = $1 AND device_id != $2"
const updateDeviceNameSQL = "" + const updateDeviceNameSQL = "" +
"UPDATE device_devices SET display_name = $1 WHERE localpart = $2 AND device_id = $3" "UPDATE device_devices SET display_name = $1 WHERE localpart = $2 AND device_id = $3"
@ -281,8 +281,9 @@ func (s *devicesStatements) selectDevicesByLocalpart(
for rows.Next() { for rows.Next() {
var dev api.Device var dev api.Device
var id, displayname sql.NullString var lastseents sql.NullInt64
err = rows.Scan(&id, &displayname) var id, displayname, ip, useragent sql.NullString
err = rows.Scan(&id, &displayname, &lastseents, &ip, &useragent)
if err != nil { if err != nil {
return devices, err return devices, err
} }
@ -292,6 +293,16 @@ func (s *devicesStatements) selectDevicesByLocalpart(
if displayname.Valid { if displayname.Valid {
dev.DisplayName = displayname.String dev.DisplayName = displayname.String
} }
if lastseents.Valid {
dev.LastSeenTS = lastseents.Int64
}
if ip.Valid {
dev.LastSeenIP = ip.String
}
if useragent.Valid {
dev.UserAgent = useragent.String
}
dev.UserID = userutil.MakeUserID(localpart, s.serverName) dev.UserID = userutil.MakeUserID(localpart, s.serverName)
devices = append(devices, dev) devices = append(devices, dev)
} }

View file

@ -62,7 +62,7 @@ const selectDeviceByIDSQL = "" +
"SELECT display_name FROM device_devices WHERE localpart = $1 and device_id = $2" "SELECT display_name FROM device_devices WHERE localpart = $1 and device_id = $2"
const selectDevicesByLocalpartSQL = "" + const selectDevicesByLocalpartSQL = "" +
"SELECT device_id, display_name FROM device_devices WHERE localpart = $1 AND device_id != $2" "SELECT device_id, display_name, last_seen_ts, ip, user_agent FROM device_devices WHERE localpart = $1 AND device_id != $2"
const updateDeviceNameSQL = "" + const updateDeviceNameSQL = "" +
"UPDATE device_devices SET display_name = $1 WHERE localpart = $2 AND device_id = $3" "UPDATE device_devices SET display_name = $1 WHERE localpart = $2 AND device_id = $3"
@ -256,8 +256,9 @@ func (s *devicesStatements) selectDevicesByLocalpart(
for rows.Next() { for rows.Next() {
var dev api.Device var dev api.Device
var id, displayname sql.NullString var lastseents sql.NullInt64
err = rows.Scan(&id, &displayname) var id, displayname, ip, useragent sql.NullString
err = rows.Scan(&id, &displayname, &lastseents, &ip, &useragent)
if err != nil { if err != nil {
return devices, err return devices, err
} }
@ -267,6 +268,16 @@ func (s *devicesStatements) selectDevicesByLocalpart(
if displayname.Valid { if displayname.Valid {
dev.DisplayName = displayname.String dev.DisplayName = displayname.String
} }
if lastseents.Valid {
dev.LastSeenTS = lastseents.Int64
}
if ip.Valid {
dev.LastSeenIP = ip.String
}
if useragent.Valid {
dev.UserAgent = useragent.String
}
dev.UserID = userutil.MakeUserID(localpart, s.serverName) dev.UserID = userutil.MakeUserID(localpart, s.serverName)
devices = append(devices, dev) devices = append(devices, dev)
} }