mirror of
https://github.com/element-hq/dendrite.git
synced 2025-09-13 12:52:24 +03:00
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
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:
parent
a408b24d28
commit
4d93d921be
26 changed files with 530 additions and 208 deletions
|
@ -176,12 +176,6 @@ func createRoom(
|
|||
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")
|
||||
|
@ -197,6 +191,49 @@ func createRoom(
|
|||
keyID := cfg.Matrix.KeyID
|
||||
privateKey := cfg.Matrix.PrivateKey
|
||||
|
||||
verImpl := gomatrixserverlib.MustGetRoomVersion(roomVersion)
|
||||
|
||||
var createEventJSON json.RawMessage
|
||||
if verImpl.DomainlessRoomIDs() {
|
||||
// make the create event up-front so the roomserver can calculate the room NID to store.
|
||||
var additionalCreators []string
|
||||
if createRequest.Preset == spec.PresetTrustedPrivateChat {
|
||||
additionalCreators = createRequest.Invite
|
||||
}
|
||||
createContent, err := roomserverAPI.GenerateCreateContent(ctx, createRequest.RoomVersion, userID.String(), createRequest.CreationContent, additionalCreators)
|
||||
if err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("GenerateCreateContent failed")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: spec.BadJSON("invalid create content"),
|
||||
}
|
||||
}
|
||||
authEvents, _ := gomatrixserverlib.NewAuthEvents(nil)
|
||||
identity, err := cfg.Matrix.SigningIdentityFor(userID.Domain())
|
||||
if err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("Failed to get signing identity")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: spec.InternalServerError{},
|
||||
}
|
||||
}
|
||||
createEvent, jsonErr := roomserverAPI.GeneratePDU(
|
||||
ctx, gomatrixserverlib.MustGetRoomVersion(roomVersion),
|
||||
gomatrixserverlib.FledglingEvent{
|
||||
Type: spec.MRoomCreate,
|
||||
Content: createContent,
|
||||
},
|
||||
authEvents, 1, "", identity, evTime, userID.String(), "", rsAPI,
|
||||
)
|
||||
if jsonErr != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("Failed to make the create event")
|
||||
return *jsonErr
|
||||
}
|
||||
createEventJSON = createEvent.JSON()
|
||||
r := createEvent.RoomID()
|
||||
roomID = &r
|
||||
}
|
||||
|
||||
req := roomserverAPI.PerformCreateRoomRequest{
|
||||
InvitedUsers: createRequest.Invite,
|
||||
RoomName: createRequest.Name,
|
||||
|
@ -204,6 +241,7 @@ func createRoom(
|
|||
Topic: createRequest.Topic,
|
||||
StatePreset: createRequest.Preset,
|
||||
CreationContent: createRequest.CreationContent,
|
||||
CreateEvent: createEventJSON,
|
||||
InitialState: createRequest.InitialState,
|
||||
RoomAliasName: createRequest.RoomAliasName,
|
||||
RoomVersion: roomVersion,
|
||||
|
@ -217,6 +255,12 @@ func createRoom(
|
|||
EventTime: evTime,
|
||||
}
|
||||
|
||||
logger.WithFields(log.Fields{
|
||||
"userID": userID.String(),
|
||||
"roomID": roomID.String(),
|
||||
"roomVersion": roomVersion,
|
||||
}).Info("Creating new room")
|
||||
|
||||
roomAlias, createRes := rsAPI.PerformCreateRoom(ctx, *userID, *roomID, &req)
|
||||
if createRes != nil {
|
||||
return *createRes
|
||||
|
|
|
@ -411,10 +411,11 @@ func SetVisibility(
|
|||
JSON: spec.InternalServerError{},
|
||||
}
|
||||
}
|
||||
privileged := isPrivilegedCreator(req.Context(), rsAPI, roomID, *senderID)
|
||||
|
||||
// NOTSPEC: Check if the user's power is greater than power required to change m.room.canonical_alias event
|
||||
power, _ := gomatrixserverlib.NewPowerLevelContentFromEvent(queryEventsRes.StateEvents[0].PDU)
|
||||
if power.UserLevel(*senderID) < power.EventLevel(spec.MRoomCanonicalAlias, true) {
|
||||
if !privileged && power.UserLevel(*senderID) < power.EventLevel(spec.MRoomCanonicalAlias, true) {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: spec.Forbidden("userID doesn't have power level to change visibility"),
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"crypto/ed25519"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
appserviceAPI "github.com/element-hq/dendrite/appservice/api"
|
||||
|
@ -79,7 +80,8 @@ func SendBan(
|
|||
if errRes != nil {
|
||||
return *errRes
|
||||
}
|
||||
allowedToBan := pl.UserLevel(*senderID) >= pl.Ban
|
||||
privileged := isPrivilegedCreator(req.Context(), rsAPI, roomID, *senderID)
|
||||
allowedToBan := privileged || pl.UserLevel(*senderID) >= pl.Ban
|
||||
if !allowedToBan {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
|
@ -118,6 +120,12 @@ func sendMembership(ctx context.Context, profileAPI userapi.ClientUserAPI, devic
|
|||
false,
|
||||
); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("SendEvents failed")
|
||||
if err.Error() == api.InputWasRejected {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: spec.Forbidden("the event was rejected"),
|
||||
}
|
||||
}
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
JSON: spec.InternalServerError{},
|
||||
|
@ -185,7 +193,8 @@ func SendKick(
|
|||
if errRes != nil {
|
||||
return *errRes
|
||||
}
|
||||
allowedToKick := pl.UserLevel(*senderID) >= pl.Kick || bodyUserID.String() == deviceUserID.String()
|
||||
privileged := isPrivilegedCreator(req.Context(), rsAPI, roomID, *senderID)
|
||||
allowedToKick := privileged || pl.UserLevel(*senderID) >= pl.Kick || bodyUserID.String() == deviceUserID.String()
|
||||
if !allowedToKick {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
|
@ -680,3 +689,12 @@ func getPowerlevels(req *http.Request, rsAPI roomserverAPI.ClientRoomserverAPI,
|
|||
}
|
||||
return pl, nil
|
||||
}
|
||||
|
||||
// Returns true if the room is a room which supports privileged creators and the sender is a creator, else false.
|
||||
func isPrivilegedCreator(ctx context.Context, rsAPI roomserverAPI.ClientRoomserverAPI, roomID string, senderID spec.SenderID) bool {
|
||||
createEvent := roomserverAPI.GetStateEvent(ctx, rsAPI, roomID, gomatrixserverlib.StateKeyTuple{
|
||||
EventType: spec.MRoomCreate,
|
||||
StateKey: "",
|
||||
})
|
||||
return gomatrixserverlib.MustGetRoomVersion(createEvent.Version()).PrivilegedCreators() && slices.Contains(gomatrixserverlib.CreatorsFromCreateEvent(createEvent), string(senderID))
|
||||
}
|
||||
|
|
|
@ -98,10 +98,12 @@ func SendRedaction(
|
|||
}
|
||||
}
|
||||
|
||||
privileged := isPrivilegedCreator(req.Context(), rsAPI, roomID, *senderID)
|
||||
|
||||
// "Users may redact their own events, and any user with a power level greater than or equal
|
||||
// to the redact power level of the room may redact events there"
|
||||
// https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
|
||||
allowedToRedact := ev.SenderID() == *senderID
|
||||
allowedToRedact := ev.SenderID() == *senderID || privileged
|
||||
if !allowedToRedact {
|
||||
plEvent := roomserverAPI.GetStateEvent(req.Context(), rsAPI, roomID, gomatrixserverlib.StateKeyTuple{
|
||||
EventType: spec.MRoomPowerLevels,
|
||||
|
|
|
@ -77,7 +77,6 @@ func SendEvent(
|
|||
JSON: spec.UnsupportedRoomVersion(err.Error()),
|
||||
}
|
||||
}
|
||||
|
||||
if txnID != nil {
|
||||
// Try to fetch response from transactionsCache
|
||||
if res, ok := txnCache.FetchTransaction(device.AccessToken, *txnID, req.URL); ok {
|
||||
|
@ -367,6 +366,12 @@ func generateSendEvent(
|
|||
JSON: spec.InternalServerError{},
|
||||
}
|
||||
}
|
||||
if proto.Type == spec.MRoomCreate && proto.StateKey != nil && *proto.StateKey == "" {
|
||||
return nil, &util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: spec.InvalidParam("cannot resend m.room.create event"),
|
||||
}
|
||||
}
|
||||
|
||||
identity, err := rsAPI.SigningIdentityFor(ctx, *validRoomID, *fullUserID)
|
||||
if err != nil {
|
||||
|
@ -424,8 +429,13 @@ func generateSendEvent(
|
|||
if err = gomatrixserverlib.Allowed(e.PDU, provider, func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
|
||||
return rsAPI.QueryUserIDForSender(ctx, *validRoomID, senderID)
|
||||
}); err != nil {
|
||||
code := 403
|
||||
validationErr, ok := err.(*gomatrixserverlib.EventValidationError)
|
||||
if ok {
|
||||
code = validationErr.Code
|
||||
}
|
||||
return nil, &util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
Code: code,
|
||||
JSON: spec.Forbidden(err.Error()), // TODO: Is this error string comprehensible to the client?
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/matrix-org/gomatrix"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
"github.com/matrix-org/gomatrixserverlib/tokens"
|
||||
"github.com/matrix-org/util"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
@ -139,7 +140,7 @@ func SendServerNotice(
|
|||
|
||||
// create a new room for the user
|
||||
if len(commonRooms) == 0 {
|
||||
powerLevelContent := eventutil.InitialPowerLevelsContent(senderUserID.String())
|
||||
powerLevelContent := eventutil.InitialPowerLevelsContent(gomatrixserverlib.MustGetRoomVersion(roomVersion), senderUserID.String())
|
||||
powerLevelContent.Users[r.UserID] = -10 // taken from Synapse
|
||||
pl, err := json.Marshal(powerLevelContent)
|
||||
if err != nil {
|
||||
|
|
|
@ -23,7 +23,8 @@ import (
|
|||
)
|
||||
|
||||
type upgradeRoomRequest struct {
|
||||
NewVersion string `json:"new_version"`
|
||||
NewVersion string `json:"new_version"`
|
||||
AdditionalCreators []string `json:"additional_creators"`
|
||||
}
|
||||
|
||||
type upgradeRoomResponse struct {
|
||||
|
@ -43,6 +44,13 @@ func UpgradeRoom(
|
|||
return *rErr
|
||||
}
|
||||
|
||||
if r.NewVersion == "" {
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusBadRequest,
|
||||
JSON: spec.InvalidParam("missing version to upgrade to"),
|
||||
}
|
||||
}
|
||||
|
||||
// Validate that the room version is supported
|
||||
if _, err := version.SupportedRoomVersion(gomatrixserverlib.RoomVersion(r.NewVersion)); err != nil {
|
||||
return util.JSONResponse{
|
||||
|
@ -59,7 +67,10 @@ func UpgradeRoom(
|
|||
JSON: spec.InternalServerError{},
|
||||
}
|
||||
}
|
||||
newRoomID, err := rsAPI.PerformRoomUpgrade(req.Context(), roomID, *userID, gomatrixserverlib.RoomVersion(r.NewVersion))
|
||||
newRoomID, err := rsAPI.PerformRoomUpgrade(req.Context(), roomID, *userID, gomatrixserverlib.RoomVersion(r.NewVersion), r.AdditionalCreators)
|
||||
if err != nil {
|
||||
util.GetLogger(req.Context()).WithError(err).Error("PerformRoomUpgrade failed")
|
||||
}
|
||||
switch e := err.(type) {
|
||||
case nil:
|
||||
case roomserverAPI.ErrNotAllowed:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue