From 0c902f49b681b2407e40b141f5663e7f7fe6a8ed Mon Sep 17 00:00:00 2001 From: Devon Hudson Date: Fri, 2 Jun 2023 15:58:42 -0600 Subject: [PATCH] Refine SenderID/UserID usage --- clientapi/routing/directory.go | 41 ++++++++++++++++--- internal/pushrules/evaluate.go | 7 ++-- internal/pushrules/evaluate_test.go | 8 ++-- roomserver/api/alias.go | 4 +- roomserver/api/api.go | 6 +++ roomserver/internal/alias.go | 12 +++--- .../internal/perform/perform_create_room.go | 6 +-- .../internal/perform/perform_upgrade.go | 4 +- roomserver/internal/query/query.go | 5 +++ roomserver/roomserver_test.go | 2 +- 10 files changed, 69 insertions(+), 26 deletions(-) diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go index c786f8cc4..f1f729cc3 100644 --- a/clientapi/routing/directory.go +++ b/clientapi/routing/directory.go @@ -181,10 +181,25 @@ func SetLocalAlias( return *resErr } + userID, err := spec.NewUserID(device.UserID, true) + if err != nil { + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: spec.InternalServerError{Err: "UserID for device is invalid"}, + } + } + + deviceSenderID, err := rsAPI.QuerySenderIDForRoom(req.Context(), alias, *userID) + if err != nil { + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: spec.InternalServerError{Err: "Could not find SenderID for this device"}, + } + } queryReq := roomserverAPI.SetRoomAliasRequest{ - UserID: device.UserID, - RoomID: r.RoomID, - Alias: alias, + SenderID: deviceSenderID, + RoomID: r.RoomID, + Alias: alias, } var queryRes roomserverAPI.SetRoomAliasResponse if err := rsAPI.SetRoomAlias(req.Context(), &queryReq, &queryRes); err != nil { @@ -215,9 +230,25 @@ func RemoveLocalAlias( alias string, rsAPI roomserverAPI.ClientRoomserverAPI, ) util.JSONResponse { + userID, err := spec.NewUserID(device.UserID, true) + if err != nil { + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: spec.InternalServerError{Err: "UserID for device is invalid"}, + } + } + + deviceSenderID, err := rsAPI.QuerySenderIDForRoom(req.Context(), alias, *userID) + if err != nil { + return util.JSONResponse{ + Code: http.StatusInternalServerError, + JSON: spec.InternalServerError{Err: "Could not find SenderID for this device"}, + } + } + queryReq := roomserverAPI.RemoveRoomAliasRequest{ - Alias: alias, - UserID: device.UserID, + Alias: alias, + SenderID: deviceSenderID, } var queryRes roomserverAPI.RemoveRoomAliasResponse if err := rsAPI.RemoveRoomAlias(req.Context(), &queryReq, &queryRes); err != nil { diff --git a/internal/pushrules/evaluate.go b/internal/pushrules/evaluate.go index 399041ad3..646cc9014 100644 --- a/internal/pushrules/evaluate.go +++ b/internal/pushrules/evaluate.go @@ -113,11 +113,12 @@ func ruleMatches(rule *Rule, kind Kind, event gomatrixserverlib.PDU, ec Evaluati return rule.RuleID == event.RoomID(), nil case SenderKind: + userID := "" sender, err := event.UserID() - if err != nil { - return false, nil + if err == nil { + userID = sender.String() } - return rule.RuleID == sender.String(), nil + return rule.RuleID == userID, nil default: return false, nil diff --git a/internal/pushrules/evaluate_test.go b/internal/pushrules/evaluate_test.go index 5045a864e..e3bfe48d0 100644 --- a/internal/pushrules/evaluate_test.go +++ b/internal/pushrules/evaluate_test.go @@ -82,11 +82,11 @@ func TestRuleMatches(t *testing.T) { {"contentMatch", ContentKind, Rule{Enabled: true, Pattern: pointer("b")}, `{"content":{"body":"abc"}}`, true}, {"contentNoMatch", ContentKind, Rule{Enabled: true, Pattern: pointer("d")}, `{"content":{"body":"abc"}}`, false}, - {"roomMatch", RoomKind, Rule{Enabled: true, RuleID: "!room@example.com"}, `{"room_id":"!room@example.com"}`, true}, - {"roomNoMatch", RoomKind, Rule{Enabled: true, RuleID: "!room@example.com"}, `{"room_id":"!otherroom@example.com"}`, false}, + {"roomMatch", RoomKind, Rule{Enabled: true, RuleID: "!room:example.com"}, `{"room_id":"!room:example.com"}`, true}, + {"roomNoMatch", RoomKind, Rule{Enabled: true, RuleID: "!room:example.com"}, `{"room_id":"!otherroom:example.com"}`, false}, - {"senderMatch", SenderKind, Rule{Enabled: true, RuleID: "@user@example.com"}, `{"sender":"@user@example.com"}`, true}, - {"senderNoMatch", SenderKind, Rule{Enabled: true, RuleID: "@user@example.com"}, `{"sender":"@otheruser@example.com"}`, false}, + {"senderMatch", SenderKind, Rule{Enabled: true, RuleID: "@user:example.com"}, `{"sender":"@user:example.com"}`, true}, + {"senderNoMatch", SenderKind, Rule{Enabled: true, RuleID: "@user:example.com"}, `{"sender":"@otheruser:example.com"}`, false}, } for _, tst := range tsts { t.Run(tst.Name, func(t *testing.T) { diff --git a/roomserver/api/alias.go b/roomserver/api/alias.go index 37892a44a..0404c1cdd 100644 --- a/roomserver/api/alias.go +++ b/roomserver/api/alias.go @@ -19,7 +19,7 @@ import "regexp" // SetRoomAliasRequest is a request to SetRoomAlias type SetRoomAliasRequest struct { // ID of the user setting the alias - UserID string `json:"user_id"` + SenderID string `json:"user_id"` // New alias for the room Alias string `json:"alias"` // The room ID the alias is referring to @@ -62,7 +62,7 @@ type GetAliasesForRoomIDResponse struct { // RemoveRoomAliasRequest is a request to RemoveRoomAlias type RemoveRoomAliasRequest struct { // ID of the user removing the alias - UserID string `json:"user_id"` + SenderID string `json:"user_id"` // The room alias to remove Alias string `json:"alias"` } diff --git a/roomserver/api/api.go b/roomserver/api/api.go index 7cb3379e0..be0e9b16e 100644 --- a/roomserver/api/api.go +++ b/roomserver/api/api.go @@ -65,6 +65,11 @@ type InputRoomEventsAPI interface { ) } +type QuerySenderIDAPI interface { + // Accepts either roomID or alias + QuerySenderIDForRoom(ctx context.Context, roomAliasOrID string, userID spec.UserID) (string, error) +} + // Query the latest events and state for a room from the room server. type QueryLatestEventsAndStateAPI interface { QueryLatestEventsAndState(ctx context.Context, req *QueryLatestEventsAndStateRequest, res *QueryLatestEventsAndStateResponse) error @@ -158,6 +163,7 @@ type ClientRoomserverAPI interface { QueryLatestEventsAndStateAPI QueryBulkStateContentAPI QueryEventsAPI + QuerySenderIDAPI 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 diff --git a/roomserver/internal/alias.go b/roomserver/internal/alias.go index 0951172a0..da275725d 100644 --- a/roomserver/internal/alias.go +++ b/roomserver/internal/alias.go @@ -51,7 +51,7 @@ func (r *RoomserverInternalAPI) SetRoomAlias( response.AliasExists = false // Save the new alias - if err := r.DB.SetRoomAlias(ctx, request.Alias, request.RoomID, request.UserID); err != nil { + if err := r.DB.SetRoomAlias(ctx, request.Alias, request.RoomID, request.SenderID); err != nil { return err } @@ -119,7 +119,7 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias( request *api.RemoveRoomAliasRequest, response *api.RemoveRoomAliasResponse, ) error { - _, virtualHost, err := r.Cfg.Global.SplitLocalID('@', request.UserID) + _, virtualHost, err := r.Cfg.Global.SplitLocalID('@', request.SenderID) if err != nil { return err } @@ -140,7 +140,7 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias( return fmt.Errorf("r.DB.GetCreatorIDForAlias: %w", err) } - if creatorID != request.UserID { + if creatorID != request.SenderID { var plEvent *types.HeaderedEvent var pls *gomatrixserverlib.PowerLevelContent @@ -154,7 +154,7 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias( return fmt.Errorf("plEvent.PowerLevels: %w", err) } - if pls.UserLevel(request.UserID) < pls.EventLevel(spec.MRoomCanonicalAlias, true) { + if pls.UserLevel(request.SenderID) < pls.EventLevel(spec.MRoomCanonicalAlias, true) { response.Removed = false return nil } @@ -172,8 +172,8 @@ func (r *RoomserverInternalAPI) RemoveRoomAlias( return err } - sender := request.UserID - if request.UserID != ev.SenderID() { + sender := request.SenderID + if request.SenderID != ev.SenderID() { sender = ev.SenderID() } diff --git a/roomserver/internal/perform/perform_create_room.go b/roomserver/internal/perform/perform_create_room.go index 41194832d..1ae47d945 100644 --- a/roomserver/internal/perform/perform_create_room.go +++ b/roomserver/internal/perform/perform_create_room.go @@ -350,9 +350,9 @@ func (c *Creator) PerformCreateRoom(ctx context.Context, userID spec.UserID, roo // been taken. if roomAlias != "" { aliasReq := api.SetRoomAliasRequest{ - Alias: roomAlias, - RoomID: roomID.String(), - UserID: userID.String(), + Alias: roomAlias, + RoomID: roomID.String(), + SenderID: userID.String(), } var aliasResp api.SetRoomAliasResponse diff --git a/roomserver/internal/perform/perform_upgrade.go b/roomserver/internal/perform/perform_upgrade.go index ff4a6a1dc..7e615f2a3 100644 --- a/roomserver/internal/perform/perform_upgrade.go +++ b/roomserver/internal/perform/perform_upgrade.go @@ -176,13 +176,13 @@ func moveLocalAliases(ctx context.Context, } for _, alias := range aliasRes.Aliases { - removeAliasReq := api.RemoveRoomAliasRequest{UserID: userID, Alias: alias} + removeAliasReq := api.RemoveRoomAliasRequest{SenderID: userID, 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) } - setAliasReq := api.SetRoomAliasRequest{UserID: userID, Alias: alias, RoomID: newRoomID} + setAliasReq := api.SetRoomAliasRequest{SenderID: userID, Alias: alias, RoomID: newRoomID} setAliasRes := api.SetRoomAliasResponse{} if err = URSAPI.SetRoomAlias(ctx, &setAliasReq, &setAliasRes); err != nil { return fmt.Errorf("Failed to set new room alias: %w", err) diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index effcc90d7..15d226a74 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -1034,3 +1034,8 @@ func (r *Queryer) QueryRestrictedJoinAllowed(ctx context.Context, req *api.Query } return nil } + +func (r *Queryer) QuerySenderIDForRoom(ctx context.Context, roomAliasOrID string, userID spec.UserID) (string, error) { + // TODO: implement this properly with pseudoIDs + return userID.String(), nil +} diff --git a/roomserver/roomserver_test.go b/roomserver/roomserver_test.go index d19ebebe4..6ff03025a 100644 --- a/roomserver/roomserver_test.go +++ b/roomserver/roomserver_test.go @@ -267,7 +267,7 @@ func TestPurgeRoom(t *testing.T) { } aliasResp := &api.SetRoomAliasResponse{} - if err = rsAPI.SetRoomAlias(ctx, &api.SetRoomAliasRequest{RoomID: room.ID, Alias: "myalias", UserID: alice.ID}, aliasResp); err != nil { + if err = rsAPI.SetRoomAlias(ctx, &api.SetRoomAliasRequest{RoomID: room.ID, Alias: "myalias", SenderID: alice.ID}, aliasResp); err != nil { t.Fatal(err) } // check the alias is actually there