diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go index 3ec959b4b..907727662 100644 --- a/clientapi/routing/directory.go +++ b/clientapi/routing/directory.go @@ -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"), diff --git a/clientapi/routing/membership.go b/clientapi/routing/membership.go index def6f0617..8b8cc47bc 100644 --- a/clientapi/routing/membership.go +++ b/clientapi/routing/membership.go @@ -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 diff --git a/clientapi/routing/profile.go b/clientapi/routing/profile.go index 35da15e0e..66b58507e 100644 --- a/clientapi/routing/profile.go +++ b/clientapi/routing/profile.go @@ -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, diff --git a/clientapi/routing/redaction.go b/clientapi/routing/redaction.go index 1b9a5a818..230c96d28 100644 --- a/clientapi/routing/redaction.go +++ b/clientapi/routing/redaction.go @@ -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, diff --git a/clientapi/routing/sendevent.go b/clientapi/routing/sendevent.go index 41a3793ae..172001714 100644 --- a/clientapi/routing/sendevent.go +++ b/clientapi/routing/sendevent.go @@ -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, diff --git a/clientapi/threepid/invites.go b/clientapi/threepid/invites.go index d15cc6d46..365e9f869 100644 --- a/clientapi/threepid/invites.go +++ b/clientapi/threepid/invites.go @@ -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, diff --git a/federationapi/federationapi_test.go b/federationapi/federationapi_test.go index 5d167c0ee..c426eb67d 100644 --- a/federationapi/federationapi_test.go +++ b/federationapi/federationapi_test.go @@ -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 diff --git a/federationapi/internal/perform.go b/federationapi/internal/perform.go index ff00305bf..3bba3ea0d 100644 --- a/federationapi/internal/perform.go +++ b/federationapi/internal/perform.go @@ -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 diff --git a/federationapi/routing/join.go b/federationapi/routing/join.go index a090dbc8d..ce7ad30ff 100644 --- a/federationapi/routing/join.go +++ b/federationapi/routing/join.go @@ -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{ diff --git a/federationapi/routing/leave.go b/federationapi/routing/leave.go index 5c8dd00f3..f28c82115 100644 --- a/federationapi/routing/leave.go +++ b/federationapi/routing/leave.go @@ -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(), diff --git a/go.mod b/go.mod index 0e77f903e..74b17166c 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 28c60df43..779c28618 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/roomserver/api/api.go b/roomserver/api/api.go index ed87ce93a..69997fc41 100644 --- a/roomserver/api/api.go +++ b/roomserver/api/api.go @@ -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) } diff --git a/roomserver/internal/perform/perform_admin.go b/roomserver/internal/perform/perform_admin.go index dd7132624..2888067b4 100644 --- a/roomserver/internal/perform/perform_admin.go +++ b/roomserver/internal/perform/perform_admin.go @@ -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("{}"), } diff --git a/roomserver/internal/perform/perform_invite.go b/roomserver/internal/perform/perform_invite.go index 278ddd7d8..e07780d68 100644 --- a/roomserver/internal/perform/perform_invite.go +++ b/roomserver/internal/perform/perform_invite.go @@ -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) { diff --git a/roomserver/internal/perform/perform_join.go b/roomserver/internal/perform/perform_join.go index dfce9cc77..23988e467 100644 --- a/roomserver/internal/perform/perform_join.go +++ b/roomserver/internal/perform/perform_join.go @@ -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 diff --git a/roomserver/internal/perform/perform_leave.go b/roomserver/internal/perform/perform_leave.go index a20896cf7..5c63a6684 100644 --- a/roomserver/internal/perform/perform_leave.go +++ b/roomserver/internal/perform/perform_leave.go @@ -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, diff --git a/roomserver/internal/perform/perform_upgrade.go b/roomserver/internal/perform/perform_upgrade.go index 74c62cd9e..c32e10d53 100644 --- a/roomserver/internal/perform/perform_upgrade.go +++ b/roomserver/internal/perform/perform_upgrade.go @@ -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 } diff --git a/roomserver/internal/query/query.go b/roomserver/internal/query/query.go index 11e5564dc..0fe0f4f27 100644 --- a/roomserver/internal/query/query.go +++ b/roomserver/internal/query/query.go @@ -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 } } diff --git a/setup/mscs/msc2836/msc2836_test.go b/setup/mscs/msc2836/msc2836_test.go index 16fb3efe1..ecbab706f 100644 --- a/setup/mscs/msc2836/msc2836_test.go +++ b/setup/mscs/msc2836/msc2836_test.go @@ -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 { diff --git a/syncapi/internal/history_visibility.go b/syncapi/internal/history_visibility.go index ce6846ca4..3c2308954 100644 --- a/syncapi/internal/history_visibility.go +++ b/syncapi/internal/history_visibility.go @@ -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 } diff --git a/syncapi/storage/shared/storage_consumer.go b/syncapi/storage/shared/storage_consumer.go index 746a324fa..69e64cc79 100644 --- a/syncapi/storage/shared/storage_consumer.go +++ b/syncapi/storage/shared/storage_consumer.go @@ -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() diff --git a/userapi/consumers/roomserver.go b/userapi/consumers/roomserver.go index 1f866ef4d..a88b2129d 100644 --- a/userapi/consumers/roomserver.go +++ b/userapi/consumers/roomserver.go @@ -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 } }