|
1 | 1 | package tests |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "context" |
4 | 5 | "encoding/json" |
5 | 6 | "net/http" |
6 | 7 | "net/url" |
7 | 8 | "testing" |
| 9 | + "time" |
8 | 10 |
|
| 11 | + "github.com/matrix-org/gomatrix" |
9 | 12 | "github.com/matrix-org/gomatrixserverlib" |
10 | 13 |
|
11 | 14 | "github.com/tidwall/sjson" |
@@ -192,3 +195,70 @@ func TestJoinFederatedRoomWithUnverifiableEvents(t *testing.T) { |
192 | 195 | alice.JoinRoom(t, roomAlias, nil) |
193 | 196 | }) |
194 | 197 | } |
| 198 | + |
| 199 | +// This test checks that users cannot circumvent the auth checks via send_join. |
| 200 | +func TestBannedUserCannotSendJoin(t *testing.T) { |
| 201 | + deployment := Deploy(t, b.BlueprintAlice) |
| 202 | + defer deployment.Destroy(t) |
| 203 | + |
| 204 | + srv := federation.NewServer(t, deployment, |
| 205 | + federation.HandleKeyRequests(), |
| 206 | + federation.HandleTransactionRequests(nil, nil), |
| 207 | + ) |
| 208 | + cancel := srv.Listen() |
| 209 | + defer cancel() |
| 210 | + |
| 211 | + fedClient := srv.FederationClient(deployment) |
| 212 | + |
| 213 | + charlie := srv.UserID("charlie") |
| 214 | + |
| 215 | + // alice creates a room, and bans charlie from it. |
| 216 | + alice := deployment.Client(t, "hs1", "@alice:hs1") |
| 217 | + roomID := alice.CreateRoom(t, map[string]interface{}{}) |
| 218 | + |
| 219 | + alice.SendEventSynced(t, roomID, b.Event{ |
| 220 | + Type: "m.room.member", |
| 221 | + Sender: alice.UserID, |
| 222 | + StateKey: &charlie, |
| 223 | + Content: map[string]interface{}{ |
| 224 | + "membership": "ban", |
| 225 | + }, |
| 226 | + }) |
| 227 | + |
| 228 | + // charlie sends a make_join for a different user |
| 229 | + makeJoinResp, err := fedClient.MakeJoin(context.Background(), "hs1", roomID, srv.UserID("charlie2"), federation.SupportedRoomVersions()) |
| 230 | + must.NotError(t, "MakeJoin", err) |
| 231 | + |
| 232 | + // ... and does a switcheroo to turn it into a join for himself |
| 233 | + makeJoinResp.JoinEvent.Sender = charlie |
| 234 | + makeJoinResp.JoinEvent.StateKey = &charlie |
| 235 | + joinEvent, err := makeJoinResp.JoinEvent.Build(time.Now(), gomatrixserverlib.ServerName(srv.ServerName), srv.KeyID, srv.Priv, makeJoinResp.RoomVersion) |
| 236 | + must.NotError(t, "JoinEvent.Build", err) |
| 237 | + |
| 238 | + // SendJoin should return a 403. |
| 239 | + _, err = fedClient.SendJoin(context.Background(), "hs1", joinEvent, makeJoinResp.RoomVersion) |
| 240 | + if err == nil { |
| 241 | + t.Errorf("SendJoin returned 200") |
| 242 | + } else if httpError, ok := err.(gomatrix.HTTPError); ok { |
| 243 | + t.Logf("SendJoin => %d/%s", httpError.Code, string(httpError.Contents)) |
| 244 | + if httpError.Code != 403 { |
| 245 | + t.Errorf("expected 403, got %d", httpError.Code) |
| 246 | + } |
| 247 | + errcode := must.GetJSONFieldStr(t, httpError.Contents, "errcode") |
| 248 | + if errcode != "M_FORBIDDEN" { |
| 249 | + t.Errorf("errcode: got %s, want M_FORBIDDEN", errcode) |
| 250 | + } |
| 251 | + } else { |
| 252 | + t.Errorf("SendJoin: non-HTTPError: %v", err) |
| 253 | + } |
| 254 | + |
| 255 | + // Alice checks the room state to check that charlie isn't a member |
| 256 | + res := alice.MustDoFunc( |
| 257 | + t, |
| 258 | + "GET", |
| 259 | + []string{"_matrix", "client", "r0", "rooms", roomID, "state", "m.room.member", charlie}, |
| 260 | + ) |
| 261 | + stateResp := client.ParseJSON(t, res) |
| 262 | + membership := must.GetJSONFieldStr(t, stateResp, "membership") |
| 263 | + must.EqualStr(t, membership, "ban", "membership of charlie") |
| 264 | +} |
0 commit comments