Refactor createRoom to remove duplicate code

This commit is contained in:
Devon Hudson 2024-01-03 17:26:19 -07:00
parent cbd547c828
commit 59753aba98
No known key found for this signature in database
GPG key ID: CD06B18E77F6A628
4 changed files with 44 additions and 159 deletions

View file

@ -108,12 +108,27 @@ type createRoomResponse struct {
RoomAlias string `json:"room_alias,omitempty"` // in synapse not spec RoomAlias string `json:"room_alias,omitempty"` // in synapse not spec
} }
// CreateRoomCryptoIDs implements /createRoom type createRoomCryptoIDsResponse struct {
func CreateRoomCryptoIDs( RoomID string `json:"room_id"`
Version string `json:"room_version"`
PDUs []json.RawMessage `json:"pdus"`
}
func ToProtoEvents(ctx context.Context, events []gomatrixserverlib.PDU, rsAPI roomserverAPI.ClientRoomserverAPI) []json.RawMessage {
result := make([]json.RawMessage, len(events))
for i, event := range events {
result[i] = json.RawMessage(event.JSON())
}
return result
}
// CreateRoom implements /createRoom
func CreateRoom(
req *http.Request, device *api.Device, req *http.Request, device *api.Device,
cfg *config.ClientAPI, cfg *config.ClientAPI,
profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI, profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI,
asAPI appserviceAPI.AppServiceInternalAPI, asAPI appserviceAPI.AppServiceInternalAPI,
cryptoIDs bool,
) util.JSONResponse { ) util.JSONResponse {
var createRequest createRoomRequest var createRequest createRoomRequest
resErr := httputil.UnmarshalJSONRequest(req, &createRequest) resErr := httputil.UnmarshalJSONRequest(req, &createRequest)
@ -130,17 +145,17 @@ func CreateRoomCryptoIDs(
JSON: spec.InvalidParam(err.Error()), JSON: spec.InvalidParam(err.Error()),
} }
} }
return createRoom(req.Context(), createRequest, device, cfg, profileAPI, rsAPI, asAPI, evTime, cryptoIDs)
return makeCreateRoomEvents(req.Context(), createRequest, device, cfg, profileAPI, rsAPI, asAPI, evTime)
} }
func makeCreateRoomEvents( func createRoom(
ctx context.Context, ctx context.Context,
createRequest createRoomRequest, device *api.Device, createRequest createRoomRequest, device *api.Device,
cfg *config.ClientAPI, cfg *config.ClientAPI,
profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI, profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI,
asAPI appserviceAPI.AppServiceInternalAPI, asAPI appserviceAPI.AppServiceInternalAPI,
evTime time.Time, evTime time.Time,
cryptoIDs bool,
) util.JSONResponse { ) util.JSONResponse {
userID, err := spec.NewUserID(device.UserID, true) userID, err := spec.NewUserID(device.UserID, true)
if err != nil { if err != nil {
@ -224,10 +239,25 @@ func makeCreateRoomEvents(
KeyID: keyID, KeyID: keyID,
PrivateKey: privateKey, PrivateKey: privateKey,
EventTime: evTime, EventTime: evTime,
SenderID: createRequest.CryptoID,
} }
if !cryptoIDs {
roomAlias, createRes := rsAPI.PerformCreateRoom(ctx, *userID, *roomID, &req)
if createRes != nil {
return *createRes
}
response := createRoomResponse{
RoomID: roomID.String(),
RoomAlias: roomAlias,
}
return util.JSONResponse{
Code: 200,
JSON: response,
}
} else {
req.SenderID = createRequest.CryptoID
createEvents, err := rsAPI.PerformCreateRoomCryptoIDs(ctx, *userID, *roomID, &req) createEvents, err := rsAPI.PerformCreateRoomCryptoIDs(ctx, *userID, *roomID, &req)
if err != nil { if err != nil {
util.GetLogger(ctx).WithError(err).Error("MakeCreateRoomEvents failed") util.GetLogger(ctx).WithError(err).Error("MakeCreateRoomEvents failed")
@ -249,149 +279,4 @@ func makeCreateRoomEvents(
} }
} }
type createRoomCryptoIDsResponse struct {
RoomID string `json:"room_id"`
Version string `json:"room_version"`
PDUs []json.RawMessage `json:"pdus"`
}
func ToProtoEvents(ctx context.Context, events []gomatrixserverlib.PDU, rsAPI roomserverAPI.ClientRoomserverAPI) []json.RawMessage {
result := make([]json.RawMessage, len(events))
for i, event := range events {
result[i] = json.RawMessage(event.JSON())
}
return result
}
// CreateRoom implements /createRoom
func CreateRoom(
req *http.Request, device *api.Device,
cfg *config.ClientAPI,
profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI,
asAPI appserviceAPI.AppServiceInternalAPI,
) util.JSONResponse {
var createRequest createRoomRequest
resErr := httputil.UnmarshalJSONRequest(req, &createRequest)
if resErr != nil {
return *resErr
}
if resErr = createRequest.Validate(); resErr != nil {
return *resErr
}
evTime, err := httputil.ParseTSParam(req)
if err != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.InvalidParam(err.Error()),
}
}
return createRoom(req.Context(), createRequest, device, cfg, profileAPI, rsAPI, asAPI, evTime)
}
func createRoom(
ctx context.Context,
createRequest createRoomRequest, device *api.Device,
cfg *config.ClientAPI,
profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI,
asAPI appserviceAPI.AppServiceInternalAPI,
evTime time.Time,
) util.JSONResponse {
userID, err := spec.NewUserID(device.UserID, true)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("invalid userID")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
if !cfg.Matrix.IsLocalServerName(userID.Domain()) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: spec.Forbidden(fmt.Sprintf("User domain %q not configured locally", userID.Domain())),
}
}
logger := util.GetLogger(ctx)
// TODO: Check room ID doesn't clash with an existing one, and we
// probably shouldn't be using pseudo-random strings, maybe GUIDs?
roomID, err := spec.NewRoomID(fmt.Sprintf("!%s:%s", util.RandomString(16), userID.Domain()))
if err != nil {
util.GetLogger(ctx).WithError(err).Error("invalid roomID")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
// Clobber keys: creator, room_version
roomVersion := rsAPI.DefaultRoomVersion()
if createRequest.RoomVersion != "" {
candidateVersion := gomatrixserverlib.RoomVersion(createRequest.RoomVersion)
_, roomVersionError := roomserverVersion.SupportedRoomVersion(candidateVersion)
if roomVersionError != nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.UnsupportedRoomVersion(roomVersionError.Error()),
}
}
roomVersion = candidateVersion
}
logger.WithFields(log.Fields{
"userID": userID.String(),
"roomID": roomID.String(),
"roomVersion": roomVersion,
}).Info("Creating new room")
profile, err := appserviceAPI.RetrieveUserProfile(ctx, userID.String(), asAPI, profileAPI)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("appserviceAPI.RetrieveUserProfile failed")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
userDisplayName := profile.DisplayName
userAvatarURL := profile.AvatarURL
keyID := cfg.Matrix.KeyID
privateKey := cfg.Matrix.PrivateKey
req := roomserverAPI.PerformCreateRoomRequest{
InvitedUsers: createRequest.Invite,
RoomName: createRequest.Name,
Visibility: createRequest.Visibility,
Topic: createRequest.Topic,
StatePreset: createRequest.Preset,
CreationContent: createRequest.CreationContent,
InitialState: createRequest.InitialState,
RoomAliasName: createRequest.RoomAliasName,
RoomVersion: roomVersion,
PowerLevelContentOverride: createRequest.PowerLevelContentOverride,
IsDirect: createRequest.IsDirect,
UserDisplayName: userDisplayName,
UserAvatarURL: userAvatarURL,
KeyID: keyID,
PrivateKey: privateKey,
EventTime: evTime,
}
roomAlias, createRes := rsAPI.PerformCreateRoom(ctx, *userID, *roomID, &req)
if createRes != nil {
return *createRes
}
response := createRoomResponse{
RoomID: roomID.String(),
RoomAlias: roomAlias,
}
return util.JSONResponse{
Code: 200,
JSON: response,
}
} }

