Add pseudoID compatibility to Invites (#3126)

This commit is contained in:
devonh 2023-07-06 15:15:24 +00:00 committed by GitHub
parent fea946d914
commit d507c5fc95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 358 additions and 136 deletions

View file

@ -16,6 +16,7 @@ package routing
import (
"context"
"crypto/ed25519"
"encoding/json"
"fmt"
"net/http"
@ -29,6 +30,73 @@ import (
"github.com/matrix-org/util"
)
// InviteV3 implements /_matrix/federation/v2/invite/{roomID}/{userID}
func InviteV3(
httpReq *http.Request,
request *fclient.FederationRequest,
roomID spec.RoomID,
invitedUser spec.UserID,
cfg *config.FederationAPI,
rsAPI api.FederationRoomserverAPI,
keys gomatrixserverlib.JSONVerifier,
) util.JSONResponse {
inviteReq := fclient.InviteV3Request{}
err := json.Unmarshal(request.Content(), &inviteReq)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.BadJSON(err.Error()),
}
}
if !cfg.Matrix.IsLocalServerName(invitedUser.Domain()) {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.InvalidParam("The invited user domain does not belong to this server"),
}
}
input := gomatrixserverlib.HandleInviteV3Input{
HandleInviteInput: gomatrixserverlib.HandleInviteInput{
RoomVersion: inviteReq.RoomVersion(),
RoomID: roomID,
InvitedUser: invitedUser,
KeyID: cfg.Matrix.KeyID,
PrivateKey: cfg.Matrix.PrivateKey,
Verifier: keys,
RoomQuerier: rsAPI,
MembershipQuerier: &api.MembershipQuerier{Roomserver: rsAPI},
StateQuerier: rsAPI.StateQuerier(),
InviteEvent: nil,
StrippedState: inviteReq.InviteRoomState(),
UserIDQuerier: func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
return rsAPI.QueryUserIDForSender(httpReq.Context(), roomID, senderID)
},
},
InviteProtoEvent: inviteReq.Event(),
GetOrCreateSenderID: func(ctx context.Context, userID spec.UserID, roomID spec.RoomID, roomVersion string) (spec.SenderID, ed25519.PrivateKey, error) {
// assign a roomNID, otherwise we can't create a private key for the user
_, nidErr := rsAPI.AssignRoomNID(ctx, roomID, gomatrixserverlib.RoomVersion(roomVersion))
if nidErr != nil {
return "", nil, nidErr
}
key, keyErr := rsAPI.GetOrCreateUserRoomPrivateKey(ctx, userID, roomID)
if keyErr != nil {
return "", nil, keyErr
}
return spec.SenderIDFromPseudoIDKey(key), key, nil
},
}
event, jsonErr := handleInviteV3(httpReq.Context(), input, rsAPI)
if jsonErr != nil {
return *jsonErr
}
return util.JSONResponse{
Code: http.StatusOK,
JSON: fclient.RespInviteV2{Event: event.JSON()},
}
}
// InviteV2 implements /_matrix/federation/v2/invite/{roomID}/{eventID}
func InviteV2(
httpReq *http.Request,
@ -204,6 +272,15 @@ func InviteV1(
func handleInvite(ctx context.Context, input gomatrixserverlib.HandleInviteInput, rsAPI api.FederationRoomserverAPI) (gomatrixserverlib.PDU, *util.JSONResponse) {
inviteEvent, err := gomatrixserverlib.HandleInvite(ctx, input)
return handleInviteResult(ctx, inviteEvent, err, rsAPI)
}
func handleInviteV3(ctx context.Context, input gomatrixserverlib.HandleInviteV3Input, rsAPI api.FederationRoomserverAPI) (gomatrixserverlib.PDU, *util.JSONResponse) {
inviteEvent, err := gomatrixserverlib.HandleInviteV3(ctx, input)
return handleInviteResult(ctx, inviteEvent, err, rsAPI)
}
func handleInviteResult(ctx context.Context, inviteEvent gomatrixserverlib.PDU, err error, rsAPI api.FederationRoomserverAPI) (gomatrixserverlib.PDU, *util.JSONResponse) {
switch e := err.(type) {
case nil:
case spec.InternalServerError:
@ -245,4 +322,5 @@ func handleInvite(ctx context.Context, input gomatrixserverlib.HandleInviteInput
}
}
return inviteEvent, nil
}

View file

@ -187,9 +187,6 @@ func MakeJoin(
}
// SendJoin implements the /send_join API
// The make-join send-join dance makes much more sense as a single
// flow so the cyclomatic complexity is high:
// nolint:gocyclo
func SendJoin(
httpReq *http.Request,
request *fclient.FederationRequest,

View file

@ -78,6 +78,7 @@ func Setup(
v2keysmux := keyMux.PathPrefix("/v2").Subrouter()
v1fedmux := fedMux.PathPrefix("/v1").Subrouter()
v2fedmux := fedMux.PathPrefix("/v2").Subrouter()
v3fedmux := fedMux.PathPrefix("/v3").Subrouter()
wakeup := &FederationWakeups{
FsAPI: fsAPI,
@ -191,6 +192,37 @@ func Setup(
},
)).Methods(http.MethodPut, http.MethodOptions)
v3fedmux.Handle("/invite/{roomID}/{userID}", MakeFedAPI(
"federation_invite", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
func(httpReq *http.Request, request *fclient.FederationRequest, vars map[string]string) util.JSONResponse {
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: spec.Forbidden("Forbidden by server ACLs"),
}
}
userID, err := spec.NewUserID(vars["userID"], true)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.InvalidParam("Invalid UserID"),
}
}
roomID, err := spec.NewRoomID(vars["roomID"])
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.InvalidParam("Invalid RoomID"),
}
}
return InviteV3(
httpReq, request, *roomID, *userID,
cfg, rsAPI, keys,
)
},
)).Methods(http.MethodPut, http.MethodOptions)
v1fedmux.Handle("/3pid/onbind", httputil.MakeExternalAPI("3pid_onbind",
func(req *http.Request) util.JSONResponse {
return CreateInvitesFrom3PIDInvites(req, rsAPI, cfg, federation, userAPI)