Room version 12 (#3623)
Some checks are pending
Dendrite / Sytest (SQLite Cgo) (push) Blocked by required conditions
Dendrite / WASM build test (push) Waiting to run
Dendrite / Linting (push) Waiting to run
Dendrite / Unit tests (push) Waiting to run
Dendrite / Build for Linux (push) Waiting to run
Dendrite / Build for Windows (push) Waiting to run
Dendrite / Initial tests passed (push) Blocked by required conditions
Dendrite / Integration tests (push) Blocked by required conditions
Dendrite / Upgrade tests (push) Blocked by required conditions
Dendrite / Upgrade tests from HEAD-2 (push) Blocked by required conditions
Dendrite / Sytest (PostgreSQL) (push) Blocked by required conditions
Dendrite / Sytest (SQLite native) (push) Blocked by required conditions
Dendrite / Complement (PostgreSQL) (push) Blocked by required conditions
Dendrite / Complement (SQLite native) (push) Blocked by required conditions
Dendrite / Complement (SQLite Cgo) (push) Blocked by required conditions
Dendrite / Integration tests passed (push) Blocked by required conditions
Dendrite / Update Docker images (push) Blocked by required conditions

This commit is contained in:
Kegan Dougal 2025-08-11 20:59:47 +01:00 committed by GitHub
parent a408b24d28
commit 4d93d921be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 530 additions and 208 deletions

View file

@ -8,6 +8,10 @@ package api
import (
"context"
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/element-hq/dendrite/roomserver/types"
"github.com/matrix-org/gomatrixserverlib"
@ -216,3 +220,117 @@ func PopulatePublicRooms(ctx context.Context, roomIDs []string, rsAPI QueryBulkS
}
return chunk, nil
}
func GenerateCreateContent(ctx context.Context, roomVer gomatrixserverlib.RoomVersion, senderID string, createContentJSON json.RawMessage, additionalCreators []string) (map[string]any, error) {
createContent := map[string]any{}
if len(createContentJSON) > 0 {
if err := json.Unmarshal(createContentJSON, &createContent); err != nil {
return nil, fmt.Errorf("invalid create content: %s", err)
}
}
// TODO: Maybe, at some point, GMSL should return the events to create, so we can define the version
// entirely there.
switch roomVer {
case gomatrixserverlib.RoomVersionV11:
fallthrough
case gomatrixserverlib.RoomVersionV12:
// RoomVersionV11 removed the creator field from the create content: https://github.com/matrix-org/matrix-spec-proposals/pull/2175
default:
createContent["creator"] = senderID
}
createContent["room_version"] = string(roomVer)
verImpl := gomatrixserverlib.MustGetRoomVersion(roomVer)
if verImpl.PrivilegedCreators() {
var finalAdditionalCreators []string
creatorsSet := make(map[string]struct{})
var unverifiedCreators []string
unverifiedCreators = append(unverifiedCreators, additionalCreators...)
// they get added to any additional creators specified already
existingAdditionalCreators, ok := createContent["additional_creators"].([]any)
if ok {
for _, add := range existingAdditionalCreators {
addStr, ok := add.(string)
if ok {
unverifiedCreators = append(unverifiedCreators, addStr)
}
}
}
for _, add := range unverifiedCreators {
if _, exists := creatorsSet[add]; exists {
continue
}
_, err := spec.NewUserID(add, true)
if err != nil {
return nil, fmt.Errorf("invalid additional creator: '%s': %s", add, err)
}
finalAdditionalCreators = append(finalAdditionalCreators, add)
creatorsSet[add] = struct{}{}
}
if len(finalAdditionalCreators) > 0 {
createContent["additional_creators"] = finalAdditionalCreators
}
}
return createContent, nil
}
func GeneratePDU(
ctx context.Context, verImpl gomatrixserverlib.IRoomVersion, e gomatrixserverlib.FledglingEvent, authEvents *gomatrixserverlib.AuthEvents, depth int, prevEventID string,
identity *fclient.SigningIdentity, timestamp time.Time, senderID, roomID string, queryer QuerySenderIDAPI,
) (gomatrixserverlib.PDU, *util.JSONResponse) {
builder := verImpl.NewEventBuilderFromProtoEvent(&gomatrixserverlib.ProtoEvent{
SenderID: senderID,
RoomID: roomID,
Type: e.Type,
StateKey: &e.StateKey,
Depth: int64(depth),
})
err := builder.SetContent(e.Content)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("builder.SetContent failed")
return nil, &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
if prevEventID != "" {
builder.PrevEvents = []string{prevEventID}
}
var ev gomatrixserverlib.PDU
if err = builder.AddAuthEvents(authEvents); err != nil {
util.GetLogger(ctx).WithError(err).Error("AddAuthEvents failed")
return nil, &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
ev, err = builder.Build(timestamp, identity.ServerName, identity.KeyID, identity.PrivateKey)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("buildEvent failed")
return nil, &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
if err = gomatrixserverlib.Allowed(ev, authEvents, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
return queryer.QueryUserIDForSender(ctx, roomID, senderID)
}); err != nil {
util.GetLogger(ctx).WithError(err).Error("gomatrixserverlib.Allowed failed")
validationErr, ok := err.(*gomatrixserverlib.EventValidationError)
if ok {
return nil, &util.JSONResponse{
Code: validationErr.Code,
JSON: spec.Forbidden(err.Error()),
}
}
return nil, &util.JSONResponse{
Code: http.StatusForbidden,
JSON: spec.Forbidden(err.Error()),
}
}
return ev, nil
}