View file

@ -67,7 +67,7 @@ func TestJoinRoomByIDOrAlias(t *testing.T) {
Preset: spec.PresetPublicChat, Preset: spec.PresetPublicChat,
RoomAliasName: "alias", RoomAliasName: "alias",
Invite: []string{bob.ID}, Invite: []string{bob.ID},
}, aliceDev, &cfg.ClientAPI, userAPI, rsAPI, asAPI, time.Now()) }, aliceDev, &cfg.ClientAPI, userAPI, rsAPI, asAPI, time.Now(), false)
crResp, ok := resp.JSON.(createRoomResponse) crResp, ok := resp.JSON.(createRoomResponse)
if !ok { if !ok {
t.Fatalf("response is not a createRoomResponse: %+v", resp) t.Fatalf("response is not a createRoomResponse: %+v", resp)
@ -81,7 +81,7 @@ func TestJoinRoomByIDOrAlias(t *testing.T) {
Visibility: "public", Visibility: "public",
Preset: spec.PresetPublicChat, Preset: spec.PresetPublicChat,
Invite: []string{charlie.ID}, Invite: []string{charlie.ID},
}, aliceDev, &cfg.ClientAPI, userAPI, rsAPI, asAPI, time.Now()) }, aliceDev, &cfg.ClientAPI, userAPI, rsAPI, asAPI, time.Now(), false)
crRespWithGuestAccess, ok := resp.JSON.(createRoomResponse) crRespWithGuestAccess, ok := resp.JSON.(createRoomResponse)
if !ok { if !ok {
t.Fatalf("response is not a createRoomResponse: %+v", resp) t.Fatalf("response is not a createRoomResponse: %+v", resp)

View file

@ -309,13 +309,13 @@ func Setup(
v3mux.Handle("/createRoom", v3mux.Handle("/createRoom",
httputil.MakeAuthAPI("createRoom", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { httputil.MakeAuthAPI("createRoom", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
return CreateRoom(req, device, cfg, userAPI, rsAPI, asAPI) return CreateRoom(req, device, cfg, userAPI, rsAPI, asAPI, false)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
unstableMux.Handle("/org.matrix.msc4080/createRoom", unstableMux.Handle("/org.matrix.msc4080/createRoom",
httputil.MakeAuthAPI("createRoom", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse { httputil.MakeAuthAPI("createRoom", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
logrus.Info("Processing request to /org.matrix.msc4080/createRoom") logrus.Info("Processing request to /org.matrix.msc4080/createRoom")
return CreateRoomCryptoIDs(req, device, cfg, userAPI, rsAPI, asAPI) return CreateRoom(req, device, cfg, userAPI, rsAPI, asAPI, true)
}), }),
).Methods(http.MethodPost, http.MethodOptions) ).Methods(http.MethodPost, http.MethodOptions)
unstableMux.Handle("/org.matrix.msc4080/send_pdus/{txnID}", unstableMux.Handle("/org.matrix.msc4080/send_pdus/{txnID}",

View file

@ -169,7 +169,7 @@ func SendServerNotice(
PowerLevelContentOverride: pl, PowerLevelContentOverride: pl,
} }
roomRes := createRoom(ctx, crReq, senderDevice, cfgClient, userAPI, rsAPI, asAPI, time.Now()) roomRes := createRoom(ctx, crReq, senderDevice, cfgClient, userAPI, rsAPI, asAPI, time.Now(), false)
switch data := roomRes.JSON.(type) { switch data := roomRes.JSON.(type) {
case createRoomResponse: case createRoomResponse: