aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clientapi/routing/createroom.go215
-rw-r--r--go.mod2
-rw-r--r--go.sum4
3 files changed, 159 insertions, 62 deletions
diff --git a/clientapi/routing/createroom.go b/clientapi/routing/createroom.go
index 2d886746..4219bb37 100644
--- a/clientapi/routing/createroom.go
+++ b/clientapi/routing/createroom.go
@@ -43,7 +43,7 @@ type createRoomRequest struct {
Visibility string `json:"visibility"`
Topic string `json:"topic"`
Preset string `json:"preset"`
- CreationContent map[string]interface{} `json:"creation_content"`
+ CreationContent json.RawMessage `json:"creation_content"`
InitialState []fledglingEvent `json:"initial_state"`
RoomAliasName string `json:"room_alias_name"`
GuestCanJoin bool `json:"guest_can_join"`
@@ -177,11 +177,6 @@ func createRoom(
// Clobber keys: creator, room_version
- if r.CreationContent == nil {
- r.CreationContent = make(map[string]interface{}, 2)
- }
-
- r.CreationContent["creator"] = userID
roomVersion := roomserverVersion.DefaultRoomVersion()
if r.RoomVersion != "" {
candidateVersion := gomatrixserverlib.RoomVersion(r.RoomVersion)
@@ -194,7 +189,6 @@ func createRoom(
}
roomVersion = candidateVersion
}
- r.CreationContent["room_version"] = roomVersion
// TODO: visibility/presets/raw initial state
// TODO: Create room alias association
@@ -203,7 +197,7 @@ func createRoom(
logger.WithFields(log.Fields{
"userID": userID,
"roomID": roomID,
- "roomVersion": r.CreationContent["room_version"],
+ "roomVersion": roomVersion,
}).Info("Creating new room")
profile, err := appserviceAPI.RetrieveUserProfile(req.Context(), userID, asAPI, accountDB)
@@ -212,6 +206,109 @@ func createRoom(
return jsonerror.InternalServerError()
}
+ createContent := map[string]interface{}{}
+ if len(r.CreationContent) > 0 {
+ if err = json.Unmarshal(r.CreationContent, &createContent); err != nil {
+ util.GetLogger(req.Context()).WithError(err).Error("json.Unmarshal for creation_content failed")
+ return util.JSONResponse{
+ Code: http.StatusBadRequest,
+ JSON: jsonerror.BadJSON("invalid create content"),
+ }
+ }
+ }
+ createContent["creator"] = userID
+ createContent["room_version"] = roomVersion
+ powerLevelContent := eventutil.InitialPowerLevelsContent(userID)
+ joinRuleContent := gomatrixserverlib.JoinRuleContent{
+ JoinRule: gomatrixserverlib.Invite,
+ }
+ historyVisibilityContent := gomatrixserverlib.HistoryVisibilityContent{
+ HistoryVisibility: historyVisibilityShared,
+ }
+
+ if r.PowerLevelContentOverride != nil {
+ // Merge powerLevelContentOverride fields by unmarshalling it atop the defaults
+ err = json.Unmarshal(r.PowerLevelContentOverride, &powerLevelContent)
+ if err != nil {
+ util.GetLogger(req.Context()).WithError(err).Error("json.Unmarshal for power_level_content_override failed")
+ return util.JSONResponse{
+ Code: http.StatusBadRequest,
+ JSON: jsonerror.BadJSON("malformed power_level_content_override"),
+ }
+ }
+ }
+
+ switch r.Preset {
+ case presetPrivateChat:
+ joinRuleContent.JoinRule = gomatrixserverlib.Invite
+ historyVisibilityContent.HistoryVisibility = historyVisibilityShared
+ case presetTrustedPrivateChat:
+ joinRuleContent.JoinRule = gomatrixserverlib.Invite
+ historyVisibilityContent.HistoryVisibility = historyVisibilityShared
+ // TODO If trusted_private_chat, all invitees are given the same power level as the room creator.
+ case presetPublicChat:
+ joinRuleContent.JoinRule = gomatrixserverlib.Public
+ historyVisibilityContent.HistoryVisibility = historyVisibilityShared
+ }
+
+ createEvent := fledglingEvent{
+ Type: gomatrixserverlib.MRoomCreate,
+ Content: createContent,
+ }
+ powerLevelEvent := fledglingEvent{
+ Type: gomatrixserverlib.MRoomPowerLevels,
+ Content: powerLevelContent,
+ }
+ joinRuleEvent := fledglingEvent{
+ Type: gomatrixserverlib.MRoomJoinRules,
+ Content: joinRuleContent,
+ }
+ historyVisibilityEvent := fledglingEvent{
+ Type: gomatrixserverlib.MRoomHistoryVisibility,
+ Content: historyVisibilityContent,
+ }
+ membershipEvent := fledglingEvent{
+ Type: gomatrixserverlib.MRoomMember,
+ StateKey: userID,
+ Content: gomatrixserverlib.MemberContent{
+ Membership: gomatrixserverlib.Join,
+ DisplayName: profile.DisplayName,
+ AvatarURL: profile.AvatarURL,
+ },
+ }
+
+ var nameEvent *fledglingEvent
+ var topicEvent *fledglingEvent
+ var guestAccessEvent *fledglingEvent
+ var aliasEvent *fledglingEvent
+
+ if r.Name != "" {
+ nameEvent = &fledglingEvent{
+ Type: gomatrixserverlib.MRoomName,
+ Content: eventutil.NameContent{
+ Name: r.Name,
+ },
+ }
+ }
+
+ if r.Topic != "" {
+ topicEvent = &fledglingEvent{
+ Type: gomatrixserverlib.MRoomTopic,
+ Content: eventutil.TopicContent{
+ Topic: r.Topic,
+ },
+ }
+ }
+
+ if r.GuestCanJoin {
+ guestAccessEvent = &fledglingEvent{
+ Type: gomatrixserverlib.MRoomGuestAccess,
+ Content: eventutil.GuestAccessContent{
+ GuestAccess: "can_join",
+ },
+ }
+ }
+
var roomAlias string
if r.RoomAliasName != "" {
roomAlias = fmt.Sprintf("#%s:%s", r.RoomAliasName, cfg.Matrix.ServerName)
@@ -230,44 +327,46 @@ func createRoom(
if aliasResp.RoomID != "" {
return util.MessageResponse(400, "Alias already exists")
}
- }
- membershipContent := gomatrixserverlib.MemberContent{
- Membership: gomatrixserverlib.Join,
- DisplayName: profile.DisplayName,
- AvatarURL: profile.AvatarURL,
+ aliasEvent = &fledglingEvent{
+ Type: gomatrixserverlib.MRoomCanonicalAlias,
+ Content: eventutil.CanonicalAlias{
+ Alias: roomAlias,
+ },
+ }
}
- var joinRules, historyVisibility string
- switch r.Preset {
- case presetPrivateChat:
- joinRules = gomatrixserverlib.Invite
- historyVisibility = historyVisibilityShared
- case presetTrustedPrivateChat:
- joinRules = gomatrixserverlib.Invite
- historyVisibility = historyVisibilityShared
- // TODO If trusted_private_chat, all invitees are given the same power level as the room creator.
- case presetPublicChat:
- joinRules = gomatrixserverlib.Public
- historyVisibility = historyVisibilityShared
- default:
- // Default room rules, r.Preset was previously checked for valid values so
- // only a request with no preset should end up here.
- joinRules = gomatrixserverlib.Invite
- historyVisibility = historyVisibilityShared
- }
+ var initialStateEvents []fledglingEvent
+ for i := range r.InitialState {
+ if r.InitialState[i].StateKey != "" {
+ initialStateEvents = append(initialStateEvents, r.InitialState[i])
+ continue
+ }
- var builtEvents []*gomatrixserverlib.HeaderedEvent
+ switch r.InitialState[i].Type {
+ case gomatrixserverlib.MRoomCreate:
+ continue
- powerLevelContent := eventutil.InitialPowerLevelsContent(userID)
- if r.PowerLevelContentOverride != nil {
- // Merge powerLevelContentOverride fields by unmarshalling it atop the defaults
- err = json.Unmarshal(r.PowerLevelContentOverride, &powerLevelContent)
- if err != nil {
- return util.JSONResponse{
- Code: http.StatusBadRequest,
- JSON: jsonerror.BadJSON("malformed power_level_content_override"),
- }
+ case gomatrixserverlib.MRoomPowerLevels:
+ powerLevelEvent = r.InitialState[i]
+
+ case gomatrixserverlib.MRoomJoinRules:
+ joinRuleEvent = r.InitialState[i]
+
+ case gomatrixserverlib.MRoomHistoryVisibility:
+ historyVisibilityEvent = r.InitialState[i]
+
+ case gomatrixserverlib.MRoomGuestAccess:
+ guestAccessEvent = &r.InitialState[i]
+
+ case gomatrixserverlib.MRoomName:
+ nameEvent = &r.InitialState[i]
+
+ case gomatrixserverlib.MRoomTopic:
+ topicEvent = &r.InitialState[i]
+
+ default:
+ initialStateEvents = append(initialStateEvents, r.InitialState[i])
}
}
@@ -290,31 +389,29 @@ func createRoom(
// harder to reason about, hence sticking to a strict static ordering.
// TODO: Synapse has txn/token ID on each event. Do we need to do this here?
eventsToMake := []fledglingEvent{
- {"m.room.create", "", r.CreationContent},
- {"m.room.member", userID, membershipContent},
- {"m.room.power_levels", "", powerLevelContent},
- {"m.room.join_rules", "", gomatrixserverlib.JoinRuleContent{JoinRule: joinRules}},
- {"m.room.history_visibility", "", eventutil.HistoryVisibilityContent{HistoryVisibility: historyVisibility}},
+ createEvent, membershipEvent, powerLevelEvent, joinRuleEvent, historyVisibilityEvent,
}
- if roomAlias != "" {
- // TODO: bit of a chicken and egg problem here as the alias doesn't exist and cannot until we have made the room.
- // This means we might fail creating the alias but say the canonical alias is something that doesn't exist.
- // m.room.aliases is handled when we call roomserver.SetRoomAlias
- eventsToMake = append(eventsToMake, fledglingEvent{"m.room.canonical_alias", "", eventutil.CanonicalAlias{Alias: roomAlias}})
+ if guestAccessEvent != nil {
+ eventsToMake = append(eventsToMake, *guestAccessEvent)
}
- if r.GuestCanJoin {
- eventsToMake = append(eventsToMake, fledglingEvent{"m.room.guest_access", "", eventutil.GuestAccessContent{GuestAccess: "can_join"}})
+ eventsToMake = append(eventsToMake, initialStateEvents...)
+ if nameEvent != nil {
+ eventsToMake = append(eventsToMake, *nameEvent)
}
- eventsToMake = append(eventsToMake, r.InitialState...)
- if r.Name != "" {
- eventsToMake = append(eventsToMake, fledglingEvent{"m.room.name", "", eventutil.NameContent{Name: r.Name}})
+ if topicEvent != nil {
+ eventsToMake = append(eventsToMake, *topicEvent)
}
- if r.Topic != "" {
- eventsToMake = append(eventsToMake, fledglingEvent{"m.room.topic", "", eventutil.TopicContent{Topic: r.Topic}})
+ if aliasEvent != nil {
+ // TODO: bit of a chicken and egg problem here as the alias doesn't exist and cannot until we have made the room.
+ // This means we might fail creating the alias but say the canonical alias is something that doesn't exist.
+ // m.room.aliases is handled when we call roomserver.SetRoomAlias
+ eventsToMake = append(eventsToMake, *aliasEvent)
}
+
// TODO: invite events
// TODO: 3pid invite events
+ var builtEvents []*gomatrixserverlib.HeaderedEvent
authEvents := gomatrixserverlib.NewAuthEvents(nil)
for i, e := range eventsToMake {
depth := i + 1 // depth starts at 1
@@ -403,7 +500,7 @@ func createRoom(
fallthrough
case gomatrixserverlib.MRoomCanonicalAlias:
fallthrough
- case "m.room.encryption": // TODO: move this to gmsl
+ case gomatrixserverlib.MRoomEncryption:
fallthrough
case gomatrixserverlib.MRoomMember:
fallthrough
diff --git a/go.mod b/go.mod
index 6799dbf5..ec17e644 100644
--- a/go.mod
+++ b/go.mod
@@ -31,7 +31,7 @@ require (
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
github.com/matrix-org/go-sqlite3-js v0.0.0-20210709140738-b0d1ba599a6d
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
- github.com/matrix-org/gomatrixserverlib v0.0.0-20210720141356-d52ec9c4dd2f
+ github.com/matrix-org/gomatrixserverlib v0.0.0-20210721094149-75792185bf42
github.com/matrix-org/naffka v0.0.0-20210623111924-14ff508b58e0
github.com/matrix-org/pinecone v0.0.0-20210623102758-74f885644c1b
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
diff --git a/go.sum b/go.sum
index c93ce247..86149343 100644
--- a/go.sum
+++ b/go.sum
@@ -1027,8 +1027,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20210709140738-b0d1ba599a6d/go.mod h1
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5dLDCud4r0r55eP4j9FuUNpl60Gmntcop4=
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
-github.com/matrix-org/gomatrixserverlib v0.0.0-20210720141356-d52ec9c4dd2f h1:FP+tOVTX4mw4GPjHJE28UsPkw59ieISgjDtkCwb1vls=
-github.com/matrix-org/gomatrixserverlib v0.0.0-20210720141356-d52ec9c4dd2f/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
+github.com/matrix-org/gomatrixserverlib v0.0.0-20210721094149-75792185bf42 h1:UsCdEX9G3svG07bBV8RKAWIyGzCgJpbX4BCP1n4ezH8=
+github.com/matrix-org/gomatrixserverlib v0.0.0-20210721094149-75792185bf42/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
github.com/matrix-org/naffka v0.0.0-20210623111924-14ff508b58e0 h1:HZCzy4oVzz55e+cOMiX/JtSF2UOY1evBl2raaE7ACcU=
github.com/matrix-org/naffka v0.0.0-20210623111924-14ff508b58e0/go.mod h1:sjyPyRxKM5uw1nD2cJ6O2OxI6GOqyVBfNXqKjBZTBZE=
github.com/matrix-org/pinecone v0.0.0-20210623102758-74f885644c1b h1:5X5vdWQ13xrNkJVqaJHPsrt7rKkMJH5iac0EtfOuxSg=