Use *spec.SenderID for QuerySenderIDForUser (#3164)

There are cases where a dendrite instance is unaware of a pseudo ID for
a user, the user is not a member of that room. To represent this case,
we currently use the 'zero' value, which is often not checked and so
causes errors later down the line. To make this case more explict, and
to be consistent with `QueryUserIDForSender`, this PR changes this to
use a pointer (and `nil` to mean no sender ID).

Signed-off-by: `Sam Wedgwood <sam@wedgwood.dev>`
This commit is contained in:
Sam Wedgwood 2023-08-02 11:12:14 +01:00 committed by GitHub
parent af13fa1c75
commit c7193e24d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 129 additions and 65 deletions

View file

@ -204,9 +204,15 @@ func SetLocalAlias(
Code: http.StatusInternalServerError,
JSON: spec.Unknown("internal server error"),
}
} else if senderID == nil {
util.GetLogger(req.Context()).WithField("roomID", *roomID).WithField("userID", *userID).Error("Sender ID not found")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.Unknown("internal server error"),
}
}
aliasAlreadyExists, err := rsAPI.SetRoomAlias(req.Context(), senderID, *roomID, alias)
aliasAlreadyExists, err := rsAPI.SetRoomAlias(req.Context(), *senderID, *roomID, alias)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("aliasAPI.SetRoomAlias failed")
return util.JSONResponse{
@ -293,14 +299,14 @@ func RemoveLocalAlias(
}
}
// TODO: how to handle this case? missing user/room keys seem to be a whole new class of errors
if deviceSenderID == "" {
if deviceSenderID == nil {
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.Unknown("internal server error"),
}
}
aliasFound, aliasRemoved, err := rsAPI.RemoveRoomAlias(req.Context(), deviceSenderID, alias)
aliasFound, aliasRemoved, err := rsAPI.RemoveRoomAlias(req.Context(), *deviceSenderID, alias)
if err != nil {
util.GetLogger(req.Context()).WithError(err).Error("aliasAPI.RemoveRoomAlias failed")
return util.JSONResponse{
@ -385,7 +391,7 @@ func SetVisibility(
}
}
senderID, err := rsAPI.QuerySenderIDForUser(req.Context(), *validRoomID, *deviceUserID)
if err != nil {
if err != nil || senderID == nil {
return util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.Unknown("failed to find senderID for this user"),
@ -416,7 +422,7 @@ func SetVisibility(
// NOTSPEC: Check if the user's power is greater than power required to change m.room.canonical_alias event
power, _ := gomatrixserverlib.NewPowerLevelContentFromEvent(queryEventsRes.StateEvents[0].PDU)
if power.UserLevel(senderID) < power.EventLevel(spec.MRoomCanonicalAlias, true) {
if power.UserLevel(*senderID) < power.EventLevel(spec.MRoomCanonicalAlias, true) {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: spec.Forbidden("userID doesn't have power level to change visibility"),

View file

@ -71,7 +71,7 @@ func SendBan(
}
}
senderID, err := rsAPI.QuerySenderIDForUser(req.Context(), *validRoomID, *deviceUserID)
if err != nil {
if err != nil || senderID == nil {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: spec.Forbidden("You don't have permission to ban this user, unknown senderID"),
@ -87,7 +87,7 @@ func SendBan(
if errRes != nil {
return *errRes
}
allowedToBan := pl.UserLevel(senderID) >= pl.Ban
allowedToBan := pl.UserLevel(*senderID) >= pl.Ban
if !allowedToBan {
return util.JSONResponse{
Code: http.StatusForbidden,
@ -169,7 +169,7 @@ func SendKick(
}
}
senderID, err := rsAPI.QuerySenderIDForUser(req.Context(), *validRoomID, *deviceUserID)
if err != nil {
if err != nil || senderID == nil {
return util.JSONResponse{
Code: http.StatusForbidden,
JSON: spec.Forbidden("You don't have permission to kick this user, unknown senderID"),
@ -185,7 +185,7 @@ func SendKick(
if errRes != nil {
return *errRes
}
allowedToKick := pl.UserLevel(senderID) >= pl.Kick
allowedToKick := pl.UserLevel(*senderID) >= pl.Kick
if !allowedToKick {
return util.JSONResponse{
Code: http.StatusForbidden,
@ -476,6 +476,8 @@ func buildMembershipEvent(
senderID, err := rsAPI.QuerySenderIDForUser(ctx, *validRoomID, *userID)
if err != nil {
return nil, err
} else if senderID == nil {
return nil, fmt.Errorf("no sender ID for %s in %s", *userID, *validRoomID)
}
targetID, err := spec.NewUserID(targetUserID, true)
@ -485,6 +487,8 @@ func buildMembershipEvent(
targetSenderID, err := rsAPI.QuerySenderIDForUser(ctx, *validRoomID, *targetID)
if err != nil {
return nil, err
} else if targetSenderID == nil {
return nil, fmt.Errorf("no sender ID for %s in %s", *targetID, *validRoomID)
}
identity, err := rsAPI.SigningIdentityFor(ctx, *validRoomID, *userID)
@ -492,8 +496,8 @@ func buildMembershipEvent(
return nil, err
}
return buildMembershipEventDirect(ctx, targetSenderID, reason, profile.DisplayName, profile.AvatarURL,
senderID, device.UserDomain(), membership, roomID, isDirect, identity.KeyID, identity.PrivateKey, evTime, rsAPI)
return buildMembershipEventDirect(ctx, *targetSenderID, reason, profile.DisplayName, profile.AvatarURL,
*senderID, device.UserDomain(), membership, roomID, isDirect, identity.KeyID, identity.PrivateKey, evTime, rsAPI)
}
// loadProfile lookups the profile of a given user from the database and returns

View file

@ -16,6 +16,7 @@ package routing
import (
"context"
"fmt"
"net/http"
"time"
@ -362,8 +363,10 @@ func buildMembershipEvents(
senderID, err := rsAPI.QuerySenderIDForUser(ctx, *validRoomID, *fullUserID)
if err != nil {
return nil, err
} else if senderID == nil {
return nil, fmt.Errorf("sender ID not found for %s in %s", *fullUserID, *validRoomID)
}
senderIDString := string(senderID)
senderIDString := string(*senderID)
proto := gomatrixserverlib.ProtoEvent{
SenderID: senderIDString,
RoomID: roomID,

View file

@ -74,6 +74,16 @@ func SendRedaction(
return *resErr
}
// if user is member of room, and sender ID is nil, then this user doesn't have a pseudo ID for some reason,
// which is unexpected.
if senderID == nil {
util.GetLogger(req.Context()).WithField("userID", *deviceUserID).WithField("roomID", roomID).Error("missing sender ID for user, despite having membership")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.Unknown("internal server error"),
}
}
if txnID != nil {
// Try to fetch response from transactionsCache
if res, ok := txnCache.FetchTransaction(device.AccessToken, *txnID, req.URL); ok {
@ -98,7 +108,7 @@ func SendRedaction(
// "Users may redact their own events, and any user with a power level greater than or equal
// to the redact power level of the room may redact events there"
// https://matrix.org/docs/spec/client_server/r0.6.1#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
allowedToRedact := ev.SenderID() == senderID
allowedToRedact := ev.SenderID() == *senderID
if !allowedToRedact {
plEvent := roomserverAPI.GetStateEvent(req.Context(), rsAPI, roomID, gomatrixserverlib.StateKeyTuple{
EventType: spec.MRoomPowerLevels,
@ -119,7 +129,7 @@ func SendRedaction(
),
}
}
allowedToRedact = pl.UserLevel(senderID) >= pl.Redact
allowedToRedact = pl.UserLevel(*senderID) >= pl.Redact
}
if !allowedToRedact {
return util.JSONResponse{
@ -136,7 +146,7 @@ func SendRedaction(
// create the new event and set all the fields we can
proto := gomatrixserverlib.ProtoEvent{
SenderID: string(senderID),
SenderID: string(*senderID),
RoomID: roomID,
Type: spec.MRoomRedaction,
Redacts: eventID,

View file

@ -251,8 +251,10 @@ func updatePowerLevels(req *http.Request, r map[string]interface{}, roomID strin
senderID, err := rsAPI.QuerySenderIDForUser(req.Context(), *validRoomID, *uID)
if err != nil {
return err
} else if senderID == nil {
return fmt.Errorf("sender ID not found for %s in %s", uID, *validRoomID)
}
userMap[string(senderID)] = level
userMap[string(*senderID)] = level
delete(userMap, user)
}
r["users"] = userMap
@ -314,7 +316,7 @@ func generateSendEvent(
}
}
senderID, err := rsAPI.QuerySenderIDForUser(ctx, *validRoomID, *fullUserID)
if err != nil {
if err != nil || senderID == nil {
return nil, &util.JSONResponse{
Code: http.StatusNotFound,
JSON: spec.NotFound("Unable to find senderID for user"),
@ -323,7 +325,7 @@ func generateSendEvent(
// create the new event and set all the fields we can
proto := gomatrixserverlib.ProtoEvent{
SenderID: string(senderID),
SenderID: string(*senderID),
RoomID: roomID,
Type: eventType,
StateKey: stateKey,

View file

@ -366,9 +366,11 @@ func emit3PIDInviteEvent(
sender, err := rsAPI.QuerySenderIDForUser(ctx, *validRoomID, *userID)
if err != nil {
return err
} else if sender == nil {
return fmt.Errorf("sender ID not found for %s in %s", *userID, *validRoomID)
}
proto := &gomatrixserverlib.ProtoEvent{
SenderID: string(sender),
SenderID: string(*sender),
RoomID: roomID,
Type: "m.room.third_party_invite",
StateKey: &res.Token,

View file

@ -40,8 +40,9 @@ func (f *fedRoomserverAPI) QueryUserIDForSender(ctx context.Context, roomID spec
return spec.NewUserID(string(senderID), true)
}
func (f *fedRoomserverAPI) QuerySenderIDForUser(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (spec.SenderID, error) {
return spec.SenderID(userID.String()), nil
func (f *fedRoomserverAPI) QuerySenderIDForUser(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (*spec.SenderID, error) {
senderID := spec.SenderID(userID.String())
return &senderID, nil
}
// PerformJoin will call this function

View file

@ -481,8 +481,10 @@ func (r *FederationInternalAPI) PerformLeave(
senderID, err := r.rsAPI.QuerySenderIDForUser(ctx, *roomID, *userID)
if err != nil {
return err
} else if senderID == nil {
return fmt.Errorf("sender ID not found for %s in %s", *userID, *roomID)
}
senderIDString := string(senderID)
senderIDString := string(*senderID)
respMakeLeave.LeaveEvent.Type = spec.MRoomMember
respMakeLeave.LeaveEvent.SenderID = senderIDString
respMakeLeave.LeaveEvent.StateKey = &senderIDString

View file

@ -99,7 +99,7 @@ func MakeJoin(
Roomserver: rsAPI,
}
senderID, err := rsAPI.QuerySenderIDForUser(httpReq.Context(), roomID, userID)
senderIDPtr, err := rsAPI.QuerySenderIDForUser(httpReq.Context(), roomID, userID)
if err != nil {
util.GetLogger(httpReq.Context()).WithError(err).Error("rsAPI.QuerySenderIDForUser failed")
return util.JSONResponse{
@ -108,8 +108,11 @@ func MakeJoin(
}
}
if senderID == "" {
var senderID spec.SenderID
if senderIDPtr == nil {
senderID = spec.SenderID(userID.String())
} else {
senderID = *senderIDPtr
}
input := gomatrixserverlib.HandleMakeJoinInput{

View file

@ -94,11 +94,17 @@ func MakeLeave(
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
} else if senderID == nil {
util.GetLogger(httpReq.Context()).WithField("roomID", roomID).WithField("userID", userID).Error("rsAPI.QuerySenderIDForUser returned nil sender ID")
return util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.InternalServerError{},
}
}
input := gomatrixserverlib.HandleMakeLeaveInput{
UserID: userID,
SenderID: senderID,
SenderID: *senderID,
RoomID: roomID,
RoomVersion: roomVersion,
RequestOrigin: request.Origin(),

4
go.mod
View file

@ -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-20230721154317-b5b0448aa378
github.com/matrix-org/gomatrixserverlib v0.0.0-20230802090652-1b697d109d87
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.17
@ -36,7 +36,7 @@ require (
github.com/prometheus/client_golang v1.16.0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.2
github.com/tidwall/gjson v1.14.4
github.com/tidwall/gjson v1.15.0
github.com/tidwall/sjson v1.2.5
github.com/uber/jaeger-client-go v2.30.0+incompatible
github.com/uber/jaeger-lib v2.4.1+incompatible

14
go.sum
View file

@ -113,6 +113,7 @@ github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
@ -175,12 +176,14 @@ github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
github.com/huandu/xstrings v1.0.0 h1:pO2K/gKgKaat5LdpAhxhluX2GPQMaI3W5FUz/I/UnWk=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/errors v1.0.0 h1:yiq7kjCLll1BiaRuNY53MGI0+EQ3rF6GB+wvboZDefM=
github.com/juju/errors v1.0.0/go.mod h1:B5x9thDqx0wIMH3+aLIMP9HjItInYWObRovoCFM5Qe8=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kardianos/minwinsvc v1.0.2 h1:JmZKFJQrmTGa/WiW+vkJXKmfzdjabuEW4Tirj5lLdR0=
github.com/kardianos/minwinsvc v1.0.2/go.mod h1:LUZNYhNmxujx2tR7FbdxqYJ9XDDoCd3MQcl1o//FWl4=
@ -207,8 +210,10 @@ 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-20230721154317-b5b0448aa378 h1:a6sfiJiNZWVbPRHvEB/YlpqSg+Dh7El+824mzccSk68=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230721154317-b5b0448aa378/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230801102756-b66c2627dc08 h1:uy1mlUraKrEbUzZ3KrSQp/nLxMccVhIJM8mZSIbQzeA=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230801102756-b66c2627dc08/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230802090652-1b697d109d87 h1:z0RFUknidOShRxkvjT3ovGCWnusyplu6OLjFHcbDYaE=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230802090652-1b697d109d87/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=
@ -241,6 +246,7 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt/v2 v2.4.1 h1:Y35W1dgbbz2SQUYDPCaclXcuqleVmpbRa7646Jf2EX4=
github.com/nats-io/jwt/v2 v2.4.1/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=
github.com/nats-io/nats-server/v2 v2.9.19 h1:OF9jSKZGo425C/FcVVIvNgpd36CUe7aVTTXEZRJk6kA=
@ -322,8 +328,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.15.0 h1:5n/pM+v3r5ujuNl4YLZLsQ+UE5jlkLVm7jMzT5Mpolw=
github.com/tidwall/gjson v1.15.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=

View file

@ -97,7 +97,7 @@ type InputRoomEventsAPI interface {
}
type QuerySenderIDAPI interface {
QuerySenderIDForUser(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (spec.SenderID, error)
QuerySenderIDForUser(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (*spec.SenderID, error)
QueryUserIDForSender(ctx context.Context, roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error)
}

View file

@ -292,10 +292,12 @@ func (r *Admin) PerformAdminDownloadState(
senderID, err := r.Queryer.QuerySenderIDForUser(ctx, *validRoomID, *fullUserID)
if err != nil {
return err
} else if senderID == nil {
return fmt.Errorf("sender ID not found for %s in %s", *fullUserID, *validRoomID)
}
proto := &gomatrixserverlib.ProtoEvent{
Type: "org.matrix.dendrite.state_download",
SenderID: string(senderID),
SenderID: string(*senderID),
RoomID: roomID,
Content: spec.RawJSON("{}"),
}

View file

@ -133,6 +133,8 @@ func (r *Inviter) PerformInvite(
senderID, err := r.RSAPI.QuerySenderIDForUser(ctx, req.InviteInput.RoomID, req.InviteInput.Inviter)
if err != nil {
return err
} else if senderID == nil {
return fmt.Errorf("sender ID not found for %s in %s", req.InviteInput.Inviter, req.InviteInput.RoomID)
}
info, err := r.DB.RoomInfo(ctx, req.InviteInput.RoomID.String())
if err != nil {
@ -140,7 +142,7 @@ func (r *Inviter) PerformInvite(
}
proto := gomatrixserverlib.ProtoEvent{
SenderID: string(senderID),
SenderID: string(*senderID),
RoomID: req.InviteInput.RoomID.String(),
Type: "m.room.member",
}
@ -187,7 +189,7 @@ func (r *Inviter) PerformInvite(
UserIDQuerier: func(roomID spec.RoomID, senderID spec.SenderID) (*spec.UserID, error) {
return r.RSAPI.QueryUserIDForSender(ctx, roomID, senderID)
},
SenderIDQuerier: func(roomID spec.RoomID, userID spec.UserID) (spec.SenderID, error) {
SenderIDQuerier: func(roomID spec.RoomID, userID spec.UserID) (*spec.SenderID, error) {
return r.RSAPI.QuerySenderIDForUser(ctx, roomID, userID)
},
SenderIDCreator: func(ctx context.Context, userID spec.UserID, roomID spec.RoomID, roomVersion string) (spec.SenderID, ed25519.PrivateKey, error) {

View file

@ -201,11 +201,11 @@ func (r *Joiner) performJoinRoomByID(
if err == nil && info != nil {
switch info.RoomVersion {
case gomatrixserverlib.RoomVersionPseudoIDs:
senderID, err = r.Queryer.QuerySenderIDForUser(ctx, *roomID, *userID)
if err == nil {
senderIDPtr, queryErr := r.Queryer.QuerySenderIDForUser(ctx, *roomID, *userID)
if queryErr == nil {
checkInvitePending = true
}
if senderID == "" {
if senderIDPtr == nil {
// create user room key if needed
key, keyErr := r.RSAPI.GetOrCreateUserRoomPrivateKey(ctx, *userID, *roomID)
if keyErr != nil {
@ -213,6 +213,8 @@ func (r *Joiner) performJoinRoomByID(
return "", "", fmt.Errorf("GetOrCreateUserRoomPrivateKey failed: %w", keyErr)
}
senderID = spec.SenderIDFromPseudoIDKey(key)
} else {
senderID = *senderIDPtr
}
default:
checkInvitePending = true

View file

@ -73,6 +73,7 @@ func (r *Leaver) PerformLeave(
return nil, fmt.Errorf("room ID %q is invalid", req.RoomID)
}
// nolint:gocyclo
func (r *Leaver) performLeaveRoomByID(
ctx context.Context,
req *api.PerformLeaveRequest,
@ -83,20 +84,20 @@ func (r *Leaver) performLeaveRoomByID(
return nil, err
}
leaver, err := r.RSAPI.QuerySenderIDForUser(ctx, *roomID, req.Leaver)
if err != nil {
if err != nil || leaver == nil {
return nil, fmt.Errorf("leaver %s has no matching senderID in this room", req.Leaver.String())
}
// If there's an invite outstanding for the room then respond to
// that.
isInvitePending, senderUser, eventID, _, err := helpers.IsInvitePending(ctx, r.DB, req.RoomID, leaver)
isInvitePending, senderUser, eventID, _, err := helpers.IsInvitePending(ctx, r.DB, req.RoomID, *leaver)
if err == nil && isInvitePending {
sender, serr := r.RSAPI.QueryUserIDForSender(ctx, *roomID, senderUser)
if serr != nil || sender == nil {
return nil, fmt.Errorf("sender %q has no matching userID", senderUser)
}
if !r.Cfg.Matrix.IsLocalServerName(sender.Domain()) {
return r.performFederatedRejectInvite(ctx, req, res, *sender, eventID, leaver)
return r.performFederatedRejectInvite(ctx, req, res, *sender, eventID, *leaver)
}
// check that this is not a "server notice room"
accData := &userapi.QueryAccountDataResponse{}
@ -132,7 +133,7 @@ func (r *Leaver) performLeaveRoomByID(
StateToFetch: []gomatrixserverlib.StateKeyTuple{
{
EventType: spec.MRoomMember,
StateKey: string(leaver),
StateKey: string(*leaver),
},
},
}
@ -157,7 +158,7 @@ func (r *Leaver) performLeaveRoomByID(
}
// Prepare the template for the leave event.
senderIDString := string(leaver)
senderIDString := string(*leaver)
proto := gomatrixserverlib.ProtoEvent{
Type: spec.MRoomMember,
SenderID: senderIDString,

View file

@ -62,10 +62,13 @@ func (r *Upgrader) performRoomUpgrade(
if err != nil {
util.GetLogger(ctx).WithError(err).Error("Failed getting senderID for user")
return "", err
} else if senderID == nil {
util.GetLogger(ctx).WithField("userID", userID).WithField("roomID", *fullRoomID).Error("No senderID for user")
return "", fmt.Errorf("No sender ID for %s in %s", userID, *fullRoomID)
}
// 1. Check if the user is authorized to actually perform the upgrade (can send m.room.tombstone)
if !r.userIsAuthorized(ctx, senderID, roomID) {
if !r.userIsAuthorized(ctx, *senderID, roomID) {
return "", api.ErrNotAllowed{Err: fmt.Errorf("You don't have permission to upgrade the room, power level too low.")}
}
@ -83,20 +86,20 @@ func (r *Upgrader) performRoomUpgrade(
}
// Make the tombstone event
tombstoneEvent, pErr := r.makeTombstoneEvent(ctx, evTime, senderID, userID.Domain(), roomID, newRoomID)
tombstoneEvent, pErr := r.makeTombstoneEvent(ctx, evTime, *senderID, userID.Domain(), roomID, newRoomID)
if pErr != nil {
return "", pErr
}
// Generate the initial events we need to send into the new room. This includes copied state events and bans
// as well as the power level events needed to set up the room
eventsToMake, pErr := r.generateInitialEvents(ctx, oldRoomRes, senderID, roomID, roomVersion, tombstoneEvent)
eventsToMake, pErr := r.generateInitialEvents(ctx, oldRoomRes, *senderID, roomID, roomVersion, tombstoneEvent)
if pErr != nil {
return "", pErr
}
// Send the setup events to the new room
if pErr = r.sendInitialEvents(ctx, evTime, senderID, userID.Domain(), newRoomID, roomVersion, eventsToMake); pErr != nil {
if pErr = r.sendInitialEvents(ctx, evTime, *senderID, userID.Domain(), newRoomID, roomVersion, eventsToMake); pErr != nil {
return "", pErr
}
@ -111,17 +114,17 @@ func (r *Upgrader) performRoomUpgrade(
}
// If the old room had a canonical alias event, it should be deleted in the old room
if pErr = r.clearOldCanonicalAliasEvent(ctx, oldRoomRes, evTime, senderID, userID.Domain(), roomID); pErr != nil {
if pErr = r.clearOldCanonicalAliasEvent(ctx, oldRoomRes, evTime, *senderID, userID.Domain(), roomID); pErr != nil {
return "", pErr
}
// 4. Move local aliases to the new room
if pErr = moveLocalAliases(ctx, roomID, newRoomID, senderID, r.URSAPI); pErr != nil {
if pErr = moveLocalAliases(ctx, roomID, newRoomID, *senderID, r.URSAPI); pErr != nil {
return "", pErr
}
// 6. Restrict power levels in the old room
if pErr = r.restrictOldRoomPowerLevels(ctx, evTime, senderID, userID.Domain(), roomID); pErr != nil {
if pErr = r.restrictOldRoomPowerLevels(ctx, evTime, *senderID, userID.Domain(), roomID); pErr != nil {
return "", pErr
}

View file

@ -283,7 +283,7 @@ func (r *Queryer) QueryMembershipForUser(
return err
}
return r.QueryMembershipForSenderID(ctx, *roomID, senderID, response)
return r.QueryMembershipForSenderID(ctx, *roomID, *senderID, response)
}
// QueryMembershipAtEvent returns the known memberships at a given event.
@ -1009,21 +1009,26 @@ func (r *Queryer) QueryRestrictedJoinAllowed(ctx context.Context, roomID spec.Ro
return verImpl.CheckRestrictedJoin(ctx, r.Cfg.Global.ServerName, &api.JoinRoomQuerier{Roomserver: r}, roomID, senderID)
}
func (r *Queryer) QuerySenderIDForUser(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (spec.SenderID, error) {
func (r *Queryer) QuerySenderIDForUser(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (*spec.SenderID, error) {
version, err := r.DB.GetRoomVersion(ctx, roomID.String())
if err != nil {
return "", err
return nil, err
}
switch version {
case gomatrixserverlib.RoomVersionPseudoIDs:
key, err := r.DB.SelectUserRoomPublicKey(ctx, userID, roomID)
if err != nil {
return "", err
return nil, err
} else if key == nil {
return nil, nil
} else {
senderID := spec.SenderID(spec.Base64Bytes(key).Encode())
return &senderID, nil
}
return spec.SenderID(spec.Base64Bytes(key).Encode()), nil
default:
return spec.SenderID(userID.String()), nil
senderID := spec.SenderID(userID.String())
return &senderID, nil
}
}

View file

@ -529,8 +529,9 @@ func (r *testRoomserverAPI) QueryUserIDForSender(ctx context.Context, roomID spe
return spec.NewUserID(string(senderID), true)
}
func (r *testRoomserverAPI) QuerySenderIDForUser(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (spec.SenderID, error) {
return spec.SenderID(userID.String()), nil
func (r *testRoomserverAPI) QuerySenderIDForUser(ctx context.Context, roomID spec.RoomID, userID spec.UserID) (*spec.SenderID, error) {
senderID := spec.SenderID(userID.String())
return &senderID, nil
}
func (r *testRoomserverAPI) QueryEventsByID(ctx context.Context, req *roomserver.QueryEventsByIDRequest, res *roomserver.QueryEventsByIDResponse) error {

View file

@ -144,8 +144,8 @@ func ApplyHistoryVisibilityFilter(
return nil, err
}
senderID, err := rsAPI.QuerySenderIDForUser(ctx, *roomID, *user)
if err == nil {
if ev.Type() == spec.MRoomMember && ev.StateKeyEquals(string(senderID)) {
if err == nil && senderID != nil {
if ev.Type() == spec.MRoomMember && ev.StateKeyEquals(string(*senderID)) {
eventsFiltered = append(eventsFiltered, ev)
continue
}

View file

@ -122,13 +122,13 @@ func (d *Database) StreamEventsToEvents(ctx context.Context, device *userapi.Dev
continue
}
deviceSenderID, err := rsAPI.QuerySenderIDForUser(ctx, *roomID, *userID)
if err != nil {
if err != nil || deviceSenderID == nil {
logrus.WithFields(logrus.Fields{
"event_id": out[i].EventID(),
}).WithError(err).Warnf("Failed to add transaction ID to event")
continue
}
if deviceSenderID == in[i].SenderID() && device.SessionID == in[i].TransactionID.SessionID {
if *deviceSenderID == in[i].SenderID() && device.SessionID == in[i].TransactionID.SessionID {
err := out[i].SetUnsignedField(
"transaction_id", in[i].TransactionID.TransactionID,
)
@ -527,11 +527,11 @@ func getMembershipFromEvent(ctx context.Context, ev gomatrixserverlib.PDU, userI
return "", ""
}
senderID, err := rsAPI.QuerySenderIDForUser(ctx, *roomID, *fullUser)
if err != nil {
if err != nil || senderID == nil {
return "", ""
}
if ev.Type() != "m.room.member" || !ev.StateKeyEquals(string(senderID)) {
if ev.Type() != "m.room.member" || !ev.StateKeyEquals(string(*senderID)) {
return "", ""
}
membership, err := ev.Membership()

View file

@ -840,8 +840,11 @@ func (s *OutputRoomEventConsumer) notifyHTTP(ctx context.Context, event *rstypes
if err != nil {
logger.WithError(err).Errorf("Failed to get local user senderID for room %s: %s", userID.String(), event.RoomID())
return nil, err
} else if localSender == nil {
logger.WithError(err).Errorf("Failed to get local user senderID for room %s: %s", userID.String(), event.RoomID())
return nil, fmt.Errorf("no sender ID for user %s in %s", userID.String(), roomID.String())
}
if event.StateKey() != nil && *event.StateKey() == string(localSender) {
if event.StateKey() != nil && *event.StateKey() == string(*localSender) {
req.Notification.UserIsTarget = true
}
}