Use SenderID Type (#3105)

This commit is contained in:
devonh 2023-06-07 17:14:35 +00:00 committed by GitHub
parent 7a1fd7f512
commit 8ea1a11105
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 502 additions and 275 deletions

View file

@ -14,7 +14,11 @@
package api
import "regexp"
import (
"regexp"
"github.com/matrix-org/gomatrixserverlib/spec"
)
// SetRoomAliasRequest is a request to SetRoomAlias
type SetRoomAliasRequest struct {
@ -62,7 +66,7 @@ type GetAliasesForRoomIDResponse struct {
// RemoveRoomAliasRequest is a request to RemoveRoomAlias
type RemoveRoomAliasRequest struct {
// ID of the user removing the alias
SenderID string `json:"user_id"`
SenderID spec.SenderID `json:"user_id"`
// The room alias to remove
Alias string `json:"alias"`
}

View file

@ -77,8 +77,8 @@ type InputRoomEventsAPI interface {
}
type QuerySenderIDAPI interface {
QuerySenderIDForUser(ctx context.Context, roomID string, userID spec.UserID) (string, error)
QueryUserIDForSender(ctx context.Context, roomID string, senderID string) (*spec.UserID, error)
QuerySenderIDForUser(ctx context.Context, roomID string, userID spec.UserID) (spec.SenderID, error)
QueryUserIDForSender(ctx context.Context, roomID string, senderID spec.SenderID) (*spec.UserID, error)
}
// Query the latest events and state for a room from the room server.

View file

@ -130,7 +130,7 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias(
}
sender, err := r.QueryUserIDForSender(ctx, roomID, request.SenderID)
if err != nil {
if err != nil || sender == nil {
return fmt.Errorf("r.QueryUserIDForSender: %w", err)
}
virtualHost := sender.Domain()
@ -141,7 +141,7 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias(
return fmt.Errorf("r.DB.GetCreatorIDForAlias: %w", err)
}
if creatorID != request.SenderID {
if spec.SenderID(creatorID) != request.SenderID {
var plEvent *types.HeaderedEvent
var pls *gomatrixserverlib.PowerLevelContent
@ -173,23 +173,24 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias(
return err
}
sender := request.SenderID
senderID := request.SenderID
if request.SenderID != ev.SenderID() {
sender = ev.SenderID()
senderID = ev.SenderID()
}
_, senderDomain, err := r.Cfg.Global.SplitLocalID('@', sender)
if err != nil {
sender, err := r.QueryUserIDForSender(ctx, roomID, senderID)
if err != nil || sender == nil {
return err
}
senderDomain := sender.Domain()
identity, err := r.Cfg.Global.SigningIdentityFor(senderDomain)
if err != nil {
return err
}
proto := &gomatrixserverlib.ProtoEvent{
Sender: sender,
SenderID: string(senderID),
RoomID: ev.RoomID(),
Type: ev.Type(),
StateKey: ev.StateKey(),

View file

@ -76,7 +76,7 @@ func CheckForSoftFail(
}
// Check if the event is allowed.
if err = gomatrixserverlib.Allowed(event.PDU, &authEvents, func(roomID, senderID string) (*spec.UserID, error) {
if err = gomatrixserverlib.Allowed(event.PDU, &authEvents, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return db.GetUserIDForSender(ctx, roomID, senderID)
}); err != nil {
// return true, nil
@ -139,8 +139,8 @@ func (ae *authEvents) JoinRules() (gomatrixserverlib.PDU, error) {
}
// Memmber implements gomatrixserverlib.AuthEventProvider
func (ae *authEvents) Member(stateKey string) (gomatrixserverlib.PDU, error) {
return ae.lookupEvent(types.MRoomMemberNID, stateKey), nil
func (ae *authEvents) Member(stateKey spec.SenderID) (gomatrixserverlib.PDU, error) {
return ae.lookupEvent(types.MRoomMemberNID, string(stateKey)), nil
}
// ThirdPartyInvite implements gomatrixserverlib.AuthEventProvider

View file

@ -282,7 +282,7 @@ func (r *Inputer) processRoomEvent(
// Check if the event is allowed by its auth events. If it isn't then
// we consider the event to be "rejected" — it will still be persisted.
if err = gomatrixserverlib.Allowed(event, &authEvents, func(roomID, senderID string) (*spec.UserID, error) {
if err = gomatrixserverlib.Allowed(event, &authEvents, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
}); err != nil {
isRejected = true
@ -501,7 +501,7 @@ func (r *Inputer) processRoomEvent(
func (r *Inputer) handleRemoteRoomUpgrade(ctx context.Context, event gomatrixserverlib.PDU) error {
oldRoomID := event.RoomID()
newRoomID := gjson.GetBytes(event.Content(), "replacement_room").Str
return r.DB.UpgradeRoom(ctx, oldRoomID, newRoomID, event.SenderID())
return r.DB.UpgradeRoom(ctx, oldRoomID, newRoomID, string(event.SenderID()))
}
// processStateBefore works out what the state is before the event and
@ -587,7 +587,7 @@ func (r *Inputer) processStateBefore(
stateBeforeAuth := gomatrixserverlib.NewAuthEvents(
gomatrixserverlib.ToPDUs(stateBeforeEvent),
)
if rejectionErr = gomatrixserverlib.Allowed(event, &stateBeforeAuth, func(roomID, senderID string) (*spec.UserID, error) {
if rejectionErr = gomatrixserverlib.Allowed(event, &stateBeforeAuth, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
}); rejectionErr != nil {
rejectionErr = fmt.Errorf("Allowed() failed for stateBeforeEvent: %w", rejectionErr)
@ -700,7 +700,7 @@ nextAuthEvent:
// Check the signatures of the event. If this fails then we'll simply
// skip it, because gomatrixserverlib.Allowed() will notice a problem
// if a critical event is missing anyway.
if err := gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.FSAPI.KeyRing(), func(roomID, senderID string) (*spec.UserID, error) {
if err := gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.FSAPI.KeyRing(), func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
}); err != nil {
continue nextAuthEvent
@ -718,7 +718,7 @@ nextAuthEvent:
}
// Check if the auth event should be rejected.
err := gomatrixserverlib.Allowed(authEvent, auth, func(roomID, senderID string) (*spec.UserID, error) {
err := gomatrixserverlib.Allowed(authEvent, auth, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
})
if isRejected = err != nil; isRejected {
@ -875,7 +875,7 @@ func (r *Inputer) kickGuests(ctx context.Context, event gomatrixserverlib.PDU, r
RoomID: event.RoomID(),
Type: spec.MRoomMember,
StateKey: &stateKey,
Sender: stateKey,
SenderID: stateKey,
PrevEvents: prevEvents,
}

View file

@ -58,7 +58,9 @@ func Test_EventAuth(t *testing.T) {
}
// Finally check that the event is NOT allowed
if err := gomatrixserverlib.Allowed(ev.PDU, &allower, func(roomID, senderID string) (*spec.UserID, error) { return spec.NewUserID(senderID, true) }); err == nil {
if err := gomatrixserverlib.Allowed(ev.PDU, &allower, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return spec.NewUserID(string(senderID), true)
}); err == nil {
t.Fatalf("event should not be allowed, but it was")
}
}

View file

@ -473,7 +473,7 @@ func (t *missingStateReq) resolveStatesAndCheck(ctx context.Context, roomVersion
stateEventList = append(stateEventList, state.StateEvents...)
}
resolvedStateEvents, err := gomatrixserverlib.ResolveConflicts(
roomVersion, gomatrixserverlib.ToPDUs(stateEventList), gomatrixserverlib.ToPDUs(authEventList), func(roomID, senderID string) (*spec.UserID, error) {
roomVersion, gomatrixserverlib.ToPDUs(stateEventList), gomatrixserverlib.ToPDUs(authEventList), func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return t.db.GetUserIDForSender(ctx, roomID, senderID)
},
)
@ -482,7 +482,7 @@ func (t *missingStateReq) resolveStatesAndCheck(ctx context.Context, roomVersion
}
// apply the current event
retryAllowedState:
if err = checkAllowedByState(backwardsExtremity, resolvedStateEvents, func(roomID, senderID string) (*spec.UserID, error) {
if err = checkAllowedByState(backwardsExtremity, resolvedStateEvents, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return t.db.GetUserIDForSender(ctx, roomID, senderID)
}); err != nil {
switch missing := err.(type) {
@ -569,7 +569,7 @@ func (t *missingStateReq) getMissingEvents(ctx context.Context, e gomatrixserver
// will be added and duplicates will be removed.
missingEvents := make([]gomatrixserverlib.PDU, 0, len(missingResp.Events))
for _, ev := range missingResp.Events.UntrustedEvents(roomVersion) {
if err = gomatrixserverlib.VerifyEventSignatures(ctx, ev, t.keys, func(roomID, senderID string) (*spec.UserID, error) {
if err = gomatrixserverlib.VerifyEventSignatures(ctx, ev, t.keys, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return t.db.GetUserIDForSender(ctx, roomID, senderID)
}); err != nil {
continue
@ -660,7 +660,7 @@ func (t *missingStateReq) lookupMissingStateViaState(
authEvents, stateEvents, err := gomatrixserverlib.CheckStateResponse(ctx, &fclient.RespState{
StateEvents: state.GetStateEvents(),
AuthEvents: state.GetAuthEvents(),
}, roomVersion, t.keys, nil, func(roomID, senderID string) (*spec.UserID, error) {
}, roomVersion, t.keys, nil, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return t.db.GetUserIDForSender(ctx, roomID, senderID)
})
if err != nil {
@ -897,7 +897,7 @@ func (t *missingStateReq) lookupEvent(ctx context.Context, roomVersion gomatrixs
t.log.WithField("missing_event_id", missingEventID).Warnf("Failed to get missing /event for event ID from %d server(s)", len(t.servers))
return nil, fmt.Errorf("wasn't able to find event via %d server(s)", len(t.servers))
}
if err := gomatrixserverlib.VerifyEventSignatures(ctx, event, t.keys, func(roomID, senderID string) (*spec.UserID, error) {
if err := gomatrixserverlib.VerifyEventSignatures(ctx, event, t.keys, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return t.db.GetUserIDForSender(ctx, roomID, senderID)
}); err != nil {
t.log.WithError(err).Warnf("Couldn't validate signature of event %q from /event", event.EventID())

View file

@ -96,14 +96,15 @@ func (r *Admin) PerformAdminEvacuateRoom(
RoomID: roomID,
Type: spec.MRoomMember,
StateKey: &stateKey,
Sender: stateKey,
SenderID: stateKey,
PrevEvents: prevEvents,
}
_, senderDomain, err = gomatrixserverlib.SplitID('@', fledglingEvent.Sender)
if err != nil {
userID, err := r.Queryer.QueryUserIDForSender(ctx, roomID, spec.SenderID(fledglingEvent.SenderID))
if err != nil || userID == nil {
continue
}
senderDomain = userID.Domain()
if fledglingEvent.Content, err = json.Marshal(memberContent); err != nil {
return nil, err
@ -233,10 +234,11 @@ func (r *Admin) PerformAdminDownloadState(
ctx context.Context,
roomID, userID string, serverName spec.ServerName,
) error {
_, senderDomain, err := r.Cfg.Matrix.SplitLocalID('@', userID)
fullUserID, err := spec.NewUserID(userID, true)
if err != nil {
return err
}
senderDomain := fullUserID.Domain()
roomInfo, err := r.DB.RoomInfo(ctx, roomID)
if err != nil {
@ -262,7 +264,7 @@ func (r *Admin) PerformAdminDownloadState(
return fmt.Errorf("r.Inputer.FSAPI.LookupState (%q): %s", fwdExtremity, err)
}
for _, authEvent := range state.GetAuthEvents().UntrustedEvents(roomInfo.RoomVersion) {
if err = gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.Inputer.KeyRing, func(roomID, senderID string) (*spec.UserID, error) {
if err = gomatrixserverlib.VerifyEventSignatures(ctx, authEvent, r.Inputer.KeyRing, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
}); err != nil {
continue
@ -270,7 +272,7 @@ func (r *Admin) PerformAdminDownloadState(
authEventMap[authEvent.EventID()] = authEvent
}
for _, stateEvent := range state.GetStateEvents().UntrustedEvents(roomInfo.RoomVersion) {
if err = gomatrixserverlib.VerifyEventSignatures(ctx, stateEvent, r.Inputer.KeyRing, func(roomID, senderID string) (*spec.UserID, error) {
if err = gomatrixserverlib.VerifyEventSignatures(ctx, stateEvent, r.Inputer.KeyRing, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
}); err != nil {
continue
@ -291,11 +293,15 @@ func (r *Admin) PerformAdminDownloadState(
stateIDs = append(stateIDs, stateEvent.EventID())
}
senderID, err := r.Queryer.QuerySenderIDForUser(ctx, roomID, *fullUserID)
if err != nil {
return err
}
proto := &gomatrixserverlib.ProtoEvent{
Type: "org.matrix.dendrite.state_download",
Sender: userID,
RoomID: roomID,
Content: spec.RawJSON("{}"),
Type: "org.matrix.dendrite.state_download",
SenderID: string(senderID),
RoomID: roomID,
Content: spec.RawJSON("{}"),
}
eventsNeeded, err := gomatrixserverlib.StateNeededForProtoEvent(proto)

View file

@ -121,7 +121,7 @@ func (r *Backfiller) backfillViaFederation(ctx context.Context, req *api.Perform
// Specifically the test "Outbound federation can backfill events"
events, err := gomatrixserverlib.RequestBackfill(
ctx, req.VirtualHost, requester,
r.KeyRing, req.RoomID, info.RoomVersion, req.PrevEventIDs(), 100, func(roomID, senderID string) (*spec.UserID, error) {
r.KeyRing, req.RoomID, info.RoomVersion, req.PrevEventIDs(), 100, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
},
)
@ -212,7 +212,7 @@ func (r *Backfiller) fetchAndStoreMissingEvents(ctx context.Context, roomVer gom
continue
}
loader := gomatrixserverlib.NewEventsLoader(roomVer, r.KeyRing, backfillRequester, backfillRequester.ProvideEvents, false)
result, err := loader.LoadAndVerify(ctx, res.PDUs, gomatrixserverlib.TopologicalOrderByPrevEvents, func(roomID, senderID string) (*spec.UserID, error) {
result, err := loader.LoadAndVerify(ctx, res.PDUs, gomatrixserverlib.TopologicalOrderByPrevEvents, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
})
if err != nil {

View file

@ -270,11 +270,19 @@ func (c *Creator) PerformCreateRoom(ctx context.Context, userID spec.UserID, roo
var builtEvents []*types.HeaderedEvent
authEvents := gomatrixserverlib.NewAuthEvents(nil)
senderID, err := c.RSAPI.QuerySenderIDForUser(ctx, roomID.String(), userID)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("rsapi.QuerySenderIDForUser failed")
return "", &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
for i, e := range eventsToMake {
depth := i + 1 // depth starts at 1
builder := verImpl.NewEventBuilderFromProtoEvent(&gomatrixserverlib.ProtoEvent{
Sender: userID.String(),
SenderID: string(senderID),
RoomID: roomID.String(),
Type: e.Type,
StateKey: &e.StateKey,
@ -308,7 +316,7 @@ func (c *Creator) PerformCreateRoom(ctx context.Context, userID spec.UserID, roo
}
}
if err = gomatrixserverlib.Allowed(ev, &authEvents, func(roomID, senderID string) (*spec.UserID, error) {
if err = gomatrixserverlib.Allowed(ev, &authEvents, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return c.DB.GetUserIDForSender(ctx, roomID, senderID)
}); err != nil {
util.GetLogger(ctx).WithError(err).Error("gomatrixserverlib.Allowed failed")
@ -409,11 +417,28 @@ func (c *Creator) PerformCreateRoom(ctx context.Context, userID spec.UserID, roo
// Process the invites.
var inviteEvent *types.HeaderedEvent
for _, invitee := range createRequest.InvitedUsers {
inviteeUserID, userIDErr := spec.NewUserID(invitee, true)
if userIDErr != nil {
util.GetLogger(ctx).WithError(userIDErr).Error("invalid UserID")
return "", &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
inviteeSenderID, queryErr := c.RSAPI.QuerySenderIDForUser(ctx, roomID.String(), *inviteeUserID)
if queryErr != nil {
util.GetLogger(ctx).WithError(queryErr).Error("rsapi.QuerySenderIDForUser failed")
return "", &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
inviteeString := string(inviteeSenderID)
proto := gomatrixserverlib.ProtoEvent{
Sender: userID.String(),
SenderID: string(senderID),
RoomID: roomID.String(),
Type: "m.room.member",
StateKey: &invitee,
StateKey: &inviteeString,
}
content := gomatrixserverlib.MemberContent{

View file

@ -98,7 +98,7 @@ func (r *Inviter) ProcessInviteMembership(
var outputUpdates []api.OutputEvent
var updater *shared.MembershipUpdater
userID, err := r.RSAPI.QueryUserIDForSender(ctx, inviteEvent.RoomID(), *inviteEvent.StateKey())
userID, err := r.RSAPI.QueryUserIDForSender(ctx, inviteEvent.RoomID(), spec.SenderID(*inviteEvent.StateKey()))
if err != nil {
return nil, api.ErrInvalidID{Err: fmt.Errorf("the user ID %s is invalid", *inviteEvent.StateKey())}
}
@ -148,15 +148,21 @@ func (r *Inviter) PerformInvite(
return err
}
invitedSenderID, err := r.RSAPI.QuerySenderIDForUser(ctx, event.RoomID(), *invitedUser)
if err != nil {
return fmt.Errorf("failed looking up senderID for invited user")
}
input := gomatrixserverlib.PerformInviteInput{
RoomID: *validRoomID,
InviteEvent: event.PDU,
InvitedUser: *invitedUser,
InvitedSenderID: invitedSenderID,
IsTargetLocal: isTargetLocal,
StrippedState: req.InviteRoomState,
MembershipQuerier: &api.MembershipQuerier{Roomserver: r.RSAPI},
StateQuerier: &QueryState{r.DB},
UserIDQuerier: func(roomID, senderID string) (*spec.UserID, error) {
UserIDQuerier: func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
},
}

View file

@ -175,15 +175,20 @@ func (r *Joiner) performJoinRoomByID(
}
// Prepare the template for the join event.
userID := req.UserID
_, userDomain, err := r.Cfg.Matrix.SplitLocalID('@', userID)
userID, err := spec.NewUserID(req.UserID, true)
if err != nil {
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("user ID %q is invalid: %w", userID, err)}
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("user ID %q is invalid: %w", req.UserID, err)}
}
senderID, err := r.RSAPI.QuerySenderIDForUser(ctx, req.RoomIDOrAlias, *userID)
if err != nil {
return "", "", rsAPI.ErrInvalidID{Err: fmt.Errorf("user ID %q is invalid: %w", req.UserID, err)}
}
senderIDString := string(senderID)
userDomain := userID.Domain()
proto := gomatrixserverlib.ProtoEvent{
Type: spec.MRoomMember,
Sender: userID,
StateKey: &userID,
SenderID: senderIDString,
StateKey: &senderIDString,
RoomID: req.RoomIDOrAlias,
Redacts: "",
}
@ -295,7 +300,7 @@ func (r *Joiner) performJoinRoomByID(
// is really no harm in just sending another membership event.
membershipReq := &api.QueryMembershipForUserRequest{
RoomID: req.RoomIDOrAlias,
UserID: userID,
UserID: userID.String(),
}
membershipRes := &api.QueryMembershipForUserResponse{}
_ = r.Queryer.QueryMembershipForUser(ctx, membershipReq, membershipRes)

View file

@ -152,11 +152,19 @@ func (r *Leaver) performLeaveRoomByID(
}
// Prepare the template for the leave event.
userID := req.UserID
fullUserID, err := spec.NewUserID(req.UserID, true)
if err != nil {
return nil, err
}
senderID, err := r.RSAPI.QuerySenderIDForUser(ctx, req.RoomID, *fullUserID)
if err != nil {
return nil, err
}
senderIDString := string(senderID)
proto := gomatrixserverlib.ProtoEvent{
Type: spec.MRoomMember,
Sender: userID,
StateKey: &userID,
SenderID: senderIDString,
StateKey: &senderIDString,
RoomID: req.RoomID,
Redacts: "",
}
@ -168,10 +176,7 @@ func (r *Leaver) performLeaveRoomByID(
}
// Get the sender domain.
_, senderDomain, serr := r.Cfg.Matrix.SplitLocalID('@', proto.Sender)
if serr != nil {
return nil, fmt.Errorf("sender %q is invalid", proto.Sender)
}
senderDomain := fullUserID.Domain()
// We know that the user is in the room at this point so let's build
// a leave event.

View file

@ -175,8 +175,16 @@ func moveLocalAliases(ctx context.Context,
return fmt.Errorf("Failed to get old room aliases: %w", err)
}
fullUserID, err := spec.NewUserID(userID, true)
if err != nil {
return fmt.Errorf("Failed to get userID: %w", err)
}
senderID, err := URSAPI.QuerySenderIDForUser(ctx, roomID, *fullUserID)
if err != nil {
return fmt.Errorf("Failed to get senderID: %w", err)
}
for _, alias := range aliasRes.Aliases {
removeAliasReq := api.RemoveRoomAliasRequest{SenderID: userID, Alias: alias}
removeAliasReq := api.RemoveRoomAliasRequest{SenderID: senderID, Alias: alias}
removeAliasRes := api.RemoveRoomAliasResponse{}
if err = URSAPI.RemoveRoomAlias(ctx, &removeAliasReq, &removeAliasRes); err != nil {
return fmt.Errorf("Failed to remove old room alias: %w", err)
@ -287,7 +295,15 @@ func (r *Upgrader) userIsAuthorized(ctx context.Context, userID, roomID string,
}
// Check for power level required to send tombstone event (marks the current room as obsolete),
// if not found, use the StateDefault power level
return pl.UserLevel(userID) >= pl.EventLevel("m.room.tombstone", true)
fullUserID, err := spec.NewUserID(userID, true)
if err != nil {
return false
}
senderID, err := r.URSAPI.QuerySenderIDForUser(ctx, roomID, *fullUserID)
if err != nil {
return false
}
return pl.UserLevel(senderID) >= pl.EventLevel("m.room.tombstone", true)
}
// nolint:gocyclo
@ -383,7 +399,16 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, oldRoom *api.Query
util.GetLogger(ctx).WithError(err).Error()
return nil, fmt.Errorf("Power level event content was invalid")
}
tempPowerLevelsEvent, powerLevelsOverridden := createTemporaryPowerLevels(powerLevelContent, userID)
fullUserID, err := spec.NewUserID(userID, true)
if err != nil {
return nil, err
}
senderID, err := r.URSAPI.QuerySenderIDForUser(ctx, roomID, *fullUserID)
if err != nil {
return nil, err
}
tempPowerLevelsEvent, powerLevelsOverridden := createTemporaryPowerLevels(powerLevelContent, senderID)
// Now do the join rules event, same as the create and membership
// events. We'll set a sane default of "invite" so that if the
@ -452,8 +477,16 @@ func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, user
for i, e := range eventsToMake {
depth := i + 1 // depth starts at 1
fullUserID, userIDErr := spec.NewUserID(userID, true)
if userIDErr != nil {
return userIDErr
}
senderID, queryErr := r.URSAPI.QuerySenderIDForUser(ctx, newRoomID, *fullUserID)
if queryErr != nil {
return queryErr
}
proto := gomatrixserverlib.ProtoEvent{
Sender: userID,
SenderID: string(senderID),
RoomID: newRoomID,
Type: e.Type,
StateKey: &e.StateKey,
@ -484,7 +517,7 @@ func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, user
}
if err = gomatrixserverlib.Allowed(event, &authEvents, func(roomID, senderID string) (*spec.UserID, error) {
if err = gomatrixserverlib.Allowed(event, &authEvents, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.URSAPI.QueryUserIDForSender(ctx, roomID, senderID)
}); err != nil {
return fmt.Errorf("Failed to auth new %q event: %w", builder.Type, err)
@ -530,21 +563,26 @@ func (r *Upgrader) makeTombstoneEvent(
}
func (r *Upgrader) makeHeaderedEvent(ctx context.Context, evTime time.Time, userID, roomID string, event gomatrixserverlib.FledglingEvent) (*types.HeaderedEvent, error) {
fullUserID, err := spec.NewUserID(userID, true)
if err != nil {
return nil, err
}
senderID, err := r.URSAPI.QuerySenderIDForUser(ctx, roomID, *fullUserID)
if err != nil {
return nil, err
}
proto := gomatrixserverlib.ProtoEvent{
Sender: userID,
SenderID: string(senderID),
RoomID: roomID,
Type: event.Type,
StateKey: &event.StateKey,
}
err := proto.SetContent(event.Content)
err = proto.SetContent(event.Content)
if err != nil {
return nil, fmt.Errorf("failed to set new %q event content: %w", proto.Type, err)
}
// Get the sender domain.
_, senderDomain, serr := r.Cfg.Matrix.SplitLocalID('@', proto.Sender)
if serr != nil {
return nil, fmt.Errorf("Failed to split user ID %q: %w", proto.Sender, err)
}
senderDomain := fullUserID.Domain()
identity, err := r.Cfg.Matrix.SigningIdentityFor(senderDomain)
if err != nil {
return nil, fmt.Errorf("failed to get signing identity for %q: %w", senderDomain, err)
@ -569,7 +607,7 @@ func (r *Upgrader) makeHeaderedEvent(ctx context.Context, evTime time.Time, user
stateEvents[i] = queryRes.StateEvents[i].PDU
}
provider := gomatrixserverlib.NewAuthEvents(stateEvents)
if err = gomatrixserverlib.Allowed(headeredEvent.PDU, &provider, func(roomID, senderID string) (*spec.UserID, error) {
if err = gomatrixserverlib.Allowed(headeredEvent.PDU, &provider, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.URSAPI.QueryUserIDForSender(ctx, roomID, senderID)
}); err != nil {
return nil, api.ErrNotAllowed{Err: fmt.Errorf("failed to auth new %q event: %w", proto.Type, err)} // TODO: Is this error string comprehensible to the client?
@ -578,7 +616,7 @@ func (r *Upgrader) makeHeaderedEvent(ctx context.Context, evTime time.Time, user
return headeredEvent, nil
}
func createTemporaryPowerLevels(powerLevelContent *gomatrixserverlib.PowerLevelContent, userID string) (gomatrixserverlib.FledglingEvent, bool) {
func createTemporaryPowerLevels(powerLevelContent *gomatrixserverlib.PowerLevelContent, senderID spec.SenderID) (gomatrixserverlib.FledglingEvent, bool) {
// Work out what power level we need in order to be able to send events
// of all types into the room.
neededPowerLevel := powerLevelContent.StateDefault
@ -603,8 +641,8 @@ func createTemporaryPowerLevels(powerLevelContent *gomatrixserverlib.PowerLevelC
// If the user who is upgrading the room doesn't already have sufficient
// power, then elevate their power levels.
if tempPowerLevelContent.UserLevel(userID) < neededPowerLevel {
tempPowerLevelContent.Users[userID] = neededPowerLevel
if tempPowerLevelContent.UserLevel(senderID) < neededPowerLevel {
tempPowerLevelContent.Users[string(senderID)] = neededPowerLevel
powerLevelsOverridden = true
}

View file

@ -159,7 +159,7 @@ func (r *Queryer) QueryStateAfterEvents(
}
stateEvents, err = gomatrixserverlib.ResolveConflicts(
info.RoomVersion, gomatrixserverlib.ToPDUs(stateEvents), gomatrixserverlib.ToPDUs(authEvents), func(roomID, senderID string) (*spec.UserID, error) {
info.RoomVersion, gomatrixserverlib.ToPDUs(stateEvents), gomatrixserverlib.ToPDUs(authEvents), func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
},
)
@ -637,7 +637,7 @@ func (r *Queryer) QueryStateAndAuthChain(
if request.ResolveState {
stateEvents, err = gomatrixserverlib.ResolveConflicts(
info.RoomVersion, gomatrixserverlib.ToPDUs(stateEvents), gomatrixserverlib.ToPDUs(authEvents), func(roomID, senderID string) (*spec.UserID, error) {
info.RoomVersion, gomatrixserverlib.ToPDUs(stateEvents), gomatrixserverlib.ToPDUs(authEvents), func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
},
)
@ -975,10 +975,10 @@ func (r *Queryer) QueryRestrictedJoinAllowed(ctx context.Context, roomID spec.Ro
return verImpl.CheckRestrictedJoin(ctx, r.Cfg.Global.ServerName, &api.JoinRoomQuerier{Roomserver: r}, roomID, userID)
}
func (r *Queryer) QuerySenderIDForUser(ctx context.Context, roomID string, userID spec.UserID) (string, error) {
func (r *Queryer) QuerySenderIDForUser(ctx context.Context, roomID string, userID spec.UserID) (spec.SenderID, error) {
return r.DB.GetSenderIDForUser(ctx, roomID, userID)
}
func (r *Queryer) QueryUserIDForSender(ctx context.Context, roomID string, senderID string) (*spec.UserID, error) {
func (r *Queryer) QueryUserIDForSender(ctx context.Context, roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return r.DB.GetUserIDForSender(ctx, roomID, senderID)
}

View file

@ -392,7 +392,7 @@ func TestPurgeRoom(t *testing.T) {
type fledglingEvent struct {
Type string
StateKey *string
Sender string
SenderID string
RoomID string
Redacts string
Depth int64
@ -405,7 +405,7 @@ func mustCreateEvent(t *testing.T, ev fledglingEvent) (result *types.HeaderedEve
seed := make([]byte, ed25519.SeedSize) // zero seed
key := ed25519.NewKeyFromSeed(seed)
eb := gomatrixserverlib.MustGetRoomVersion(roomVer).NewEventBuilderFromProtoEvent(&gomatrixserverlib.ProtoEvent{
Sender: ev.Sender,
SenderID: ev.SenderID,
Type: ev.Type,
StateKey: ev.StateKey,
RoomID: ev.RoomID,
@ -444,7 +444,7 @@ func TestRedaction(t *testing.T) {
builderEv := mustCreateEvent(t, fledglingEvent{
Type: spec.MRoomRedaction,
Sender: alice.ID,
SenderID: alice.ID,
RoomID: room.ID,
Redacts: redactedEvent.EventID(),
Depth: redactedEvent.Depth() + 1,
@ -461,7 +461,7 @@ func TestRedaction(t *testing.T) {
builderEv := mustCreateEvent(t, fledglingEvent{
Type: spec.MRoomRedaction,
Sender: alice.ID,
SenderID: alice.ID,
RoomID: room.ID,
Redacts: redactedEvent.EventID(),
Depth: redactedEvent.Depth() + 1,
@ -478,7 +478,7 @@ func TestRedaction(t *testing.T) {
builderEv := mustCreateEvent(t, fledglingEvent{
Type: spec.MRoomRedaction,
Sender: bob.ID,
SenderID: bob.ID,
RoomID: room.ID,
Redacts: redactedEvent.EventID(),
Depth: redactedEvent.Depth() + 1,
@ -494,7 +494,7 @@ func TestRedaction(t *testing.T) {
builderEv := mustCreateEvent(t, fledglingEvent{
Type: spec.MRoomRedaction,
Sender: charlie.ID,
SenderID: charlie.ID,
RoomID: room.ID,
Redacts: redactedEvent.EventID(),
Depth: redactedEvent.Depth() + 1,

View file

@ -44,7 +44,7 @@ type StateResolutionStorage interface {
AddState(ctx context.Context, roomNID types.RoomNID, stateBlockNIDs []types.StateBlockNID, state []types.StateEntry) (types.StateSnapshotNID, error)
Events(ctx context.Context, roomVersion gomatrixserverlib.RoomVersion, eventNIDs []types.EventNID) ([]types.Event, error)
EventsFromIDs(ctx context.Context, roomInfo *types.RoomInfo, eventIDs []string) ([]types.Event, error)
GetUserIDForSender(ctx context.Context, roomID string, senderID string) (*spec.UserID, error)
GetUserIDForSender(ctx context.Context, roomID string, senderID spec.SenderID) (*spec.UserID, error)
}
type StateResolution struct {
@ -947,7 +947,7 @@ func (v *StateResolution) resolveConflictsV1(
}
// Resolve the conflicts.
resolvedEvents := gomatrixserverlib.ResolveStateConflicts(conflictedEvents, authEvents, func(roomID, senderID string) (*spec.UserID, error) {
resolvedEvents := gomatrixserverlib.ResolveStateConflicts(conflictedEvents, authEvents, func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return v.db.GetUserIDForSender(ctx, roomID, senderID)
})
@ -1061,7 +1061,7 @@ func (v *StateResolution) resolveConflictsV2(
conflictedEvents,
nonConflictedEvents,
authEvents,
func(roomID, senderID string) (*spec.UserID, error) {
func(roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return v.db.GetUserIDForSender(ctx, roomID, senderID)
},
)

View file

@ -167,9 +167,9 @@ type Database interface {
// GetKnownUsers searches all users that userID knows about.
GetKnownUsers(ctx context.Context, userID, searchString string, limit int) ([]string, error)
// GetKnownUsers tries to obtain the current mxid for a given user.
GetUserIDForSender(ctx context.Context, roomID string, senderID string) (*spec.UserID, error)
GetUserIDForSender(ctx context.Context, roomID string, senderID spec.SenderID) (*spec.UserID, error)
// GetKnownUsers tries to obtain the current senderID for a given user.
GetSenderIDForUser(ctx context.Context, roomID string, userID spec.UserID) (string, error)
GetSenderIDForUser(ctx context.Context, roomID string, userID spec.UserID) (spec.SenderID, error)
// GetKnownRooms returns a list of all rooms we know about.
GetKnownRooms(ctx context.Context) ([]string, error)
// ForgetRoom sets a flag in the membership table, that the user wishes to forget a specific room
@ -215,7 +215,7 @@ type RoomDatabase interface {
GetOrCreateEventTypeNID(ctx context.Context, eventType string) (eventTypeNID types.EventTypeNID, err error)
GetOrCreateEventStateKeyNID(ctx context.Context, eventStateKey *string) (types.EventStateKeyNID, error)
GetStateEvent(ctx context.Context, roomID, evType, stateKey string) (*types.HeaderedEvent, error)
GetUserIDForSender(ctx context.Context, roomID string, senderID string) (*spec.UserID, error)
GetUserIDForSender(ctx context.Context, roomID string, senderID spec.SenderID) (*spec.UserID, error)
}
type EventDatabase interface {

View file

@ -101,7 +101,7 @@ func (u *MembershipUpdater) Update(newMembership tables.MembershipState, event *
var inserted bool // Did the query result in a membership change?
var retired []string // Did we retire any updates in the process?
return inserted, retired, u.d.Writer.Do(u.d.DB, u.txn, func(txn *sql.Tx) error {
senderUserNID, err := u.d.assignStateKeyNID(u.ctx, u.txn, event.SenderID())
senderUserNID, err := u.d.assignStateKeyNID(u.ctx, u.txn, string(event.SenderID()))
if err != nil {
return fmt.Errorf("u.d.AssignStateKeyNID: %w", err)
}

View file

@ -252,6 +252,6 @@ func (u *RoomUpdater) MembershipUpdater(targetUserNID types.EventStateKeyNID, ta
return u.d.membershipUpdaterTxn(u.ctx, u.txn, u.roomInfo.RoomNID, targetUserNID, targetLocal)
}
func (u *RoomUpdater) GetUserIDForSender(ctx context.Context, roomID string, senderID string) (*spec.UserID, error) {
func (u *RoomUpdater) GetUserIDForSender(ctx context.Context, roomID string, senderID spec.SenderID) (*spec.UserID, error) {
return u.d.GetUserIDForSender(ctx, roomID, senderID)
}

View file

@ -990,13 +990,13 @@ func (d *EventDatabase) MaybeRedactEvent(
// TODO: Don't hack senderID into userID here (pseudoIDs)
sender1Domain := ""
sender1, err1 := spec.NewUserID(redactedEvent.SenderID(), true)
sender1, err1 := spec.NewUserID(string(redactedEvent.SenderID()), true)
if err1 == nil {
sender1Domain = string(sender1.Domain())
}
// TODO: Don't hack senderID into userID here (pseudoIDs)
sender2Domain := ""
sender2, err2 := spec.NewUserID(redactionEvent.SenderID(), true)
sender2, err2 := spec.NewUserID(string(redactionEvent.SenderID()), true)
if err2 == nil {
sender2Domain = string(sender2.Domain())
}
@ -1524,14 +1524,14 @@ func (d *Database) GetKnownUsers(ctx context.Context, userID, searchString strin
return d.MembershipTable.SelectKnownUsers(ctx, nil, stateKeyNID, searchString, limit)
}
func (d *Database) GetUserIDForSender(ctx context.Context, roomID string, senderID string) (*spec.UserID, error) {
func (d *Database) GetUserIDForSender(ctx context.Context, roomID string, senderID spec.SenderID) (*spec.UserID, error) {
// TODO: Use real logic once DB for pseudoIDs is in place
return spec.NewUserID(senderID, true)
return spec.NewUserID(string(senderID), true)
}
func (d *Database) GetSenderIDForUser(ctx context.Context, roomID string, userID spec.UserID) (string, error) {
func (d *Database) GetSenderIDForUser(ctx context.Context, roomID string, userID spec.UserID) (spec.SenderID, error) {
// TODO: Use real logic once DB for pseudoIDs is in place
return userID.String(), nil
return spec.SenderID(userID.String()), nil
}
// GetKnownRooms returns a list of all rooms we know about.