mirror of
https://github.com/hoernschen/dendrite.git
synced 2024-12-27 07:28:27 +00:00
[pseudoIDs] Fixes for room alias tests (#3159)
Some (deceptively) simple fixes for some bugs that caused room alias
tests to fail (sytext `tests/30rooms/05aliases.pl`). Each commit has
details about what it fixes.
Sytest results:
- Sytest before (79d4a0e
):
https://gist.github.com/swedgwood/972ac4ef93edd130d3db0930703d6c82
- Sytest after (4b09bed):
https://gist.github.com/swedgwood/504b00ac4ee892acb757b7fac55fa28a
Room aliases go from `8/15` to `15/15`, but looks like these fixes also
managed to fix about `4` other tests, which is a nice bonus :)
Signed-off-by: `Sam Wedgwood <sam@wedgwood.dev>`
This commit is contained in:
parent
3f727485d6
commit
af13fa1c75
8 changed files with 160 additions and 138 deletions
|
@ -181,13 +181,33 @@ func SetLocalAlias(
|
||||||
return *resErr
|
return *resErr
|
||||||
}
|
}
|
||||||
|
|
||||||
queryReq := roomserverAPI.SetRoomAliasRequest{
|
roomID, err := spec.NewRoomID(r.RoomID)
|
||||||
UserID: device.UserID,
|
if err != nil {
|
||||||
RoomID: r.RoomID,
|
return util.JSONResponse{
|
||||||
Alias: alias,
|
Code: http.StatusBadRequest,
|
||||||
|
JSON: spec.InvalidParam("invalid room ID"),
|
||||||
}
|
}
|
||||||
var queryRes roomserverAPI.SetRoomAliasResponse
|
}
|
||||||
if err := rsAPI.SetRoomAlias(req.Context(), &queryReq, &queryRes); err != nil {
|
|
||||||
|
userID, err := spec.NewUserID(device.UserID, true)
|
||||||
|
if err != nil {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
JSON: spec.Unknown("internal server error"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
senderID, err := rsAPI.QuerySenderIDForUser(req.Context(), *roomID, *userID)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("QuerySenderIDForUser failed")
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
JSON: spec.Unknown("internal server error"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aliasAlreadyExists, err := rsAPI.SetRoomAlias(req.Context(), senderID, *roomID, alias)
|
||||||
|
if err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("aliasAPI.SetRoomAlias failed")
|
util.GetLogger(req.Context()).WithError(err).Error("aliasAPI.SetRoomAlias failed")
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
|
@ -195,7 +215,7 @@ func SetLocalAlias(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if queryRes.AliasExists {
|
if aliasAlreadyExists {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusConflict,
|
Code: http.StatusConflict,
|
||||||
JSON: spec.Unknown("The alias " + alias + " already exists."),
|
JSON: spec.Unknown("The alias " + alias + " already exists."),
|
||||||
|
@ -240,6 +260,31 @@ func RemoveLocalAlias(
|
||||||
JSON: spec.NotFound("The alias does not exist."),
|
JSON: spec.NotFound("The alias does not exist."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This seems like the kind of auth check that should be done in the roomserver, but
|
||||||
|
// if this check fails (user is not in the room), then there will be no SenderID for the user
|
||||||
|
// for pseudo-ID rooms - it will just return "". However, we can't use lack of a sender ID
|
||||||
|
// as meaning they are not in the room, since lacking a sender ID could be caused by other bugs.
|
||||||
|
// TODO: maybe have QuerySenderIDForUser return richer errors?
|
||||||
|
var queryResp roomserverAPI.QueryMembershipForUserResponse
|
||||||
|
err = rsAPI.QueryMembershipForUser(req.Context(), &roomserverAPI.QueryMembershipForUserRequest{
|
||||||
|
RoomID: validRoomID.String(),
|
||||||
|
UserID: *userID,
|
||||||
|
}, &queryResp)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("roomserverAPI.QueryMembershipForUser failed")
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
JSON: spec.Unknown("internal server error"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !queryResp.IsInRoom {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: spec.Forbidden("You do not have permission to remove this alias."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
deviceSenderID, err := rsAPI.QuerySenderIDForUser(req.Context(), *validRoomID, *userID)
|
deviceSenderID, err := rsAPI.QuerySenderIDForUser(req.Context(), *validRoomID, *userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
@ -247,28 +292,31 @@ func RemoveLocalAlias(
|
||||||
JSON: spec.NotFound("The alias does not exist."),
|
JSON: spec.NotFound("The alias does not exist."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: how to handle this case? missing user/room keys seem to be a whole new class of errors
|
||||||
queryReq := roomserverAPI.RemoveRoomAliasRequest{
|
if deviceSenderID == "" {
|
||||||
Alias: alias,
|
return util.JSONResponse{
|
||||||
SenderID: deviceSenderID,
|
Code: http.StatusInternalServerError,
|
||||||
|
JSON: spec.Unknown("internal server error"),
|
||||||
}
|
}
|
||||||
var queryRes roomserverAPI.RemoveRoomAliasResponse
|
}
|
||||||
if err := rsAPI.RemoveRoomAlias(req.Context(), &queryReq, &queryRes); err != nil {
|
|
||||||
|
aliasFound, aliasRemoved, err := rsAPI.RemoveRoomAlias(req.Context(), deviceSenderID, alias)
|
||||||
|
if err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("aliasAPI.RemoveRoomAlias failed")
|
util.GetLogger(req.Context()).WithError(err).Error("aliasAPI.RemoveRoomAlias failed")
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
JSON: spec.InternalServerError{},
|
JSON: spec.Unknown("internal server error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !queryRes.Found {
|
if !aliasFound {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusNotFound,
|
Code: http.StatusNotFound,
|
||||||
JSON: spec.NotFound("The alias does not exist."),
|
JSON: spec.NotFound("The alias does not exist."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !queryRes.Removed {
|
if !aliasRemoved {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusForbidden,
|
Code: http.StatusForbidden,
|
||||||
JSON: spec.Forbidden("You do not have permission to remove this alias."),
|
JSON: spec.Forbidden("You do not have permission to remove this alias."),
|
||||||
|
|
|
@ -16,26 +16,8 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"github.com/matrix-org/gomatrixserverlib/spec"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetRoomAliasRequest is a request to SetRoomAlias
|
|
||||||
type SetRoomAliasRequest struct {
|
|
||||||
// ID of the user setting the alias
|
|
||||||
UserID string `json:"user_id"`
|
|
||||||
// New alias for the room
|
|
||||||
Alias string `json:"alias"`
|
|
||||||
// The room ID the alias is referring to
|
|
||||||
RoomID string `json:"room_id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRoomAliasResponse is a response to SetRoomAlias
|
|
||||||
type SetRoomAliasResponse struct {
|
|
||||||
// Does the alias already refer to a room?
|
|
||||||
AliasExists bool `json:"alias_exists"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRoomIDForAliasRequest is a request to GetRoomIDForAlias
|
// GetRoomIDForAliasRequest is a request to GetRoomIDForAlias
|
||||||
type GetRoomIDForAliasRequest struct {
|
type GetRoomIDForAliasRequest struct {
|
||||||
// Alias we want to lookup
|
// Alias we want to lookup
|
||||||
|
@ -63,22 +45,6 @@ type GetAliasesForRoomIDResponse struct {
|
||||||
Aliases []string `json:"aliases"`
|
Aliases []string `json:"aliases"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveRoomAliasRequest is a request to RemoveRoomAlias
|
|
||||||
type RemoveRoomAliasRequest struct {
|
|
||||||
// ID of the user removing the alias
|
|
||||||
SenderID spec.SenderID `json:"user_id"`
|
|
||||||
// The room alias to remove
|
|
||||||
Alias string `json:"alias"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveRoomAliasResponse is a response to RemoveRoomAlias
|
|
||||||
type RemoveRoomAliasResponse struct {
|
|
||||||
// Did the alias exist before?
|
|
||||||
Found bool `json:"found"`
|
|
||||||
// Did we remove it?
|
|
||||||
Removed bool `json:"removed"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type AliasEvent struct {
|
type AliasEvent struct {
|
||||||
Alias string `json:"alias"`
|
Alias string `json:"alias"`
|
||||||
AltAliases []string `json:"alt_aliases"`
|
AltAliases []string `json:"alt_aliases"`
|
||||||
|
|
|
@ -237,8 +237,19 @@ type ClientRoomserverAPI interface {
|
||||||
PerformPublish(ctx context.Context, req *PerformPublishRequest) error
|
PerformPublish(ctx context.Context, req *PerformPublishRequest) error
|
||||||
// PerformForget forgets a rooms history for a specific user
|
// PerformForget forgets a rooms history for a specific user
|
||||||
PerformForget(ctx context.Context, req *PerformForgetRequest, resp *PerformForgetResponse) error
|
PerformForget(ctx context.Context, req *PerformForgetRequest, resp *PerformForgetResponse) error
|
||||||
SetRoomAlias(ctx context.Context, req *SetRoomAliasRequest, res *SetRoomAliasResponse) error
|
|
||||||
RemoveRoomAlias(ctx context.Context, req *RemoveRoomAliasRequest, res *RemoveRoomAliasResponse) error
|
// Sets a room alias, as provided sender, pointing to the provided room ID.
|
||||||
|
//
|
||||||
|
// If err is nil, then the returned boolean indicates if the alias is already in use.
|
||||||
|
// If true, then the alias has not been set to the provided room, as it already in use.
|
||||||
|
SetRoomAlias(ctx context.Context, senderID spec.SenderID, roomID spec.RoomID, alias string) (aliasAlreadyExists bool, err error)
|
||||||
|
|
||||||
|
//RemoveRoomAlias(ctx context.Context, req *RemoveRoomAliasRequest, res *RemoveRoomAliasResponse) error
|
||||||
|
// Removes a room alias, as provided sender.
|
||||||
|
//
|
||||||
|
// Returns whether the alias was found, whether it was removed, and an error (if any occurred)
|
||||||
|
RemoveRoomAlias(ctx context.Context, senderID spec.SenderID, alias string) (aliasFound bool, aliasRemoved bool, err error)
|
||||||
|
|
||||||
SigningIdentityFor(ctx context.Context, roomID spec.RoomID, senderID spec.UserID) (fclient.SigningIdentity, error)
|
SigningIdentityFor(ctx context.Context, roomID spec.RoomID, senderID spec.UserID) (fclient.SigningIdentity, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,27 +35,27 @@ import (
|
||||||
// SetRoomAlias implements alias.RoomserverInternalAPI
|
// SetRoomAlias implements alias.RoomserverInternalAPI
|
||||||
func (r *RoomserverInternalAPI) SetRoomAlias(
|
func (r *RoomserverInternalAPI) SetRoomAlias(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.SetRoomAliasRequest,
|
senderID spec.SenderID,
|
||||||
response *api.SetRoomAliasResponse,
|
roomID spec.RoomID,
|
||||||
) error {
|
alias string,
|
||||||
|
) (aliasAlreadyUsed bool, err error) {
|
||||||
// Check if the alias isn't already referring to a room
|
// Check if the alias isn't already referring to a room
|
||||||
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
existingRoomID, err := r.DB.GetRoomIDForAlias(ctx, alias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
if len(roomID) > 0 {
|
|
||||||
|
if len(existingRoomID) > 0 {
|
||||||
// If the alias already exists, stop the process
|
// If the alias already exists, stop the process
|
||||||
response.AliasExists = true
|
return true, nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
response.AliasExists = false
|
|
||||||
|
|
||||||
// Save the new alias
|
// Save the new alias
|
||||||
if err := r.DB.SetRoomAlias(ctx, request.Alias, request.RoomID, request.UserID); err != nil {
|
if err := r.DB.SetRoomAlias(ctx, alias, roomID.String(), string(senderID)); err != nil {
|
||||||
return err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRoomIDForAlias implements alias.RoomserverInternalAPI
|
// GetRoomIDForAlias implements alias.RoomserverInternalAPI
|
||||||
|
@ -116,90 +116,79 @@ func (r *RoomserverInternalAPI) GetAliasesForRoomID(
|
||||||
// nolint:gocyclo
|
// nolint:gocyclo
|
||||||
// RemoveRoomAlias implements alias.RoomserverInternalAPI
|
// RemoveRoomAlias implements alias.RoomserverInternalAPI
|
||||||
// nolint: gocyclo
|
// nolint: gocyclo
|
||||||
func (r *RoomserverInternalAPI) RemoveRoomAlias(
|
func (r *RoomserverInternalAPI) RemoveRoomAlias(ctx context.Context, senderID spec.SenderID, alias string) (aliasFound bool, aliasRemoved bool, err error) {
|
||||||
ctx context.Context,
|
roomID, err := r.DB.GetRoomIDForAlias(ctx, alias)
|
||||||
request *api.RemoveRoomAliasRequest,
|
|
||||||
response *api.RemoveRoomAliasResponse,
|
|
||||||
) error {
|
|
||||||
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("r.DB.GetRoomIDForAlias: %w", err)
|
return false, false, fmt.Errorf("r.DB.GetRoomIDForAlias: %w", err)
|
||||||
}
|
}
|
||||||
if roomID == "" {
|
if roomID == "" {
|
||||||
response.Found = false
|
return false, false, nil
|
||||||
response.Removed = false
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validRoomID, err := spec.NewRoomID(roomID)
|
validRoomID, err := spec.NewRoomID(roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return true, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sender, err := r.QueryUserIDForSender(ctx, *validRoomID, request.SenderID)
|
sender, err := r.QueryUserIDForSender(ctx, *validRoomID, senderID)
|
||||||
if err != nil || sender == nil {
|
if err != nil || sender == nil {
|
||||||
return fmt.Errorf("r.QueryUserIDForSender: %w", err)
|
return true, false, fmt.Errorf("r.QueryUserIDForSender: %w", err)
|
||||||
}
|
}
|
||||||
virtualHost := sender.Domain()
|
virtualHost := sender.Domain()
|
||||||
|
|
||||||
response.Found = true
|
creatorID, err := r.DB.GetCreatorIDForAlias(ctx, alias)
|
||||||
creatorID, err := r.DB.GetCreatorIDForAlias(ctx, request.Alias)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("r.DB.GetCreatorIDForAlias: %w", err)
|
return true, false, fmt.Errorf("r.DB.GetCreatorIDForAlias: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if spec.SenderID(creatorID) != request.SenderID {
|
if spec.SenderID(creatorID) != senderID {
|
||||||
var plEvent *types.HeaderedEvent
|
var plEvent *types.HeaderedEvent
|
||||||
var pls *gomatrixserverlib.PowerLevelContent
|
var pls *gomatrixserverlib.PowerLevelContent
|
||||||
|
|
||||||
plEvent, err = r.DB.GetStateEvent(ctx, roomID, spec.MRoomPowerLevels, "")
|
plEvent, err = r.DB.GetStateEvent(ctx, roomID, spec.MRoomPowerLevels, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("r.DB.GetStateEvent: %w", err)
|
return true, false, fmt.Errorf("r.DB.GetStateEvent: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pls, err = plEvent.PowerLevels()
|
pls, err = plEvent.PowerLevels()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("plEvent.PowerLevels: %w", err)
|
return true, false, fmt.Errorf("plEvent.PowerLevels: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pls.UserLevel(request.SenderID) < pls.EventLevel(spec.MRoomCanonicalAlias, true) {
|
if pls.UserLevel(senderID) < pls.EventLevel(spec.MRoomCanonicalAlias, true) {
|
||||||
response.Removed = false
|
return true, false, nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ev, err := r.DB.GetStateEvent(ctx, roomID, spec.MRoomCanonicalAlias, "")
|
ev, err := r.DB.GetStateEvent(ctx, roomID, spec.MRoomCanonicalAlias, "")
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
return err
|
return true, false, err
|
||||||
} else if ev != nil {
|
} else if ev != nil {
|
||||||
stateAlias := gjson.GetBytes(ev.Content(), "alias").Str
|
stateAlias := gjson.GetBytes(ev.Content(), "alias").Str
|
||||||
// the alias to remove is currently set as the canonical alias, remove it
|
// the alias to remove is currently set as the canonical alias, remove it
|
||||||
if stateAlias == request.Alias {
|
if stateAlias == alias {
|
||||||
res, err := sjson.DeleteBytes(ev.Content(), "alias")
|
res, err := sjson.DeleteBytes(ev.Content(), "alias")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return true, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
senderID := request.SenderID
|
canonicalSenderID := ev.SenderID()
|
||||||
if request.SenderID != ev.SenderID() {
|
canonicalSender, err := r.QueryUserIDForSender(ctx, *validRoomID, canonicalSenderID)
|
||||||
senderID = ev.SenderID()
|
if err != nil || canonicalSender == nil {
|
||||||
}
|
return true, false, err
|
||||||
sender, err := r.QueryUserIDForSender(ctx, *validRoomID, senderID)
|
|
||||||
if err != nil || sender == nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validRoomID, err := spec.NewRoomID(roomID)
|
validRoomID, err := spec.NewRoomID(roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return true, false, err
|
||||||
}
|
}
|
||||||
identity, err := r.SigningIdentityFor(ctx, *validRoomID, *sender)
|
identity, err := r.SigningIdentityFor(ctx, *validRoomID, *canonicalSender)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return true, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
proto := &gomatrixserverlib.ProtoEvent{
|
proto := &gomatrixserverlib.ProtoEvent{
|
||||||
SenderID: string(senderID),
|
SenderID: string(canonicalSenderID),
|
||||||
RoomID: ev.RoomID(),
|
RoomID: ev.RoomID(),
|
||||||
Type: ev.Type(),
|
Type: ev.Type(),
|
||||||
StateKey: ev.StateKey(),
|
StateKey: ev.StateKey(),
|
||||||
|
@ -208,34 +197,33 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias(
|
||||||
|
|
||||||
eventsNeeded, err := gomatrixserverlib.StateNeededForProtoEvent(proto)
|
eventsNeeded, err := gomatrixserverlib.StateNeededForProtoEvent(proto)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
|
return true, false, fmt.Errorf("gomatrixserverlib.StateNeededForEventBuilder: %w", err)
|
||||||
}
|
}
|
||||||
if len(eventsNeeded.Tuples()) == 0 {
|
if len(eventsNeeded.Tuples()) == 0 {
|
||||||
return errors.New("expecting state tuples for event builder, got none")
|
return true, false, errors.New("expecting state tuples for event builder, got none")
|
||||||
}
|
}
|
||||||
|
|
||||||
stateRes := &api.QueryLatestEventsAndStateResponse{}
|
stateRes := &api.QueryLatestEventsAndStateResponse{}
|
||||||
if err = helpers.QueryLatestEventsAndState(ctx, r.DB, r, &api.QueryLatestEventsAndStateRequest{RoomID: roomID, StateToFetch: eventsNeeded.Tuples()}, stateRes); err != nil {
|
if err = helpers.QueryLatestEventsAndState(ctx, r.DB, r, &api.QueryLatestEventsAndStateRequest{RoomID: roomID, StateToFetch: eventsNeeded.Tuples()}, stateRes); err != nil {
|
||||||
return err
|
return true, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
newEvent, err := eventutil.BuildEvent(ctx, proto, &identity, time.Now(), &eventsNeeded, stateRes)
|
newEvent, err := eventutil.BuildEvent(ctx, proto, &identity, time.Now(), &eventsNeeded, stateRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return true, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = api.SendEvents(ctx, r, api.KindNew, []*types.HeaderedEvent{newEvent}, virtualHost, r.ServerName, r.ServerName, nil, false)
|
err = api.SendEvents(ctx, r, api.KindNew, []*types.HeaderedEvent{newEvent}, virtualHost, r.ServerName, r.ServerName, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return true, false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the alias from the database
|
// Remove the alias from the database
|
||||||
if err := r.DB.RemoveRoomAlias(ctx, request.Alias); err != nil {
|
if err := r.DB.RemoveRoomAlias(ctx, alias); err != nil {
|
||||||
return err
|
return true, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Removed = true
|
return true, true, nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,23 +433,16 @@ func (c *Creator) PerformCreateRoom(ctx context.Context, userID spec.UserID, roo
|
||||||
// from creating the room but still failing due to the alias having already
|
// from creating the room but still failing due to the alias having already
|
||||||
// been taken.
|
// been taken.
|
||||||
if roomAlias != "" {
|
if roomAlias != "" {
|
||||||
aliasReq := api.SetRoomAliasRequest{
|
aliasAlreadyExists, aliasErr := c.RSAPI.SetRoomAlias(ctx, senderID, roomID, roomAlias)
|
||||||
Alias: roomAlias,
|
if aliasErr != nil {
|
||||||
RoomID: roomID.String(),
|
util.GetLogger(ctx).WithError(aliasErr).Error("aliasAPI.SetRoomAlias failed")
|
||||||
UserID: userID.String(),
|
|
||||||
}
|
|
||||||
|
|
||||||
var aliasResp api.SetRoomAliasResponse
|
|
||||||
err = c.RSAPI.SetRoomAlias(ctx, &aliasReq, &aliasResp)
|
|
||||||
if err != nil {
|
|
||||||
util.GetLogger(ctx).WithError(err).Error("aliasAPI.SetRoomAlias failed")
|
|
||||||
return "", &util.JSONResponse{
|
return "", &util.JSONResponse{
|
||||||
Code: http.StatusInternalServerError,
|
Code: http.StatusInternalServerError,
|
||||||
JSON: spec.InternalServerError{},
|
JSON: spec.InternalServerError{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if aliasResp.AliasExists {
|
if aliasAlreadyExists {
|
||||||
return "", &util.JSONResponse{
|
return "", &util.JSONResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
JSON: spec.RoomInUse("Room alias already exists."),
|
JSON: spec.RoomInUse("Room alias already exists."),
|
||||||
|
|
|
@ -116,7 +116,7 @@ func (r *Upgrader) performRoomUpgrade(
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Move local aliases to the new room
|
// 4. Move local aliases to the new room
|
||||||
if pErr = moveLocalAliases(ctx, roomID, newRoomID, senderID, userID, r.URSAPI); pErr != nil {
|
if pErr = moveLocalAliases(ctx, roomID, newRoomID, senderID, r.URSAPI); pErr != nil {
|
||||||
return "", pErr
|
return "", pErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.T
|
||||||
}
|
}
|
||||||
|
|
||||||
func moveLocalAliases(ctx context.Context,
|
func moveLocalAliases(ctx context.Context,
|
||||||
roomID, newRoomID string, senderID spec.SenderID, userID spec.UserID,
|
roomID, newRoomID string, senderID spec.SenderID,
|
||||||
URSAPI api.RoomserverInternalAPI,
|
URSAPI api.RoomserverInternalAPI,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
|
|
||||||
|
@ -181,17 +181,27 @@ func moveLocalAliases(ctx context.Context,
|
||||||
return fmt.Errorf("Failed to get old room aliases: %w", err)
|
return fmt.Errorf("Failed to get old room aliases: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, alias := range aliasRes.Aliases {
|
// TODO: this should be spec.RoomID further up the call stack
|
||||||
removeAliasReq := api.RemoveRoomAliasRequest{SenderID: senderID, Alias: alias}
|
parsedNewRoomID, err := spec.NewRoomID(newRoomID)
|
||||||
removeAliasRes := api.RemoveRoomAliasResponse{}
|
if err != nil {
|
||||||
if err = URSAPI.RemoveRoomAlias(ctx, &removeAliasReq, &removeAliasRes); err != nil {
|
return err
|
||||||
return fmt.Errorf("Failed to remove old room alias: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setAliasReq := api.SetRoomAliasRequest{UserID: userID.String(), Alias: alias, RoomID: newRoomID}
|
for _, alias := range aliasRes.Aliases {
|
||||||
setAliasRes := api.SetRoomAliasResponse{}
|
aliasFound, aliasRemoved, err := URSAPI.RemoveRoomAlias(ctx, senderID, alias)
|
||||||
if err = URSAPI.SetRoomAlias(ctx, &setAliasReq, &setAliasRes); err != nil {
|
if err != nil {
|
||||||
|
return fmt.Errorf("Failed to remove old room alias: %w", err)
|
||||||
|
} else if !aliasFound {
|
||||||
|
return fmt.Errorf("Failed to remove old room alias: alias not found, possible race")
|
||||||
|
} else if !aliasRemoved {
|
||||||
|
return fmt.Errorf("Failed to remove old alias")
|
||||||
|
}
|
||||||
|
|
||||||
|
aliasAlreadyExists, err := URSAPI.SetRoomAlias(ctx, senderID, *parsedNewRoomID, alias)
|
||||||
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to set new room alias: %w", err)
|
return fmt.Errorf("Failed to set new room alias: %w", err)
|
||||||
|
} else if aliasAlreadyExists {
|
||||||
|
return fmt.Errorf("Failed to set new room alias: alias exists when it should have just been removed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -227,6 +227,11 @@ func TestPurgeRoom(t *testing.T) {
|
||||||
bob := test.NewUser(t)
|
bob := test.NewUser(t)
|
||||||
room := test.NewRoom(t, alice, test.RoomPreset(test.PresetTrustedPrivateChat))
|
room := test.NewRoom(t, alice, test.RoomPreset(test.PresetTrustedPrivateChat))
|
||||||
|
|
||||||
|
roomID, err := spec.NewRoomID(room.ID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// Invite Bob
|
// Invite Bob
|
||||||
inviteEvent := room.CreateAndInsert(t, alice, spec.MRoomMember, map[string]interface{}{
|
inviteEvent := room.CreateAndInsert(t, alice, spec.MRoomMember, map[string]interface{}{
|
||||||
"membership": "invite",
|
"membership": "invite",
|
||||||
|
@ -274,9 +279,7 @@ func TestPurgeRoom(t *testing.T) {
|
||||||
if !isPublished {
|
if !isPublished {
|
||||||
t.Fatalf("room should be published before purging")
|
t.Fatalf("room should be published before purging")
|
||||||
}
|
}
|
||||||
|
if _, err = rsAPI.SetRoomAlias(ctx, spec.SenderID(alice.ID), *roomID, "myalias"); err != nil {
|
||||||
aliasResp := &api.SetRoomAliasResponse{}
|
|
||||||
if err = rsAPI.SetRoomAlias(ctx, &api.SetRoomAliasRequest{RoomID: room.ID, Alias: "myalias", UserID: alice.ID}, aliasResp); err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
// check the alias is actually there
|
// check the alias is actually there
|
||||||
|
@ -930,14 +933,17 @@ func TestUpgrade(t *testing.T) {
|
||||||
upgradeUser: alice.ID,
|
upgradeUser: alice.ID,
|
||||||
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
roomFunc: func(rsAPI api.RoomserverInternalAPI) string {
|
||||||
r := test.NewRoom(t, alice)
|
r := test.NewRoom(t, alice)
|
||||||
|
roomID, err := spec.NewRoomID(r.ID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, r.Events(), "test", "test", "test", nil, false); err != nil {
|
if err := api.SendEvents(ctx, rsAPI, api.KindNew, r.Events(), "test", "test", "test", nil, false); err != nil {
|
||||||
t.Errorf("failed to send events: %v", err)
|
t.Errorf("failed to send events: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := rsAPI.SetRoomAlias(ctx, &api.SetRoomAliasRequest{
|
if _, err := rsAPI.SetRoomAlias(ctx, spec.SenderID(alice.ID),
|
||||||
RoomID: r.ID,
|
*roomID,
|
||||||
Alias: "#myroomalias:test",
|
"#myroomalias:test"); err != nil {
|
||||||
}, &api.SetRoomAliasResponse{}); err != nil {
|
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -519,7 +519,7 @@ func (p *PDUStreamProvider) updatePowerLevelEvent(ctx context.Context, ev *rstyp
|
||||||
}
|
}
|
||||||
|
|
||||||
var evNew gomatrixserverlib.PDU
|
var evNew gomatrixserverlib.PDU
|
||||||
evNew, err = gomatrixserverlib.MustGetRoomVersion(gomatrixserverlib.RoomVersionPseudoIDs).NewEventFromTrustedJSON(newEv, false)
|
evNew, err = gomatrixserverlib.MustGetRoomVersion(gomatrixserverlib.RoomVersionPseudoIDs).NewEventFromTrustedJSONWithEventID(ev.EventID(), newEv, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue