More useful errors when joining federated rooms

This commit is contained in:
Neil Alexander 2022-06-29 12:11:18 +01:00
parent 2086992caf
commit 24cd9bb0e2
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
2 changed files with 34 additions and 16 deletions

View file

@ -75,10 +75,11 @@ const (
) )
type PerformJoinRequest struct { type PerformJoinRequest struct {
RoomIDOrAlias string `json:"room_id_or_alias"` RoomIDOrAlias string `json:"room_id_or_alias"`
UserID string `json:"user_id"` UserID string `json:"user_id"`
Content map[string]interface{} `json:"content"` Content map[string]interface{} `json:"content"`
ServerNames []gomatrixserverlib.ServerName `json:"server_names"` ServerNames []gomatrixserverlib.ServerName `json:"server_names"`
ForceFederated bool `json:"force_federated"`
} }
type PerformJoinResponse struct { type PerformJoinResponse struct {

View file

@ -53,6 +53,10 @@ func (r *Joiner) PerformJoin(
req *rsAPI.PerformJoinRequest, req *rsAPI.PerformJoinRequest,
res *rsAPI.PerformJoinResponse, res *rsAPI.PerformJoinResponse,
) { ) {
// We'll store whether the user intended to force a federated join
// here, since req.ServerNames will be mutated when we've performed
// a directory lookup, so it's difficult to check later.
req.ForceFederated = len(req.ServerNames) > 0
logger := logrus.WithContext(ctx).WithFields(logrus.Fields{ logger := logrus.WithContext(ctx).WithFields(logrus.Fields{
"room_id": req.RoomIDOrAlias, "room_id": req.RoomIDOrAlias,
"user_id": req.UserID, "user_id": req.UserID,
@ -221,17 +225,27 @@ func (r *Joiner) performJoinRoomByID(
return "", "", fmt.Errorf("eb.SetContent: %w", err) return "", "", fmt.Errorf("eb.SetContent: %w", err)
} }
// Force a federated join if we aren't in the room and we've been // Force a federated join if we aren't in the room or if the
// given some server names to try joining by. // user specifically requested to force a federated join. The
inRoomReq := &rsAPI.QueryServerJoinedToRoomRequest{ // server names by this point may have been populated by a
RoomID: req.RoomIDOrAlias, // directory lookup.
forceFederatedJoin := req.ForceFederated
if !forceFederatedJoin {
inRoomReq := &rsAPI.QueryServerJoinedToRoomRequest{
RoomID: req.RoomIDOrAlias,
}
inRoomRes := &rsAPI.QueryServerJoinedToRoomResponse{}
if err = r.Queryer.QueryServerJoinedToRoom(ctx, inRoomReq, inRoomRes); err != nil {
return "", "", fmt.Errorf("r.Queryer.QueryServerJoinedToRoom: %w", err)
}
forceFederatedJoin = !inRoomRes.IsInRoom
} }
inRoomRes := &rsAPI.QueryServerJoinedToRoomResponse{} if forceFederatedJoin && len(req.ServerNames) == 0 {
if err = r.Queryer.QueryServerJoinedToRoom(ctx, inRoomReq, inRoomRes); err != nil { return "", "", &rsAPI.PerformError{
return "", "", fmt.Errorf("r.Queryer.QueryServerJoinedToRoom: %w", err) Code: rsAPI.PerformErrorBadRequest,
Msg: "Unable to find any servers to complete a federated join to this room",
}
} }
serverInRoom := inRoomRes.IsInRoom
forceFederatedJoin := len(req.ServerNames) > 0 && !serverInRoom
// Force a federated join if we're dealing with a pending invite // Force a federated join if we're dealing with a pending invite
// and we aren't in the room. // and we aren't in the room.
@ -297,7 +311,7 @@ func (r *Joiner) performJoinRoomByID(
if err = inputRes.Err(); err != nil { if err = inputRes.Err(); err != nil {
return "", "", &rsAPI.PerformError{ return "", "", &rsAPI.PerformError{
Code: rsAPI.PerformErrorNotAllowed, Code: rsAPI.PerformErrorNotAllowed,
Msg: fmt.Sprintf("InputRoomEvents auth failed: %s", err), Msg: fmt.Sprintf("Authenticating the room join failed: %s", err),
} }
} }
} }
@ -313,7 +327,7 @@ func (r *Joiner) performJoinRoomByID(
if len(req.ServerNames) == 0 { if len(req.ServerNames) == 0 {
return "", "", &rsAPI.PerformError{ return "", "", &rsAPI.PerformError{
Code: rsAPI.PerformErrorNoRoom, Code: rsAPI.PerformErrorNoRoom,
Msg: fmt.Sprintf("room ID %q does not exist", req.RoomIDOrAlias), Msg: fmt.Sprintf("Room %q does not exist on this server", req.RoomIDOrAlias),
} }
} }
} }
@ -324,7 +338,10 @@ func (r *Joiner) performJoinRoomByID(
default: default:
// Something else went wrong. // Something else went wrong.
return "", "", fmt.Errorf("error joining local room: %q", err) return "", "", &rsAPI.PerformError{
Code: rsAPI.PerformErrorBadRequest,
Msg: fmt.Sprintf("Failed to join the room: %s", err),
}
} }
// By this point, if req.RoomIDOrAlias contained an alias, then // By this point, if req.RoomIDOrAlias contained an alias, then