Skip to content

Commit 1502a00

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents 35ad9d9 + 3fbfb75 commit 1502a00

6 files changed

Lines changed: 266 additions & 146 deletions

File tree

federation/handle.go

Lines changed: 25 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -59,29 +59,22 @@ func MakeJoinRequestsHandler(s *Server, w http.ResponseWriter, req *http.Request
5959
// or dealing with HTTP responses itself.
6060
func MakeRespMakeJoin(s *Server, room *ServerRoom, userID string) (resp fclient.RespMakeJoin, err error) {
6161
// Generate a join event
62-
proto := gomatrixserverlib.ProtoEvent{
63-
SenderID: userID,
64-
RoomID: room.RoomID,
65-
Type: "m.room.member",
66-
StateKey: &userID,
67-
PrevEvents: []string{room.Timeline[len(room.Timeline)-1].EventID()},
68-
Depth: room.Timeline[len(room.Timeline)-1].Depth() + 1,
69-
}
70-
err = proto.SetContent(map[string]interface{}{"membership": spec.Join})
71-
if err != nil {
72-
err = fmt.Errorf("make_join cannot set membership content: %w", err)
73-
return
74-
}
75-
stateNeeded, err := gomatrixserverlib.StateNeededForProtoEvent(&proto)
62+
proto, err := room.ProtoEventCreator(room, Event{
63+
Type: "m.room.member",
64+
StateKey: &userID,
65+
Content: map[string]interface{}{
66+
"membership": spec.Join,
67+
},
68+
Sender: userID,
69+
})
7670
if err != nil {
77-
err = fmt.Errorf("make_join cannot calculate auth_events: %w", err)
71+
err = fmt.Errorf("make_join cannot set create proto event: %w", err)
7872
return
7973
}
80-
proto.AuthEvents = room.AuthEvents(stateNeeded)
8174

8275
resp = fclient.RespMakeJoin{
8376
RoomVersion: room.Version,
84-
JoinEvent: proto,
77+
JoinEvent: *proto,
8578
}
8679
return
8780
}
@@ -91,29 +84,22 @@ func MakeRespMakeJoin(s *Server, room *ServerRoom, userID string) (resp fclient.
9184
// or dealing with HTTP responses itself.
9285
func MakeRespMakeKnock(s *Server, room *ServerRoom, userID string) (resp fclient.RespMakeKnock, err error) {
9386
// Generate a knock event
94-
proto := gomatrixserverlib.ProtoEvent{
95-
SenderID: userID,
96-
RoomID: room.RoomID,
97-
Type: "m.room.member",
98-
StateKey: &userID,
99-
PrevEvents: []string{room.Timeline[len(room.Timeline)-1].EventID()},
100-
Depth: room.Timeline[len(room.Timeline)-1].Depth() + 1,
101-
}
102-
err = proto.SetContent(map[string]interface{}{"membership": spec.Join})
103-
if err != nil {
104-
err = fmt.Errorf("make_knock cannot set membership content: %w", err)
105-
return
106-
}
107-
stateNeeded, err := gomatrixserverlib.StateNeededForProtoEvent(&proto)
87+
proto, err := room.ProtoEventCreator(room, Event{
88+
Type: "m.room.member",
89+
StateKey: &userID,
90+
Content: map[string]interface{}{
91+
"membership": spec.Join, // XXX this feels wrong?
92+
},
93+
Sender: userID,
94+
})
10895
if err != nil {
109-
err = fmt.Errorf("make_knock cannot calculate auth_events: %w", err)
96+
err = fmt.Errorf("make_knock cannot set create proto event: %w", err)
11097
return
11198
}
112-
proto.AuthEvents = room.AuthEvents(stateNeeded)
11399

114100
resp = fclient.RespMakeKnock{
115101
RoomVersion: room.Version,
116-
KnockEvent: proto,
102+
KnockEvent: *proto,
117103
}
118104
return
119105
}
@@ -173,40 +159,8 @@ func SendJoinRequestsHandler(s *Server, w http.ResponseWriter, req *http.Request
173159
return
174160
}
175161

176-
// build the state list *before* we insert the new event
177-
var stateEvents []gomatrixserverlib.PDU
178-
room.StateMutex.RLock()
179-
for _, ev := range room.State {
180-
// filter out non-critical memberships if this is a partial-state join
181-
if expectPartialState {
182-
if ev.Type() == "m.room.member" && ev.StateKey() != event.StateKey() {
183-
continue
184-
}
185-
}
186-
stateEvents = append(stateEvents, ev)
187-
}
188-
room.StateMutex.RUnlock()
189-
190-
authEvents := room.AuthChainForEvents(stateEvents)
191-
192-
// get servers in room *before* the join event
193-
serversInRoom := []string{s.serverName}
194-
if !omitServersInRoom {
195-
serversInRoom = room.ServersInRoom()
196-
}
197-
198-
// insert the join event into the room state
199-
room.AddEvent(event)
200-
log.Printf("Received send-join of event %s", event.EventID())
201-
202-
// return state and auth chain
203-
b, err := json.Marshal(fclient.RespSendJoin{
204-
Origin: spec.ServerName(s.serverName),
205-
AuthEvents: gomatrixserverlib.NewEventJSONsFromEvents(authEvents),
206-
StateEvents: gomatrixserverlib.NewEventJSONsFromEvents(stateEvents),
207-
MembersOmitted: expectPartialState,
208-
ServersInRoom: serversInRoom,
209-
})
162+
resp := room.GenerateSendJoinResponse(room, s, event, expectPartialState, omitServersInRoom)
163+
b, err := json.Marshal(resp)
210164
if err != nil {
211165
w.WriteHeader(500)
212166
w.Write([]byte("complement: HandleMakeSendJoinRequests send_join cannot marshal RespSendJoin: " + err.Error()))
@@ -410,7 +364,7 @@ func HandleEventAuthRequests() func(*Server) {
410364

411365
authEvents := room.AuthChainForEvents([]gomatrixserverlib.PDU{event})
412366
resp := fclient.RespEventAuth{
413-
gomatrixserverlib.NewEventJSONsFromEvents(authEvents),
367+
AuthEvents: gomatrixserverlib.NewEventJSONsFromEvents(authEvents),
414368
}
415369
respJSON, err := json.Marshal(resp)
416370
if err != nil {
@@ -590,8 +544,8 @@ func HandleTransactionRequests(pduCallback func(gomatrixserverlib.PDU), eduCallb
590544
verImpl, err := gomatrixserverlib.GetRoomVersion(room.Version)
591545
if err != nil {
592546
log.Printf(
593-
"complement: Transaction '%s': Failed to get room version '%s': %s",
594-
transaction.TransactionID, event.EventID(), err.Error(),
547+
"complement: Transaction '%s': Failed to get room version: %s",
548+
transaction.TransactionID, err.Error(),
595549
)
596550
continue
597551
}

federation/server.go

Lines changed: 45 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func (s *Server) MakeAliasMapping(aliasLocalpart, roomID string) string {
172172

173173
// MustMakeRoom will add a room to this server so it is accessible to other servers when prompted via federation.
174174
// The `events` will be added to this room. Returns the created room.
175-
func (s *Server) MustMakeRoom(t ct.TestLike, roomVer gomatrixserverlib.RoomVersion, events []Event) *ServerRoom {
175+
func (s *Server) MustMakeRoom(t ct.TestLike, roomVer gomatrixserverlib.RoomVersion, events []Event, opts ...ServerRoomOpt) *ServerRoom {
176176
if !s.listening {
177177
ct.Fatalf(s.t, "MustMakeRoom() called before Listen() - this is not supported because Listen() chooses a high-numbered port and thus changes the server name and thus changes the room ID. Ensure you Listen() first!")
178178
}
@@ -183,14 +183,17 @@ func (s *Server) MustMakeRoom(t ct.TestLike, roomVer gomatrixserverlib.RoomVersi
183183
// * prevents homeservers from getting confused when multiple test cases re-use the same homeserver deployment.
184184
roomID := fmt.Sprintf("!%d-%s:%s", len(s.rooms), util.RandomString(18), s.serverName)
185185
t.Logf("Creating room %s with version %s", roomID, roomVer)
186-
room := newRoom(roomVer, roomID)
186+
room := NewServerRoom(roomVer, roomID)
187+
for _, opt := range opts {
188+
opt(room)
189+
}
187190

188191
// sign all these events
189192
for _, ev := range events {
190193
signedEvent := s.MustCreateEvent(t, room, ev)
191194
room.AddEvent(signedEvent)
192195
}
193-
s.rooms[roomID] = room
196+
s.rooms[room.RoomID] = room
194197
return room
195198
}
196199

@@ -303,64 +306,25 @@ func (s *Server) DoFederationRequest(
303306
// It does not insert this event into the room however. See ServerRoom.AddEvent for that.
304307
func (s *Server) MustCreateEvent(t ct.TestLike, room *ServerRoom, ev Event) gomatrixserverlib.PDU {
305308
t.Helper()
306-
content, err := json.Marshal(ev.Content)
307-
if err != nil {
308-
ct.Fatalf(t, "MustCreateEvent: failed to marshal event content %s - %+v", err, ev.Content)
309-
}
310-
var unsigned []byte
311-
if ev.Unsigned != nil {
312-
unsigned, err = json.Marshal(ev.Unsigned)
313-
if err != nil {
314-
ct.Fatalf(t, "MustCreateEvent: failed to marshal event unsigned: %s - %+v", err, ev.Unsigned)
315-
}
316-
}
317-
318-
var prevEvents interface{}
319-
if ev.PrevEvents != nil {
320-
// We deliberately want to set the prev events.
321-
prevEvents = ev.PrevEvents
322-
} else {
323-
// No other prev events were supplied so we'll just
324-
// use the forward extremities of the room, which is
325-
// the usual behaviour.
326-
prevEvents = room.ForwardExtremities
327-
}
328-
proto := gomatrixserverlib.ProtoEvent{
329-
SenderID: ev.Sender,
330-
Depth: int64(room.Depth + 1), // depth starts at 1
331-
Type: ev.Type,
332-
StateKey: ev.StateKey,
333-
Content: content,
334-
RoomID: room.RoomID,
335-
PrevEvents: prevEvents,
336-
Unsigned: unsigned,
337-
AuthEvents: ev.AuthEvents,
338-
Redacts: ev.Redacts,
339-
}
340-
if proto.AuthEvents == nil {
341-
var stateNeeded gomatrixserverlib.StateNeeded
342-
stateNeeded, err = gomatrixserverlib.StateNeededForProtoEvent(&proto)
343-
if err != nil {
344-
ct.Fatalf(t, "MustCreateEvent: failed to work out auth_events : %s", err)
345-
}
346-
proto.AuthEvents = room.AuthEvents(stateNeeded)
347-
}
348-
verImpl, err := gomatrixserverlib.GetRoomVersion(room.Version)
309+
proto, err := room.ProtoEventCreator(room, ev)
349310
if err != nil {
350-
ct.Fatalf(t, "MustCreateEvent: invalid room version: %s", err)
311+
ct.Fatalf(t, "MustCreateEvent: failed to create proto event: %v", err)
351312
}
352-
eb := verImpl.NewEventBuilderFromProtoEvent(&proto)
353-
signedEvent, err := eb.Build(time.Now(), spec.ServerName(s.serverName), s.KeyID, s.Priv)
313+
pdu, err := room.EventCreator(room, s, proto)
354314
if err != nil {
355-
ct.Fatalf(t, "MustCreateEvent: failed to sign event: %s", err)
315+
ct.Fatalf(t, "MustCreateEvent: failed to create PDU: %v", err)
356316
}
357-
return signedEvent
317+
return pdu
358318
}
359319

360320
// MustJoinRoom will make the server send a make_join and a send_join to join a room
361321
// It returns the resultant room.
362-
func (s *Server) MustJoinRoom(t ct.TestLike, deployment FederationDeployment, remoteServer spec.ServerName, roomID string, userID string, partialState ...bool) *ServerRoom {
322+
func (s *Server) MustJoinRoom(t ct.TestLike, deployment FederationDeployment, remoteServer spec.ServerName, roomID string, userID string, opts ...JoinRoomOpt) *ServerRoom {
363323
t.Helper()
324+
var jr joinRoom
325+
for _, opt := range opts {
326+
opt(&jr)
327+
}
364328
origin := spec.ServerName(s.serverName)
365329
fedClient := s.FederationClient(deployment)
366330
makeJoinResp, err := fedClient.MakeJoin(context.Background(), origin, remoteServer, roomID, userID)
@@ -415,7 +379,7 @@ func (s *Server) MustJoinRoom(t ct.TestLike, deployment FederationDeployment, re
415379
ct.Fatalf(t, "MustJoinRoom: failed to sign event: %v", err)
416380
}
417381
var sendJoinResp fclient.RespSendJoin
418-
if len(partialState) == 0 || !partialState[0] {
382+
if !jr.partialState {
419383
// Default to doing a regular join.
420384
sendJoinResp, err = fedClient.SendJoin(context.Background(), origOrigin, remoteServer, joinEvent)
421385
} else {
@@ -424,15 +388,14 @@ func (s *Server) MustJoinRoom(t ct.TestLike, deployment FederationDeployment, re
424388
if err != nil {
425389
ct.Fatalf(t, "MustJoinRoom: send_join failed: %v", err)
426390
}
427-
stateEvents := sendJoinResp.StateEvents.UntrustedEvents(roomVer)
428-
room := newRoom(roomVer, roomID)
429-
for _, ev := range stateEvents {
430-
room.replaceCurrentState(ev)
391+
room := NewServerRoom(roomVer, roomID)
392+
for _, opt := range jr.roomOpts {
393+
opt(room)
431394
}
432-
room.AddEvent(joinEvent)
433-
s.rooms[roomID] = room
395+
room.PopulateFromSendJoinResponse(room, joinEvent, sendJoinResp)
396+
s.rooms[room.RoomID] = room
434397

435-
t.Logf("Server.MustJoinRoom joined room ID %s", roomID)
398+
t.Logf("Server.MustJoinRoom joined room ID %s", room.RoomID)
436399

437400
return room
438401
}
@@ -555,6 +518,28 @@ func (s *Server) Listen() (cancel func()) {
555518
}
556519
}
557520

521+
type joinRoom struct {
522+
partialState bool
523+
roomOpts []ServerRoomOpt
524+
}
525+
526+
// JoinRoomOpt is an option for configuring how the server should join the room
527+
type JoinRoomOpt func(jr *joinRoom)
528+
529+
// WithPartialState tells the server to join the room with partial state
530+
func WithPartialState() JoinRoomOpt {
531+
return func(jr *joinRoom) {
532+
jr.partialState = true
533+
}
534+
}
535+
536+
// WithRoomOpts controls how the newly joined room is created
537+
func WithRoomOpts(opts ...ServerRoomOpt) JoinRoomOpt {
538+
return func(jr *joinRoom) {
539+
jr.roomOpts = opts
540+
}
541+
}
542+
558543
// federationServer creates a federation server with the given handler
559544
func federationServer(cfg *config.Complement, h http.Handler) (*http.Server, string, string, error) {
560545
var derBytes []byte

0 commit comments

Comments
 (0)