Remove PerformError from PerformInvite

This commit is contained in:
Till Faelligen 2023-04-24 15:31:58 +02:00
parent ba0ebb115d
commit e3f1456517
No known key found for this signature in database
GPG key ID: ACCDC9606D472758
7 changed files with 87 additions and 55 deletions

View file

@ -22,6 +22,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/getsentry/sentry-go"
appserviceAPI "github.com/matrix-org/dendrite/appservice/api" appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
roomserverVersion "github.com/matrix-org/dendrite/roomserver/version" roomserverVersion "github.com/matrix-org/dendrite/roomserver/version"
@ -556,23 +557,33 @@ func createRoom(
fclient.NewInviteV2StrippedState(inviteEvent.Event), fclient.NewInviteV2StrippedState(inviteEvent.Event),
) )
// Send the invite event to the roomserver. // Send the invite event to the roomserver.
var inviteRes roomserverAPI.PerformInviteResponse
event := inviteEvent.Headered(roomVersion) event := inviteEvent.Headered(roomVersion)
if err := rsAPI.PerformInvite(ctx, &roomserverAPI.PerformInviteRequest{ err = rsAPI.PerformInvite(ctx, &roomserverAPI.PerformInviteRequest{
Event: event, Event: event,
InviteRoomState: inviteStrippedState, InviteRoomState: inviteStrippedState,
RoomVersion: event.RoomVersion, RoomVersion: event.RoomVersion,
SendAsServer: string(userDomain), SendAsServer: string(userDomain),
}, &inviteRes); err != nil { })
switch e := err.(type) {
case roomserverAPI.ErrInvalidID:
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.Unknown(e.Error()),
}
case roomserverAPI.ErrNotAllowed:
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden(e.Error()),
}
case nil:
default:
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed") util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
sentry.CaptureException(err)
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusInternalServerError, Code: http.StatusInternalServerError,
JSON: jsonerror.InternalServerError(), JSON: jsonerror.InternalServerError(),
} }
} }
if inviteRes.Error != nil {
return inviteRes.Error.JSONResponse()
}
} }
} }

View file

@ -20,6 +20,7 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/getsentry/sentry-go"
"github.com/matrix-org/gomatrixserverlib" "github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/spec" "github.com/matrix-org/gomatrixserverlib/spec"
@ -264,22 +265,33 @@ func sendInvite(
return jsonerror.InternalServerError(), err return jsonerror.InternalServerError(), err
} }
var inviteRes api.PerformInviteResponse err = rsAPI.PerformInvite(ctx, &api.PerformInviteRequest{
if err := rsAPI.PerformInvite(ctx, &api.PerformInviteRequest{
Event: event, Event: event,
InviteRoomState: nil, // ask the roomserver to draw up invite room state for us InviteRoomState: nil, // ask the roomserver to draw up invite room state for us
RoomVersion: event.RoomVersion, RoomVersion: event.RoomVersion,
SendAsServer: string(device.UserDomain()), SendAsServer: string(device.UserDomain()),
}, &inviteRes); err != nil { })
switch e := err.(type) {
case roomserverAPI.ErrInvalidID:
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.Unknown(e.Error()),
}, e
case roomserverAPI.ErrNotAllowed:
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden(e.Error()),
}, e
case nil:
default:
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed") util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
sentry.CaptureException(err)
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusInternalServerError, Code: http.StatusInternalServerError,
JSON: jsonerror.InternalServerError(), JSON: jsonerror.InternalServerError(),
}, err }, err
} }
if inviteRes.Error != nil {
return inviteRes.Error.JSONResponse(), inviteRes.Error
}
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusOK, Code: http.StatusOK,

