Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

Add MXIDMapping for pseudoID rooms #3112

Merged
merged 24 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d63685a
Add MXIDMapping for pseudoID rooms, also sign with the pseudoIDKey
S7evinK Jun 13, 2023
781bd80
Update GMSL
S7evinK Jun 13, 2023
50615c7
Sign MXIDMapping for join events
S7evinK Jun 14, 2023
34ab4d1
Get signing identity depending on the room version
S7evinK Jun 14, 2023
93a2687
Merge branch 'main' of github.com:matrix-org/dendrite into s7evink/mx…
S7evinK Jun 14, 2023
fd99925
Correctly resolve userID
S7evinK Jun 15, 2023
b655017
Workaround problem with senderID/userID
S7evinK Jun 15, 2023
8f967e5
Partially working pseudo IDs
S7evinK Jun 15, 2023
7f41a6a
Update GMSL
S7evinK Jun 15, 2023
07960a5
Cleanup, fix test
S7evinK Jun 15, 2023
e6fd65b
Fix empty senderID
S7evinK Jun 15, 2023
4406c85
Merge main, fix issues
S7evinK Jun 15, 2023
0f30550
Merge branch 'main' of github.com:matrix-org/dendrite into s7evink/mx…
S7evinK Jun 15, 2023
b4d5c83
Update test
S7evinK Jun 15, 2023
31609d6
Replace senderID with userID in powerlevel events, workaround invites
S7evinK Jun 15, 2023
708e950
Update GMSL
S7evinK Jun 15, 2023
75ffbc6
Linter
S7evinK Jun 15, 2023
45003cc
Also set the prev_content, if present
S7evinK Jun 16, 2023
f2e9815
Change the powerlevels from userID -> senderID
S7evinK Jun 16, 2023
52c888c
Update GMSL
S7evinK Jun 16, 2023
a33ef5b
Merge branch 'main' of github.com:matrix-org/dendrite into s7evink/mx…
S7evinK Jun 28, 2023
88b0f6a
We don't need to sign these events (correctly)?
S7evinK Jun 28, 2023
6697f43
Move creation of pseudo ID keys to the roomserver
S7evinK Jun 28, 2023
86f217f
Make it possible to join pseudo ID rooms (#3119)
S7evinK Jun 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions clientapi/routing/membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ import (
"time"

"github.com/getsentry/sentry-go"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/matrix-org/gomatrixserverlib/spec"

appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
"github.com/matrix-org/dendrite/clientapi/httputil"
Expand All @@ -36,6 +32,9 @@ import (
"github.com/matrix-org/dendrite/roomserver/types"
"github.com/matrix-org/dendrite/setup/config"
userapi "github.com/matrix-org/dendrite/userapi/api"
"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/matrix-org/gomatrixserverlib/spec"

"github.com/matrix-org/util"
)
Expand Down Expand Up @@ -433,11 +432,6 @@ func buildMembershipEvent(
return nil, err
}

identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
if err != nil {
return nil, err
}

userID, err := spec.NewUserID(device.UserID, true)
if err != nil {
return nil, err
Expand All @@ -459,6 +453,31 @@ func buildMembershipEvent(
if err != nil {
return nil, err
}

// If we're inviting a local user, we can generate the needed key here.
if targetSenderID == "" && cfg.Matrix.IsLocalServerName(targetID.Domain()) { // todo: remove
devonh marked this conversation as resolved.
Show resolved Hide resolved
var roomVersion gomatrixserverlib.RoomVersion
roomVersion, err = rsAPI.QueryRoomVersionForRoom(ctx, roomID)
if err != nil {
return nil, err
}
switch roomVersion {
case gomatrixserverlib.RoomVersionPseudoIDs:
var key ed25519.PrivateKey
key, err = rsAPI.GetOrCreateUserRoomPrivateKey(ctx, *targetID, *validRoomID)
if err != nil {
return nil, err
}
targetSenderID = spec.SenderIDFromPseudoIDKey(key)
}

}

identity, err := rsAPI.SigningIdentityFor(ctx, *validRoomID, *userID)
if err != nil {
return nil, err
}

return buildMembershipEventDirect(ctx, targetSenderID, reason, profile.DisplayName, profile.AvatarURL,
senderID, device.UserDomain(), membership, roomID, isDirect, identity.KeyID, identity.PrivateKey, evTime, rsAPI)
}
Expand Down
20 changes: 12 additions & 8 deletions clientapi/routing/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func SetAvatarURL(
}
}

response, err := updateProfile(req.Context(), rsAPI, device, profile, userID, cfg, evTime)
response, err := updateProfile(req.Context(), rsAPI, device, profile, userID, evTime)
if err != nil {
return response
}
Expand Down Expand Up @@ -246,7 +246,7 @@ func SetDisplayName(
}
}

response, err := updateProfile(req.Context(), rsAPI, device, profile, userID, cfg, evTime)
response, err := updateProfile(req.Context(), rsAPI, device, profile, userID, evTime)
if err != nil {
return response
}
Expand All @@ -260,7 +260,7 @@ func SetDisplayName(
func updateProfile(
ctx context.Context, rsAPI api.ClientRoomserverAPI, device *userapi.Device,
profile *authtypes.Profile,
userID string, cfg *config.ClientAPI, evTime time.Time,
userID string, evTime time.Time,
) (util.JSONResponse, error) {
var res api.QueryRoomsForUserResponse
err := rsAPI.QueryRoomsForUser(ctx, &api.QueryRoomsForUserRequest{
Expand All @@ -285,7 +285,7 @@ func updateProfile(
}

events, err := buildMembershipEvents(
ctx, device, res.RoomIDs, *profile, userID, cfg, evTime, rsAPI,
ctx, res.RoomIDs, *profile, userID, evTime, rsAPI,
)
switch e := err.(type) {
case nil:
Expand Down Expand Up @@ -356,9 +356,8 @@ func getProfile(

func buildMembershipEvents(
ctx context.Context,
device *userapi.Device,
roomIDs []string,
newProfile authtypes.Profile, userID string, cfg *config.ClientAPI,
newProfile authtypes.Profile, userID string,
evTime time.Time, rsAPI api.ClientRoomserverAPI,
) ([]*types.HeaderedEvent, error) {
evs := []*types.HeaderedEvent{}
Expand Down Expand Up @@ -395,12 +394,17 @@ func buildMembershipEvents(
return nil, err
}

identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
user, err := spec.NewUserID(userID, true)
if err != nil {
return nil, err
}

event, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, evTime, rsAPI, nil)
identity, err := rsAPI.SigningIdentityFor(ctx, *validRoomID, *user)
if err != nil {
return nil, err
}

event, err := eventutil.QueryAndBuildEvent(ctx, &proto, &identity, evTime, rsAPI, nil)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions clientapi/routing/redaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func SendRedaction(
}
}

identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
identity, err := rsAPI.SigningIdentityFor(req.Context(), *validRoomID, *deviceUserID)
if err != nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
Expand All @@ -159,7 +159,7 @@ func SendRedaction(
}

var queryRes roomserverAPI.QueryLatestEventsAndStateResponse
e, err := eventutil.QueryAndBuildEvent(req.Context(), &proto, identity, time.Now(), rsAPI, &queryRes)
e, err := eventutil.QueryAndBuildEvent(req.Context(), &proto, &identity, time.Now(), rsAPI, &queryRes)
if errors.Is(err, eventutil.ErrRoomNoExists{}) {
return util.JSONResponse{
Code: http.StatusNotFound,
Expand Down
7 changes: 3 additions & 4 deletions clientapi/routing/sendevent.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func SendEvent(
}
}

e, resErr := generateSendEvent(req.Context(), r, device, roomID, eventType, stateKey, cfg, rsAPI, evTime)
e, resErr := generateSendEvent(req.Context(), r, device, roomID, eventType, stateKey, rsAPI, evTime)
if resErr != nil {
return *resErr
}
Expand Down Expand Up @@ -261,7 +261,6 @@ func generateSendEvent(
r map[string]interface{},
device *userapi.Device,
roomID, eventType string, stateKey *string,
cfg *config.ClientAPI,
rsAPI api.ClientRoomserverAPI,
evTime time.Time,
) (gomatrixserverlib.PDU, *util.JSONResponse) {
Expand Down Expand Up @@ -304,7 +303,7 @@ func generateSendEvent(
}
}

identity, err := cfg.Matrix.SigningIdentityFor(device.UserDomain())
identity, err := rsAPI.SigningIdentityFor(ctx, *validRoomID, *fullUserID)
if err != nil {
return nil, &util.JSONResponse{
Code: http.StatusInternalServerError,
Expand All @@ -313,7 +312,7 @@ func generateSendEvent(
}

var queryRes api.QueryLatestEventsAndStateResponse
e, err := eventutil.QueryAndBuildEvent(ctx, &proto, identity, evTime, rsAPI, &queryRes)
e, err := eventutil.QueryAndBuildEvent(ctx, &proto, &identity, evTime, rsAPI, &queryRes)
switch specificErr := err.(type) {
case nil:
case eventutil.ErrRoomNoExists:
Expand Down
4 changes: 2 additions & 2 deletions clientapi/routing/server_notices.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ func SendServerNotice(
"body": r.Content.Body,
"msgtype": r.Content.MsgType,
}
e, resErr := generateSendEvent(ctx, request, senderDevice, roomID, "m.room.message", nil, cfgClient, rsAPI, time.Now())
e, resErr := generateSendEvent(ctx, request, senderDevice, roomID, "m.room.message", nil, rsAPI, time.Now())
if resErr != nil {
logrus.Errorf("failed to send message: %+v", resErr)
return *resErr
Expand Down Expand Up @@ -350,7 +350,7 @@ func getSenderDevice(
if len(deviceRes.Devices) > 0 {
// If there were changes to the profile, create a new membership event
if displayNameChanged || avatarChanged {
_, err = updateProfile(ctx, rsAPI, &deviceRes.Devices[0], profile, accRes.Account.UserID, cfg, time.Now())
_, err = updateProfile(ctx, rsAPI, &deviceRes.Devices[0], profile, accRes.Account.UserID, time.Now())
if err != nil {
return nil, err
}
Expand Down
15 changes: 10 additions & 5 deletions federationapi/consumers/roomserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (s *OutputRoomEventConsumer) processMessage(ore api.OutputNewRoomEvent, rew
evs[i] = addsStateEvents[i].PDU
}

addsJoinedHosts, err := JoinedHostsFromEvents(evs)
addsJoinedHosts, err := JoinedHostsFromEvents(s.ctx, evs, s.rsAPI)
if err != nil {
return err
}
Expand Down Expand Up @@ -345,7 +345,7 @@ func (s *OutputRoomEventConsumer) joinedHostsAtEvent(
return nil, err
}

combinedAddsJoinedHosts, err := JoinedHostsFromEvents(combinedAddsEvents)
combinedAddsJoinedHosts, err := JoinedHostsFromEvents(s.ctx, combinedAddsEvents, s.rsAPI)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -394,7 +394,7 @@ func (s *OutputRoomEventConsumer) joinedHostsAtEvent(
// JoinedHostsFromEvents turns a list of state events into a list of joined hosts.
// This errors if one of the events was invalid.
// It should be impossible for an invalid event to get this far in the pipeline.
func JoinedHostsFromEvents(evs []gomatrixserverlib.PDU) ([]types.JoinedHost, error) {
func JoinedHostsFromEvents(ctx context.Context, evs []gomatrixserverlib.PDU, rsAPI api.FederationRoomserverAPI) ([]types.JoinedHost, error) {
var joinedHosts []types.JoinedHost
for _, ev := range evs {
if ev.Type() != "m.room.member" || ev.StateKey() == nil {
Expand All @@ -407,12 +407,17 @@ func JoinedHostsFromEvents(evs []gomatrixserverlib.PDU) ([]types.JoinedHost, err
if membership != spec.Join {
continue
}
_, serverName, err := gomatrixserverlib.SplitID('@', *ev.StateKey())
validRoomID, err := spec.NewRoomID(ev.RoomID())
if err != nil {
return nil, err
}
userID, err := rsAPI.QueryUserIDForSender(ctx, *validRoomID, spec.SenderID(*ev.StateKey()))
if err != nil {
return nil, err
}

joinedHosts = append(joinedHosts, types.JoinedHost{
MemberEventID: ev.EventID(), ServerName: serverName,
MemberEventID: ev.EventID(), ServerName: userID.Domain(),
})
}
return joinedHosts, nil
Expand Down
4 changes: 2 additions & 2 deletions federationapi/internal/perform.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ func (r *FederationInternalAPI) performJoinUsingServer(
return "", keyErr
}

return spec.SenderID(spec.Base64Bytes(key).Encode()), nil
return spec.SenderIDFromPseudoIDKey(key), nil
},
}
response, joinErr := gomatrixserverlib.PerformJoin(ctx, r, joinInput)
Expand All @@ -200,7 +200,7 @@ func (r *FederationInternalAPI) performJoinUsingServer(
// joining a room, waiting for 200 OK then changing device keys and have those keys not be sent
// to other servers (this was a cause of a flakey sytest "Local device key changes get to remote servers")
// The events are trusted now as we performed auth checks above.
joinedHosts, err := consumers.JoinedHostsFromEvents(response.StateSnapshot.GetStateEvents().TrustedEvents(response.JoinEvent.Version(), false))
joinedHosts, err := consumers.JoinedHostsFromEvents(ctx, response.StateSnapshot.GetStateEvents().TrustedEvents(response.JoinEvent.Version(), false), r.rsAPI)
if err != nil {
return fmt.Errorf("JoinedHostsFromEvents: failed to get joined hosts: %s", err)
}
Expand Down
10 changes: 8 additions & 2 deletions federationapi/routing/join.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,13 @@ func MakeJoin(
}

createJoinTemplate := func(proto *gomatrixserverlib.ProtoEvent) (gomatrixserverlib.PDU, []gomatrixserverlib.PDU, error) {
identity, signErr := cfg.Matrix.SigningIdentityFor(request.Destination())
// TODO: remove this once the join dance understands pseudo IDs
var dummyUserID *spec.UserID
dummyUserID, err = spec.NewUserID(fmt.Sprintf("@dummy:%s", request.Destination()), true)
devonh marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, nil, err
}
identity, signErr := rsAPI.SigningIdentityFor(httpReq.Context(), roomID, *dummyUserID)
if signErr != nil {
util.GetLogger(httpReq.Context()).WithError(signErr).Errorf("obtaining signing identity for %s failed", request.Destination())
return nil, nil, spec.NotFound(fmt.Sprintf("Server name %q does not exist", request.Destination()))
Expand All @@ -73,7 +79,7 @@ func MakeJoin(
queryRes := api.QueryLatestEventsAndStateResponse{
RoomVersion: roomVersion,
}
event, signErr := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, identity, time.Now(), rsAPI, &queryRes)
event, signErr := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, &identity, time.Now(), rsAPI, &queryRes)
switch e := signErr.(type) {
case nil:
case eventutil.ErrRoomNoExists:
Expand Down
10 changes: 8 additions & 2 deletions federationapi/routing/leave.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,20 @@ func MakeLeave(
}

createLeaveTemplate := func(proto *gomatrixserverlib.ProtoEvent) (gomatrixserverlib.PDU, []gomatrixserverlib.PDU, error) {
identity, signErr := cfg.Matrix.SigningIdentityFor(request.Destination())
// TODO: remove this once the leave dance understands pseudo IDs
var dummyUserID *spec.UserID
dummyUserID, err = spec.NewUserID(fmt.Sprintf("@dummy:%s", request.Destination()), true)
devonh marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, nil, err
}
identity, signErr := rsAPI.SigningIdentityFor(httpReq.Context(), roomID, *dummyUserID)
if signErr != nil {
util.GetLogger(httpReq.Context()).WithError(signErr).Errorf("obtaining signing identity for %s failed", request.Destination())
return nil, nil, spec.NotFound(fmt.Sprintf("Server name %q does not exist", request.Destination()))
}

queryRes := api.QueryLatestEventsAndStateResponse{}
event, buildErr := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, identity, time.Now(), rsAPI, &queryRes)
event, buildErr := eventutil.QueryAndBuildEvent(httpReq.Context(), proto, &identity, time.Now(), rsAPI, &queryRes)
switch e := buildErr.(type) {
case nil:
case eventutil.ErrRoomNoExists:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530
github.com/matrix-org/gomatrixserverlib v0.0.0-20230614140620-4dea2171c8f1
github.com/matrix-org/gomatrixserverlib v0.0.0-20230615155745-0c9f18717a12
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66
github.com/mattn/go-sqlite3 v1.14.16
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 h1:s7fexw
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U=
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230614140620-4dea2171c8f1 h1:k75Fy0iQVbDjvddip/x898+BdyopBNAfL1BMNx0awA0=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230614140620-4dea2171c8f1/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230615155745-0c9f18717a12 h1:KqEEv5zDBgsLV/dkQPBpuMg65U8Us7AK2T8uQMKyu4k=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230615155745-0c9f18717a12/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a h1:awrPDf9LEFySxTLKYBMCiObelNx/cBuv/wzllvCCH3A=
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a/go.mod h1:HchJX9oKMXaT2xYFs0Ha/6Zs06mxLU8k6F1ODnrGkeQ=
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=
Expand Down
4 changes: 4 additions & 0 deletions roomserver/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/ed25519"

"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/matrix-org/gomatrixserverlib/spec"
"github.com/matrix-org/util"

Expand Down Expand Up @@ -184,6 +185,7 @@ type ClientRoomserverAPI interface {
QueryBulkStateContentAPI
QueryEventsAPI
QuerySenderIDAPI
UserRoomPrivateKeyCreator
QueryMembershipForUser(ctx context.Context, req *QueryMembershipForUserRequest, res *QueryMembershipForUserResponse) error
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
QueryRoomsForUser(ctx context.Context, req *QueryRoomsForUserRequest, res *QueryRoomsForUserResponse) error
Expand Down Expand Up @@ -213,6 +215,7 @@ type ClientRoomserverAPI interface {
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
SigningIdentityFor(ctx context.Context, roomID spec.RoomID, senderID spec.UserID) (fclient.SigningIdentity, error)
}

type UserRoomserverAPI interface {
Expand All @@ -233,6 +236,7 @@ type FederationRoomserverAPI interface {
QuerySenderIDAPI
UserRoomPrivateKeyCreator

SigningIdentityFor(ctx context.Context, roomID spec.RoomID, senderID spec.UserID) (fclient.SigningIdentity, error)
// QueryServerBannedFromRoom returns whether a server is banned from a room by server ACLs.
QueryServerBannedFromRoom(ctx context.Context, req *QueryServerBannedFromRoomRequest, res *QueryServerBannedFromRoomResponse) error
QueryMembershipForUser(ctx context.Context, req *QueryMembershipForUserRequest, res *QueryMembershipForUserResponse) error
Expand Down
2 changes: 2 additions & 0 deletions roomserver/api/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ type QueryServerJoinedToRoomResponse struct {
RoomExists bool `json:"room_exists"`
// True if we still believe that the server is participating in the room
IsInRoom bool `json:"is_in_room"`
// The roomversion if joined to room
RoomVersion gomatrixserverlib.RoomVersion
}

// QueryServerAllowedToSeeEventRequest is a request to QueryServerAllowedToSeeEvent
Expand Down
Loading