2017-04-20 17:40:52 -05:00
|
|
|
// Copyright 2017 Vector Creations Ltd
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2017-10-11 12:16:53 -05:00
|
|
|
package routing
|
2017-03-07 10:11:08 -06:00
|
|
|
|
|
|
|
import (
|
2022-02-18 09:05:03 -06:00
|
|
|
"context"
|
2019-07-24 11:15:36 -05:00
|
|
|
"encoding/json"
|
2017-03-09 05:47:06 -06:00
|
|
|
"fmt"
|
2017-03-07 10:11:08 -06:00
|
|
|
"net/http"
|
2017-03-09 05:47:06 -06:00
|
|
|
"strings"
|
2018-08-06 08:09:25 -05:00
|
|
|
"time"
|
2017-03-07 10:11:08 -06:00
|
|
|
|
2018-08-20 04:45:17 -05:00
|
|
|
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
|
|
|
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
2020-03-17 10:12:01 -05:00
|
|
|
roomserverVersion "github.com/matrix-org/dendrite/roomserver/version"
|
2020-06-16 08:10:55 -05:00
|
|
|
"github.com/matrix-org/dendrite/userapi/api"
|
2023-04-19 09:50:33 -05:00
|
|
|
"github.com/matrix-org/gomatrixserverlib/spec"
|
2017-09-27 10:44:40 -05:00
|
|
|
|
2017-03-10 05:32:53 -06:00
|
|
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
2020-12-02 11:41:00 -06:00
|
|
|
"github.com/matrix-org/dendrite/setup/config"
|
2017-03-10 05:32:53 -06:00
|
|
|
"github.com/matrix-org/gomatrixserverlib"
|
2017-03-07 10:11:08 -06:00
|
|
|
"github.com/matrix-org/util"
|
2017-11-16 04:12:02 -06:00
|
|
|
log "github.com/sirupsen/logrus"
|
2017-03-07 10:11:08 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
// https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-createroom
|
|
|
|
type createRoomRequest struct {
|
2023-05-31 10:27:08 -05:00
|
|
|
Invite []string `json:"invite"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
Visibility string `json:"visibility"`
|
|
|
|
Topic string `json:"topic"`
|
|
|
|
Preset string `json:"preset"`
|
|
|
|
CreationContent json.RawMessage `json:"creation_content"`
|
|
|
|
InitialState []gomatrixserverlib.FledglingEvent `json:"initial_state"`
|
|
|
|
RoomAliasName string `json:"room_alias_name"`
|
|
|
|
RoomVersion gomatrixserverlib.RoomVersion `json:"room_version"`
|
|
|
|
PowerLevelContentOverride json.RawMessage `json:"power_level_content_override"`
|
|
|
|
IsDirect bool `json:"is_direct"`
|
2023-10-04 12:21:23 -05:00
|
|
|
SenderID string `json:"sender_id"`
|
2017-03-07 10:11:08 -06:00
|
|
|
}
|
|
|
|
|
2017-03-09 05:47:06 -06:00
|
|
|
func (r createRoomRequest) Validate() *util.JSONResponse {
|
|
|
|
whitespace := "\t\n\x0b\x0c\r " // https://docs.python.org/2/library/string.html#string.whitespace
|
|
|
|
// https://github.com/matrix-org/synapse/blob/v0.19.2/synapse/handlers/room.py#L81
|
|
|
|
// Synapse doesn't check for ':' but we will else it will break parsers badly which split things into 2 segments.
|
|
|
|
if strings.ContainsAny(r.RoomAliasName, whitespace+":") {
|
|
|
|
return &util.JSONResponse{
|
2018-03-13 10:55:45 -05:00
|
|
|
Code: http.StatusBadRequest,
|
2023-05-09 17:46:49 -05:00
|
|
|
JSON: spec.BadJSON("room_alias_name cannot contain whitespace or ':'"),
|
2017-03-09 05:47:06 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, userID := range r.Invite {
|
2023-05-31 10:27:08 -05:00
|
|
|
if _, err := spec.NewUserID(userID, true); err != nil {
|
2017-03-09 05:47:06 -06:00
|
|
|
return &util.JSONResponse{
|
2018-03-13 10:55:45 -05:00
|
|
|
Code: http.StatusBadRequest,
|
2023-05-09 17:46:49 -05:00
|
|
|
JSON: spec.BadJSON("user id must be in the form @localpart:domain"),
|
2017-03-09 05:47:06 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-01-02 04:32:53 -06:00
|
|
|
switch r.Preset {
|
2023-05-31 10:27:08 -05:00
|
|
|
case spec.PresetPrivateChat, spec.PresetTrustedPrivateChat, spec.PresetPublicChat, "":
|
2018-01-02 04:32:53 -06:00
|
|
|
default:
|
|
|
|
return &util.JSONResponse{
|
2018-03-13 10:55:45 -05:00
|
|
|
Code: http.StatusBadRequest,
|
2023-05-09 17:46:49 -05:00
|
|
|
JSON: spec.BadJSON("preset must be any of 'private_chat', 'trusted_private_chat', 'public_chat'"),
|
2018-01-02 04:32:53 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-24 11:15:36 -05:00
|
|
|
// Validate creation_content fields defined in the spec by marshalling the
|
|
|
|
// creation_content map into bytes and then unmarshalling the bytes into
|
2020-06-12 08:55:57 -05:00
|
|
|
// eventutil.CreateContent.
|
2019-07-24 11:15:36 -05:00
|
|
|
|
|
|
|
creationContentBytes, err := json.Marshal(r.CreationContent)
|
|
|
|
if err != nil {
|
|
|
|
return &util.JSONResponse{
|
|
|
|
Code: http.StatusBadRequest,
|
2023-05-09 17:46:49 -05:00
|
|
|
JSON: spec.BadJSON("malformed creation_content"),
|
2019-07-24 11:15:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-15 12:45:11 -05:00
|
|
|
var CreationContent gomatrixserverlib.CreateContent
|
2019-07-24 11:15:36 -05:00
|
|
|
err = json.Unmarshal(creationContentBytes, &CreationContent)
|
|
|
|
if err != nil {
|
|
|
|
return &util.JSONResponse{
|
|
|
|
Code: http.StatusBadRequest,
|
2023-05-09 17:46:49 -05:00
|
|
|
JSON: spec.BadJSON("malformed creation_content"),
|
2019-07-24 11:15:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-09 05:47:06 -06:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// https://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-client-r0-createroom
|
|
|
|
type createRoomResponse struct {
|
|
|
|
RoomID string `json:"room_id"`
|
|
|
|
RoomAlias string `json:"room_alias,omitempty"` // in synapse not spec
|
|
|
|
}
|
|
|
|
|
2023-10-04 12:21:23 -05:00
|
|
|
// CreateRoomCryptoIDs implements /createRoom
|
|
|
|
func CreateRoomCryptoIDs(
|
|
|
|
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 makeCreateRoomEvents(req.Context(), createRequest, device, cfg, profileAPI, rsAPI, asAPI, evTime)
|
|
|
|
}
|
|
|
|
|
|
|
|
func makeCreateRoomEvents(
|
|
|
|
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,
|
|
|
|
|
|
|
|
SenderID: createRequest.SenderID,
|
|
|
|
}
|
|
|
|
|
|
|
|
createEvents, err := rsAPI.PerformCreateRoomCryptoIDs(ctx, *userID, *roomID, &req)
|
|
|
|
if err != nil {
|
|
|
|
util.GetLogger(ctx).WithError(err).Error("MakeCreateRoomEvents failed")
|
|
|
|
return util.JSONResponse{
|
|
|
|
Code: http.StatusInternalServerError,
|
|
|
|
JSON: spec.InternalServerError{Err: err.Error()},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
response := createRoomCryptoIDsResponse{
|
|
|
|
RoomID: roomID.String(),
|
|
|
|
Version: string(roomVersion),
|
|
|
|
PDUs: ToProtoEvents(ctx, createEvents, rsAPI),
|
|
|
|
}
|
|
|
|
|
|
|
|
return util.JSONResponse{
|
|
|
|
Code: 200,
|
|
|
|
JSON: response,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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())
|
|
|
|
//fmt.Printf("\nProcessing %s event (%s)\n", events[i].Type(), events[i].EventID())
|
|
|
|
//var rawJson interface{}
|
|
|
|
//json.Unmarshal(events[i].JSON(), &rawJson)
|
|
|
|
//fmt.Printf("JSON: %+v\n", rawJson)
|
|
|
|
//result[i] = gomatrixserverlib.ProtoEvent{
|
|
|
|
// SenderID: string(events[i].SenderID()),
|
|
|
|
// RoomID: events[i].RoomID().String(),
|
|
|
|
// Type: events[i].Type(),
|
|
|
|
// StateKey: events[i].StateKey(),
|
|
|
|
// PrevEvents: events[i].PrevEventIDs(),
|
|
|
|
// AuthEvents: events[i].AuthEventIDs(),
|
|
|
|
// Redacts: events[i].Redacts(),
|
|
|
|
// Depth: events[i].Depth(),
|
|
|
|
// Content: events[i].Content(),
|
|
|
|
// Unsigned: events[i].Unsigned(),
|
|
|
|
// Hashes: events[i].Hashes(),
|
|
|
|
// OriginServerTimestamp: events[i].OriginServerTS(),
|
|
|
|
//}
|
|
|
|
|
|
|
|
//roomVersion, _ := rsAPI.QueryRoomVersionForRoom(ctx, events[i].RoomID().String())
|
|
|
|
//verImpl, _ := gomatrixserverlib.GetRoomVersion(roomVersion)
|
|
|
|
//eventJSON, err := json.Marshal(result[i])
|
|
|
|
//if err != nil {
|
|
|
|
// util.GetLogger(ctx).WithError(err).Error("failed marshalling event")
|
|
|
|
// continue
|
|
|
|
//}
|
|
|
|
//pdu, err := verImpl.NewEventFromUntrustedJSON(eventJSON)
|
|
|
|
//if err != nil {
|
|
|
|
// util.GetLogger(ctx).WithError(err).Error("failed making event from json")
|
|
|
|
// continue
|
|
|
|
//}
|
|
|
|
//fmt.Printf("\nProcessing %s event (%s) - PDU\n", result[i].Type, pdu.EventID())
|
|
|
|
//fmt.Printf(" EventID: %v - %v\n", events[i].EventID(), pdu.EventID())
|
|
|
|
//fmt.Printf(" SenderID: %s - %s\n", events[i].SenderID(), pdu.SenderID())
|
|
|
|
//fmt.Printf(" RoomID: %s - %s\n", events[i].RoomID().String(), pdu.RoomID().String())
|
|
|
|
//fmt.Printf(" Type: %s - %s\n", events[i].Type(), pdu.Type())
|
|
|
|
//fmt.Printf(" StateKey: %s - %s\n", *events[i].StateKey(), *pdu.StateKey())
|
|
|
|
//fmt.Printf(" PrevEvents: %v - %v\n", events[i].PrevEventIDs(), pdu.PrevEventIDs())
|
|
|
|
//fmt.Printf(" AuthEvents: %v - %v\n", events[i].AuthEventIDs(), pdu.AuthEventIDs())
|
|
|
|
//fmt.Printf(" Redacts: %s - %s\n", events[i].Redacts(), pdu.Redacts())
|
|
|
|
//fmt.Printf(" Depth: %d - %d\n", events[i].Depth(), pdu.Depth())
|
|
|
|
//fmt.Printf(" Content: %v - %v\n", events[i].Content(), pdu.Content())
|
|
|
|
//fmt.Printf(" Unsigned: %v - %v\n", events[i].Unsigned(), pdu.Unsigned())
|
|
|
|
//fmt.Printf(" Hashes: %v - %v\n", events[i].Hashes(), pdu.Hashes())
|
|
|
|
//fmt.Printf(" OriginServerTS: %d - %d\n", events[i].OriginServerTS(), pdu.OriginServerTS())
|
|
|
|
//json.Unmarshal(eventJSON, &rawJson)
|
|
|
|
//fmt.Printf("JSON: %+v\n", rawJson)
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
2017-03-07 10:11:08 -06:00
|
|
|
// CreateRoom implements /createRoom
|
2018-07-17 10:45:30 -05:00
|
|
|
func CreateRoom(
|
2020-06-16 08:10:55 -05:00
|
|
|
req *http.Request, device *api.Device,
|
2020-08-10 08:18:04 -05:00
|
|
|
cfg *config.ClientAPI,
|
2022-05-05 07:17:38 -05:00
|
|
|
profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI,
|
2022-05-06 06:39:26 -05:00
|
|
|
asAPI appserviceAPI.AppServiceInternalAPI,
|
2017-07-25 10:10:59 -05:00
|
|
|
) util.JSONResponse {
|
2023-05-31 10:27:08 -05:00
|
|
|
var createRequest createRoomRequest
|
|
|
|
resErr := httputil.UnmarshalJSONRequest(req, &createRequest)
|
2017-03-07 10:11:08 -06:00
|
|
|
if resErr != nil {
|
|
|
|
return *resErr
|
|
|
|
}
|
2023-05-31 10:27:08 -05:00
|
|
|
if resErr = createRequest.Validate(); resErr != nil {
|
2017-03-09 05:47:06 -06:00
|
|
|
return *resErr
|
|
|
|
}
|
2018-08-22 07:40:25 -05:00
|
|
|
evTime, err := httputil.ParseTSParam(req)
|
|
|
|
if err != nil {
|
|
|
|
return util.JSONResponse{
|
|
|
|
Code: http.StatusBadRequest,
|
2023-05-09 17:46:49 -05:00
|
|
|
JSON: spec.InvalidParam(err.Error()),
|
2018-08-22 07:40:25 -05:00
|
|
|
}
|
|
|
|
}
|
2023-05-31 10:27:08 -05:00
|
|
|
return createRoom(req.Context(), createRequest, device, cfg, profileAPI, rsAPI, asAPI, evTime)
|
2022-02-18 09:05:03 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func createRoom(
|
|
|
|
ctx context.Context,
|
2023-05-31 10:27:08 -05:00
|
|
|
createRequest createRoomRequest, device *api.Device,
|
2022-02-18 09:05:03 -06:00
|
|
|
cfg *config.ClientAPI,
|
2022-05-05 07:17:38 -05:00
|
|
|
profileAPI api.ClientUserAPI, rsAPI roomserverAPI.ClientRoomserverAPI,
|
2022-05-06 06:39:26 -05:00
|
|
|
asAPI appserviceAPI.AppServiceInternalAPI,
|
2022-02-18 09:05:03 -06:00
|
|
|
evTime time.Time,
|
|
|
|
) util.JSONResponse {
|
2023-05-31 10:27:08 -05:00
|
|
|
userID, err := spec.NewUserID(device.UserID, true)
|
2022-10-26 06:59:19 -05:00
|
|
|
if err != nil {
|
2023-05-31 10:27:08 -05:00
|
|
|
util.GetLogger(ctx).WithError(err).Error("invalid userID")
|
2023-05-16 19:33:27 -05:00
|
|
|
return util.JSONResponse{
|
|
|
|
Code: http.StatusInternalServerError,
|
|
|
|
JSON: spec.InternalServerError{},
|
|
|
|
}
|
2022-10-26 06:59:19 -05:00
|
|
|
}
|
2023-05-31 10:27:08 -05:00
|
|
|
if !cfg.Matrix.IsLocalServerName(userID.Domain()) {
|
2022-10-26 06:59:19 -05:00
|
|
|
return util.JSONResponse{
|
|
|
|
Code: http.StatusForbidden,
|
2023-05-31 10:27:08 -05:00
|
|
|
JSON: spec.Forbidden(fmt.Sprintf("User domain %q not configured locally", userID.Domain())),
|
2022-10-26 06:59:19 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-18 09:05:03 -06:00
|
|
|
logger := util.GetLogger(ctx)
|
2023-05-31 10:27:08 -05:00
|
|
|
|
|
|
|
// 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{},
|
|
|
|
}
|
|
|
|
}
|
2019-07-24 11:15:36 -05:00
|
|
|
|
|
|
|
// Clobber keys: creator, room_version
|
|
|
|
|
2023-08-08 08:20:05 -05:00
|
|
|
roomVersion := rsAPI.DefaultRoomVersion()
|
2023-05-31 10:27:08 -05:00
|
|
|
if createRequest.RoomVersion != "" {
|
|
|
|
candidateVersion := gomatrixserverlib.RoomVersion(createRequest.RoomVersion)
|
2020-03-17 10:12:01 -05:00
|
|
|
_, roomVersionError := roomserverVersion.SupportedRoomVersion(candidateVersion)
|
|
|
|
if roomVersionError != nil {
|
|
|
|
return util.JSONResponse{
|
|
|
|
Code: http.StatusBadRequest,
|
2023-05-09 17:46:49 -05:00
|
|
|
JSON: spec.UnsupportedRoomVersion(roomVersionError.Error()),
|
2020-03-17 10:12:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
roomVersion = candidateVersion
|
|
|
|
}
|
2019-07-24 11:15:36 -05:00
|
|
|
|
2017-03-07 10:11:08 -06:00
|
|
|
logger.WithFields(log.Fields{
|
2023-05-31 10:27:08 -05:00
|
|
|
"userID": userID.String(),
|
|
|
|
"roomID": roomID.String(),
|
2021-07-21 06:31:46 -05:00
|
|
|
"roomVersion": roomVersion,
|
2017-03-10 05:32:53 -06:00
|
|
|
}).Info("Creating new room")
|
|
|
|
|
2023-05-31 10:27:08 -05:00
|
|
|
profile, err := appserviceAPI.RetrieveUserProfile(ctx, userID.String(), asAPI, profileAPI)
|
2017-07-25 10:10:59 -05:00
|
|
|
if err != nil {
|
2022-02-18 09:05:03 -06:00
|
|
|
util.GetLogger(ctx).WithError(err).Error("appserviceAPI.RetrieveUserProfile failed")
|
2023-05-16 19:33:27 -05:00
|
|
|
return util.JSONResponse{
|
|
|
|
Code: http.StatusInternalServerError,
|
|
|
|
JSON: spec.InternalServerError{},
|
|
|
|
}
|
2017-07-25 10:10:59 -05:00
|
|
|
}
|
|
|
|
|
2023-05-31 10:27:08 -05:00
|
|
|
userDisplayName := profile.DisplayName
|
|
|
|
userAvatarURL := profile.AvatarURL
|
2017-09-27 10:44:40 -05:00
|
|
|
|
2023-05-31 10:27:08 -05:00
|
|
|
keyID := cfg.Matrix.KeyID
|
|
|
|
privateKey := cfg.Matrix.PrivateKey
|
2017-09-27 10:44:40 -05:00
|
|
|
|
2023-05-31 10:27:08 -05:00
|
|
|
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,
|
2020-08-17 11:33:19 -05:00
|
|
|
|
2023-05-31 10:27:08 -05:00
|
|
|
UserDisplayName: userDisplayName,
|
|
|
|
UserAvatarURL: userAvatarURL,
|
|
|
|
KeyID: keyID,
|
|
|
|
PrivateKey: privateKey,
|
|
|
|
EventTime: evTime,
|
2020-05-07 10:46:11 -05:00
|
|
|
}
|
2023-06-12 06:19:25 -05:00
|
|
|
|
2023-05-31 10:27:08 -05:00
|
|
|
roomAlias, createRes := rsAPI.PerformCreateRoom(ctx, *userID, *roomID, &req)
|
|
|
|
if createRes != nil {
|
|
|
|
return *createRes
|
2020-07-02 09:41:18 -05:00
|
|
|
}
|
|
|
|
|
2017-07-06 05:44:15 -05:00
|
|
|
response := createRoomResponse{
|
2023-05-31 10:27:08 -05:00
|
|
|
RoomID: roomID.String(),
|
2017-09-27 10:44:40 -05:00
|
|
|
RoomAlias: roomAlias,
|
2017-07-06 05:44:15 -05:00
|
|
|
}
|
|
|
|
|
2017-03-10 05:32:53 -06:00
|
|
|
return util.JSONResponse{
|
|
|
|
Code: 200,
|
2017-07-06 05:44:15 -05:00
|
|
|
JSON: response,
|
2017-03-10 05:32:53 -06:00
|
|
|
}
|
|
|
|
}
|