Skip to content

Commit 81c0d9a

Browse files
kegsaydevonh
andauthored
Add ServerRoomImpl to allow tests to reuse helpers with custom code (#766)
* Mostly factor out ProtoEvent logic This allows tests to replace how we map Complement Events to PDUs. This does not yet do everything as the mapping of /send_join to Rooms isn't factored out. * Factor out /send_join code to ServerRoomImpl * Add ServerRoomImplCustom to make it more ergonomic to write overrides * Update federation/server_room.go Co-authored-by: Devon Hudson <[email protected]> * More comments --------- Co-authored-by: Devon Hudson <[email protected]>
1 parent bff6ad0 commit 81c0d9a

File tree

3 files changed

+197
-125
lines changed

3 files changed

+197
-125
lines changed

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(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(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(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: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -303,58 +303,15 @@ func (s *Server) DoFederationRequest(
303303
// It does not insert this event into the room however. See ServerRoom.AddEvent for that.
304304
func (s *Server) MustCreateEvent(t ct.TestLike, room *ServerRoom, ev Event) gomatrixserverlib.PDU {
305305
t.Helper()
306-
content, err := json.Marshal(ev.Content)
306+
proto, err := room.ProtoEventCreator(ev)
307307
if err != nil {
308-
ct.Fatalf(t, "MustCreateEvent: failed to marshal event content %s - %+v", err, ev.Content)
308+
ct.Fatalf(t, "MustCreateEvent: failed to create proto event: %v", err)
309309
}
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)
310+
pdu, err := room.EventCreator(s, proto)
349311
if err != nil {
350-
ct.Fatalf(t, "MustCreateEvent: invalid room version: %s", err)
312+
ct.Fatalf(t, "MustCreateEvent: failed to create PDU: %v", err)
351313
}
352-
eb := verImpl.NewEventBuilderFromProtoEvent(&proto)
353-
signedEvent, err := eb.Build(time.Now(), spec.ServerName(s.serverName), s.KeyID, s.Priv)
354-
if err != nil {
355-
ct.Fatalf(t, "MustCreateEvent: failed to sign event: %s", err)
356-
}
357-
return signedEvent
314+
return pdu
358315
}
359316

360317
// MustJoinRoom will make the server send a make_join and a send_join to join a room
@@ -424,12 +381,8 @@ func (s *Server) MustJoinRoom(t ct.TestLike, deployment FederationDeployment, re
424381
if err != nil {
425382
ct.Fatalf(t, "MustJoinRoom: send_join failed: %v", err)
426383
}
427-
stateEvents := sendJoinResp.StateEvents.UntrustedEvents(roomVer)
428384
room := NewServerRoom(roomVer, roomID)
429-
for _, ev := range stateEvents {
430-
room.ReplaceCurrentState(ev)
431-
}
432-
room.AddEvent(joinEvent)
385+
room.PopulateFromSendJoinResponse(joinEvent, sendJoinResp)
433386
s.rooms[roomID] = room
434387

435388
t.Logf("Server.MustJoinRoom joined room ID %s", roomID)

0 commit comments

Comments
 (0)