View file

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/getsentry/sentry-go"
"github.com/matrix-org/dendrite/clientapi/jsonerror" "github.com/matrix-org/dendrite/clientapi/jsonerror"
"github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/setup/config" "github.com/matrix-org/dendrite/setup/config"
@ -204,17 +205,36 @@ func processInvite(
SendAsServer: string(api.DoNotSendToOtherServers), SendAsServer: string(api.DoNotSendToOtherServers),
TransactionID: nil, TransactionID: nil,
} }
response := &api.PerformInviteResponse{}
if err := rsAPI.PerformInvite(ctx, request, response); err != nil { if err := rsAPI.PerformInvite(ctx, request); err != nil {
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed") util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
return util.JSONResponse{ return util.JSONResponse{
Code: http.StatusInternalServerError, Code: http.StatusInternalServerError,
JSON: jsonerror.InternalServerError(), JSON: jsonerror.InternalServerError(),
} }
} }
if response.Error != nil {
return response.Error.JSONResponse() switch e := err.(type) {
case api.ErrInvalidID:
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: jsonerror.Unknown(e.Error()),
}
case api.ErrNotAllowed:
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: jsonerror.Forbidden(e.Error()),
}
case nil:
default:
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
sentry.CaptureException(err)
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: jsonerror.InternalServerError(),
}
} }
// Return the signed event to the originating server, it should then tell // Return the signed event to the originating server, it should then tell
// the other servers in the room that we have been invited. // the other servers in the room that we have been invited.
if isInviteV2 { if isInviteV2 {

View file

@ -11,6 +11,25 @@ import (
userapi "github.com/matrix-org/dendrite/userapi/api" userapi "github.com/matrix-org/dendrite/userapi/api"
) )
// ErrInvalidID is an error returned if the userID is invalid
type ErrInvalidID struct {
Err error
}
func (e ErrInvalidID) Error() string {
return e.Err.Error()
}
// ErrNotAllowed is an error returned if the user is not allowed
// to execute some action (e.g. invite)
type ErrNotAllowed struct {
Err error
}
func (e ErrNotAllowed) Error() string {
return e.Err.Error()
}
// RoomserverInputAPI is used to write events to the room server. // RoomserverInputAPI is used to write events to the room server.
type RoomserverInternalAPI interface { type RoomserverInternalAPI interface {
SyncRoomserverAPI SyncRoomserverAPI
@ -157,7 +176,7 @@ type ClientRoomserverAPI interface {
PerformAdminDownloadState(ctx context.Context, roomID, userID string, serverName spec.ServerName) error PerformAdminDownloadState(ctx context.Context, roomID, userID string, serverName spec.ServerName) error
PerformPeek(ctx context.Context, req *PerformPeekRequest, res *PerformPeekResponse) error PerformPeek(ctx context.Context, req *PerformPeekRequest, res *PerformPeekResponse) error
PerformUnpeek(ctx context.Context, req *PerformUnpeekRequest, res *PerformUnpeekResponse) error PerformUnpeek(ctx context.Context, req *PerformUnpeekRequest, res *PerformUnpeekResponse) error
PerformInvite(ctx context.Context, req *PerformInviteRequest, res *PerformInviteResponse) error PerformInvite(ctx context.Context, req *PerformInviteRequest) error
PerformJoin(ctx context.Context, req *PerformJoinRequest, res *PerformJoinResponse) error PerformJoin(ctx context.Context, req *PerformJoinRequest, res *PerformJoinResponse) error
PerformLeave(ctx context.Context, req *PerformLeaveRequest, res *PerformLeaveResponse) error PerformLeave(ctx context.Context, req *PerformLeaveRequest, res *PerformLeaveResponse) error
PerformPublish(ctx context.Context, req *PerformPublishRequest, res *PerformPublishResponse) error PerformPublish(ctx context.Context, req *PerformPublishRequest, res *PerformPublishResponse) error
@ -202,7 +221,7 @@ type FederationRoomserverAPI interface {
QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error
QueryRestrictedJoinAllowed(ctx context.Context, req *QueryRestrictedJoinAllowedRequest, res *QueryRestrictedJoinAllowedResponse) error QueryRestrictedJoinAllowed(ctx context.Context, req *QueryRestrictedJoinAllowedRequest, res *QueryRestrictedJoinAllowedResponse) error
PerformInboundPeek(ctx context.Context, req *PerformInboundPeekRequest, res *PerformInboundPeekResponse) error PerformInboundPeek(ctx context.Context, req *PerformInboundPeekRequest, res *PerformInboundPeekResponse) error
PerformInvite(ctx context.Context, req *PerformInviteRequest, res *PerformInviteResponse) error PerformInvite(ctx context.Context, req *PerformInviteRequest) error
// Query a given amount (or less) of events prior to a given set of events. // Query a given amount (or less) of events prior to a given set of events.
PerformBackfill(ctx context.Context, req *PerformBackfillRequest, res *PerformBackfillResponse) error PerformBackfill(ctx context.Context, req *PerformBackfillRequest, res *PerformBackfillResponse) error
} }

View file

@ -112,10 +112,6 @@ type PerformInviteRequest struct {
TransactionID *TransactionID `json:"transaction_id"` TransactionID *TransactionID `json:"transaction_id"`
} }
type PerformInviteResponse struct {
Error *PerformError
}
type PerformPeekRequest struct { type PerformPeekRequest 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"`

View file

@ -209,11 +209,9 @@ func (r *RoomserverInternalAPI) SetAppserviceAPI(asAPI asAPI.AppServiceInternalA
func (r *RoomserverInternalAPI) PerformInvite( func (r *RoomserverInternalAPI) PerformInvite(
ctx context.Context, ctx context.Context,
req *api.PerformInviteRequest, req *api.PerformInviteRequest,
res *api.PerformInviteResponse,
) error { ) error {
outputEvents, err := r.Inviter.PerformInvite(ctx, req, res) outputEvents, err := r.Inviter.PerformInvite(ctx, req)
if err != nil { if err != nil {
sentry.CaptureException(err)
return err return err
} }
if len(outputEvents) == 0 { if len(outputEvents) == 0 {

View file

@ -45,7 +45,6 @@ type Inviter struct {
func (r *Inviter) PerformInvite( func (r *Inviter) PerformInvite(
ctx context.Context, ctx context.Context,
req *api.PerformInviteRequest, req *api.PerformInviteRequest,
res *api.PerformInviteResponse,
) ([]api.OutputEvent, error) { ) ([]api.OutputEvent, error) {
var outputUpdates []api.OutputEvent var outputUpdates []api.OutputEvent
event := req.Event event := req.Event
@ -66,20 +65,12 @@ func (r *Inviter) PerformInvite(
_, domain, err := gomatrixserverlib.SplitID('@', targetUserID) _, domain, err := gomatrixserverlib.SplitID('@', targetUserID)
if err != nil { if err != nil {
res.Error = &api.PerformError{ return nil, api.ErrInvalidID{Err: fmt.Errorf("the user ID %s is invalid", targetUserID)}
Code: api.PerformErrorBadRequest,
Msg: fmt.Sprintf("The user ID %q is invalid!", targetUserID),
}
return nil, nil
} }
isTargetLocal := r.Cfg.Matrix.IsLocalServerName(domain) isTargetLocal := r.Cfg.Matrix.IsLocalServerName(domain)
isOriginLocal := r.Cfg.Matrix.IsLocalServerName(senderDomain) isOriginLocal := r.Cfg.Matrix.IsLocalServerName(senderDomain)
if !isOriginLocal && !isTargetLocal { if !isOriginLocal && !isTargetLocal {
res.Error = &api.PerformError{ return nil, api.ErrInvalidID{Err: fmt.Errorf("the invite must be either from or to a local user")}
Code: api.PerformErrorBadRequest,
Msg: "The invite must be either from or to a local user",
}
return nil, nil
} }
logger := util.GetLogger(ctx).WithFields(map[string]interface{}{ logger := util.GetLogger(ctx).WithFields(map[string]interface{}{
@ -175,12 +166,8 @@ func (r *Inviter) PerformInvite(
// For now we will implement option 2. Since in the abesence of a retry // For now we will implement option 2. Since in the abesence of a retry
// mechanism it will be equivalent to option 1, and we don't have a // mechanism it will be equivalent to option 1, and we don't have a
// signalling mechanism to implement option 3. // signalling mechanism to implement option 3.
res.Error = &api.PerformError{
Code: api.PerformErrorNotAllowed,
Msg: "User is already joined to room",
}
logger.Debugf("user already joined") logger.Debugf("user already joined")
return nil, nil return nil, api.ErrNotAllowed{Err: fmt.Errorf("user is already joined to room")}
} }
// If the invite originated remotely then we can't send an // If the invite originated remotely then we can't send an
@ -201,11 +188,7 @@ func (r *Inviter) PerformInvite(
logger.WithError(err).WithField("event_id", event.EventID()).WithField("auth_event_ids", event.AuthEventIDs()).Error( logger.WithError(err).WithField("event_id", event.EventID()).WithField("auth_event_ids", event.AuthEventIDs()).Error(
"processInviteEvent.checkAuthEvents failed for event", "processInviteEvent.checkAuthEvents failed for event",
) )
res.Error = &api.PerformError{ return nil, api.ErrNotAllowed{Err: err}
Msg: err.Error(),
Code: api.PerformErrorNotAllowed,
}
return nil, nil
} }
// If the invite originated from us and the target isn't local then we // If the invite originated from us and the target isn't local then we
@ -220,12 +203,8 @@ func (r *Inviter) PerformInvite(
} }
fsRes := &federationAPI.PerformInviteResponse{} fsRes := &federationAPI.PerformInviteResponse{}
if err = r.FSAPI.PerformInvite(ctx, fsReq, fsRes); err != nil { if err = r.FSAPI.PerformInvite(ctx, fsReq, fsRes); err != nil {
res.Error = &api.PerformError{
Msg: err.Error(),
Code: api.PerformErrorNotAllowed,
}
logger.WithError(err).WithField("event_id", event.EventID()).Error("r.FSAPI.PerformInvite failed") logger.WithError(err).WithField("event_id", event.EventID()).Error("r.FSAPI.PerformInvite failed")
return nil, nil return nil, api.ErrNotAllowed{Err: err}
} }
event = fsRes.Event event = fsRes.Event
logger.Debugf("Federated PerformInvite success with event ID %s", event.EventID()) logger.Debugf("Federated PerformInvite success with event ID %s", event.EventID())
@ -251,11 +230,8 @@ func (r *Inviter) PerformInvite(
return nil, fmt.Errorf("r.Inputer.InputRoomEvents: %w", err) return nil, fmt.Errorf("r.Inputer.InputRoomEvents: %w", err)
} }
if err = inputRes.Err(); err != nil { if err = inputRes.Err(); err != nil {
res.Error = &api.PerformError{
Msg: fmt.Sprintf("r.InputRoomEvents: %s", err.Error()),
Code: api.PerformErrorNotAllowed,
}
logger.WithError(err).WithField("event_id", event.EventID()).Error("r.InputRoomEvents failed") logger.WithError(err).WithField("event_id", event.EventID()).Error("r.InputRoomEvents failed")
return nil, api.ErrNotAllowed{Err: err}
} }
// Don't notify the sync api of this event in the same way as a federated invite so the invitee // Don't notify the sync api of this event in the same way as a federated invite so the invitee