mirror of
https://github.com/matrix-org/dendrite.git
synced 2026-01-20 04:23:09 -06:00
Merge branch 'main' into ea-multicast-fix
This commit is contained in:
commit
64c843492d
7
.github/workflows/dendrite.yml
vendored
7
.github/workflows/dendrite.yml
vendored
|
|
@ -109,6 +109,11 @@ jobs:
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go }}
|
go-version: ${{ matrix.go }}
|
||||||
|
- name: Set up gotestfmt
|
||||||
|
uses: gotesttools/gotestfmt-action@v2
|
||||||
|
with:
|
||||||
|
# Optional: pass GITHUB_TOKEN to avoid rate limiting.
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
|
|
@ -117,7 +122,7 @@ jobs:
|
||||||
key: ${{ runner.os }}-go${{ matrix.go }}-test-${{ hashFiles('**/go.sum') }}
|
key: ${{ runner.os }}-go${{ matrix.go }}-test-${{ hashFiles('**/go.sum') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-go${{ matrix.go }}-test-
|
${{ runner.os }}-go${{ matrix.go }}-test-
|
||||||
- run: go test ./...
|
- run: go test -json -v ./... 2>&1 | gotestfmt
|
||||||
env:
|
env:
|
||||||
POSTGRES_HOST: localhost
|
POSTGRES_HOST: localhost
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login,
|
||||||
JSON: jsonerror.BadJSON("A password must be supplied."),
|
JSON: jsonerror.BadJSON("A password must be supplied."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
localpart, err := userutil.ParseUsernameParam(username, &t.Config.Matrix.ServerName)
|
localpart, _, err := userutil.ParseUsernameParam(username, t.Config.Matrix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &util.JSONResponse{
|
return nil, &util.JSONResponse{
|
||||||
Code: http.StatusUnauthorized,
|
Code: http.StatusUnauthorized,
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ func AdminEvacuateUser(req *http.Request, cfg *config.ClientAPI, device *userapi
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||||
}
|
}
|
||||||
if domain != cfg.Matrix.ServerName {
|
if !cfg.Matrix.IsLocalServerName(domain) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
JSON: jsonerror.MissingArgument("User ID must belong to this server."),
|
JSON: jsonerror.MissingArgument("User ID must belong to this server."),
|
||||||
|
|
@ -169,7 +169,7 @@ func AdminMarkAsStale(req *http.Request, cfg *config.ClientAPI, keyAPI api.Clien
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
return util.MessageResponse(http.StatusBadRequest, err.Error())
|
||||||
}
|
}
|
||||||
if domain == cfg.Matrix.ServerName {
|
if cfg.Matrix.IsLocalServerName(domain) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusBadRequest,
|
Code: http.StatusBadRequest,
|
||||||
JSON: jsonerror.InvalidParam("Can not mark local device list as stale"),
|
JSON: jsonerror.InvalidParam("Can not mark local device list as stale"),
|
||||||
|
|
|
||||||
|
|
@ -169,9 +169,21 @@ func createRoom(
|
||||||
asAPI appserviceAPI.AppServiceInternalAPI,
|
asAPI appserviceAPI.AppServiceInternalAPI,
|
||||||
evTime time.Time,
|
evTime time.Time,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
|
_, userDomain, err := gomatrixserverlib.SplitID('@', device.UserID)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(ctx).WithError(err).Error("gomatrixserverlib.SplitID failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
if !cfg.Matrix.IsLocalServerName(userDomain) {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: jsonerror.Forbidden(fmt.Sprintf("User domain %q not configured locally", userDomain)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO (#267): Check room ID doesn't clash with an existing one, and we
|
// TODO (#267): Check room ID doesn't clash with an existing one, and we
|
||||||
// probably shouldn't be using pseudo-random strings, maybe GUIDs?
|
// probably shouldn't be using pseudo-random strings, maybe GUIDs?
|
||||||
roomID := fmt.Sprintf("!%s:%s", util.RandomString(16), cfg.Matrix.ServerName)
|
roomID := fmt.Sprintf("!%s:%s", util.RandomString(16), userDomain)
|
||||||
|
|
||||||
logger := util.GetLogger(ctx)
|
logger := util.GetLogger(ctx)
|
||||||
userID := device.UserID
|
userID := device.UserID
|
||||||
|
|
@ -314,7 +326,7 @@ func createRoom(
|
||||||
|
|
||||||
var roomAlias string
|
var roomAlias string
|
||||||
if r.RoomAliasName != "" {
|
if r.RoomAliasName != "" {
|
||||||
roomAlias = fmt.Sprintf("#%s:%s", r.RoomAliasName, cfg.Matrix.ServerName)
|
roomAlias = fmt.Sprintf("#%s:%s", r.RoomAliasName, userDomain)
|
||||||
// check it's free TODO: This races but is better than nothing
|
// check it's free TODO: This races but is better than nothing
|
||||||
hasAliasReq := roomserverAPI.GetRoomIDForAliasRequest{
|
hasAliasReq := roomserverAPI.GetRoomIDForAliasRequest{
|
||||||
Alias: roomAlias,
|
Alias: roomAlias,
|
||||||
|
|
@ -436,7 +448,7 @@ func createRoom(
|
||||||
builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()}
|
builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()}
|
||||||
}
|
}
|
||||||
var ev *gomatrixserverlib.Event
|
var ev *gomatrixserverlib.Event
|
||||||
ev, err = buildEvent(&builder, &authEvents, cfg, evTime, roomVersion)
|
ev, err = buildEvent(&builder, userDomain, &authEvents, cfg, evTime, roomVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Error("buildEvent failed")
|
util.GetLogger(ctx).WithError(err).Error("buildEvent failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
|
|
@ -461,7 +473,7 @@ func createRoom(
|
||||||
inputs = append(inputs, roomserverAPI.InputRoomEvent{
|
inputs = append(inputs, roomserverAPI.InputRoomEvent{
|
||||||
Kind: roomserverAPI.KindNew,
|
Kind: roomserverAPI.KindNew,
|
||||||
Event: event,
|
Event: event,
|
||||||
Origin: cfg.Matrix.ServerName,
|
Origin: userDomain,
|
||||||
SendAsServer: roomserverAPI.DoNotSendToOtherServers,
|
SendAsServer: roomserverAPI.DoNotSendToOtherServers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -548,7 +560,7 @@ func createRoom(
|
||||||
Event: event,
|
Event: event,
|
||||||
InviteRoomState: inviteStrippedState,
|
InviteRoomState: inviteStrippedState,
|
||||||
RoomVersion: event.RoomVersion,
|
RoomVersion: event.RoomVersion,
|
||||||
SendAsServer: string(cfg.Matrix.ServerName),
|
SendAsServer: string(userDomain),
|
||||||
}, &inviteRes); err != nil {
|
}, &inviteRes); err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
|
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -591,6 +603,7 @@ func createRoom(
|
||||||
// buildEvent fills out auth_events for the builder then builds the event
|
// buildEvent fills out auth_events for the builder then builds the event
|
||||||
func buildEvent(
|
func buildEvent(
|
||||||
builder *gomatrixserverlib.EventBuilder,
|
builder *gomatrixserverlib.EventBuilder,
|
||||||
|
serverName gomatrixserverlib.ServerName,
|
||||||
provider gomatrixserverlib.AuthEventProvider,
|
provider gomatrixserverlib.AuthEventProvider,
|
||||||
cfg *config.ClientAPI,
|
cfg *config.ClientAPI,
|
||||||
evTime time.Time,
|
evTime time.Time,
|
||||||
|
|
@ -606,7 +619,7 @@ func buildEvent(
|
||||||
}
|
}
|
||||||
builder.AuthEvents = refs
|
builder.AuthEvents = refs
|
||||||
event, err := builder.Build(
|
event, err := builder.Build(
|
||||||
evTime, cfg.Matrix.ServerName, cfg.Matrix.KeyID,
|
evTime, serverName, cfg.Matrix.KeyID,
|
||||||
cfg.Matrix.PrivateKey, roomVersion,
|
cfg.Matrix.PrivateKey, roomVersion,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ func DirectoryRoom(
|
||||||
if res.RoomID == "" {
|
if res.RoomID == "" {
|
||||||
// If we don't know it locally, do a federation query.
|
// If we don't know it locally, do a federation query.
|
||||||
// But don't send the query to ourselves.
|
// But don't send the query to ourselves.
|
||||||
if domain != cfg.Matrix.ServerName {
|
if !cfg.Matrix.IsLocalServerName(domain) {
|
||||||
fedRes, fedErr := federation.LookupRoomAlias(req.Context(), domain, roomAlias)
|
fedRes, fedErr := federation.LookupRoomAlias(req.Context(), domain, roomAlias)
|
||||||
if fedErr != nil {
|
if fedErr != nil {
|
||||||
// TODO: Return 502 if the remote server errored.
|
// TODO: Return 502 if the remote server errored.
|
||||||
|
|
@ -127,7 +127,7 @@ func SetLocalAlias(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if domain != cfg.Matrix.ServerName {
|
if !cfg.Matrix.IsLocalServerName(domain) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusForbidden,
|
Code: http.StatusForbidden,
|
||||||
JSON: jsonerror.Forbidden("Alias must be on local homeserver"),
|
JSON: jsonerror.Forbidden("Alias must be on local homeserver"),
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,7 @@ func GetPostPublicRooms(
|
||||||
}
|
}
|
||||||
|
|
||||||
serverName := gomatrixserverlib.ServerName(request.Server)
|
serverName := gomatrixserverlib.ServerName(request.Server)
|
||||||
|
if serverName != "" && !cfg.Matrix.IsLocalServerName(serverName) {
|
||||||
if serverName != "" && serverName != cfg.Matrix.ServerName {
|
|
||||||
res, err := federation.GetPublicRoomsFiltered(
|
res, err := federation.GetPublicRoomsFiltered(
|
||||||
req.Context(), serverName,
|
req.Context(), serverName,
|
||||||
int(request.Limit), request.Since,
|
int(request.Limit), request.Since,
|
||||||
|
|
|
||||||
52
clientapi/routing/joined_rooms.go
Normal file
52
clientapi/routing/joined_rooms.go
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package routing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
|
)
|
||||||
|
|
||||||
|
type getJoinedRoomsResponse struct {
|
||||||
|
JoinedRooms []string `json:"joined_rooms"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetJoinedRooms(
|
||||||
|
req *http.Request,
|
||||||
|
device *userapi.Device,
|
||||||
|
rsAPI api.ClientRoomserverAPI,
|
||||||
|
) util.JSONResponse {
|
||||||
|
var res api.QueryRoomsForUserResponse
|
||||||
|
err := rsAPI.QueryRoomsForUser(req.Context(), &api.QueryRoomsForUserRequest{
|
||||||
|
UserID: device.UserID,
|
||||||
|
WantMembership: "join",
|
||||||
|
}, &res)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("QueryRoomsForUser failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
if res.RoomIDs == nil {
|
||||||
|
res.RoomIDs = []string{}
|
||||||
|
}
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
JSON: getJoinedRoomsResponse{res.RoomIDs},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -99,7 +99,11 @@ func (r *queryKeysRequest) GetTimeout() time.Duration {
|
||||||
if r.Timeout == 0 {
|
if r.Timeout == 0 {
|
||||||
return 10 * time.Second
|
return 10 * time.Second
|
||||||
}
|
}
|
||||||
return time.Duration(r.Timeout) * time.Millisecond
|
timeout := time.Duration(r.Timeout) * time.Millisecond
|
||||||
|
if timeout > time.Second*20 {
|
||||||
|
timeout = time.Second * 20
|
||||||
|
}
|
||||||
|
return timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
func QueryKeys(req *http.Request, keyAPI api.ClientKeyAPI, device *userapi.Device) util.JSONResponse {
|
func QueryKeys(req *http.Request, keyAPI api.ClientKeyAPI, device *userapi.Device) util.JSONResponse {
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ func Login(
|
||||||
return *authErr
|
return *authErr
|
||||||
}
|
}
|
||||||
// make a device/access token
|
// make a device/access token
|
||||||
authErr2 := completeAuth(req.Context(), cfg.Matrix.ServerName, userAPI, login, req.RemoteAddr, req.UserAgent())
|
authErr2 := completeAuth(req.Context(), cfg.Matrix, userAPI, login, req.RemoteAddr, req.UserAgent())
|
||||||
cleanup(req.Context(), &authErr2)
|
cleanup(req.Context(), &authErr2)
|
||||||
return authErr2
|
return authErr2
|
||||||
}
|
}
|
||||||
|
|
@ -79,7 +79,7 @@ func Login(
|
||||||
}
|
}
|
||||||
|
|
||||||
func completeAuth(
|
func completeAuth(
|
||||||
ctx context.Context, serverName gomatrixserverlib.ServerName, userAPI userapi.ClientUserAPI, login *auth.Login,
|
ctx context.Context, cfg *config.Global, userAPI userapi.ClientUserAPI, login *auth.Login,
|
||||||
ipAddr, userAgent string,
|
ipAddr, userAgent string,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
token, err := auth.GenerateAccessToken()
|
token, err := auth.GenerateAccessToken()
|
||||||
|
|
@ -88,7 +88,7 @@ func completeAuth(
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
|
|
||||||
localpart, err := userutil.ParseUsernameParam(login.Username(), &serverName)
|
localpart, serverName, err := userutil.ParseUsernameParam(login.Username(), cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Error("auth.ParseUsernameParam failed")
|
util.GetLogger(ctx).WithError(err).Error("auth.ParseUsernameParam failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
|
|
|
||||||
|
|
@ -105,12 +105,13 @@ func sendMembership(ctx context.Context, profileAPI userapi.ClientUserAPI, devic
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
serverName := device.UserDomain()
|
||||||
if err = roomserverAPI.SendEvents(
|
if err = roomserverAPI.SendEvents(
|
||||||
ctx, rsAPI,
|
ctx, rsAPI,
|
||||||
roomserverAPI.KindNew,
|
roomserverAPI.KindNew,
|
||||||
[]*gomatrixserverlib.HeaderedEvent{event.Event.Headered(roomVer)},
|
[]*gomatrixserverlib.HeaderedEvent{event.Event.Headered(roomVer)},
|
||||||
cfg.Matrix.ServerName,
|
serverName,
|
||||||
cfg.Matrix.ServerName,
|
serverName,
|
||||||
nil,
|
nil,
|
||||||
false,
|
false,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|
@ -271,7 +272,7 @@ func sendInvite(
|
||||||
Event: event,
|
Event: event,
|
||||||
InviteRoomState: nil, // ask the roomserver to draw up invite room state for us
|
InviteRoomState: nil, // ask the roomserver to draw up invite room state for us
|
||||||
RoomVersion: event.RoomVersion,
|
RoomVersion: event.RoomVersion,
|
||||||
SendAsServer: string(cfg.Matrix.ServerName),
|
SendAsServer: string(device.UserDomain()),
|
||||||
}, &inviteRes); err != nil {
|
}, &inviteRes); err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
|
util.GetLogger(ctx).WithError(err).Error("PerformInvite failed")
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -341,7 +342,7 @@ func loadProfile(
|
||||||
}
|
}
|
||||||
|
|
||||||
var profile *authtypes.Profile
|
var profile *authtypes.Profile
|
||||||
if serverName == cfg.Matrix.ServerName {
|
if cfg.Matrix.IsLocalServerName(serverName) {
|
||||||
profile, err = appserviceAPI.RetrieveUserProfile(ctx, userID, asAPI, profileAPI)
|
profile, err = appserviceAPI.RetrieveUserProfile(ctx, userID, asAPI, profileAPI)
|
||||||
} else {
|
} else {
|
||||||
profile = &authtypes.Profile{}
|
profile = &authtypes.Profile{}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ func CreateOpenIDToken(
|
||||||
JSON: openIDTokenResponse{
|
JSON: openIDTokenResponse{
|
||||||
AccessToken: response.Token.Token,
|
AccessToken: response.Token.Token,
|
||||||
TokenType: "Bearer",
|
TokenType: "Bearer",
|
||||||
MatrixServerName: string(cfg.Matrix.ServerName),
|
MatrixServerName: string(device.UserDomain()),
|
||||||
ExpiresIn: response.Token.ExpiresAtMS / 1000, // convert ms to s
|
ExpiresIn: response.Token.ExpiresAtMS / 1000, // convert ms to s
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,12 +113,19 @@ func SetAvatarURL(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
localpart, _, err := gomatrixserverlib.SplitID('@', userID)
|
localpart, domain, err := gomatrixserverlib.SplitID('@', userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
|
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !cfg.Matrix.IsLocalServerName(domain) {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: jsonerror.Forbidden("userID does not belong to a locally configured domain"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
evTime, err := httputil.ParseTSParam(req)
|
evTime, err := httputil.ParseTSParam(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -129,8 +136,9 @@ func SetAvatarURL(
|
||||||
|
|
||||||
setRes := &userapi.PerformSetAvatarURLResponse{}
|
setRes := &userapi.PerformSetAvatarURLResponse{}
|
||||||
if err = profileAPI.SetAvatarURL(req.Context(), &userapi.PerformSetAvatarURLRequest{
|
if err = profileAPI.SetAvatarURL(req.Context(), &userapi.PerformSetAvatarURLRequest{
|
||||||
Localpart: localpart,
|
Localpart: localpart,
|
||||||
AvatarURL: r.AvatarURL,
|
ServerName: domain,
|
||||||
|
AvatarURL: r.AvatarURL,
|
||||||
}, setRes); err != nil {
|
}, setRes); err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("profileAPI.SetAvatarURL failed")
|
util.GetLogger(req.Context()).WithError(err).Error("profileAPI.SetAvatarURL failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
|
|
@ -204,12 +212,19 @@ func SetDisplayName(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
localpart, _, err := gomatrixserverlib.SplitID('@', userID)
|
localpart, domain, err := gomatrixserverlib.SplitID('@', userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
|
util.GetLogger(req.Context()).WithError(err).Error("gomatrixserverlib.SplitID failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !cfg.Matrix.IsLocalServerName(domain) {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: jsonerror.Forbidden("userID does not belong to a locally configured domain"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
evTime, err := httputil.ParseTSParam(req)
|
evTime, err := httputil.ParseTSParam(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -221,6 +236,7 @@ func SetDisplayName(
|
||||||
profileRes := &userapi.PerformUpdateDisplayNameResponse{}
|
profileRes := &userapi.PerformUpdateDisplayNameResponse{}
|
||||||
err = profileAPI.SetDisplayName(req.Context(), &userapi.PerformUpdateDisplayNameRequest{
|
err = profileAPI.SetDisplayName(req.Context(), &userapi.PerformUpdateDisplayNameRequest{
|
||||||
Localpart: localpart,
|
Localpart: localpart,
|
||||||
|
ServerName: domain,
|
||||||
DisplayName: r.DisplayName,
|
DisplayName: r.DisplayName,
|
||||||
}, profileRes)
|
}, profileRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -261,6 +277,12 @@ func updateProfile(
|
||||||
return jsonerror.InternalServerError(), err
|
return jsonerror.InternalServerError(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, domain, err := gomatrixserverlib.SplitID('@', userID)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(ctx).WithError(err).Error("gomatrixserverlib.SplitID failed")
|
||||||
|
return jsonerror.InternalServerError(), err
|
||||||
|
}
|
||||||
|
|
||||||
events, err := buildMembershipEvents(
|
events, err := buildMembershipEvents(
|
||||||
ctx, res.RoomIDs, *profile, userID, cfg, evTime, rsAPI,
|
ctx, res.RoomIDs, *profile, userID, cfg, evTime, rsAPI,
|
||||||
)
|
)
|
||||||
|
|
@ -276,7 +298,7 @@ func updateProfile(
|
||||||
return jsonerror.InternalServerError(), e
|
return jsonerror.InternalServerError(), e
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, events, cfg.Matrix.ServerName, cfg.Matrix.ServerName, nil, true); err != nil {
|
if err := api.SendEvents(ctx, rsAPI, api.KindNew, events, domain, domain, nil, true); err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Error("SendEvents failed")
|
util.GetLogger(ctx).WithError(err).Error("SendEvents failed")
|
||||||
return jsonerror.InternalServerError(), err
|
return jsonerror.InternalServerError(), err
|
||||||
}
|
}
|
||||||
|
|
@ -298,7 +320,7 @@ func getProfile(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if domain != cfg.Matrix.ServerName {
|
if !cfg.Matrix.IsLocalServerName(domain) {
|
||||||
profile, fedErr := federation.LookupProfile(ctx, domain, userID, "")
|
profile, fedErr := federation.LookupProfile(ctx, domain, userID, "")
|
||||||
if fedErr != nil {
|
if fedErr != nil {
|
||||||
if x, ok := fedErr.(gomatrix.HTTPError); ok {
|
if x, ok := fedErr.(gomatrix.HTTPError); ok {
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,8 @@ func SendRedaction(
|
||||||
JSON: jsonerror.NotFound("Room does not exist"),
|
JSON: jsonerror.NotFound("Room does not exist"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = roomserverAPI.SendEvents(context.Background(), rsAPI, roomserverAPI.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, cfg.Matrix.ServerName, cfg.Matrix.ServerName, nil, false); err != nil {
|
domain := device.UserDomain()
|
||||||
|
if err = roomserverAPI.SendEvents(context.Background(), rsAPI, roomserverAPI.KindNew, []*gomatrixserverlib.HeaderedEvent{e}, domain, domain, nil, false); err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Errorf("failed to SendEvents")
|
util.GetLogger(req.Context()).WithError(err).Errorf("failed to SendEvents")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -412,7 +412,7 @@ func UserIDIsWithinApplicationServiceNamespace(
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if domain != cfg.Matrix.ServerName {
|
if !cfg.Matrix.IsLocalServerName(domain) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -950,26 +950,6 @@ func Setup(
|
||||||
}),
|
}),
|
||||||
).Methods(http.MethodPost, http.MethodOptions)
|
).Methods(http.MethodPost, http.MethodOptions)
|
||||||
|
|
||||||
v3mux.Handle("/rooms/{roomID}/members",
|
|
||||||
httputil.MakeAuthAPI("rooms_members", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
|
||||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
|
||||||
if err != nil {
|
|
||||||
return util.ErrorResponse(err)
|
|
||||||
}
|
|
||||||
return GetMemberships(req, device, vars["roomID"], false, cfg, rsAPI)
|
|
||||||
}),
|
|
||||||
).Methods(http.MethodGet, http.MethodOptions)
|
|
||||||
|
|
||||||
v3mux.Handle("/rooms/{roomID}/joined_members",
|
|
||||||
httputil.MakeAuthAPI("rooms_members", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
|
||||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
|
||||||
if err != nil {
|
|
||||||
return util.ErrorResponse(err)
|
|
||||||
}
|
|
||||||
return GetMemberships(req, device, vars["roomID"], true, cfg, rsAPI)
|
|
||||||
}),
|
|
||||||
).Methods(http.MethodGet, http.MethodOptions)
|
|
||||||
|
|
||||||
v3mux.Handle("/rooms/{roomID}/read_markers",
|
v3mux.Handle("/rooms/{roomID}/read_markers",
|
||||||
httputil.MakeAuthAPI("rooms_read_markers", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
httputil.MakeAuthAPI("rooms_read_markers", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
if r := rateLimits.Limit(req, device); r != nil {
|
if r := rateLimits.Limit(req, device); r != nil {
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,7 @@ func SendEvent(
|
||||||
// create a mutex for the specific user in the specific room
|
// create a mutex for the specific user in the specific room
|
||||||
// this avoids a situation where events that are received in quick succession are sent to the roomserver in a jumbled order
|
// this avoids a situation where events that are received in quick succession are sent to the roomserver in a jumbled order
|
||||||
userID := device.UserID
|
userID := device.UserID
|
||||||
|
domain := device.UserDomain()
|
||||||
mutex, _ := userRoomSendMutexes.LoadOrStore(roomID+userID, &sync.Mutex{})
|
mutex, _ := userRoomSendMutexes.LoadOrStore(roomID+userID, &sync.Mutex{})
|
||||||
mutex.(*sync.Mutex).Lock()
|
mutex.(*sync.Mutex).Lock()
|
||||||
defer mutex.(*sync.Mutex).Unlock()
|
defer mutex.(*sync.Mutex).Unlock()
|
||||||
|
|
@ -185,8 +186,8 @@ func SendEvent(
|
||||||
[]*gomatrixserverlib.HeaderedEvent{
|
[]*gomatrixserverlib.HeaderedEvent{
|
||||||
e.Headered(verRes.RoomVersion),
|
e.Headered(verRes.RoomVersion),
|
||||||
},
|
},
|
||||||
cfg.Matrix.ServerName,
|
domain,
|
||||||
cfg.Matrix.ServerName,
|
domain,
|
||||||
txnAndSessionID,
|
txnAndSessionID,
|
||||||
false,
|
false,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ func queryIDServerStoreInvite(
|
||||||
}
|
}
|
||||||
|
|
||||||
var profile *authtypes.Profile
|
var profile *authtypes.Profile
|
||||||
if serverName == cfg.Matrix.ServerName {
|
if cfg.Matrix.IsLocalServerName(serverName) {
|
||||||
res := &userapi.QueryProfileResponse{}
|
res := &userapi.QueryProfileResponse{}
|
||||||
err = userAPI.QueryProfile(ctx, &userapi.QueryProfileRequest{UserID: device.UserID}, res)
|
err = userAPI.QueryProfile(ctx, &userapi.QueryProfileRequest{UserID: device.UserID}, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -24,23 +25,23 @@ import (
|
||||||
// usernameParam can either be a user ID or just the localpart/username.
|
// usernameParam can either be a user ID or just the localpart/username.
|
||||||
// If serverName is passed, it is verified against the domain obtained from usernameParam (if present)
|
// If serverName is passed, it is verified against the domain obtained from usernameParam (if present)
|
||||||
// Returns error in case of invalid usernameParam.
|
// Returns error in case of invalid usernameParam.
|
||||||
func ParseUsernameParam(usernameParam string, expectedServerName *gomatrixserverlib.ServerName) (string, error) {
|
func ParseUsernameParam(usernameParam string, cfg *config.Global) (string, gomatrixserverlib.ServerName, error) {
|
||||||
localpart := usernameParam
|
localpart := usernameParam
|
||||||
|
|
||||||
if strings.HasPrefix(usernameParam, "@") {
|
if strings.HasPrefix(usernameParam, "@") {
|
||||||
lp, domain, err := gomatrixserverlib.SplitID('@', usernameParam)
|
lp, domain, err := gomatrixserverlib.SplitID('@', usernameParam)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("invalid username")
|
return "", "", errors.New("invalid username")
|
||||||
}
|
}
|
||||||
|
|
||||||
if expectedServerName != nil && domain != *expectedServerName {
|
if !cfg.IsLocalServerName(domain) {
|
||||||
return "", errors.New("user ID does not belong to this server")
|
return "", "", errors.New("user ID does not belong to this server")
|
||||||
}
|
}
|
||||||
|
|
||||||
localpart = lp
|
return lp, domain, nil
|
||||||
}
|
}
|
||||||
return localpart, nil
|
return localpart, cfg.ServerName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeUserID generates user ID from localpart & server name
|
// MakeUserID generates user ID from localpart & server name
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ package userutil
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -28,7 +29,11 @@ var (
|
||||||
|
|
||||||
// TestGoodUserID checks that correct localpart is returned for a valid user ID.
|
// TestGoodUserID checks that correct localpart is returned for a valid user ID.
|
||||||
func TestGoodUserID(t *testing.T) {
|
func TestGoodUserID(t *testing.T) {
|
||||||
lp, err := ParseUsernameParam(goodUserID, &serverName)
|
cfg := &config.Global{
|
||||||
|
ServerName: serverName,
|
||||||
|
}
|
||||||
|
|
||||||
|
lp, _, err := ParseUsernameParam(goodUserID, cfg)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("User ID Parsing failed for ", goodUserID, " with error: ", err.Error())
|
t.Error("User ID Parsing failed for ", goodUserID, " with error: ", err.Error())
|
||||||
|
|
@ -41,7 +46,11 @@ func TestGoodUserID(t *testing.T) {
|
||||||
|
|
||||||
// TestWithLocalpartOnly checks that localpart is returned when usernameParam contains only localpart.
|
// TestWithLocalpartOnly checks that localpart is returned when usernameParam contains only localpart.
|
||||||
func TestWithLocalpartOnly(t *testing.T) {
|
func TestWithLocalpartOnly(t *testing.T) {
|
||||||
lp, err := ParseUsernameParam(localpart, &serverName)
|
cfg := &config.Global{
|
||||||
|
ServerName: serverName,
|
||||||
|
}
|
||||||
|
|
||||||
|
lp, _, err := ParseUsernameParam(localpart, cfg)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("User ID Parsing failed for ", localpart, " with error: ", err.Error())
|
t.Error("User ID Parsing failed for ", localpart, " with error: ", err.Error())
|
||||||
|
|
@ -54,7 +63,11 @@ func TestWithLocalpartOnly(t *testing.T) {
|
||||||
|
|
||||||
// TestIncorrectDomain checks for error when there's server name mismatch.
|
// TestIncorrectDomain checks for error when there's server name mismatch.
|
||||||
func TestIncorrectDomain(t *testing.T) {
|
func TestIncorrectDomain(t *testing.T) {
|
||||||
_, err := ParseUsernameParam(goodUserID, &invalidServerName)
|
cfg := &config.Global{
|
||||||
|
ServerName: invalidServerName,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := ParseUsernameParam(goodUserID, cfg)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Invalid Domain should return an error")
|
t.Error("Invalid Domain should return an error")
|
||||||
|
|
@ -63,7 +76,11 @@ func TestIncorrectDomain(t *testing.T) {
|
||||||
|
|
||||||
// TestBadUserID checks that ParseUsernameParam fails for invalid user ID
|
// TestBadUserID checks that ParseUsernameParam fails for invalid user ID
|
||||||
func TestBadUserID(t *testing.T) {
|
func TestBadUserID(t *testing.T) {
|
||||||
_, err := ParseUsernameParam(badUserID, &serverName)
|
cfg := &config.Global{
|
||||||
|
ServerName: serverName,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _, err := ParseUsernameParam(badUserID, cfg)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("Illegal User ID should return an error")
|
t.Error("Illegal User ID should return an error")
|
||||||
|
|
|
||||||
|
|
@ -310,6 +310,14 @@ user_api:
|
||||||
# The default lifetime is 3600000ms (60 minutes).
|
# The default lifetime is 3600000ms (60 minutes).
|
||||||
# openid_token_lifetime_ms: 3600000
|
# openid_token_lifetime_ms: 3600000
|
||||||
|
|
||||||
|
# Users who register on this homeserver will automatically be joined to the rooms listed under "auto_join_rooms" option.
|
||||||
|
# By default, any room aliases included in this list will be created as a publicly joinable room
|
||||||
|
# when the first user registers for the homeserver. If the room already exists,
|
||||||
|
# make certain it is a publicly joinable room, i.e. the join rule of the room must be set to 'public'.
|
||||||
|
# As Spaces are just rooms under the hood, Space aliases may also be used.
|
||||||
|
auto_join_rooms:
|
||||||
|
# - "#main:matrix.org"
|
||||||
|
|
||||||
# Configuration for Opentracing.
|
# Configuration for Opentracing.
|
||||||
# See https://github.com/matrix-org/dendrite/tree/master/docs/tracing for information on
|
# See https://github.com/matrix-org/dendrite/tree/master/docs/tracing for information on
|
||||||
# how this works and how to set it up.
|
# how this works and how to set it up.
|
||||||
|
|
|
||||||
|
|
@ -375,6 +375,14 @@ user_api:
|
||||||
# The default lifetime is 3600000ms (60 minutes).
|
# The default lifetime is 3600000ms (60 minutes).
|
||||||
# openid_token_lifetime_ms: 3600000
|
# openid_token_lifetime_ms: 3600000
|
||||||
|
|
||||||
|
# Users who register on this homeserver will automatically be joined to the rooms listed under "auto_join_rooms" option.
|
||||||
|
# By default, any room aliases included in this list will be created as a publicly joinable room
|
||||||
|
# when the first user registers for the homeserver. If the room already exists,
|
||||||
|
# make certain it is a publicly joinable room, i.e. the join rule of the room must be set to 'public'.
|
||||||
|
# As Spaces are just rooms under the hood, Space aliases may also be used.
|
||||||
|
auto_join_rooms:
|
||||||
|
# - "#main:matrix.org"
|
||||||
|
|
||||||
# Configuration for Opentracing.
|
# Configuration for Opentracing.
|
||||||
# See https://github.com/matrix-org/dendrite/tree/master/docs/tracing for information on
|
# See https://github.com/matrix-org/dendrite/tree/master/docs/tracing for information on
|
||||||
# how this works and how to set it up.
|
# how this works and how to set it up.
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ matrix.example.com {
|
||||||
# Change the end of each reverse_proxy line to the correct
|
# Change the end of each reverse_proxy line to the correct
|
||||||
# address for your various services.
|
# address for your various services.
|
||||||
@sync_api {
|
@sync_api {
|
||||||
path_regexp /_matrix/client/.*?/(sync|user/.*?/filter/?.*|keys/changes|rooms/.*?/(messages|context/.*?|relations/.*?|event/.*?))$
|
path_regexp /_matrix/client/.*?/(sync|user/.*?/filter/?.*|keys/changes|rooms/.*?/(messages|.*?_?members|context/.*?|relations/.*?|event/.*?))$
|
||||||
}
|
}
|
||||||
reverse_proxy @sync_api sync_api:8073
|
reverse_proxy @sync_api sync_api:8073
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,10 @@ VirtualHost {
|
||||||
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}
|
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}
|
||||||
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}/{relType}
|
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}/{relType}
|
||||||
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}/{relType}/{eventType}
|
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}/{relType}/{eventType}
|
||||||
|
# /_matrix/client/.*/rooms/{roomId}/members
|
||||||
|
# /_matrix/client/.*/rooms/{roomId}/joined_members
|
||||||
# to sync_api
|
# to sync_api
|
||||||
ReverseProxy = /_matrix/client/.*?/(sync|user/.*?/filter/?.*|keys/changes|rooms/.*?/(messages|context/.*?|relations/.*?|event/.*?))$ http://localhost:8073 600
|
ReverseProxy = /_matrix/client/.*?/(sync|user/.*?/filter/?.*|keys/changes|rooms/.*?/(messages|.*?_?members|context/.*?|relations/.*?|event/.*?))$ http://localhost:8073 600
|
||||||
ReverseProxy = /_matrix/client http://localhost:8071 600
|
ReverseProxy = /_matrix/client http://localhost:8071 600
|
||||||
ReverseProxy = /_matrix/federation http://localhost:8072 600
|
ReverseProxy = /_matrix/federation http://localhost:8072 600
|
||||||
ReverseProxy = /_matrix/key http://localhost:8072 600
|
ReverseProxy = /_matrix/key http://localhost:8072 600
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,10 @@ server {
|
||||||
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}
|
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}
|
||||||
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}/{relType}
|
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}/{relType}
|
||||||
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}/{relType}/{eventType}
|
# /_matrix/client/.*/rooms/{roomId}/relations/{eventID}/{relType}/{eventType}
|
||||||
|
# /_matrix/client/.*/rooms/{roomId}/members
|
||||||
|
# /_matrix/client/.*/rooms/{roomId}/joined_members
|
||||||
# to sync_api
|
# to sync_api
|
||||||
location ~ /_matrix/client/.*?/(sync|user/.*?/filter/?.*|keys/changes|rooms/.*?/(messages|context/.*?|relations/.*?|event/.*?))$ {
|
location ~ /_matrix/client/.*?/(sync|user/.*?/filter/?.*|keys/changes|rooms/.*?/(messages|.*?_?members|context/.*?|relations/.*?|event/.*?))$ {
|
||||||
proxy_pass http://sync_api:8073;
|
proxy_pass http://sync_api:8073;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,14 +35,14 @@ import (
|
||||||
|
|
||||||
// KeyChangeConsumer consumes events that originate in key server.
|
// KeyChangeConsumer consumes events that originate in key server.
|
||||||
type KeyChangeConsumer struct {
|
type KeyChangeConsumer struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
jetstream nats.JetStreamContext
|
jetstream nats.JetStreamContext
|
||||||
durable string
|
durable string
|
||||||
db storage.Database
|
db storage.Database
|
||||||
queues *queue.OutgoingQueues
|
queues *queue.OutgoingQueues
|
||||||
serverName gomatrixserverlib.ServerName
|
isLocalServerName func(gomatrixserverlib.ServerName) bool
|
||||||
rsAPI roomserverAPI.FederationRoomserverAPI
|
rsAPI roomserverAPI.FederationRoomserverAPI
|
||||||
topic string
|
topic string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewKeyChangeConsumer creates a new KeyChangeConsumer. Call Start() to begin consuming from key servers.
|
// NewKeyChangeConsumer creates a new KeyChangeConsumer. Call Start() to begin consuming from key servers.
|
||||||
|
|
@ -55,14 +55,14 @@ func NewKeyChangeConsumer(
|
||||||
rsAPI roomserverAPI.FederationRoomserverAPI,
|
rsAPI roomserverAPI.FederationRoomserverAPI,
|
||||||
) *KeyChangeConsumer {
|
) *KeyChangeConsumer {
|
||||||
return &KeyChangeConsumer{
|
return &KeyChangeConsumer{
|
||||||
ctx: process.Context(),
|
ctx: process.Context(),
|
||||||
jetstream: js,
|
jetstream: js,
|
||||||
durable: cfg.Matrix.JetStream.Prefixed("FederationAPIKeyChangeConsumer"),
|
durable: cfg.Matrix.JetStream.Prefixed("FederationAPIKeyChangeConsumer"),
|
||||||
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputKeyChangeEvent),
|
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputKeyChangeEvent),
|
||||||
queues: queues,
|
queues: queues,
|
||||||
db: store,
|
db: store,
|
||||||
serverName: cfg.Matrix.ServerName,
|
isLocalServerName: cfg.Matrix.IsLocalServerName,
|
||||||
rsAPI: rsAPI,
|
rsAPI: rsAPI,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +112,7 @@ func (t *KeyChangeConsumer) onDeviceKeyMessage(m api.DeviceMessage) bool {
|
||||||
logger.WithError(err).Error("Failed to extract domain from key change event")
|
logger.WithError(err).Error("Failed to extract domain from key change event")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if originServerName != t.serverName {
|
if !t.isLocalServerName(originServerName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,7 +141,7 @@ func (t *KeyChangeConsumer) onDeviceKeyMessage(m api.DeviceMessage) bool {
|
||||||
// Pack the EDU and marshal it
|
// Pack the EDU and marshal it
|
||||||
edu := &gomatrixserverlib.EDU{
|
edu := &gomatrixserverlib.EDU{
|
||||||
Type: gomatrixserverlib.MDeviceListUpdate,
|
Type: gomatrixserverlib.MDeviceListUpdate,
|
||||||
Origin: string(t.serverName),
|
Origin: string(originServerName),
|
||||||
}
|
}
|
||||||
event := gomatrixserverlib.DeviceListUpdateEvent{
|
event := gomatrixserverlib.DeviceListUpdateEvent{
|
||||||
UserID: m.UserID,
|
UserID: m.UserID,
|
||||||
|
|
@ -159,7 +159,7 @@ func (t *KeyChangeConsumer) onDeviceKeyMessage(m api.DeviceMessage) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debugf("Sending device list update message to %q", destinations)
|
logger.Debugf("Sending device list update message to %q", destinations)
|
||||||
err = t.queues.SendEDU(edu, t.serverName, destinations)
|
err = t.queues.SendEDU(edu, originServerName, destinations)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,7 +171,7 @@ func (t *KeyChangeConsumer) onCrossSigningMessage(m api.DeviceMessage) bool {
|
||||||
logrus.WithError(err).Errorf("fedsender key change consumer: user ID parse failure")
|
logrus.WithError(err).Errorf("fedsender key change consumer: user ID parse failure")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if host != gomatrixserverlib.ServerName(t.serverName) {
|
if !t.isLocalServerName(host) {
|
||||||
// Ignore any messages that didn't originate locally, otherwise we'll
|
// Ignore any messages that didn't originate locally, otherwise we'll
|
||||||
// end up parroting information we received from other servers.
|
// end up parroting information we received from other servers.
|
||||||
return true
|
return true
|
||||||
|
|
@ -203,7 +203,7 @@ func (t *KeyChangeConsumer) onCrossSigningMessage(m api.DeviceMessage) bool {
|
||||||
// Pack the EDU and marshal it
|
// Pack the EDU and marshal it
|
||||||
edu := &gomatrixserverlib.EDU{
|
edu := &gomatrixserverlib.EDU{
|
||||||
Type: types.MSigningKeyUpdate,
|
Type: types.MSigningKeyUpdate,
|
||||||
Origin: string(t.serverName),
|
Origin: string(host),
|
||||||
}
|
}
|
||||||
if edu.Content, err = json.Marshal(output); err != nil {
|
if edu.Content, err = json.Marshal(output); err != nil {
|
||||||
sentry.CaptureException(err)
|
sentry.CaptureException(err)
|
||||||
|
|
@ -212,7 +212,7 @@ func (t *KeyChangeConsumer) onCrossSigningMessage(m api.DeviceMessage) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Debugf("Sending cross-signing update message to %q", destinations)
|
logger.Debugf("Sending cross-signing update message to %q", destinations)
|
||||||
err = t.queues.SendEDU(edu, t.serverName, destinations)
|
err = t.queues.SendEDU(edu, host, destinations)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ type OutputPresenceConsumer struct {
|
||||||
durable string
|
durable string
|
||||||
db storage.Database
|
db storage.Database
|
||||||
queues *queue.OutgoingQueues
|
queues *queue.OutgoingQueues
|
||||||
ServerName gomatrixserverlib.ServerName
|
isLocalServerName func(gomatrixserverlib.ServerName) bool
|
||||||
topic string
|
topic string
|
||||||
outboundPresenceEnabled bool
|
outboundPresenceEnabled bool
|
||||||
}
|
}
|
||||||
|
|
@ -56,7 +56,7 @@ func NewOutputPresenceConsumer(
|
||||||
jetstream: js,
|
jetstream: js,
|
||||||
queues: queues,
|
queues: queues,
|
||||||
db: store,
|
db: store,
|
||||||
ServerName: cfg.Matrix.ServerName,
|
isLocalServerName: cfg.Matrix.IsLocalServerName,
|
||||||
durable: cfg.Matrix.JetStream.Durable("FederationAPIPresenceConsumer"),
|
durable: cfg.Matrix.JetStream.Durable("FederationAPIPresenceConsumer"),
|
||||||
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputPresenceEvent),
|
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputPresenceEvent),
|
||||||
outboundPresenceEnabled: cfg.Matrix.Presence.EnableOutbound,
|
outboundPresenceEnabled: cfg.Matrix.Presence.EnableOutbound,
|
||||||
|
|
@ -85,7 +85,7 @@ func (t *OutputPresenceConsumer) onMessage(ctx context.Context, msgs []*nats.Msg
|
||||||
log.WithError(err).WithField("user_id", userID).Error("failed to extract domain from receipt sender")
|
log.WithError(err).WithField("user_id", userID).Error("failed to extract domain from receipt sender")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if serverName != t.ServerName {
|
if !t.isLocalServerName(serverName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,7 +127,7 @@ func (t *OutputPresenceConsumer) onMessage(ctx context.Context, msgs []*nats.Msg
|
||||||
|
|
||||||
edu := &gomatrixserverlib.EDU{
|
edu := &gomatrixserverlib.EDU{
|
||||||
Type: gomatrixserverlib.MPresence,
|
Type: gomatrixserverlib.MPresence,
|
||||||
Origin: string(t.ServerName),
|
Origin: string(serverName),
|
||||||
}
|
}
|
||||||
if edu.Content, err = json.Marshal(content); err != nil {
|
if edu.Content, err = json.Marshal(content); err != nil {
|
||||||
log.WithError(err).Error("failed to marshal EDU JSON")
|
log.WithError(err).Error("failed to marshal EDU JSON")
|
||||||
|
|
@ -135,7 +135,7 @@ func (t *OutputPresenceConsumer) onMessage(ctx context.Context, msgs []*nats.Msg
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Tracef("sending presence EDU to %d servers", len(joined))
|
log.Tracef("sending presence EDU to %d servers", len(joined))
|
||||||
if err = t.queues.SendEDU(edu, t.ServerName, joined); err != nil {
|
if err = t.queues.SendEDU(edu, serverName, joined); err != nil {
|
||||||
log.WithError(err).Error("failed to send EDU")
|
log.WithError(err).Error("failed to send EDU")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,13 @@ import (
|
||||||
|
|
||||||
// OutputReceiptConsumer consumes events that originate in the clientapi.
|
// OutputReceiptConsumer consumes events that originate in the clientapi.
|
||||||
type OutputReceiptConsumer struct {
|
type OutputReceiptConsumer struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
jetstream nats.JetStreamContext
|
jetstream nats.JetStreamContext
|
||||||
durable string
|
durable string
|
||||||
db storage.Database
|
db storage.Database
|
||||||
queues *queue.OutgoingQueues
|
queues *queue.OutgoingQueues
|
||||||
ServerName gomatrixserverlib.ServerName
|
isLocalServerName func(gomatrixserverlib.ServerName) bool
|
||||||
topic string
|
topic string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOutputReceiptConsumer creates a new OutputReceiptConsumer. Call Start() to begin consuming typing events.
|
// NewOutputReceiptConsumer creates a new OutputReceiptConsumer. Call Start() to begin consuming typing events.
|
||||||
|
|
@ -52,13 +52,13 @@ func NewOutputReceiptConsumer(
|
||||||
store storage.Database,
|
store storage.Database,
|
||||||
) *OutputReceiptConsumer {
|
) *OutputReceiptConsumer {
|
||||||
return &OutputReceiptConsumer{
|
return &OutputReceiptConsumer{
|
||||||
ctx: process.Context(),
|
ctx: process.Context(),
|
||||||
jetstream: js,
|
jetstream: js,
|
||||||
queues: queues,
|
queues: queues,
|
||||||
db: store,
|
db: store,
|
||||||
ServerName: cfg.Matrix.ServerName,
|
isLocalServerName: cfg.Matrix.IsLocalServerName,
|
||||||
durable: cfg.Matrix.JetStream.Durable("FederationAPIReceiptConsumer"),
|
durable: cfg.Matrix.JetStream.Durable("FederationAPIReceiptConsumer"),
|
||||||
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputReceiptEvent),
|
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputReceiptEvent),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ func (t *OutputReceiptConsumer) onMessage(ctx context.Context, msgs []*nats.Msg)
|
||||||
log.WithError(err).WithField("user_id", receipt.UserID).Error("failed to extract domain from receipt sender")
|
log.WithError(err).WithField("user_id", receipt.UserID).Error("failed to extract domain from receipt sender")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if receiptServerName != t.ServerName {
|
if !t.isLocalServerName(receiptServerName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,14 +134,14 @@ func (t *OutputReceiptConsumer) onMessage(ctx context.Context, msgs []*nats.Msg)
|
||||||
|
|
||||||
edu := &gomatrixserverlib.EDU{
|
edu := &gomatrixserverlib.EDU{
|
||||||
Type: gomatrixserverlib.MReceipt,
|
Type: gomatrixserverlib.MReceipt,
|
||||||
Origin: string(t.ServerName),
|
Origin: string(receiptServerName),
|
||||||
}
|
}
|
||||||
if edu.Content, err = json.Marshal(content); err != nil {
|
if edu.Content, err = json.Marshal(content); err != nil {
|
||||||
log.WithError(err).Error("failed to marshal EDU JSON")
|
log.WithError(err).Error("failed to marshal EDU JSON")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.queues.SendEDU(edu, t.ServerName, names); err != nil {
|
if err := t.queues.SendEDU(edu, receiptServerName, names); err != nil {
|
||||||
log.WithError(err).Error("failed to send EDU")
|
log.WithError(err).Error("failed to send EDU")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,13 +34,13 @@ import (
|
||||||
|
|
||||||
// OutputSendToDeviceConsumer consumes events that originate in the clientapi.
|
// OutputSendToDeviceConsumer consumes events that originate in the clientapi.
|
||||||
type OutputSendToDeviceConsumer struct {
|
type OutputSendToDeviceConsumer struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
jetstream nats.JetStreamContext
|
jetstream nats.JetStreamContext
|
||||||
durable string
|
durable string
|
||||||
db storage.Database
|
db storage.Database
|
||||||
queues *queue.OutgoingQueues
|
queues *queue.OutgoingQueues
|
||||||
ServerName gomatrixserverlib.ServerName
|
isLocalServerName func(gomatrixserverlib.ServerName) bool
|
||||||
topic string
|
topic string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOutputSendToDeviceConsumer creates a new OutputSendToDeviceConsumer. Call Start() to begin consuming send-to-device events.
|
// NewOutputSendToDeviceConsumer creates a new OutputSendToDeviceConsumer. Call Start() to begin consuming send-to-device events.
|
||||||
|
|
@ -52,13 +52,13 @@ func NewOutputSendToDeviceConsumer(
|
||||||
store storage.Database,
|
store storage.Database,
|
||||||
) *OutputSendToDeviceConsumer {
|
) *OutputSendToDeviceConsumer {
|
||||||
return &OutputSendToDeviceConsumer{
|
return &OutputSendToDeviceConsumer{
|
||||||
ctx: process.Context(),
|
ctx: process.Context(),
|
||||||
jetstream: js,
|
jetstream: js,
|
||||||
queues: queues,
|
queues: queues,
|
||||||
db: store,
|
db: store,
|
||||||
ServerName: cfg.Matrix.ServerName,
|
isLocalServerName: cfg.Matrix.IsLocalServerName,
|
||||||
durable: cfg.Matrix.JetStream.Durable("FederationAPIESendToDeviceConsumer"),
|
durable: cfg.Matrix.JetStream.Durable("FederationAPIESendToDeviceConsumer"),
|
||||||
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputSendToDeviceEvent),
|
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputSendToDeviceEvent),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ func (t *OutputSendToDeviceConsumer) onMessage(ctx context.Context, msgs []*nats
|
||||||
log.WithError(err).WithField("user_id", sender).Error("Failed to extract domain from send-to-device sender")
|
log.WithError(err).WithField("user_id", sender).Error("Failed to extract domain from send-to-device sender")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if originServerName != t.ServerName {
|
if !t.isLocalServerName(originServerName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// Extract the send-to-device event from msg.
|
// Extract the send-to-device event from msg.
|
||||||
|
|
@ -101,14 +101,14 @@ func (t *OutputSendToDeviceConsumer) onMessage(ctx context.Context, msgs []*nats
|
||||||
}
|
}
|
||||||
|
|
||||||
// The SyncAPI is already handling sendToDevice for the local server
|
// The SyncAPI is already handling sendToDevice for the local server
|
||||||
if destServerName == t.ServerName {
|
if t.isLocalServerName(destServerName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pack the EDU and marshal it
|
// Pack the EDU and marshal it
|
||||||
edu := &gomatrixserverlib.EDU{
|
edu := &gomatrixserverlib.EDU{
|
||||||
Type: gomatrixserverlib.MDirectToDevice,
|
Type: gomatrixserverlib.MDirectToDevice,
|
||||||
Origin: string(t.ServerName),
|
Origin: string(originServerName),
|
||||||
}
|
}
|
||||||
tdm := gomatrixserverlib.ToDeviceMessage{
|
tdm := gomatrixserverlib.ToDeviceMessage{
|
||||||
Sender: ote.Sender,
|
Sender: ote.Sender,
|
||||||
|
|
@ -127,7 +127,7 @@ func (t *OutputSendToDeviceConsumer) onMessage(ctx context.Context, msgs []*nats
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Sending send-to-device message into %q destination queue", destServerName)
|
log.Debugf("Sending send-to-device message into %q destination queue", destServerName)
|
||||||
if err := t.queues.SendEDU(edu, t.ServerName, []gomatrixserverlib.ServerName{destServerName}); err != nil {
|
if err := t.queues.SendEDU(edu, originServerName, []gomatrixserverlib.ServerName{destServerName}); err != nil {
|
||||||
log.WithError(err).Error("failed to send EDU")
|
log.WithError(err).Error("failed to send EDU")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,13 @@ import (
|
||||||
|
|
||||||
// OutputTypingConsumer consumes events that originate in the clientapi.
|
// OutputTypingConsumer consumes events that originate in the clientapi.
|
||||||
type OutputTypingConsumer struct {
|
type OutputTypingConsumer struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
jetstream nats.JetStreamContext
|
jetstream nats.JetStreamContext
|
||||||
durable string
|
durable string
|
||||||
db storage.Database
|
db storage.Database
|
||||||
queues *queue.OutgoingQueues
|
queues *queue.OutgoingQueues
|
||||||
ServerName gomatrixserverlib.ServerName
|
isLocalServerName func(gomatrixserverlib.ServerName) bool
|
||||||
topic string
|
topic string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOutputTypingConsumer creates a new OutputTypingConsumer. Call Start() to begin consuming typing events.
|
// NewOutputTypingConsumer creates a new OutputTypingConsumer. Call Start() to begin consuming typing events.
|
||||||
|
|
@ -49,13 +49,13 @@ func NewOutputTypingConsumer(
|
||||||
store storage.Database,
|
store storage.Database,
|
||||||
) *OutputTypingConsumer {
|
) *OutputTypingConsumer {
|
||||||
return &OutputTypingConsumer{
|
return &OutputTypingConsumer{
|
||||||
ctx: process.Context(),
|
ctx: process.Context(),
|
||||||
jetstream: js,
|
jetstream: js,
|
||||||
queues: queues,
|
queues: queues,
|
||||||
db: store,
|
db: store,
|
||||||
ServerName: cfg.Matrix.ServerName,
|
isLocalServerName: cfg.Matrix.IsLocalServerName,
|
||||||
durable: cfg.Matrix.JetStream.Durable("FederationAPITypingConsumer"),
|
durable: cfg.Matrix.JetStream.Durable("FederationAPITypingConsumer"),
|
||||||
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputTypingEvent),
|
topic: cfg.Matrix.JetStream.Prefixed(jetstream.OutputTypingEvent),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ func (t *OutputTypingConsumer) onMessage(ctx context.Context, msgs []*nats.Msg)
|
||||||
_ = msg.Ack()
|
_ = msg.Ack()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if typingServerName != t.ServerName {
|
if !t.isLocalServerName(typingServerName) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ func (t *OutputTypingConsumer) onMessage(ctx context.Context, msgs []*nats.Msg)
|
||||||
log.WithError(err).Error("failed to marshal EDU JSON")
|
log.WithError(err).Error("failed to marshal EDU JSON")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if err := t.queues.SendEDU(edu, t.ServerName, names); err != nil {
|
if err := t.queues.SendEDU(edu, typingServerName, names); err != nil {
|
||||||
log.WithError(err).Error("failed to send EDU")
|
log.WithError(err).Error("failed to send EDU")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ func AddPublicRoutes(
|
||||||
TopicPresenceEvent: cfg.Matrix.JetStream.Prefixed(jetstream.OutputPresenceEvent),
|
TopicPresenceEvent: cfg.Matrix.JetStream.Prefixed(jetstream.OutputPresenceEvent),
|
||||||
TopicDeviceListUpdate: cfg.Matrix.JetStream.Prefixed(jetstream.InputDeviceListUpdate),
|
TopicDeviceListUpdate: cfg.Matrix.JetStream.Prefixed(jetstream.InputDeviceListUpdate),
|
||||||
TopicSigningKeyUpdate: cfg.Matrix.JetStream.Prefixed(jetstream.InputSigningKeyUpdate),
|
TopicSigningKeyUpdate: cfg.Matrix.JetStream.Prefixed(jetstream.InputSigningKeyUpdate),
|
||||||
ServerName: cfg.Matrix.ServerName,
|
Config: cfg,
|
||||||
UserAPI: userAPI,
|
UserAPI: userAPI,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +107,7 @@ func NewInternalAPI(
|
||||||
) api.FederationInternalAPI {
|
) api.FederationInternalAPI {
|
||||||
cfg := &base.Cfg.FederationAPI
|
cfg := &base.Cfg.FederationAPI
|
||||||
|
|
||||||
federationDB, err := storage.NewDatabase(base, &cfg.Database, base.Caches, base.Cfg.Global.ServerName)
|
federationDB, err := storage.NewDatabase(base, &cfg.Database, base.Caches, base.Cfg.Global.IsLocalServerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).Panic("failed to connect to federation sender db")
|
logrus.WithError(err).Panic("failed to connect to federation sender db")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ func TestMain(m *testing.M) {
|
||||||
cfg.Global.JetStream.StoragePath = config.Path(d)
|
cfg.Global.JetStream.StoragePath = config.Path(d)
|
||||||
cfg.Global.KeyID = serverKeyID
|
cfg.Global.KeyID = serverKeyID
|
||||||
cfg.Global.KeyValidityPeriod = s.validity
|
cfg.Global.KeyValidityPeriod = s.validity
|
||||||
|
cfg.FederationAPI.KeyPerspectives = nil
|
||||||
f, err := os.CreateTemp(d, "federation_keys_test*.db")
|
f, err := os.CreateTemp(d, "federation_keys_test*.db")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1
|
return -1
|
||||||
|
|
@ -207,7 +208,6 @@ func TestRenewalBehaviour(t *testing.T) {
|
||||||
// happy at this point that the key that we already have is from the past
|
// happy at this point that the key that we already have is from the past
|
||||||
// then repeating a key fetch should cause us to try and renew the key.
|
// then repeating a key fetch should cause us to try and renew the key.
|
||||||
// If so, then the new key will end up in our cache.
|
// If so, then the new key will end up in our cache.
|
||||||
|
|
||||||
serverC.renew()
|
serverC.renew()
|
||||||
|
|
||||||
res, err = serverA.api.FetchKeys(
|
res, err = serverA.api.FetchKeys(
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,7 @@ func TestFederationAPIJoinThenKeyUpdate(t *testing.T) {
|
||||||
func testFederationAPIJoinThenKeyUpdate(t *testing.T, dbType test.DBType) {
|
func testFederationAPIJoinThenKeyUpdate(t *testing.T, dbType test.DBType) {
|
||||||
base, close := testrig.CreateBaseDendrite(t, dbType)
|
base, close := testrig.CreateBaseDendrite(t, dbType)
|
||||||
base.Cfg.FederationAPI.PreferDirectFetch = true
|
base.Cfg.FederationAPI.PreferDirectFetch = true
|
||||||
|
base.Cfg.FederationAPI.KeyPerspectives = nil
|
||||||
defer close()
|
defer close()
|
||||||
jsctx, _ := base.NATS.Prepare(base.ProcessContext, &base.Cfg.Global.JetStream)
|
jsctx, _ := base.NATS.Prepare(base.ProcessContext, &base.Cfg.Global.JetStream)
|
||||||
defer jetstream.DeleteAllStreams(jsctx, &base.Cfg.Global.JetStream)
|
defer jetstream.DeleteAllStreams(jsctx, &base.Cfg.Global.JetStream)
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ func (s *FederationInternalAPI) handleLocalKeys(
|
||||||
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
results map[gomatrixserverlib.PublicKeyLookupRequest]gomatrixserverlib.PublicKeyLookupResult,
|
||||||
) {
|
) {
|
||||||
for req := range requests {
|
for req := range requests {
|
||||||
if req.ServerName != s.cfg.Matrix.ServerName {
|
if !s.cfg.Matrix.IsLocalServerName(req.ServerName) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if req.KeyID == s.cfg.Matrix.KeyID {
|
if req.KeyID == s.cfg.Matrix.KeyID {
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ func (r *FederationInternalAPI) PerformJoin(
|
||||||
seenSet := make(map[gomatrixserverlib.ServerName]bool)
|
seenSet := make(map[gomatrixserverlib.ServerName]bool)
|
||||||
var uniqueList []gomatrixserverlib.ServerName
|
var uniqueList []gomatrixserverlib.ServerName
|
||||||
for _, srv := range request.ServerNames {
|
for _, srv := range request.ServerNames {
|
||||||
if seenSet[srv] || srv == r.cfg.Matrix.ServerName {
|
if seenSet[srv] || r.cfg.Matrix.IsLocalServerName(srv) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
seenSet[srv] = true
|
seenSet[srv] = true
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/setup/jetstream"
|
"github.com/matrix-org/dendrite/setup/jetstream"
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
|
|
@ -39,7 +40,7 @@ type SyncAPIProducer struct {
|
||||||
TopicDeviceListUpdate string
|
TopicDeviceListUpdate string
|
||||||
TopicSigningKeyUpdate string
|
TopicSigningKeyUpdate string
|
||||||
JetStream nats.JetStreamContext
|
JetStream nats.JetStreamContext
|
||||||
ServerName gomatrixserverlib.ServerName
|
Config *config.FederationAPI
|
||||||
UserAPI userapi.UserInternalAPI
|
UserAPI userapi.UserInternalAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +78,7 @@ func (p *SyncAPIProducer) SendToDevice(
|
||||||
// device. If the event isn't targeted locally then we can't expand the
|
// device. If the event isn't targeted locally then we can't expand the
|
||||||
// wildcard as we don't know about the remote devices, so instead we leave it
|
// wildcard as we don't know about the remote devices, so instead we leave it
|
||||||
// as-is, so that the federation sender can send it on with the wildcard intact.
|
// as-is, so that the federation sender can send it on with the wildcard intact.
|
||||||
if domain == p.ServerName && deviceID == "*" {
|
if p.Config.Matrix.IsLocalServerName(domain) && deviceID == "*" {
|
||||||
var res userapi.QueryDevicesResponse
|
var res userapi.QueryDevicesResponse
|
||||||
err = p.UserAPI.QueryDevices(context.TODO(), &userapi.QueryDevicesRequest{
|
err = p.UserAPI.QueryDevices(context.TODO(), &userapi.QueryDevicesRequest{
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ func mustCreateFederationDatabase(t *testing.T, dbType test.DBType, realDatabase
|
||||||
connStr, dbClose := test.PrepareDBConnectionString(t, dbType)
|
connStr, dbClose := test.PrepareDBConnectionString(t, dbType)
|
||||||
db, err := storage.NewDatabase(b, &config.DatabaseOptions{
|
db, err := storage.NewDatabase(b, &config.DatabaseOptions{
|
||||||
ConnectionString: config.DataSource(connStr),
|
ConnectionString: config.DataSource(connStr),
|
||||||
}, b.Caches, b.Cfg.Global.ServerName)
|
}, b.Caches, b.Cfg.Global.IsLocalServerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("NewDatabase returned %s", err)
|
t.Fatalf("NewDatabase returned %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ func Setup(
|
||||||
|
|
||||||
mu := internal.NewMutexByRoom()
|
mu := internal.NewMutexByRoom()
|
||||||
v1fedmux.Handle("/send/{txnID}", MakeFedAPI(
|
v1fedmux.Handle("/send/{txnID}", MakeFedAPI(
|
||||||
"federation_send", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_send", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
return Send(
|
return Send(
|
||||||
httpReq, request, gomatrixserverlib.TransactionID(vars["txnID"]),
|
httpReq, request, gomatrixserverlib.TransactionID(vars["txnID"]),
|
||||||
|
|
@ -134,7 +134,7 @@ func Setup(
|
||||||
)).Methods(http.MethodPut, http.MethodOptions)
|
)).Methods(http.MethodPut, http.MethodOptions)
|
||||||
|
|
||||||
v1fedmux.Handle("/invite/{roomID}/{eventID}", MakeFedAPI(
|
v1fedmux.Handle("/invite/{roomID}/{eventID}", MakeFedAPI(
|
||||||
"federation_invite", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_invite", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -150,7 +150,7 @@ func Setup(
|
||||||
)).Methods(http.MethodPut, http.MethodOptions)
|
)).Methods(http.MethodPut, http.MethodOptions)
|
||||||
|
|
||||||
v2fedmux.Handle("/invite/{roomID}/{eventID}", MakeFedAPI(
|
v2fedmux.Handle("/invite/{roomID}/{eventID}", MakeFedAPI(
|
||||||
"federation_invite", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_invite", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -172,7 +172,7 @@ func Setup(
|
||||||
)).Methods(http.MethodPost, http.MethodOptions)
|
)).Methods(http.MethodPost, http.MethodOptions)
|
||||||
|
|
||||||
v1fedmux.Handle("/exchange_third_party_invite/{roomID}", MakeFedAPI(
|
v1fedmux.Handle("/exchange_third_party_invite/{roomID}", MakeFedAPI(
|
||||||
"exchange_third_party_invite", cfg.Matrix.ServerName, keys, wakeup,
|
"exchange_third_party_invite", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
return ExchangeThirdPartyInvite(
|
return ExchangeThirdPartyInvite(
|
||||||
httpReq, request, vars["roomID"], rsAPI, cfg, federation,
|
httpReq, request, vars["roomID"], rsAPI, cfg, federation,
|
||||||
|
|
@ -181,7 +181,7 @@ func Setup(
|
||||||
)).Methods(http.MethodPut, http.MethodOptions)
|
)).Methods(http.MethodPut, http.MethodOptions)
|
||||||
|
|
||||||
v1fedmux.Handle("/event/{eventID}", MakeFedAPI(
|
v1fedmux.Handle("/event/{eventID}", MakeFedAPI(
|
||||||
"federation_get_event", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_get_event", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
return GetEvent(
|
return GetEvent(
|
||||||
httpReq.Context(), request, rsAPI, vars["eventID"], cfg.Matrix.ServerName,
|
httpReq.Context(), request, rsAPI, vars["eventID"], cfg.Matrix.ServerName,
|
||||||
|
|
@ -190,7 +190,7 @@ func Setup(
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
v1fedmux.Handle("/state/{roomID}", MakeFedAPI(
|
v1fedmux.Handle("/state/{roomID}", MakeFedAPI(
|
||||||
"federation_get_state", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_get_state", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -205,7 +205,7 @@ func Setup(
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
v1fedmux.Handle("/state_ids/{roomID}", MakeFedAPI(
|
v1fedmux.Handle("/state_ids/{roomID}", MakeFedAPI(
|
||||||
"federation_get_state_ids", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_get_state_ids", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -220,7 +220,7 @@ func Setup(
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
v1fedmux.Handle("/event_auth/{roomID}/{eventID}", MakeFedAPI(
|
v1fedmux.Handle("/event_auth/{roomID}/{eventID}", MakeFedAPI(
|
||||||
"federation_get_event_auth", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_get_event_auth", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -235,7 +235,7 @@ func Setup(
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
v1fedmux.Handle("/query/directory", MakeFedAPI(
|
v1fedmux.Handle("/query/directory", MakeFedAPI(
|
||||||
"federation_query_room_alias", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_query_room_alias", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
return RoomAliasToID(
|
return RoomAliasToID(
|
||||||
httpReq, federation, cfg, rsAPI, fsAPI,
|
httpReq, federation, cfg, rsAPI, fsAPI,
|
||||||
|
|
@ -244,7 +244,7 @@ func Setup(
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
v1fedmux.Handle("/query/profile", MakeFedAPI(
|
v1fedmux.Handle("/query/profile", MakeFedAPI(
|
||||||
"federation_query_profile", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_query_profile", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
return GetProfile(
|
return GetProfile(
|
||||||
httpReq, userAPI, cfg,
|
httpReq, userAPI, cfg,
|
||||||
|
|
@ -253,7 +253,7 @@ func Setup(
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
v1fedmux.Handle("/user/devices/{userID}", MakeFedAPI(
|
v1fedmux.Handle("/user/devices/{userID}", MakeFedAPI(
|
||||||
"federation_user_devices", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_user_devices", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
return GetUserDevices(
|
return GetUserDevices(
|
||||||
httpReq, keyAPI, vars["userID"],
|
httpReq, keyAPI, vars["userID"],
|
||||||
|
|
@ -263,7 +263,7 @@ func Setup(
|
||||||
|
|
||||||
if mscCfg.Enabled("msc2444") {
|
if mscCfg.Enabled("msc2444") {
|
||||||
v1fedmux.Handle("/peek/{roomID}/{peekID}", MakeFedAPI(
|
v1fedmux.Handle("/peek/{roomID}/{peekID}", MakeFedAPI(
|
||||||
"federation_peek", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_peek", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -294,7 +294,7 @@ func Setup(
|
||||||
}
|
}
|
||||||
|
|
||||||
v1fedmux.Handle("/make_join/{roomID}/{userID}", MakeFedAPI(
|
v1fedmux.Handle("/make_join/{roomID}/{userID}", MakeFedAPI(
|
||||||
"federation_make_join", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_make_join", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -325,7 +325,7 @@ func Setup(
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
v1fedmux.Handle("/send_join/{roomID}/{eventID}", MakeFedAPI(
|
v1fedmux.Handle("/send_join/{roomID}/{eventID}", MakeFedAPI(
|
||||||
"federation_send_join", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_send_join", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -357,7 +357,7 @@ func Setup(
|
||||||
)).Methods(http.MethodPut)
|
)).Methods(http.MethodPut)
|
||||||
|
|
||||||
v2fedmux.Handle("/send_join/{roomID}/{eventID}", MakeFedAPI(
|
v2fedmux.Handle("/send_join/{roomID}/{eventID}", MakeFedAPI(
|
||||||
"federation_send_join", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_send_join", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -374,7 +374,7 @@ func Setup(
|
||||||
)).Methods(http.MethodPut)
|
)).Methods(http.MethodPut)
|
||||||
|
|
||||||
v1fedmux.Handle("/make_leave/{roomID}/{eventID}", MakeFedAPI(
|
v1fedmux.Handle("/make_leave/{roomID}/{eventID}", MakeFedAPI(
|
||||||
"federation_make_leave", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_make_leave", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -391,7 +391,7 @@ func Setup(
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
v1fedmux.Handle("/send_leave/{roomID}/{eventID}", MakeFedAPI(
|
v1fedmux.Handle("/send_leave/{roomID}/{eventID}", MakeFedAPI(
|
||||||
"federation_send_leave", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_send_leave", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -423,7 +423,7 @@ func Setup(
|
||||||
)).Methods(http.MethodPut)
|
)).Methods(http.MethodPut)
|
||||||
|
|
||||||
v2fedmux.Handle("/send_leave/{roomID}/{eventID}", MakeFedAPI(
|
v2fedmux.Handle("/send_leave/{roomID}/{eventID}", MakeFedAPI(
|
||||||
"federation_send_leave", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_send_leave", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -447,7 +447,7 @@ func Setup(
|
||||||
)).Methods(http.MethodGet)
|
)).Methods(http.MethodGet)
|
||||||
|
|
||||||
v1fedmux.Handle("/get_missing_events/{roomID}", MakeFedAPI(
|
v1fedmux.Handle("/get_missing_events/{roomID}", MakeFedAPI(
|
||||||
"federation_get_missing_events", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_get_missing_events", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -460,7 +460,7 @@ func Setup(
|
||||||
)).Methods(http.MethodPost)
|
)).Methods(http.MethodPost)
|
||||||
|
|
||||||
v1fedmux.Handle("/backfill/{roomID}", MakeFedAPI(
|
v1fedmux.Handle("/backfill/{roomID}", MakeFedAPI(
|
||||||
"federation_backfill", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_backfill", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
if roomserverAPI.IsServerBannedFromRoom(httpReq.Context(), rsAPI, vars["roomID"], request.Origin()) {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
|
|
@ -479,14 +479,14 @@ func Setup(
|
||||||
).Methods(http.MethodGet, http.MethodPost)
|
).Methods(http.MethodGet, http.MethodPost)
|
||||||
|
|
||||||
v1fedmux.Handle("/user/keys/claim", MakeFedAPI(
|
v1fedmux.Handle("/user/keys/claim", MakeFedAPI(
|
||||||
"federation_keys_claim", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_keys_claim", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
return ClaimOneTimeKeys(httpReq, request, keyAPI, cfg.Matrix.ServerName)
|
return ClaimOneTimeKeys(httpReq, request, keyAPI, cfg.Matrix.ServerName)
|
||||||
},
|
},
|
||||||
)).Methods(http.MethodPost)
|
)).Methods(http.MethodPost)
|
||||||
|
|
||||||
v1fedmux.Handle("/user/keys/query", MakeFedAPI(
|
v1fedmux.Handle("/user/keys/query", MakeFedAPI(
|
||||||
"federation_keys_query", cfg.Matrix.ServerName, keys, wakeup,
|
"federation_keys_query", cfg.Matrix.ServerName, cfg.Matrix.IsLocalServerName, keys, wakeup,
|
||||||
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
func(httpReq *http.Request, request *gomatrixserverlib.FederationRequest, vars map[string]string) util.JSONResponse {
|
||||||
return QueryDeviceKeys(httpReq, request, keyAPI, cfg.Matrix.ServerName)
|
return QueryDeviceKeys(httpReq, request, keyAPI, cfg.Matrix.ServerName)
|
||||||
},
|
},
|
||||||
|
|
@ -525,15 +525,15 @@ func ErrorIfLocalServerNotInRoom(
|
||||||
|
|
||||||
// MakeFedAPI makes an http.Handler that checks matrix federation authentication.
|
// MakeFedAPI makes an http.Handler that checks matrix federation authentication.
|
||||||
func MakeFedAPI(
|
func MakeFedAPI(
|
||||||
metricsName string,
|
metricsName string, serverName gomatrixserverlib.ServerName,
|
||||||
serverName gomatrixserverlib.ServerName,
|
isLocalServerName func(gomatrixserverlib.ServerName) bool,
|
||||||
keyRing gomatrixserverlib.JSONVerifier,
|
keyRing gomatrixserverlib.JSONVerifier,
|
||||||
wakeup *FederationWakeups,
|
wakeup *FederationWakeups,
|
||||||
f func(*http.Request, *gomatrixserverlib.FederationRequest, map[string]string) util.JSONResponse,
|
f func(*http.Request, *gomatrixserverlib.FederationRequest, map[string]string) util.JSONResponse,
|
||||||
) http.Handler {
|
) http.Handler {
|
||||||
h := func(req *http.Request) util.JSONResponse {
|
h := func(req *http.Request) util.JSONResponse {
|
||||||
fedReq, errResp := gomatrixserverlib.VerifyHTTPRequest(
|
fedReq, errResp := gomatrixserverlib.VerifyHTTPRequest(
|
||||||
req, time.Now(), serverName, keyRing,
|
req, time.Now(), serverName, isLocalServerName, keyRing,
|
||||||
)
|
)
|
||||||
if fedReq == nil {
|
if fedReq == nil {
|
||||||
return errResp
|
return errResp
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ type Database struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabase opens a new database
|
// NewDatabase opens a new database
|
||||||
func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions, cache caching.FederationCache, serverName gomatrixserverlib.ServerName) (*Database, error) {
|
func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions, cache caching.FederationCache, isLocalServerName func(gomatrixserverlib.ServerName) bool) (*Database, error) {
|
||||||
var d Database
|
var d Database
|
||||||
var err error
|
var err error
|
||||||
if d.db, d.writer, err = base.DatabaseConnection(dbProperties, sqlutil.NewDummyWriter()); err != nil {
|
if d.db, d.writer, err = base.DatabaseConnection(dbProperties, sqlutil.NewDummyWriter()); err != nil {
|
||||||
|
|
@ -96,7 +96,7 @@ func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions,
|
||||||
}
|
}
|
||||||
d.Database = shared.Database{
|
d.Database = shared.Database{
|
||||||
DB: d.db,
|
DB: d.db,
|
||||||
ServerName: serverName,
|
IsLocalServerName: isLocalServerName,
|
||||||
Cache: cache,
|
Cache: cache,
|
||||||
Writer: d.writer,
|
Writer: d.writer,
|
||||||
FederationJoinedHosts: joinedHosts,
|
FederationJoinedHosts: joinedHosts,
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ import (
|
||||||
|
|
||||||
type Database struct {
|
type Database struct {
|
||||||
DB *sql.DB
|
DB *sql.DB
|
||||||
ServerName gomatrixserverlib.ServerName
|
IsLocalServerName func(gomatrixserverlib.ServerName) bool
|
||||||
Cache caching.FederationCache
|
Cache caching.FederationCache
|
||||||
Writer sqlutil.Writer
|
Writer sqlutil.Writer
|
||||||
FederationQueuePDUs tables.FederationQueuePDUs
|
FederationQueuePDUs tables.FederationQueuePDUs
|
||||||
|
|
@ -124,7 +124,7 @@ func (d *Database) GetJoinedHostsForRooms(ctx context.Context, roomIDs []string,
|
||||||
}
|
}
|
||||||
if excludeSelf {
|
if excludeSelf {
|
||||||
for i, server := range servers {
|
for i, server := range servers {
|
||||||
if server == d.ServerName {
|
if d.IsLocalServerName(server) {
|
||||||
servers = append(servers[:i], servers[i+1:]...)
|
servers = append(servers[:i], servers[i+1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ type Database struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabase opens a new database
|
// NewDatabase opens a new database
|
||||||
func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions, cache caching.FederationCache, serverName gomatrixserverlib.ServerName) (*Database, error) {
|
func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions, cache caching.FederationCache, isLocalServerName func(gomatrixserverlib.ServerName) bool) (*Database, error) {
|
||||||
var d Database
|
var d Database
|
||||||
var err error
|
var err error
|
||||||
if d.db, d.writer, err = base.DatabaseConnection(dbProperties, sqlutil.NewExclusiveWriter()); err != nil {
|
if d.db, d.writer, err = base.DatabaseConnection(dbProperties, sqlutil.NewExclusiveWriter()); err != nil {
|
||||||
|
|
@ -95,7 +95,7 @@ func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions,
|
||||||
}
|
}
|
||||||
d.Database = shared.Database{
|
d.Database = shared.Database{
|
||||||
DB: d.db,
|
DB: d.db,
|
||||||
ServerName: serverName,
|
IsLocalServerName: isLocalServerName,
|
||||||
Cache: cache,
|
Cache: cache,
|
||||||
Writer: d.writer,
|
Writer: d.writer,
|
||||||
FederationJoinedHosts: joinedHosts,
|
FederationJoinedHosts: joinedHosts,
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewDatabase opens a new database
|
// NewDatabase opens a new database
|
||||||
func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions, cache caching.FederationCache, serverName gomatrixserverlib.ServerName) (Database, error) {
|
func NewDatabase(base *base.BaseDendrite, dbProperties *config.DatabaseOptions, cache caching.FederationCache, isLocalServerName func(gomatrixserverlib.ServerName) bool) (Database, error) {
|
||||||
switch {
|
switch {
|
||||||
case dbProperties.ConnectionString.IsSQLite():
|
case dbProperties.ConnectionString.IsSQLite():
|
||||||
return sqlite3.NewDatabase(base, dbProperties, cache, serverName)
|
return sqlite3.NewDatabase(base, dbProperties, cache, isLocalServerName)
|
||||||
case dbProperties.ConnectionString.IsPostgres():
|
case dbProperties.ConnectionString.IsPostgres():
|
||||||
return postgres.NewDatabase(base, dbProperties, cache, serverName)
|
return postgres.NewDatabase(base, dbProperties, cache, isLocalServerName)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected database type")
|
return nil, fmt.Errorf("unexpected database type")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ func mustCreateFederationDatabase(t *testing.T, dbType test.DBType) (storage.Dat
|
||||||
connStr, dbClose := test.PrepareDBConnectionString(t, dbType)
|
connStr, dbClose := test.PrepareDBConnectionString(t, dbType)
|
||||||
db, err := storage.NewDatabase(b, &config.DatabaseOptions{
|
db, err := storage.NewDatabase(b, &config.DatabaseOptions{
|
||||||
ConnectionString: config.DataSource(connStr),
|
ConnectionString: config.DataSource(connStr),
|
||||||
}, b.Caches, b.Cfg.Global.ServerName)
|
}, b.Caches, func(server gomatrixserverlib.ServerName) bool { return server == "localhost" })
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("NewDatabase returned %s", err)
|
t.Fatalf("NewDatabase returned %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -22,7 +22,7 @@ require (
|
||||||
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
|
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/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530
|
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20221021091412-7c772f1b388a
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20221025142407-17b0be811afa
|
||||||
github.com/matrix-org/pinecone v0.0.0-20221026160848-639feeff74d6
|
github.com/matrix-org/pinecone v0.0.0-20221026160848-639feeff74d6
|
||||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
|
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
|
||||||
github.com/mattn/go-sqlite3 v1.14.15
|
github.com/mattn/go-sqlite3 v1.14.15
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -387,8 +387,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/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 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U=
|
||||||
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20221021091412-7c772f1b388a h1:6rJFN5NBuzZ7h5meYkLtXKa6VFZfDc8oVXHd4SDXr5o=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20221025142407-17b0be811afa h1:S98DShDv3sn7O4n4HjtJOejypseYVpv1R/XPg+cDnfI=
|
||||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20221021091412-7c772f1b388a/go.mod h1:Mtifyr8q8htcBeugvlDnkBcNUy5LO8OzUoplAf1+mb4=
|
github.com/matrix-org/gomatrixserverlib v0.0.0-20221025142407-17b0be811afa/go.mod h1:Mtifyr8q8htcBeugvlDnkBcNUy5LO8OzUoplAf1+mb4=
|
||||||
github.com/matrix-org/pinecone v0.0.0-20221026160848-639feeff74d6 h1:nAT5w41Q9uWTSnpKW55/hBwP91j2IFYPDRs0jJ8TyFI=
|
github.com/matrix-org/pinecone v0.0.0-20221026160848-639feeff74d6 h1:nAT5w41Q9uWTSnpKW55/hBwP91j2IFYPDRs0jJ8TyFI=
|
||||||
github.com/matrix-org/pinecone v0.0.0-20221026160848-639feeff74d6/go.mod h1:K0N1ixHQxXoCyqolDqVxPM3ArrDtcMs8yegOx2Lfv9k=
|
github.com/matrix-org/pinecone v0.0.0-20221026160848-639feeff74d6/go.mod h1:K0N1ixHQxXoCyqolDqVxPM3ArrDtcMs8yegOx2Lfv9k=
|
||||||
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk=
|
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk=
|
||||||
|
|
|
||||||
|
|
@ -257,9 +257,6 @@ func (a *KeyInternalAPI) QueryKeys(ctx context.Context, req *api.QueryKeysReques
|
||||||
res.UserSigningKeys = make(map[string]gomatrixserverlib.CrossSigningKey)
|
res.UserSigningKeys = make(map[string]gomatrixserverlib.CrossSigningKey)
|
||||||
res.Failures = make(map[string]interface{})
|
res.Failures = make(map[string]interface{})
|
||||||
|
|
||||||
// get cross-signing keys from the database
|
|
||||||
a.crossSigningKeysFromDatabase(ctx, req, res)
|
|
||||||
|
|
||||||
// make a map from domain to device keys
|
// make a map from domain to device keys
|
||||||
domainToDeviceKeys := make(map[string]map[string][]string)
|
domainToDeviceKeys := make(map[string]map[string][]string)
|
||||||
domainToCrossSigningKeys := make(map[string]map[string]struct{})
|
domainToCrossSigningKeys := make(map[string]map[string]struct{})
|
||||||
|
|
@ -336,6 +333,10 @@ func (a *KeyInternalAPI) QueryKeys(ctx context.Context, req *api.QueryKeysReques
|
||||||
a.queryRemoteKeys(ctx, req.Timeout, res, domainToDeviceKeys, domainToCrossSigningKeys)
|
a.queryRemoteKeys(ctx, req.Timeout, res, domainToDeviceKeys, domainToCrossSigningKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now that we've done the potentially expensive work of asking the federation,
|
||||||
|
// try filling the cross-signing keys from the database that we know about.
|
||||||
|
a.crossSigningKeysFromDatabase(ctx, req, res)
|
||||||
|
|
||||||
// Finally, append signatures that we know about
|
// Finally, append signatures that we know about
|
||||||
// TODO: This is horrible because we need to round-trip the signature from
|
// TODO: This is horrible because we need to round-trip the signature from
|
||||||
// JSON, add the signatures and marshal it again, for some reason?
|
// JSON, add the signatures and marshal it again, for some reason?
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ CREATE INDEX IF NOT EXISTS keyserver_cross_signing_sigs_idx ON keyserver_cross_s
|
||||||
|
|
||||||
const selectCrossSigningSigsForTargetSQL = "" +
|
const selectCrossSigningSigsForTargetSQL = "" +
|
||||||
"SELECT origin_user_id, origin_key_id, signature FROM keyserver_cross_signing_sigs" +
|
"SELECT origin_user_id, origin_key_id, signature FROM keyserver_cross_signing_sigs" +
|
||||||
" WHERE (origin_user_id = $1 OR origin_user_id = target_user_id) AND target_user_id = $2 AND target_key_id = $3"
|
" WHERE (origin_user_id = $1 OR origin_user_id = $2) AND target_user_id = $2 AND target_key_id = $3"
|
||||||
|
|
||||||
const upsertCrossSigningSigsForTargetSQL = "" +
|
const upsertCrossSigningSigsForTargetSQL = "" +
|
||||||
"INSERT INTO keyserver_cross_signing_sigs (origin_user_id, origin_key_id, target_user_id, target_key_id, signature)" +
|
"INSERT INTO keyserver_cross_signing_sigs (origin_user_id, origin_key_id, target_user_id, target_key_id, signature)" +
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ CREATE INDEX IF NOT EXISTS keyserver_cross_signing_sigs_idx ON keyserver_cross_s
|
||||||
|
|
||||||
const selectCrossSigningSigsForTargetSQL = "" +
|
const selectCrossSigningSigsForTargetSQL = "" +
|
||||||
"SELECT origin_user_id, origin_key_id, signature FROM keyserver_cross_signing_sigs" +
|
"SELECT origin_user_id, origin_key_id, signature FROM keyserver_cross_signing_sigs" +
|
||||||
" WHERE (origin_user_id = $1 OR origin_user_id = target_user_id) AND target_user_id = $2 AND target_key_id = $3"
|
" WHERE (origin_user_id = $1 OR origin_user_id = $2) AND target_user_id = $3 AND target_key_id = $4"
|
||||||
|
|
||||||
const upsertCrossSigningSigsForTargetSQL = "" +
|
const upsertCrossSigningSigsForTargetSQL = "" +
|
||||||
"INSERT OR REPLACE INTO keyserver_cross_signing_sigs (origin_user_id, origin_key_id, target_user_id, target_key_id, signature)" +
|
"INSERT OR REPLACE INTO keyserver_cross_signing_sigs (origin_user_id, origin_key_id, target_user_id, target_key_id, signature)" +
|
||||||
|
|
@ -85,7 +85,7 @@ func NewSqliteCrossSigningSigsTable(db *sql.DB) (tables.CrossSigningSigs, error)
|
||||||
func (s *crossSigningSigsStatements) SelectCrossSigningSigsForTarget(
|
func (s *crossSigningSigsStatements) SelectCrossSigningSigsForTarget(
|
||||||
ctx context.Context, txn *sql.Tx, originUserID, targetUserID string, targetKeyID gomatrixserverlib.KeyID,
|
ctx context.Context, txn *sql.Tx, originUserID, targetUserID string, targetKeyID gomatrixserverlib.KeyID,
|
||||||
) (r types.CrossSigningSigMap, err error) {
|
) (r types.CrossSigningSigMap, err error) {
|
||||||
rows, err := sqlutil.TxStmt(txn, s.selectCrossSigningSigsForTargetStmt).QueryContext(ctx, originUserID, targetUserID, targetKeyID)
|
rows, err := sqlutil.TxStmt(txn, s.selectCrossSigningSigsForTargetStmt).QueryContext(ctx, originUserID, targetUserID, targetUserID, targetKeyID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ type UserRoomserverAPI interface {
|
||||||
QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error
|
QueryCurrentState(ctx context.Context, req *QueryCurrentStateRequest, res *QueryCurrentStateResponse) error
|
||||||
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
|
QueryMembershipsForRoom(ctx context.Context, req *QueryMembershipsForRoomRequest, res *QueryMembershipsForRoomResponse) error
|
||||||
PerformAdminEvacuateUser(ctx context.Context, req *PerformAdminEvacuateUserRequest, res *PerformAdminEvacuateUserResponse) error
|
PerformAdminEvacuateUser(ctx context.Context, req *PerformAdminEvacuateUserRequest, res *PerformAdminEvacuateUserResponse) error
|
||||||
|
PerformJoin(ctx context.Context, req *PerformJoinRequest, res *PerformJoinResponse) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type FederationRoomserverAPI interface {
|
type FederationRoomserverAPI interface {
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,11 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
||||||
PrevEvents: prevEvents,
|
PrevEvents: prevEvents,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, senderDomain, err := gomatrixserverlib.SplitID('@', fledglingEvent.Sender)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if fledglingEvent.Content, err = json.Marshal(memberContent); err != nil {
|
if fledglingEvent.Content, err = json.Marshal(memberContent); err != nil {
|
||||||
res.Error = &api.PerformError{
|
res.Error = &api.PerformError{
|
||||||
Code: api.PerformErrorBadRequest,
|
Code: api.PerformErrorBadRequest,
|
||||||
|
|
@ -146,8 +151,8 @@ func (r *Admin) PerformAdminEvacuateRoom(
|
||||||
inputEvents = append(inputEvents, api.InputRoomEvent{
|
inputEvents = append(inputEvents, api.InputRoomEvent{
|
||||||
Kind: api.KindNew,
|
Kind: api.KindNew,
|
||||||
Event: event,
|
Event: event,
|
||||||
Origin: r.Cfg.Matrix.ServerName,
|
Origin: senderDomain,
|
||||||
SendAsServer: string(r.Cfg.Matrix.ServerName),
|
SendAsServer: string(senderDomain),
|
||||||
})
|
})
|
||||||
res.Affected = append(res.Affected, stateKey)
|
res.Affected = append(res.Affected, stateKey)
|
||||||
prevEvents = []gomatrixserverlib.EventReference{
|
prevEvents = []gomatrixserverlib.EventReference{
|
||||||
|
|
@ -176,7 +181,7 @@ func (r *Admin) PerformAdminEvacuateUser(
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
res.Error = &api.PerformError{
|
res.Error = &api.PerformError{
|
||||||
Code: api.PerformErrorBadRequest,
|
Code: api.PerformErrorBadRequest,
|
||||||
Msg: "Can only evacuate local users using this endpoint",
|
Msg: "Can only evacuate local users using this endpoint",
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ func (r *Inviter) PerformInvite(
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
isTargetLocal := domain == r.Cfg.Matrix.ServerName
|
isTargetLocal := r.Cfg.Matrix.IsLocalServerName(domain)
|
||||||
isOriginLocal := senderDomain == r.Cfg.Matrix.ServerName
|
isOriginLocal := r.Cfg.Matrix.IsLocalServerName(senderDomain)
|
||||||
if !isOriginLocal && !isTargetLocal {
|
if !isOriginLocal && !isTargetLocal {
|
||||||
res.Error = &api.PerformError{
|
res.Error = &api.PerformError{
|
||||||
Code: api.PerformErrorBadRequest,
|
Code: api.PerformErrorBadRequest,
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ func (r *Joiner) performJoin(
|
||||||
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
return "", "", &rsAPI.PerformError{
|
return "", "", &rsAPI.PerformError{
|
||||||
Code: rsAPI.PerformErrorBadRequest,
|
Code: rsAPI.PerformErrorBadRequest,
|
||||||
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
||||||
|
|
@ -124,7 +124,7 @@ func (r *Joiner) performJoinRoomByAlias(
|
||||||
// Check if this alias matches our own server configuration. If it
|
// Check if this alias matches our own server configuration. If it
|
||||||
// doesn't then we'll need to try a federated join.
|
// doesn't then we'll need to try a federated join.
|
||||||
var roomID string
|
var roomID string
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
// The alias isn't owned by us, so we will need to try joining using
|
// The alias isn't owned by us, so we will need to try joining using
|
||||||
// a remote server.
|
// a remote server.
|
||||||
dirReq := fsAPI.PerformDirectoryLookupRequest{
|
dirReq := fsAPI.PerformDirectoryLookupRequest{
|
||||||
|
|
@ -172,7 +172,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
// The original client request ?server_name=... may include this HS so filter that out so we
|
// The original client request ?server_name=... may include this HS so filter that out so we
|
||||||
// don't attempt to make_join with ourselves
|
// don't attempt to make_join with ourselves
|
||||||
for i := 0; i < len(req.ServerNames); i++ {
|
for i := 0; i < len(req.ServerNames); i++ {
|
||||||
if req.ServerNames[i] == r.Cfg.Matrix.ServerName {
|
if r.Cfg.Matrix.IsLocalServerName(req.ServerNames[i]) {
|
||||||
// delete this entry
|
// delete this entry
|
||||||
req.ServerNames = append(req.ServerNames[:i], req.ServerNames[i+1:]...)
|
req.ServerNames = append(req.ServerNames[:i], req.ServerNames[i+1:]...)
|
||||||
i--
|
i--
|
||||||
|
|
@ -191,12 +191,19 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
// If the server name in the room ID isn't ours then it's a
|
// If the server name in the room ID isn't ours then it's a
|
||||||
// possible candidate for finding the room via federation. Add
|
// possible candidate for finding the room via federation. Add
|
||||||
// it to the list of servers to try.
|
// it to the list of servers to try.
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
req.ServerNames = append(req.ServerNames, domain)
|
req.ServerNames = append(req.ServerNames, domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the template for the join event.
|
// Prepare the template for the join event.
|
||||||
userID := req.UserID
|
userID := req.UserID
|
||||||
|
_, userDomain, err := gomatrixserverlib.SplitID('@', userID)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", &rsAPI.PerformError{
|
||||||
|
Code: rsAPI.PerformErrorBadRequest,
|
||||||
|
Msg: fmt.Sprintf("User ID %q is invalid: %s", userID, err),
|
||||||
|
}
|
||||||
|
}
|
||||||
eb := gomatrixserverlib.EventBuilder{
|
eb := gomatrixserverlib.EventBuilder{
|
||||||
Type: gomatrixserverlib.MRoomMember,
|
Type: gomatrixserverlib.MRoomMember,
|
||||||
Sender: userID,
|
Sender: userID,
|
||||||
|
|
@ -247,7 +254,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
|
|
||||||
// If we were invited by someone from another server then we can
|
// If we were invited by someone from another server then we can
|
||||||
// assume they are in the room so we can join via them.
|
// assume they are in the room so we can join via them.
|
||||||
if inviterDomain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(inviterDomain) {
|
||||||
req.ServerNames = append(req.ServerNames, inviterDomain)
|
req.ServerNames = append(req.ServerNames, inviterDomain)
|
||||||
forceFederatedJoin = true
|
forceFederatedJoin = true
|
||||||
memberEvent := gjson.Parse(string(inviteEvent.JSON()))
|
memberEvent := gjson.Parse(string(inviteEvent.JSON()))
|
||||||
|
|
@ -300,7 +307,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
{
|
{
|
||||||
Kind: rsAPI.KindNew,
|
Kind: rsAPI.KindNew,
|
||||||
Event: event.Headered(buildRes.RoomVersion),
|
Event: event.Headered(buildRes.RoomVersion),
|
||||||
SendAsServer: string(r.Cfg.Matrix.ServerName),
|
SendAsServer: string(userDomain),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
@ -323,7 +330,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
// The room doesn't exist locally. If the room ID looks like it should
|
// The room doesn't exist locally. If the room ID looks like it should
|
||||||
// be ours then this probably means that we've nuked our database at
|
// be ours then this probably means that we've nuked our database at
|
||||||
// some point.
|
// some point.
|
||||||
if domain == r.Cfg.Matrix.ServerName {
|
if r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
// If there are no more server names to try then give up here.
|
// If there are no more server names to try then give up here.
|
||||||
// Otherwise we'll try a federated join as normal, since it's quite
|
// Otherwise we'll try a federated join as normal, since it's quite
|
||||||
// possible that the room still exists on other servers.
|
// possible that the room still exists on other servers.
|
||||||
|
|
@ -348,7 +355,7 @@ func (r *Joiner) performJoinRoomByID(
|
||||||
// it will have been overwritten with a room ID by performJoinRoomByAlias.
|
// it will have been overwritten with a room ID by performJoinRoomByAlias.
|
||||||
// We should now include this in the response so that the CS API can
|
// We should now include this in the response so that the CS API can
|
||||||
// return the right room ID.
|
// return the right room ID.
|
||||||
return req.RoomIDOrAlias, r.Cfg.Matrix.ServerName, nil
|
return req.RoomIDOrAlias, userDomain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Joiner) performFederatedJoinRoomByID(
|
func (r *Joiner) performFederatedJoinRoomByID(
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ func (r *Leaver) PerformLeave(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("supplied user ID %q in incorrect format", req.UserID)
|
return nil, fmt.Errorf("supplied user ID %q in incorrect format", req.UserID)
|
||||||
}
|
}
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
return nil, fmt.Errorf("user %q does not belong to this homeserver", req.UserID)
|
return nil, fmt.Errorf("user %q does not belong to this homeserver", req.UserID)
|
||||||
}
|
}
|
||||||
logger := logrus.WithContext(ctx).WithFields(logrus.Fields{
|
logger := logrus.WithContext(ctx).WithFields(logrus.Fields{
|
||||||
|
|
@ -85,7 +85,7 @@ func (r *Leaver) performLeaveRoomByID(
|
||||||
if serr != nil {
|
if serr != nil {
|
||||||
return nil, fmt.Errorf("sender %q is invalid", senderUser)
|
return nil, fmt.Errorf("sender %q is invalid", senderUser)
|
||||||
}
|
}
|
||||||
if senderDomain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(senderDomain) {
|
||||||
return r.performFederatedRejectInvite(ctx, req, res, senderUser, eventID)
|
return r.performFederatedRejectInvite(ctx, req, res, senderUser, eventID)
|
||||||
}
|
}
|
||||||
// check that this is not a "server notice room"
|
// check that this is not a "server notice room"
|
||||||
|
|
@ -186,7 +186,7 @@ func (r *Leaver) performLeaveRoomByID(
|
||||||
Kind: api.KindNew,
|
Kind: api.KindNew,
|
||||||
Event: event.Headered(buildRes.RoomVersion),
|
Event: event.Headered(buildRes.RoomVersion),
|
||||||
Origin: senderDomain,
|
Origin: senderDomain,
|
||||||
SendAsServer: string(r.Cfg.Matrix.ServerName),
|
SendAsServer: string(senderDomain),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ func (r *Peeker) performPeek(
|
||||||
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
return "", &api.PerformError{
|
return "", &api.PerformError{
|
||||||
Code: api.PerformErrorBadRequest,
|
Code: api.PerformErrorBadRequest,
|
||||||
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
||||||
|
|
@ -104,7 +104,7 @@ func (r *Peeker) performPeekRoomByAlias(
|
||||||
// Check if this alias matches our own server configuration. If it
|
// Check if this alias matches our own server configuration. If it
|
||||||
// doesn't then we'll need to try a federated peek.
|
// doesn't then we'll need to try a federated peek.
|
||||||
var roomID string
|
var roomID string
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
// The alias isn't owned by us, so we will need to try peeking using
|
// The alias isn't owned by us, so we will need to try peeking using
|
||||||
// a remote server.
|
// a remote server.
|
||||||
dirReq := fsAPI.PerformDirectoryLookupRequest{
|
dirReq := fsAPI.PerformDirectoryLookupRequest{
|
||||||
|
|
@ -154,7 +154,7 @@ func (r *Peeker) performPeekRoomByID(
|
||||||
|
|
||||||
// handle federated peeks
|
// handle federated peeks
|
||||||
// FIXME: don't create an outbound peek if we already have one going.
|
// FIXME: don't create an outbound peek if we already have one going.
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
// If the server name in the room ID isn't ours then it's a
|
// If the server name in the room ID isn't ours then it's a
|
||||||
// possible candidate for finding the room via federation. Add
|
// possible candidate for finding the room via federation. Add
|
||||||
// it to the list of servers to try.
|
// it to the list of servers to try.
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ func (r *Unpeeker) performUnpeek(
|
||||||
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
Msg: fmt.Sprintf("Supplied user ID %q in incorrect format", req.UserID),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if domain != r.Cfg.Matrix.ServerName {
|
if !r.Cfg.Matrix.IsLocalServerName(domain) {
|
||||||
return &api.PerformError{
|
return &api.PerformError{
|
||||||
Code: api.PerformErrorBadRequest,
|
Code: api.PerformErrorBadRequest,
|
||||||
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
Msg: fmt.Sprintf("User %q does not belong to this homeserver", req.UserID),
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,13 @@ func (r *Upgrader) performRoomUpgrade(
|
||||||
) (string, *api.PerformError) {
|
) (string, *api.PerformError) {
|
||||||
roomID := req.RoomID
|
roomID := req.RoomID
|
||||||
userID := req.UserID
|
userID := req.UserID
|
||||||
|
_, userDomain, err := gomatrixserverlib.SplitID('@', userID)
|
||||||
|
if err != nil {
|
||||||
|
return "", &api.PerformError{
|
||||||
|
Code: api.PerformErrorNotAllowed,
|
||||||
|
Msg: "Error validating the user ID",
|
||||||
|
}
|
||||||
|
}
|
||||||
evTime := time.Now()
|
evTime := time.Now()
|
||||||
|
|
||||||
// Return an immediate error if the room does not exist
|
// Return an immediate error if the room does not exist
|
||||||
|
|
@ -80,7 +87,7 @@ func (r *Upgrader) performRoomUpgrade(
|
||||||
|
|
||||||
// TODO (#267): Check room ID doesn't clash with an existing one, and we
|
// TODO (#267): Check room ID doesn't clash with an existing one, and we
|
||||||
// probably shouldn't be using pseudo-random strings, maybe GUIDs?
|
// probably shouldn't be using pseudo-random strings, maybe GUIDs?
|
||||||
newRoomID := fmt.Sprintf("!%s:%s", util.RandomString(16), r.Cfg.Matrix.ServerName)
|
newRoomID := fmt.Sprintf("!%s:%s", util.RandomString(16), userDomain)
|
||||||
|
|
||||||
// Get the existing room state for the old room.
|
// Get the existing room state for the old room.
|
||||||
oldRoomReq := &api.QueryLatestEventsAndStateRequest{
|
oldRoomReq := &api.QueryLatestEventsAndStateRequest{
|
||||||
|
|
@ -107,12 +114,12 @@ func (r *Upgrader) performRoomUpgrade(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the setup events to the new room
|
// Send the setup events to the new room
|
||||||
if pErr = r.sendInitialEvents(ctx, evTime, userID, newRoomID, string(req.RoomVersion), eventsToMake); pErr != nil {
|
if pErr = r.sendInitialEvents(ctx, evTime, userID, userDomain, newRoomID, string(req.RoomVersion), eventsToMake); pErr != nil {
|
||||||
return "", pErr
|
return "", pErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Send the tombstone event to the old room
|
// 5. Send the tombstone event to the old room
|
||||||
if pErr = r.sendHeaderedEvent(ctx, tombstoneEvent, string(r.Cfg.Matrix.ServerName)); pErr != nil {
|
if pErr = r.sendHeaderedEvent(ctx, userDomain, tombstoneEvent, string(userDomain)); pErr != nil {
|
||||||
return "", pErr
|
return "", pErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,7 +129,7 @@ func (r *Upgrader) performRoomUpgrade(
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the old room had a canonical alias event, it should be deleted in the old room
|
// If the old room had a canonical alias event, it should be deleted in the old room
|
||||||
if pErr = r.clearOldCanonicalAliasEvent(ctx, oldRoomRes, evTime, userID, roomID); pErr != nil {
|
if pErr = r.clearOldCanonicalAliasEvent(ctx, oldRoomRes, evTime, userID, userDomain, roomID); pErr != nil {
|
||||||
return "", pErr
|
return "", pErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,7 +139,7 @@ func (r *Upgrader) performRoomUpgrade(
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. Restrict power levels in the old room
|
// 6. Restrict power levels in the old room
|
||||||
if pErr = r.restrictOldRoomPowerLevels(ctx, evTime, userID, roomID); pErr != nil {
|
if pErr = r.restrictOldRoomPowerLevels(ctx, evTime, userID, userDomain, roomID); pErr != nil {
|
||||||
return "", pErr
|
return "", pErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,7 +161,7 @@ func (r *Upgrader) getRoomPowerLevels(ctx context.Context, roomID string) (*goma
|
||||||
return powerLevelContent, nil
|
return powerLevelContent, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.Time, userID, roomID string) *api.PerformError {
|
func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.Time, userID string, userDomain gomatrixserverlib.ServerName, roomID string) *api.PerformError {
|
||||||
restrictedPowerLevelContent, pErr := r.getRoomPowerLevels(ctx, roomID)
|
restrictedPowerLevelContent, pErr := r.getRoomPowerLevels(ctx, roomID)
|
||||||
if pErr != nil {
|
if pErr != nil {
|
||||||
return pErr
|
return pErr
|
||||||
|
|
@ -183,7 +190,7 @@ func (r *Upgrader) restrictOldRoomPowerLevels(ctx context.Context, evTime time.T
|
||||||
return resErr
|
return resErr
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if resErr = r.sendHeaderedEvent(ctx, restrictedPowerLevelsHeadered, api.DoNotSendToOtherServers); resErr != nil {
|
if resErr = r.sendHeaderedEvent(ctx, userDomain, restrictedPowerLevelsHeadered, api.DoNotSendToOtherServers); resErr != nil {
|
||||||
return resErr
|
return resErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -223,7 +230,7 @@ func moveLocalAliases(ctx context.Context,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api.QueryLatestEventsAndStateResponse, evTime time.Time, userID, roomID string) *api.PerformError {
|
func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api.QueryLatestEventsAndStateResponse, evTime time.Time, userID string, userDomain gomatrixserverlib.ServerName, roomID string) *api.PerformError {
|
||||||
for _, event := range oldRoom.StateEvents {
|
for _, event := range oldRoom.StateEvents {
|
||||||
if event.Type() != gomatrixserverlib.MRoomCanonicalAlias || !event.StateKeyEquals("") {
|
if event.Type() != gomatrixserverlib.MRoomCanonicalAlias || !event.StateKeyEquals("") {
|
||||||
continue
|
continue
|
||||||
|
|
@ -254,7 +261,7 @@ func (r *Upgrader) clearOldCanonicalAliasEvent(ctx context.Context, oldRoom *api
|
||||||
return resErr
|
return resErr
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if resErr = r.sendHeaderedEvent(ctx, emptyCanonicalAliasEvent, api.DoNotSendToOtherServers); resErr != nil {
|
if resErr = r.sendHeaderedEvent(ctx, userDomain, emptyCanonicalAliasEvent, api.DoNotSendToOtherServers); resErr != nil {
|
||||||
return resErr
|
return resErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -495,7 +502,7 @@ func (r *Upgrader) generateInitialEvents(ctx context.Context, oldRoom *api.Query
|
||||||
return eventsToMake, nil
|
return eventsToMake, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, userID, newRoomID, newVersion string, eventsToMake []fledglingEvent) *api.PerformError {
|
func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, userID string, userDomain gomatrixserverlib.ServerName, newRoomID, newVersion string, eventsToMake []fledglingEvent) *api.PerformError {
|
||||||
var err error
|
var err error
|
||||||
var builtEvents []*gomatrixserverlib.HeaderedEvent
|
var builtEvents []*gomatrixserverlib.HeaderedEvent
|
||||||
authEvents := gomatrixserverlib.NewAuthEvents(nil)
|
authEvents := gomatrixserverlib.NewAuthEvents(nil)
|
||||||
|
|
@ -519,7 +526,7 @@ func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, user
|
||||||
builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()}
|
builder.PrevEvents = []gomatrixserverlib.EventReference{builtEvents[i-1].EventReference()}
|
||||||
}
|
}
|
||||||
var event *gomatrixserverlib.Event
|
var event *gomatrixserverlib.Event
|
||||||
event, err = r.buildEvent(&builder, &authEvents, evTime, gomatrixserverlib.RoomVersion(newVersion))
|
event, err = r.buildEvent(&builder, userDomain, &authEvents, evTime, gomatrixserverlib.RoomVersion(newVersion))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &api.PerformError{
|
return &api.PerformError{
|
||||||
Msg: fmt.Sprintf("Failed to build new %q event: %s", builder.Type, err),
|
Msg: fmt.Sprintf("Failed to build new %q event: %s", builder.Type, err),
|
||||||
|
|
@ -547,7 +554,7 @@ func (r *Upgrader) sendInitialEvents(ctx context.Context, evTime time.Time, user
|
||||||
inputs = append(inputs, api.InputRoomEvent{
|
inputs = append(inputs, api.InputRoomEvent{
|
||||||
Kind: api.KindNew,
|
Kind: api.KindNew,
|
||||||
Event: event,
|
Event: event,
|
||||||
Origin: r.Cfg.Matrix.ServerName,
|
Origin: userDomain,
|
||||||
SendAsServer: api.DoNotSendToOtherServers,
|
SendAsServer: api.DoNotSendToOtherServers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -668,6 +675,7 @@ func createTemporaryPowerLevels(powerLevelContent *gomatrixserverlib.PowerLevelC
|
||||||
|
|
||||||
func (r *Upgrader) sendHeaderedEvent(
|
func (r *Upgrader) sendHeaderedEvent(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
serverName gomatrixserverlib.ServerName,
|
||||||
headeredEvent *gomatrixserverlib.HeaderedEvent,
|
headeredEvent *gomatrixserverlib.HeaderedEvent,
|
||||||
sendAsServer string,
|
sendAsServer string,
|
||||||
) *api.PerformError {
|
) *api.PerformError {
|
||||||
|
|
@ -675,7 +683,7 @@ func (r *Upgrader) sendHeaderedEvent(
|
||||||
inputs = append(inputs, api.InputRoomEvent{
|
inputs = append(inputs, api.InputRoomEvent{
|
||||||
Kind: api.KindNew,
|
Kind: api.KindNew,
|
||||||
Event: headeredEvent,
|
Event: headeredEvent,
|
||||||
Origin: r.Cfg.Matrix.ServerName,
|
Origin: serverName,
|
||||||
SendAsServer: sendAsServer,
|
SendAsServer: sendAsServer,
|
||||||
})
|
})
|
||||||
if err := api.SendInputRoomEvents(ctx, r.URSAPI, inputs, false); err != nil {
|
if err := api.SendInputRoomEvents(ctx, r.URSAPI, inputs, false); err != nil {
|
||||||
|
|
@ -689,6 +697,7 @@ func (r *Upgrader) sendHeaderedEvent(
|
||||||
|
|
||||||
func (r *Upgrader) buildEvent(
|
func (r *Upgrader) buildEvent(
|
||||||
builder *gomatrixserverlib.EventBuilder,
|
builder *gomatrixserverlib.EventBuilder,
|
||||||
|
serverName gomatrixserverlib.ServerName,
|
||||||
provider gomatrixserverlib.AuthEventProvider,
|
provider gomatrixserverlib.AuthEventProvider,
|
||||||
evTime time.Time,
|
evTime time.Time,
|
||||||
roomVersion gomatrixserverlib.RoomVersion,
|
roomVersion gomatrixserverlib.RoomVersion,
|
||||||
|
|
@ -703,7 +712,7 @@ func (r *Upgrader) buildEvent(
|
||||||
}
|
}
|
||||||
builder.AuthEvents = refs
|
builder.AuthEvents = refs
|
||||||
event, err := builder.Build(
|
event, err := builder.Build(
|
||||||
evTime, r.Cfg.Matrix.ServerName, r.Cfg.Matrix.KeyID,
|
evTime, serverName, r.Cfg.Matrix.KeyID,
|
||||||
r.Cfg.Matrix.PrivateKey, roomVersion,
|
r.Cfg.Matrix.PrivateKey, roomVersion,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@ type Global struct {
|
||||||
// The name of the server. This is usually the domain name, e.g 'matrix.org', 'localhost'.
|
// The name of the server. This is usually the domain name, e.g 'matrix.org', 'localhost'.
|
||||||
ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
|
ServerName gomatrixserverlib.ServerName `yaml:"server_name"`
|
||||||
|
|
||||||
|
// The secondary server names, used for virtual hosting.
|
||||||
|
SecondaryServerNames []gomatrixserverlib.ServerName `yaml:"-"`
|
||||||
|
|
||||||
// Path to the private key which will be used to sign requests and events.
|
// Path to the private key which will be used to sign requests and events.
|
||||||
PrivateKeyPath Path `yaml:"private_key"`
|
PrivateKeyPath Path `yaml:"private_key"`
|
||||||
|
|
||||||
|
|
@ -120,6 +123,18 @@ func (c *Global) Verify(configErrs *ConfigErrors, isMonolith bool) {
|
||||||
c.Cache.Verify(configErrs, isMonolith)
|
c.Cache.Verify(configErrs, isMonolith)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Global) IsLocalServerName(serverName gomatrixserverlib.ServerName) bool {
|
||||||
|
if c.ServerName == serverName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, secondaryName := range c.SecondaryServerNames {
|
||||||
|
if secondaryName == serverName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type OldVerifyKeys struct {
|
type OldVerifyKeys struct {
|
||||||
// Path to the private key.
|
// Path to the private key.
|
||||||
PrivateKeyPath Path `yaml:"private_key"`
|
PrivateKeyPath Path `yaml:"private_key"`
|
||||||
|
|
@ -170,7 +185,7 @@ type ServerNotices struct {
|
||||||
// The displayname to be used when sending notices
|
// The displayname to be used when sending notices
|
||||||
DisplayName string `yaml:"display_name"`
|
DisplayName string `yaml:"display_name"`
|
||||||
// The avatar of this user
|
// The avatar of this user
|
||||||
AvatarURL string `yaml:"avatar"`
|
AvatarURL string `yaml:"avatar_url"`
|
||||||
// The roomname to be used when creating messages
|
// The roomname to be used when creating messages
|
||||||
RoomName string `yaml:"room_name"`
|
RoomName string `yaml:"room_name"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,10 @@ type UserAPI struct {
|
||||||
// The Account database stores the login details and account information
|
// The Account database stores the login details and account information
|
||||||
// for local users. It is accessed by the UserAPI.
|
// for local users. It is accessed by the UserAPI.
|
||||||
AccountDatabase DatabaseOptions `yaml:"account_database,omitempty"`
|
AccountDatabase DatabaseOptions `yaml:"account_database,omitempty"`
|
||||||
|
|
||||||
|
// Users who register on this homeserver will automatically
|
||||||
|
// be joined to the rooms listed under this option.
|
||||||
|
AutoJoinRooms []string `yaml:"auto_join_rooms"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const DefaultOpenIDTokenLifetimeMS = 3600000 // 60 minutes
|
const DefaultOpenIDTokenLifetimeMS = 3600000 // 60 minutes
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ func Enable(
|
||||||
base.PublicFederationAPIMux.Handle("/unstable/event_relationships", httputil.MakeExternalAPI(
|
base.PublicFederationAPIMux.Handle("/unstable/event_relationships", httputil.MakeExternalAPI(
|
||||||
"msc2836_event_relationships", func(req *http.Request) util.JSONResponse {
|
"msc2836_event_relationships", func(req *http.Request) util.JSONResponse {
|
||||||
fedReq, errResp := gomatrixserverlib.VerifyHTTPRequest(
|
fedReq, errResp := gomatrixserverlib.VerifyHTTPRequest(
|
||||||
req, time.Now(), base.Cfg.Global.ServerName, keyRing,
|
req, time.Now(), base.Cfg.Global.ServerName, base.Cfg.Global.IsLocalServerName, keyRing,
|
||||||
)
|
)
|
||||||
if fedReq == nil {
|
if fedReq == nil {
|
||||||
return errResp
|
return errResp
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ func Enable(
|
||||||
fedAPI := httputil.MakeExternalAPI(
|
fedAPI := httputil.MakeExternalAPI(
|
||||||
"msc2946_fed_spaces", func(req *http.Request) util.JSONResponse {
|
"msc2946_fed_spaces", func(req *http.Request) util.JSONResponse {
|
||||||
fedReq, errResp := gomatrixserverlib.VerifyHTTPRequest(
|
fedReq, errResp := gomatrixserverlib.VerifyHTTPRequest(
|
||||||
req, time.Now(), base.Cfg.Global.ServerName, keyRing,
|
req, time.Now(), base.Cfg.Global.ServerName, base.Cfg.Global.IsLocalServerName, keyRing,
|
||||||
)
|
)
|
||||||
if fedReq == nil {
|
if fedReq == nil {
|
||||||
return errResp
|
return errResp
|
||||||
|
|
|
||||||
|
|
@ -18,22 +18,20 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
|
||||||
"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"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
"github.com/matrix-org/dendrite/syncapi/storage"
|
||||||
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
type getMembershipResponse struct {
|
type getMembershipResponse struct {
|
||||||
Chunk []gomatrixserverlib.ClientEvent `json:"chunk"`
|
Chunk []gomatrixserverlib.ClientEvent `json:"chunk"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type getJoinedRoomsResponse struct {
|
|
||||||
JoinedRooms []string `json:"joined_rooms"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-joined-members
|
// https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-joined-members
|
||||||
type getJoinedMembersResponse struct {
|
type getJoinedMembersResponse struct {
|
||||||
Joined map[string]joinedMember `json:"joined"`
|
Joined map[string]joinedMember `json:"joined"`
|
||||||
|
|
@ -51,19 +49,22 @@ type databaseJoinedMember struct {
|
||||||
AvatarURL string `json:"avatar_url"`
|
AvatarURL string `json:"avatar_url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMemberships implements GET /rooms/{roomId}/members
|
// GetMemberships implements
|
||||||
|
//
|
||||||
|
// GET /rooms/{roomId}/members
|
||||||
|
// GET /rooms/{roomId}/joined_members
|
||||||
func GetMemberships(
|
func GetMemberships(
|
||||||
req *http.Request, device *userapi.Device, roomID string, joinedOnly bool,
|
req *http.Request, device *userapi.Device, roomID string,
|
||||||
_ *config.ClientAPI,
|
syncDB storage.Database, rsAPI api.SyncRoomserverAPI,
|
||||||
rsAPI api.ClientRoomserverAPI,
|
joinedOnly bool, membership, notMembership *string, at string,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
queryReq := api.QueryMembershipsForRoomRequest{
|
queryReq := api.QueryMembershipForUserRequest{
|
||||||
JoinedOnly: joinedOnly,
|
RoomID: roomID,
|
||||||
RoomID: roomID,
|
UserID: device.UserID,
|
||||||
Sender: device.UserID,
|
|
||||||
}
|
}
|
||||||
var queryRes api.QueryMembershipsForRoomResponse
|
|
||||||
if err := rsAPI.QueryMembershipsForRoom(req.Context(), &queryReq, &queryRes); err != nil {
|
var queryRes api.QueryMembershipForUserResponse
|
||||||
|
if err := rsAPI.QueryMembershipForUser(req.Context(), &queryReq, &queryRes); err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("rsAPI.QueryMembershipsForRoom failed")
|
util.GetLogger(req.Context()).WithError(err).Error("rsAPI.QueryMembershipsForRoom failed")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
|
|
@ -75,16 +76,54 @@ func GetMemberships(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db, err := syncDB.NewDatabaseSnapshot(req.Context())
|
||||||
|
if err != nil {
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
atToken, err := types.NewTopologyTokenFromString(at)
|
||||||
|
if err != nil {
|
||||||
|
if queryRes.HasBeenInRoom && !queryRes.IsInRoom {
|
||||||
|
// If you have left the room then this will be the members of the room when you left.
|
||||||
|
atToken, err = db.EventPositionInTopology(req.Context(), queryRes.EventID)
|
||||||
|
} else {
|
||||||
|
// If you are joined to the room then this will be the current members of the room.
|
||||||
|
atToken, err = db.MaxTopologicalPosition(req.Context(), roomID)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("unable to get 'atToken'")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eventIDs, err := db.SelectMemberships(req.Context(), roomID, atToken, membership, notMembership)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("db.SelectMemberships failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := db.Events(req.Context(), eventIDs)
|
||||||
|
if err != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(err).Error("db.Events failed")
|
||||||
|
return jsonerror.InternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
if joinedOnly {
|
if joinedOnly {
|
||||||
|
if !queryRes.IsInRoom {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: jsonerror.Forbidden("You aren't a member of the room and weren't previously a member of the room."),
|
||||||
|
}
|
||||||
|
}
|
||||||
var res getJoinedMembersResponse
|
var res getJoinedMembersResponse
|
||||||
res.Joined = make(map[string]joinedMember)
|
res.Joined = make(map[string]joinedMember)
|
||||||
for _, ev := range queryRes.JoinEvents {
|
for _, ev := range result {
|
||||||
var content databaseJoinedMember
|
var content databaseJoinedMember
|
||||||
if err := json.Unmarshal(ev.Content, &content); err != nil {
|
if err := json.Unmarshal(ev.Content(), &content); err != nil {
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("failed to unmarshal event content")
|
util.GetLogger(req.Context()).WithError(err).Error("failed to unmarshal event content")
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
res.Joined[ev.Sender] = joinedMember(content)
|
res.Joined[ev.Sender()] = joinedMember(content)
|
||||||
}
|
}
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
|
|
@ -93,29 +132,6 @@ func GetMemberships(
|
||||||
}
|
}
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
JSON: getMembershipResponse{queryRes.JoinEvents},
|
JSON: getMembershipResponse{gomatrixserverlib.HeaderedToClientEvents(result, gomatrixserverlib.FormatSync)},
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetJoinedRooms(
|
|
||||||
req *http.Request,
|
|
||||||
device *userapi.Device,
|
|
||||||
rsAPI api.ClientRoomserverAPI,
|
|
||||||
) util.JSONResponse {
|
|
||||||
var res api.QueryRoomsForUserResponse
|
|
||||||
err := rsAPI.QueryRoomsForUser(req.Context(), &api.QueryRoomsForUserRequest{
|
|
||||||
UserID: device.UserID,
|
|
||||||
WantMembership: "join",
|
|
||||||
}, &res)
|
|
||||||
if err != nil {
|
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("QueryRoomsForUser failed")
|
|
||||||
return jsonerror.InternalServerError()
|
|
||||||
}
|
|
||||||
if res.RoomIDs == nil {
|
|
||||||
res.RoomIDs = []string{}
|
|
||||||
}
|
|
||||||
return util.JSONResponse{
|
|
||||||
Code: http.StatusOK,
|
|
||||||
JSON: getJoinedRoomsResponse{res.RoomIDs},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -83,18 +83,18 @@ func OnIncomingMessagesRequest(
|
||||||
defer sqlutil.EndTransactionWithCheck(snapshot, &succeeded, &err)
|
defer sqlutil.EndTransactionWithCheck(snapshot, &succeeded, &err)
|
||||||
|
|
||||||
// check if the user has already forgotten about this room
|
// check if the user has already forgotten about this room
|
||||||
isForgotten, roomExists, err := checkIsRoomForgotten(req.Context(), roomID, device.UserID, rsAPI)
|
membershipResp, err := getMembershipForUser(req.Context(), roomID, device.UserID, rsAPI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return jsonerror.InternalServerError()
|
return jsonerror.InternalServerError()
|
||||||
}
|
}
|
||||||
if !roomExists {
|
if !membershipResp.RoomExists {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusForbidden,
|
Code: http.StatusForbidden,
|
||||||
JSON: jsonerror.Forbidden("room does not exist"),
|
JSON: jsonerror.Forbidden("room does not exist"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isForgotten {
|
if membershipResp.IsRoomForgotten {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusForbidden,
|
Code: http.StatusForbidden,
|
||||||
JSON: jsonerror.Forbidden("user already forgot about this room"),
|
JSON: jsonerror.Forbidden("user already forgot about this room"),
|
||||||
|
|
@ -195,6 +195,20 @@ func OnIncomingMessagesRequest(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the user already left the room, grep events from before that
|
||||||
|
if membershipResp.Membership == gomatrixserverlib.Leave {
|
||||||
|
var token types.TopologyToken
|
||||||
|
token, err = snapshot.EventPositionInTopology(req.Context(), membershipResp.EventID)
|
||||||
|
if err != nil {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if backwardOrdering {
|
||||||
|
from = token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mReq := messagesReq{
|
mReq := messagesReq{
|
||||||
ctx: req.Context(),
|
ctx: req.Context(),
|
||||||
db: db,
|
db: db,
|
||||||
|
|
@ -283,17 +297,16 @@ func (m *messagesResp) applyLazyLoadMembers(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkIsRoomForgotten(ctx context.Context, roomID, userID string, rsAPI api.SyncRoomserverAPI) (forgotten bool, exists bool, err error) {
|
func getMembershipForUser(ctx context.Context, roomID, userID string, rsAPI api.SyncRoomserverAPI) (resp api.QueryMembershipForUserResponse, err error) {
|
||||||
req := api.QueryMembershipForUserRequest{
|
req := api.QueryMembershipForUserRequest{
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
}
|
}
|
||||||
resp := api.QueryMembershipForUserResponse{}
|
|
||||||
if err := rsAPI.QueryMembershipForUser(ctx, &req, &resp); err != nil {
|
if err := rsAPI.QueryMembershipForUser(ctx, &req, &resp); err != nil {
|
||||||
return false, false, err
|
return api.QueryMembershipForUserResponse{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp.IsRoomForgotten, resp.RoomExists, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieveEvents retrieves events from the local database for a request on
|
// retrieveEvents retrieves events from the local database for a request on
|
||||||
|
|
@ -313,7 +326,11 @@ func (r *messagesReq) retrieveEvents() (
|
||||||
}
|
}
|
||||||
|
|
||||||
var events []*gomatrixserverlib.HeaderedEvent
|
var events []*gomatrixserverlib.HeaderedEvent
|
||||||
util.GetLogger(r.ctx).WithField("start", start).WithField("end", end).Infof("Fetched %d events locally", len(streamEvents))
|
util.GetLogger(r.ctx).WithFields(logrus.Fields{
|
||||||
|
"start": r.from,
|
||||||
|
"end": r.to,
|
||||||
|
"backwards": r.backwardOrdering,
|
||||||
|
}).Infof("Fetched %d events locally", len(streamEvents))
|
||||||
|
|
||||||
// There can be two reasons for streamEvents to be empty: either we've
|
// There can be two reasons for streamEvents to be empty: either we've
|
||||||
// reached the oldest event in the room (or the most recent one, depending
|
// reached the oldest event in the room (or the most recent one, depending
|
||||||
|
|
|
||||||
|
|
@ -172,4 +172,37 @@ func Setup(
|
||||||
return Search(req, device, syncDB, fts, nextBatch)
|
return Search(req, device, syncDB, fts, nextBatch)
|
||||||
}),
|
}),
|
||||||
).Methods(http.MethodPost, http.MethodOptions)
|
).Methods(http.MethodPost, http.MethodOptions)
|
||||||
|
|
||||||
|
v3mux.Handle("/rooms/{roomID}/members",
|
||||||
|
httputil.MakeAuthAPI("rooms_members", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
|
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||||
|
if err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
var membership, notMembership *string
|
||||||
|
if req.URL.Query().Has("membership") {
|
||||||
|
m := req.URL.Query().Get("membership")
|
||||||
|
membership = &m
|
||||||
|
}
|
||||||
|
if req.URL.Query().Has("not_membership") {
|
||||||
|
m := req.URL.Query().Get("not_membership")
|
||||||
|
notMembership = &m
|
||||||
|
}
|
||||||
|
|
||||||
|
at := req.URL.Query().Get("at")
|
||||||
|
return GetMemberships(req, device, vars["roomID"], syncDB, rsAPI, false, membership, notMembership, at)
|
||||||
|
}),
|
||||||
|
).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
|
||||||
|
v3mux.Handle("/rooms/{roomID}/joined_members",
|
||||||
|
httputil.MakeAuthAPI("rooms_members", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
|
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||||
|
if err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
at := req.URL.Query().Get("at")
|
||||||
|
membership := gomatrixserverlib.Join
|
||||||
|
return GetMemberships(req, device, vars["roomID"], syncDB, rsAPI, true, &membership, nil, at)
|
||||||
|
}),
|
||||||
|
).Methods(http.MethodGet, http.MethodOptions)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,11 @@ type Database interface {
|
||||||
ReIndex(ctx context.Context, limit, afterID int64) (map[int64]gomatrixserverlib.HeaderedEvent, error)
|
ReIndex(ctx context.Context, limit, afterID int64) (map[int64]gomatrixserverlib.HeaderedEvent, error)
|
||||||
UpdateRelations(ctx context.Context, event *gomatrixserverlib.HeaderedEvent) error
|
UpdateRelations(ctx context.Context, event *gomatrixserverlib.HeaderedEvent) error
|
||||||
RedactRelations(ctx context.Context, roomID, redactedEventID string) error
|
RedactRelations(ctx context.Context, roomID, redactedEventID string) error
|
||||||
|
SelectMemberships(
|
||||||
|
ctx context.Context,
|
||||||
|
roomID string, pos types.TopologyToken,
|
||||||
|
membership, notMembership *string,
|
||||||
|
) (eventIDs []string, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Presence interface {
|
type Presence interface {
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,12 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal"
|
"github.com/matrix-org/dendrite/internal"
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
"github.com/matrix-org/dendrite/syncapi/storage/tables"
|
"github.com/matrix-org/dendrite/syncapi/storage/tables"
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The memberships table is designed to track the last time that
|
// The memberships table is designed to track the last time that
|
||||||
|
|
@ -69,11 +70,20 @@ const selectHeroesSQL = "" +
|
||||||
const selectMembershipBeforeSQL = "" +
|
const selectMembershipBeforeSQL = "" +
|
||||||
"SELECT membership, topological_pos FROM syncapi_memberships WHERE room_id = $1 and user_id = $2 AND topological_pos <= $3 ORDER BY topological_pos DESC LIMIT 1"
|
"SELECT membership, topological_pos FROM syncapi_memberships WHERE room_id = $1 and user_id = $2 AND topological_pos <= $3 ORDER BY topological_pos DESC LIMIT 1"
|
||||||
|
|
||||||
|
const selectMembersSQL = `
|
||||||
|
SELECT event_id FROM (
|
||||||
|
SELECT DISTINCT ON (room_id, user_id) room_id, user_id, event_id, membership FROM syncapi_memberships WHERE room_id = $1 AND topological_pos <= $2 ORDER BY room_id, user_id, stream_pos DESC
|
||||||
|
) t
|
||||||
|
WHERE ($3::text IS NULL OR t.membership = $3)
|
||||||
|
AND ($4::text IS NULL OR t.membership <> $4)
|
||||||
|
`
|
||||||
|
|
||||||
type membershipsStatements struct {
|
type membershipsStatements struct {
|
||||||
upsertMembershipStmt *sql.Stmt
|
upsertMembershipStmt *sql.Stmt
|
||||||
selectMembershipCountStmt *sql.Stmt
|
selectMembershipCountStmt *sql.Stmt
|
||||||
selectHeroesStmt *sql.Stmt
|
selectHeroesStmt *sql.Stmt
|
||||||
selectMembershipForUserStmt *sql.Stmt
|
selectMembershipForUserStmt *sql.Stmt
|
||||||
|
selectMembersStmt *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPostgresMembershipsTable(db *sql.DB) (tables.Memberships, error) {
|
func NewPostgresMembershipsTable(db *sql.DB) (tables.Memberships, error) {
|
||||||
|
|
@ -87,6 +97,7 @@ func NewPostgresMembershipsTable(db *sql.DB) (tables.Memberships, error) {
|
||||||
{&s.selectMembershipCountStmt, selectMembershipCountSQL},
|
{&s.selectMembershipCountStmt, selectMembershipCountSQL},
|
||||||
{&s.selectHeroesStmt, selectHeroesSQL},
|
{&s.selectHeroesStmt, selectHeroesSQL},
|
||||||
{&s.selectMembershipForUserStmt, selectMembershipBeforeSQL},
|
{&s.selectMembershipForUserStmt, selectMembershipBeforeSQL},
|
||||||
|
{&s.selectMembersStmt, selectMembersSQL},
|
||||||
}.Prepare(db)
|
}.Prepare(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -154,3 +165,25 @@ func (s *membershipsStatements) SelectMembershipForUser(
|
||||||
}
|
}
|
||||||
return membership, topologyPos, nil
|
return membership, topologyPos, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *membershipsStatements) SelectMemberships(
|
||||||
|
ctx context.Context, txn *sql.Tx,
|
||||||
|
roomID string, pos types.TopologyToken,
|
||||||
|
membership, notMembership *string,
|
||||||
|
) (eventIDs []string, err error) {
|
||||||
|
stmt := sqlutil.TxStmt(txn, s.selectMembersStmt)
|
||||||
|
rows, err := stmt.QueryContext(ctx, roomID, pos.Depth, membership, notMembership)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
eventID string
|
||||||
|
)
|
||||||
|
for rows.Next() {
|
||||||
|
if err = rows.Scan(&eventID); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
eventIDs = append(eventIDs, eventID)
|
||||||
|
}
|
||||||
|
return eventIDs, rows.Err()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -617,3 +617,11 @@ func (d *Database) RedactRelations(ctx context.Context, roomID, redactedEventID
|
||||||
return d.Relations.DeleteRelation(ctx, txn, roomID, redactedEventID)
|
return d.Relations.DeleteRelation(ctx, txn, roomID, redactedEventID)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Database) SelectMemberships(
|
||||||
|
ctx context.Context,
|
||||||
|
roomID string, pos types.TopologyToken,
|
||||||
|
membership, notMembership *string,
|
||||||
|
) (eventIDs []string, err error) {
|
||||||
|
return d.Memberships.SelectMemberships(ctx, nil, roomID, pos, membership, notMembership)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,12 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal"
|
"github.com/matrix-org/dendrite/internal"
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
"github.com/matrix-org/dendrite/syncapi/storage/tables"
|
"github.com/matrix-org/dendrite/syncapi/storage/tables"
|
||||||
"github.com/matrix-org/dendrite/syncapi/types"
|
"github.com/matrix-org/dendrite/syncapi/types"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The memberships table is designed to track the last time that
|
// The memberships table is designed to track the last time that
|
||||||
|
|
@ -69,12 +70,20 @@ const selectHeroesSQL = "" +
|
||||||
const selectMembershipBeforeSQL = "" +
|
const selectMembershipBeforeSQL = "" +
|
||||||
"SELECT membership, topological_pos FROM syncapi_memberships WHERE room_id = $1 and user_id = $2 AND topological_pos <= $3 ORDER BY topological_pos DESC LIMIT 1"
|
"SELECT membership, topological_pos FROM syncapi_memberships WHERE room_id = $1 and user_id = $2 AND topological_pos <= $3 ORDER BY topological_pos DESC LIMIT 1"
|
||||||
|
|
||||||
|
const selectMembersSQL = `
|
||||||
|
SELECT event_id FROM
|
||||||
|
( SELECT event_id, membership FROM syncapi_memberships WHERE room_id = $1 AND topological_pos <= $2 GROUP BY user_id HAVING(max(stream_pos))) t
|
||||||
|
WHERE ($3 IS NULL OR t.membership = $3)
|
||||||
|
AND ($4 IS NULL OR t.membership <> $4)
|
||||||
|
`
|
||||||
|
|
||||||
type membershipsStatements struct {
|
type membershipsStatements struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
upsertMembershipStmt *sql.Stmt
|
upsertMembershipStmt *sql.Stmt
|
||||||
selectMembershipCountStmt *sql.Stmt
|
selectMembershipCountStmt *sql.Stmt
|
||||||
//selectHeroesStmt *sql.Stmt - prepared at runtime due to variadic
|
//selectHeroesStmt *sql.Stmt - prepared at runtime due to variadic
|
||||||
selectMembershipForUserStmt *sql.Stmt
|
selectMembershipForUserStmt *sql.Stmt
|
||||||
|
selectMembersStmt *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSqliteMembershipsTable(db *sql.DB) (tables.Memberships, error) {
|
func NewSqliteMembershipsTable(db *sql.DB) (tables.Memberships, error) {
|
||||||
|
|
@ -89,6 +98,7 @@ func NewSqliteMembershipsTable(db *sql.DB) (tables.Memberships, error) {
|
||||||
{&s.upsertMembershipStmt, upsertMembershipSQL},
|
{&s.upsertMembershipStmt, upsertMembershipSQL},
|
||||||
{&s.selectMembershipCountStmt, selectMembershipCountSQL},
|
{&s.selectMembershipCountStmt, selectMembershipCountSQL},
|
||||||
{&s.selectMembershipForUserStmt, selectMembershipBeforeSQL},
|
{&s.selectMembershipForUserStmt, selectMembershipBeforeSQL},
|
||||||
|
{&s.selectMembersStmt, selectMembersSQL},
|
||||||
// {&s.selectHeroesStmt, selectHeroesSQL}, - prepared at runtime due to variadic
|
// {&s.selectHeroesStmt, selectHeroesSQL}, - prepared at runtime due to variadic
|
||||||
}.Prepare(db)
|
}.Prepare(db)
|
||||||
}
|
}
|
||||||
|
|
@ -170,3 +180,23 @@ func (s *membershipsStatements) SelectMembershipForUser(
|
||||||
}
|
}
|
||||||
return membership, topologyPos, nil
|
return membership, topologyPos, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *membershipsStatements) SelectMemberships(
|
||||||
|
ctx context.Context, txn *sql.Tx,
|
||||||
|
roomID string, pos types.TopologyToken,
|
||||||
|
membership, notMembership *string,
|
||||||
|
) (eventIDs []string, err error) {
|
||||||
|
stmt := sqlutil.TxStmt(txn, s.selectMembersStmt)
|
||||||
|
rows, err := stmt.QueryContext(ctx, roomID, pos.Depth, membership, notMembership)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var eventID string
|
||||||
|
for rows.Next() {
|
||||||
|
if err = rows.Scan(&eventID); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
eventIDs = append(eventIDs, eventID)
|
||||||
|
}
|
||||||
|
return eventIDs, rows.Err()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,11 @@ type Memberships interface {
|
||||||
SelectMembershipCount(ctx context.Context, txn *sql.Tx, roomID, membership string, pos types.StreamPosition) (count int, err error)
|
SelectMembershipCount(ctx context.Context, txn *sql.Tx, roomID, membership string, pos types.StreamPosition) (count int, err error)
|
||||||
SelectHeroes(ctx context.Context, txn *sql.Tx, roomID, userID string, memberships []string) (heroes []string, err error)
|
SelectHeroes(ctx context.Context, txn *sql.Tx, roomID, userID string, memberships []string) (heroes []string, err error)
|
||||||
SelectMembershipForUser(ctx context.Context, txn *sql.Tx, roomID, userID string, pos int64) (membership string, topologicalPos int, err error)
|
SelectMembershipForUser(ctx context.Context, txn *sql.Tx, roomID, userID string, pos int64) (membership string, topologicalPos int, err error)
|
||||||
|
SelectMemberships(
|
||||||
|
ctx context.Context, txn *sql.Tx,
|
||||||
|
roomID string, pos types.TopologyToken,
|
||||||
|
membership, notMembership *string,
|
||||||
|
) (eventIDs []string, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type NotificationData interface {
|
type NotificationData interface {
|
||||||
|
|
|
||||||
|
|
@ -227,14 +227,10 @@ func (p *PDUStreamProvider) addRoomDeltaToResponse(
|
||||||
stateFilter *gomatrixserverlib.StateFilter,
|
stateFilter *gomatrixserverlib.StateFilter,
|
||||||
req *types.SyncRequest,
|
req *types.SyncRequest,
|
||||||
) (types.StreamPosition, error) {
|
) (types.StreamPosition, error) {
|
||||||
if delta.MembershipPos > 0 && delta.Membership == gomatrixserverlib.Leave {
|
|
||||||
// make sure we don't leak recent events after the leave event.
|
originalLimit := eventFilter.Limit
|
||||||
// TODO: History visibility makes this somewhat complex to handle correctly. For example:
|
if r.Backwards {
|
||||||
// TODO: This doesn't work for join -> leave in a single /sync request (see events prior to join).
|
eventFilter.Limit = int(r.From - r.To)
|
||||||
// TODO: This will fail on join -> leave -> sensitive msg -> join -> leave
|
|
||||||
// in a single /sync request
|
|
||||||
// This is all "okay" assuming history_visibility == "shared" which it is by default.
|
|
||||||
r.To = delta.MembershipPos
|
|
||||||
}
|
}
|
||||||
recentStreamEvents, limited, err := snapshot.RecentEvents(
|
recentStreamEvents, limited, err := snapshot.RecentEvents(
|
||||||
ctx, delta.RoomID, r,
|
ctx, delta.RoomID, r,
|
||||||
|
|
@ -303,6 +299,12 @@ func (p *PDUStreamProvider) addRoomDeltaToResponse(
|
||||||
logrus.WithError(err).Error("unable to apply history visibility filter")
|
logrus.WithError(err).Error("unable to apply history visibility filter")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if r.Backwards && len(events) > originalLimit {
|
||||||
|
// We're going backwards and the events are ordered chronologically, so take the last `limit` events
|
||||||
|
events = events[len(events)-originalLimit:]
|
||||||
|
limited = true
|
||||||
|
}
|
||||||
|
|
||||||
if len(delta.StateEvents) > 0 {
|
if len(delta.StateEvents) > 0 {
|
||||||
updateLatestPosition(delta.StateEvents[len(delta.StateEvents)-1].EventID())
|
updateLatestPosition(delta.StateEvents[len(delta.StateEvents)-1].EventID())
|
||||||
}
|
}
|
||||||
|
|
@ -473,7 +475,13 @@ func (p *PDUStreamProvider) getJoinResponseForCompleteSync(
|
||||||
var prevBatch *types.TopologyToken
|
var prevBatch *types.TopologyToken
|
||||||
if len(recentStreamEvents) > 0 {
|
if len(recentStreamEvents) > 0 {
|
||||||
var backwardTopologyPos, backwardStreamPos types.StreamPosition
|
var backwardTopologyPos, backwardStreamPos types.StreamPosition
|
||||||
backwardTopologyPos, backwardStreamPos, err = snapshot.PositionInTopology(ctx, recentStreamEvents[0].EventID())
|
event := recentStreamEvents[0]
|
||||||
|
// If this is the beginning of the room, we can't go back further. We're going to return
|
||||||
|
// the TopologyToken from the last event instead. (Synapse returns the /sync next_Batch)
|
||||||
|
if event.Type() == gomatrixserverlib.MRoomCreate && event.StateKeyEquals("") {
|
||||||
|
event = recentStreamEvents[len(recentStreamEvents)-1]
|
||||||
|
}
|
||||||
|
backwardTopologyPos, backwardStreamPos, err = snapshot.PositionInTopology(ctx, event.EventID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,9 @@ func (t *TopologyToken) StreamToken() StreamingToken {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t TopologyToken) String() string {
|
func (t TopologyToken) String() string {
|
||||||
|
if t.Depth <= 0 && t.PDUPosition <= 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
return fmt.Sprintf("t%d_%d", t.Depth, t.PDUPosition)
|
return fmt.Sprintf("t%d_%d", t.Depth, t.PDUPosition)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -752,4 +752,9 @@ When user joins a room the state is included in the next sync
|
||||||
When user joins a room the state is included in a gapped sync
|
When user joins a room the state is included in a gapped sync
|
||||||
Messages that notify from another user increment notification_count
|
Messages that notify from another user increment notification_count
|
||||||
Messages that highlight from another user increment unread highlight count
|
Messages that highlight from another user increment unread highlight count
|
||||||
Notifications can be viewed with GET /notifications
|
Notifications can be viewed with GET /notifications
|
||||||
|
Can get rooms/{roomId}/messages for a departed room (SPEC-216)
|
||||||
|
Local device key changes appear in /keys/changes
|
||||||
|
Can get rooms/{roomId}/members at a given point
|
||||||
|
Can filter rooms/{roomId}/members
|
||||||
|
Current state appears in timeline in private history with many messages after
|
||||||
|
|
@ -36,6 +36,7 @@ func CreateBaseDendrite(t *testing.T, dbType test.DBType) (*base.BaseDendrite, f
|
||||||
Monolithic: true,
|
Monolithic: true,
|
||||||
})
|
})
|
||||||
cfg.Global.JetStream.InMemory = true
|
cfg.Global.JetStream.InMemory = true
|
||||||
|
cfg.FederationAPI.KeyPerspectives = nil
|
||||||
switch dbType {
|
switch dbType {
|
||||||
case test.DBTypePostgres:
|
case test.DBTypePostgres:
|
||||||
cfg.Global.Defaults(config.DefaultOpts{ // autogen a signing key
|
cfg.Global.Defaults(config.DefaultOpts{ // autogen a signing key
|
||||||
|
|
@ -106,6 +107,7 @@ func Base(cfg *config.Dendrite) (*base.BaseDendrite, nats.JetStreamContext, *nat
|
||||||
}
|
}
|
||||||
cfg.Global.JetStream.InMemory = true
|
cfg.Global.JetStream.InMemory = true
|
||||||
cfg.SyncAPI.Fulltext.InMemory = true
|
cfg.SyncAPI.Fulltext.InMemory = true
|
||||||
|
cfg.FederationAPI.KeyPerspectives = nil
|
||||||
base := base.NewBaseDendrite(cfg, "Tests")
|
base := base.NewBaseDendrite(cfg, "Tests")
|
||||||
js, jc := base.NATS.Prepare(base.ProcessContext, &cfg.Global.JetStream)
|
js, jc := base.NATS.Prepare(base.ProcessContext, &cfg.Global.JetStream)
|
||||||
return base, js, jc
|
return base, js, jc
|
||||||
|
|
|
||||||
|
|
@ -318,8 +318,9 @@ type QuerySearchProfilesResponse struct {
|
||||||
|
|
||||||
// PerformAccountCreationRequest is the request for PerformAccountCreation
|
// PerformAccountCreationRequest is the request for PerformAccountCreation
|
||||||
type PerformAccountCreationRequest struct {
|
type PerformAccountCreationRequest struct {
|
||||||
AccountType AccountType // Required: whether this is a guest or user account
|
AccountType AccountType // Required: whether this is a guest or user account
|
||||||
Localpart string // Required: The localpart for this account. Ignored if account type is guest.
|
Localpart string // Required: The localpart for this account. Ignored if account type is guest.
|
||||||
|
ServerName gomatrixserverlib.ServerName // optional: if not specified, default server name used instead
|
||||||
|
|
||||||
AppServiceID string // optional: the application service ID (not user ID) creating this account, if any.
|
AppServiceID string // optional: the application service ID (not user ID) creating this account, if any.
|
||||||
Password string // optional: if missing then this account will be a passwordless account
|
Password string // optional: if missing then this account will be a passwordless account
|
||||||
|
|
@ -360,7 +361,8 @@ type PerformLastSeenUpdateResponse struct {
|
||||||
// PerformDeviceCreationRequest is the request for PerformDeviceCreation
|
// PerformDeviceCreationRequest is the request for PerformDeviceCreation
|
||||||
type PerformDeviceCreationRequest struct {
|
type PerformDeviceCreationRequest struct {
|
||||||
Localpart string
|
Localpart string
|
||||||
AccessToken string // optional: if blank one will be made on your behalf
|
ServerName gomatrixserverlib.ServerName // optional: if blank, default server name used
|
||||||
|
AccessToken string // optional: if blank one will be made on your behalf
|
||||||
// optional: if nil an ID is generated for you. If set, replaces any existing device session,
|
// optional: if nil an ID is generated for you. If set, replaces any existing device session,
|
||||||
// which will generate a new access token and invalidate the old one.
|
// which will generate a new access token and invalidate the old one.
|
||||||
DeviceID *string
|
DeviceID *string
|
||||||
|
|
@ -384,7 +386,8 @@ type PerformDeviceCreationResponse struct {
|
||||||
|
|
||||||
// PerformAccountDeactivationRequest is the request for PerformAccountDeactivation
|
// PerformAccountDeactivationRequest is the request for PerformAccountDeactivation
|
||||||
type PerformAccountDeactivationRequest struct {
|
type PerformAccountDeactivationRequest struct {
|
||||||
Localpart string
|
Localpart string
|
||||||
|
ServerName gomatrixserverlib.ServerName // optional: if blank, default server name used
|
||||||
}
|
}
|
||||||
|
|
||||||
// PerformAccountDeactivationResponse is the response for PerformAccountDeactivation
|
// PerformAccountDeactivationResponse is the response for PerformAccountDeactivation
|
||||||
|
|
@ -434,6 +437,18 @@ type Device struct {
|
||||||
AccountType AccountType
|
AccountType AccountType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Device) UserDomain() gomatrixserverlib.ServerName {
|
||||||
|
_, domain, err := gomatrixserverlib.SplitID('@', d.UserID)
|
||||||
|
if err != nil {
|
||||||
|
// This really is catastrophic because it means that someone
|
||||||
|
// managed to forge a malformed user ID for a device during
|
||||||
|
// login.
|
||||||
|
// TODO: Is there a better way to deal with this than panic?
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return domain
|
||||||
|
}
|
||||||
|
|
||||||
// Account represents a Matrix account on this home server.
|
// Account represents a Matrix account on this home server.
|
||||||
type Account struct {
|
type Account struct {
|
||||||
UserID string
|
UserID string
|
||||||
|
|
@ -577,7 +592,9 @@ type Notification struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PerformSetAvatarURLRequest struct {
|
type PerformSetAvatarURLRequest struct {
|
||||||
Localpart, AvatarURL string
|
Localpart string
|
||||||
|
ServerName gomatrixserverlib.ServerName
|
||||||
|
AvatarURL string
|
||||||
}
|
}
|
||||||
type PerformSetAvatarURLResponse struct {
|
type PerformSetAvatarURLResponse struct {
|
||||||
Profile *authtypes.Profile `json:"profile"`
|
Profile *authtypes.Profile `json:"profile"`
|
||||||
|
|
@ -606,7 +623,9 @@ type QueryAccountByPasswordResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PerformUpdateDisplayNameRequest struct {
|
type PerformUpdateDisplayNameRequest struct {
|
||||||
Localpart, DisplayName string
|
Localpart string
|
||||||
|
ServerName gomatrixserverlib.ServerName
|
||||||
|
DisplayName string
|
||||||
}
|
}
|
||||||
|
|
||||||
type PerformUpdateDisplayNameResponse struct {
|
type PerformUpdateDisplayNameResponse struct {
|
||||||
|
|
|
||||||
|
|
@ -46,14 +46,15 @@ import (
|
||||||
type UserInternalAPI struct {
|
type UserInternalAPI struct {
|
||||||
DB storage.Database
|
DB storage.Database
|
||||||
SyncProducer *producers.SyncAPI
|
SyncProducer *producers.SyncAPI
|
||||||
|
Config *config.UserAPI
|
||||||
|
|
||||||
DisableTLSValidation bool
|
DisableTLSValidation bool
|
||||||
ServerName gomatrixserverlib.ServerName
|
|
||||||
// AppServices is the list of all registered AS
|
// AppServices is the list of all registered AS
|
||||||
AppServices []config.ApplicationService
|
AppServices []config.ApplicationService
|
||||||
KeyAPI keyapi.UserKeyAPI
|
KeyAPI keyapi.UserKeyAPI
|
||||||
RSAPI rsapi.UserRoomserverAPI
|
RSAPI rsapi.UserRoomserverAPI
|
||||||
PgClient pushgateway.Client
|
PgClient pushgateway.Client
|
||||||
|
Cfg *config.UserAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *UserInternalAPI) InputAccountData(ctx context.Context, req *api.InputAccountDataRequest, res *api.InputAccountDataResponse) error {
|
func (a *UserInternalAPI) InputAccountData(ctx context.Context, req *api.InputAccountDataRequest, res *api.InputAccountDataResponse) error {
|
||||||
|
|
@ -61,8 +62,8 @@ func (a *UserInternalAPI) InputAccountData(ctx context.Context, req *api.InputAc
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if domain != a.ServerName {
|
if !a.Config.Matrix.IsLocalServerName(domain) {
|
||||||
return fmt.Errorf("cannot query profile of remote users: got %s want %s", domain, a.ServerName)
|
return fmt.Errorf("cannot update account data of remote users (server name %s)", domain)
|
||||||
}
|
}
|
||||||
if req.DataType == "" {
|
if req.DataType == "" {
|
||||||
return fmt.Errorf("data type must not be empty")
|
return fmt.Errorf("data type must not be empty")
|
||||||
|
|
@ -103,7 +104,7 @@ func (a *UserInternalAPI) setFullyRead(ctx context.Context, req *api.InputAccoun
|
||||||
logrus.WithError(err).Error("UserInternalAPI.setFullyRead: SplitID failure")
|
logrus.WithError(err).Error("UserInternalAPI.setFullyRead: SplitID failure")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if domain != a.ServerName {
|
if !a.Config.Matrix.IsLocalServerName(domain) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,7 +131,51 @@ func (a *UserInternalAPI) setFullyRead(ctx context.Context, req *api.InputAccoun
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func postRegisterJoinRooms(cfg *config.UserAPI, acc *api.Account, rsAPI rsapi.UserRoomserverAPI) {
|
||||||
|
// POST register behaviour: check if the user is a normal user.
|
||||||
|
// If the user is a normal user, add user to room specified in the configuration "auto_join_rooms".
|
||||||
|
if acc.AccountType != api.AccountTypeAppService && acc.AppServiceID == "" {
|
||||||
|
for room := range cfg.AutoJoinRooms {
|
||||||
|
userID := userutil.MakeUserID(acc.Localpart, cfg.Matrix.ServerName)
|
||||||
|
err := addUserToRoom(context.Background(), rsAPI, cfg.AutoJoinRooms[room], acc.Localpart, userID)
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithFields(logrus.Fields{
|
||||||
|
"user_id": userID,
|
||||||
|
"room": cfg.AutoJoinRooms[room],
|
||||||
|
}).WithError(err).Errorf("user failed to auto-join room")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add user to a room. This function currently working for auto_join_rooms config,
|
||||||
|
// which can add a newly registered user to a specified room.
|
||||||
|
func addUserToRoom(
|
||||||
|
ctx context.Context,
|
||||||
|
rsAPI rsapi.UserRoomserverAPI,
|
||||||
|
roomID string,
|
||||||
|
username string,
|
||||||
|
userID string,
|
||||||
|
) error {
|
||||||
|
addGroupContent := make(map[string]interface{})
|
||||||
|
// This make sure the user's username can be displayed correctly.
|
||||||
|
// Because the newly-registered user doesn't have an avatar, the avatar_url is not needed.
|
||||||
|
addGroupContent["displayname"] = username
|
||||||
|
joinReq := rsapi.PerformJoinRequest{
|
||||||
|
RoomIDOrAlias: roomID,
|
||||||
|
UserID: userID,
|
||||||
|
Content: addGroupContent,
|
||||||
|
}
|
||||||
|
joinRes := rsapi.PerformJoinResponse{}
|
||||||
|
return rsAPI.PerformJoin(ctx, &joinReq, &joinRes)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *UserInternalAPI) PerformAccountCreation(ctx context.Context, req *api.PerformAccountCreationRequest, res *api.PerformAccountCreationResponse) error {
|
func (a *UserInternalAPI) PerformAccountCreation(ctx context.Context, req *api.PerformAccountCreationRequest, res *api.PerformAccountCreationResponse) error {
|
||||||
|
serverName := req.ServerName
|
||||||
|
if serverName == "" {
|
||||||
|
serverName = a.Config.Matrix.ServerName
|
||||||
|
}
|
||||||
|
// XXXX: Use the server name here
|
||||||
acc, err := a.DB.CreateAccount(ctx, req.Localpart, req.Password, req.AppServiceID, req.AccountType)
|
acc, err := a.DB.CreateAccount(ctx, req.Localpart, req.Password, req.AppServiceID, req.AccountType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, sqlutil.ErrUserExists) { // This account already exists
|
if errors.Is(err, sqlutil.ErrUserExists) { // This account already exists
|
||||||
|
|
@ -148,8 +193,8 @@ func (a *UserInternalAPI) PerformAccountCreation(ctx context.Context, req *api.P
|
||||||
res.Account = &api.Account{
|
res.Account = &api.Account{
|
||||||
AppServiceID: req.AppServiceID,
|
AppServiceID: req.AppServiceID,
|
||||||
Localpart: req.Localpart,
|
Localpart: req.Localpart,
|
||||||
ServerName: a.ServerName,
|
ServerName: serverName,
|
||||||
UserID: fmt.Sprintf("@%s:%s", req.Localpart, a.ServerName),
|
UserID: fmt.Sprintf("@%s:%s", req.Localpart, serverName),
|
||||||
AccountType: req.AccountType,
|
AccountType: req.AccountType,
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -174,6 +219,8 @@ func (a *UserInternalAPI) PerformAccountCreation(ctx context.Context, req *api.P
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postRegisterJoinRooms(a.Cfg, acc, a.RSAPI)
|
||||||
|
|
||||||
res.AccountCreated = true
|
res.AccountCreated = true
|
||||||
res.Account = acc
|
res.Account = acc
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -193,6 +240,12 @@ func (a *UserInternalAPI) PerformPasswordUpdate(ctx context.Context, req *api.Pe
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *UserInternalAPI) PerformDeviceCreation(ctx context.Context, req *api.PerformDeviceCreationRequest, res *api.PerformDeviceCreationResponse) error {
|
func (a *UserInternalAPI) PerformDeviceCreation(ctx context.Context, req *api.PerformDeviceCreationRequest, res *api.PerformDeviceCreationResponse) error {
|
||||||
|
serverName := req.ServerName
|
||||||
|
if serverName == "" {
|
||||||
|
serverName = a.Config.Matrix.ServerName
|
||||||
|
}
|
||||||
|
_ = serverName
|
||||||
|
// XXXX: Use the server name here
|
||||||
util.GetLogger(ctx).WithFields(logrus.Fields{
|
util.GetLogger(ctx).WithFields(logrus.Fields{
|
||||||
"localpart": req.Localpart,
|
"localpart": req.Localpart,
|
||||||
"device_id": req.DeviceID,
|
"device_id": req.DeviceID,
|
||||||
|
|
@ -217,8 +270,8 @@ func (a *UserInternalAPI) PerformDeviceDeletion(ctx context.Context, req *api.Pe
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if domain != a.ServerName {
|
if !a.Config.Matrix.IsLocalServerName(domain) {
|
||||||
return fmt.Errorf("cannot PerformDeviceDeletion of remote users: got %s want %s", domain, a.ServerName)
|
return fmt.Errorf("cannot PerformDeviceDeletion of remote users (server name %s)", domain)
|
||||||
}
|
}
|
||||||
deletedDeviceIDs := req.DeviceIDs
|
deletedDeviceIDs := req.DeviceIDs
|
||||||
if len(req.DeviceIDs) == 0 {
|
if len(req.DeviceIDs) == 0 {
|
||||||
|
|
@ -350,8 +403,8 @@ func (a *UserInternalAPI) QueryProfile(ctx context.Context, req *api.QueryProfil
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if domain != a.ServerName {
|
if !a.Config.Matrix.IsLocalServerName(domain) {
|
||||||
return fmt.Errorf("cannot query profile of remote users: got %s want %s", domain, a.ServerName)
|
return fmt.Errorf("cannot query profile of remote users (server name %s)", domain)
|
||||||
}
|
}
|
||||||
prof, err := a.DB.GetProfileByLocalpart(ctx, local)
|
prof, err := a.DB.GetProfileByLocalpart(ctx, local)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -401,8 +454,8 @@ func (a *UserInternalAPI) QueryDevices(ctx context.Context, req *api.QueryDevice
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if domain != a.ServerName {
|
if !a.Config.Matrix.IsLocalServerName(domain) {
|
||||||
return fmt.Errorf("cannot query devices of remote users: got %s want %s", domain, a.ServerName)
|
return fmt.Errorf("cannot query devices of remote users (server name %s)", domain)
|
||||||
}
|
}
|
||||||
devs, err := a.DB.GetDevicesByLocalpart(ctx, local)
|
devs, err := a.DB.GetDevicesByLocalpart(ctx, local)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -418,8 +471,8 @@ func (a *UserInternalAPI) QueryAccountData(ctx context.Context, req *api.QueryAc
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if domain != a.ServerName {
|
if !a.Config.Matrix.IsLocalServerName(domain) {
|
||||||
return fmt.Errorf("cannot query account data of remote users: got %s want %s", domain, a.ServerName)
|
return fmt.Errorf("cannot query account data of remote users (server name %s)", domain)
|
||||||
}
|
}
|
||||||
if req.DataType != "" {
|
if req.DataType != "" {
|
||||||
var data json.RawMessage
|
var data json.RawMessage
|
||||||
|
|
@ -467,10 +520,13 @@ func (a *UserInternalAPI) QueryAccessToken(ctx context.Context, req *api.QueryAc
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
localPart, _, err := gomatrixserverlib.SplitID('@', device.UserID)
|
localPart, domain, err := gomatrixserverlib.SplitID('@', device.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if !a.Config.Matrix.IsLocalServerName(domain) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
acc, err := a.DB.GetAccountByLocalpart(ctx, localPart)
|
acc, err := a.DB.GetAccountByLocalpart(ctx, localPart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -505,7 +561,7 @@ func (a *UserInternalAPI) queryAppServiceToken(ctx context.Context, token, appSe
|
||||||
AccountType: api.AccountTypeAppService,
|
AccountType: api.AccountTypeAppService,
|
||||||
}
|
}
|
||||||
|
|
||||||
localpart, err := userutil.ParseUsernameParam(appServiceUserID, &a.ServerName)
|
localpart, _, err := userutil.ParseUsernameParam(appServiceUserID, a.Config.Matrix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -530,8 +586,16 @@ func (a *UserInternalAPI) queryAppServiceToken(ctx context.Context, token, appSe
|
||||||
|
|
||||||
// PerformAccountDeactivation deactivates the user's account, removing all ability for the user to login again.
|
// PerformAccountDeactivation deactivates the user's account, removing all ability for the user to login again.
|
||||||
func (a *UserInternalAPI) PerformAccountDeactivation(ctx context.Context, req *api.PerformAccountDeactivationRequest, res *api.PerformAccountDeactivationResponse) error {
|
func (a *UserInternalAPI) PerformAccountDeactivation(ctx context.Context, req *api.PerformAccountDeactivationRequest, res *api.PerformAccountDeactivationResponse) error {
|
||||||
|
serverName := req.ServerName
|
||||||
|
if serverName == "" {
|
||||||
|
serverName = a.Config.Matrix.ServerName
|
||||||
|
}
|
||||||
|
if !a.Config.Matrix.IsLocalServerName(serverName) {
|
||||||
|
return fmt.Errorf("server name %q not locally configured", serverName)
|
||||||
|
}
|
||||||
|
|
||||||
evacuateReq := &rsapi.PerformAdminEvacuateUserRequest{
|
evacuateReq := &rsapi.PerformAdminEvacuateUserRequest{
|
||||||
UserID: fmt.Sprintf("@%s:%s", req.Localpart, a.ServerName),
|
UserID: fmt.Sprintf("@%s:%s", req.Localpart, serverName),
|
||||||
}
|
}
|
||||||
evacuateRes := &rsapi.PerformAdminEvacuateUserResponse{}
|
evacuateRes := &rsapi.PerformAdminEvacuateUserResponse{}
|
||||||
if err := a.RSAPI.PerformAdminEvacuateUser(ctx, evacuateReq, evacuateRes); err != nil {
|
if err := a.RSAPI.PerformAdminEvacuateUser(ctx, evacuateReq, evacuateRes); err != nil {
|
||||||
|
|
@ -542,7 +606,7 @@ func (a *UserInternalAPI) PerformAccountDeactivation(ctx context.Context, req *a
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceReq := &api.PerformDeviceDeletionRequest{
|
deviceReq := &api.PerformDeviceDeletionRequest{
|
||||||
UserID: fmt.Sprintf("@%s:%s", req.Localpart, a.ServerName),
|
UserID: fmt.Sprintf("@%s:%s", req.Localpart, serverName),
|
||||||
}
|
}
|
||||||
deviceRes := &api.PerformDeviceDeletionResponse{}
|
deviceRes := &api.PerformDeviceDeletionResponse{}
|
||||||
if err := a.PerformDeviceDeletion(ctx, deviceReq, deviceRes); err != nil {
|
if err := a.PerformDeviceDeletion(ctx, deviceReq, deviceRes); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@ func (a *UserInternalAPI) PerformLoginTokenCreation(ctx context.Context, req *ap
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if domain != a.ServerName {
|
if !a.Config.Matrix.IsLocalServerName(domain) {
|
||||||
return fmt.Errorf("cannot create a login token for a remote user: got %s want %s", domain, a.ServerName)
|
return fmt.Errorf("cannot create a login token for a remote user (server name %s)", domain)
|
||||||
}
|
}
|
||||||
tokenMeta, err := a.DB.CreateLoginToken(ctx, &req.Data)
|
tokenMeta, err := a.DB.CreateLoginToken(ctx, &req.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -63,8 +63,8 @@ func (a *UserInternalAPI) QueryLoginToken(ctx context.Context, req *api.QueryLog
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if domain != a.ServerName {
|
if !a.Config.Matrix.IsLocalServerName(domain) {
|
||||||
return fmt.Errorf("cannot return a login token for a remote user: got %s want %s", domain, a.ServerName)
|
return fmt.Errorf("cannot return a login token for a remote user (server name %s)", domain)
|
||||||
}
|
}
|
||||||
if _, err := a.DB.GetAccountByLocalpart(ctx, localpart); err != nil {
|
if _, err := a.DB.GetAccountByLocalpart(ctx, localpart); err != nil {
|
||||||
res.Data = nil
|
res.Data = nil
|
||||||
|
|
|
||||||
|
|
@ -76,12 +76,13 @@ func NewInternalAPI(
|
||||||
userAPI := &internal.UserInternalAPI{
|
userAPI := &internal.UserInternalAPI{
|
||||||
DB: db,
|
DB: db,
|
||||||
SyncProducer: syncProducer,
|
SyncProducer: syncProducer,
|
||||||
ServerName: cfg.Matrix.ServerName,
|
Config: cfg,
|
||||||
AppServices: appServices,
|
AppServices: appServices,
|
||||||
KeyAPI: keyAPI,
|
KeyAPI: keyAPI,
|
||||||
RSAPI: rsAPI,
|
RSAPI: rsAPI,
|
||||||
DisableTLSValidation: cfg.PushGatewayDisableTLSValidation,
|
DisableTLSValidation: cfg.PushGatewayDisableTLSValidation,
|
||||||
PgClient: pgClient,
|
PgClient: pgClient,
|
||||||
|
Cfg: cfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
receiptConsumer := consumers.NewOutputReceiptEventConsumer(
|
receiptConsumer := consumers.NewOutputReceiptEventConsumer(
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,8 @@ func MustMakeInternalAPI(t *testing.T, opts apiTestOpts, dbType test.DBType) (ap
|
||||||
}
|
}
|
||||||
|
|
||||||
return &internal.UserInternalAPI{
|
return &internal.UserInternalAPI{
|
||||||
DB: accountDB,
|
DB: accountDB,
|
||||||
ServerName: cfg.Matrix.ServerName,
|
Config: cfg,
|
||||||
}, accountDB, func() {
|
}, accountDB, func() {
|
||||||
close()
|
close()
|
||||||
baseclose()
|
baseclose()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue