Add AS specific public room list endpoints (#2836)
Adds `PUT /_matrix/client/v3/directory/list/appservice/{networkId}/{roomId}` and `DELTE /_matrix/client/v3/directory/list/appservice/{networkId}/{roomId}` support, as well as the ability to filter `/publicRooms` on networkID and including all networks.
This commit is contained in:
parent
a169a9121a
commit
444b4bbdb8
|
@ -18,14 +18,15 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
|
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
userapi "github.com/matrix-org/dendrite/userapi/api"
|
userapi "github.com/matrix-org/dendrite/userapi/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
"github.com/matrix-org/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type roomDirectoryResponse struct {
|
type roomDirectoryResponse struct {
|
||||||
|
@ -318,3 +319,43 @@ func SetVisibility(
|
||||||
JSON: struct{}{},
|
JSON: struct{}{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetVisibilityAS(
|
||||||
|
req *http.Request, rsAPI roomserverAPI.ClientRoomserverAPI, dev *userapi.Device,
|
||||||
|
networkID, roomID string,
|
||||||
|
) util.JSONResponse {
|
||||||
|
if dev.AccountType != userapi.AccountTypeAppService {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusForbidden,
|
||||||
|
JSON: jsonerror.Forbidden("Only appservice may use this endpoint"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var v roomVisibility
|
||||||
|
|
||||||
|
// If the method is delete, we simply mark the visibility as private
|
||||||
|
if req.Method == http.MethodDelete {
|
||||||
|
v.Visibility = "private"
|
||||||
|
} else {
|
||||||
|
if reqErr := httputil.UnmarshalJSONRequest(req, &v); reqErr != nil {
|
||||||
|
return *reqErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var publishRes roomserverAPI.PerformPublishResponse
|
||||||
|
if err := rsAPI.PerformPublish(req.Context(), &roomserverAPI.PerformPublishRequest{
|
||||||
|
RoomID: roomID,
|
||||||
|
Visibility: v.Visibility,
|
||||||
|
NetworkID: networkID,
|
||||||
|
AppserviceID: dev.AppserviceID,
|
||||||
|
}, &publishRes); err != nil {
|
||||||
|
return jsonerror.InternalAPIError(req.Context(), err)
|
||||||
|
}
|
||||||
|
if publishRes.Error != nil {
|
||||||
|
util.GetLogger(req.Context()).WithError(publishRes.Error).Error("PerformPublish failed")
|
||||||
|
return publishRes.Error.JSONResponse()
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusOK,
|
||||||
|
JSON: struct{}{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -39,14 +39,17 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type PublicRoomReq struct {
|
type PublicRoomReq struct {
|
||||||
Since string `json:"since,omitempty"`
|
Since string `json:"since,omitempty"`
|
||||||
Limit int16 `json:"limit,omitempty"`
|
Limit int64 `json:"limit,omitempty"`
|
||||||
Filter filter `json:"filter,omitempty"`
|
Filter filter `json:"filter,omitempty"`
|
||||||
Server string `json:"server,omitempty"`
|
Server string `json:"server,omitempty"`
|
||||||
|
IncludeAllNetworks bool `json:"include_all_networks,omitempty"`
|
||||||
|
NetworkID string `json:"third_party_instance_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type filter struct {
|
type filter struct {
|
||||||
SearchTerms string `json:"generic_search_term,omitempty"`
|
SearchTerms string `json:"generic_search_term,omitempty"`
|
||||||
|
RoomTypes []string `json:"room_types,omitempty"` // TODO: Implement filter on this
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPostPublicRooms implements GET and POST /publicRooms
|
// GetPostPublicRooms implements GET and POST /publicRooms
|
||||||
|
@ -61,6 +64,13 @@ func GetPostPublicRooms(
|
||||||
return *fillErr
|
return *fillErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if request.IncludeAllNetworks && request.NetworkID != "" {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusBadRequest,
|
||||||
|
JSON: jsonerror.InvalidParam("include_all_networks and third_party_instance_id can not be used together"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
serverName := gomatrixserverlib.ServerName(request.Server)
|
serverName := gomatrixserverlib.ServerName(request.Server)
|
||||||
if serverName != "" && !cfg.Matrix.IsLocalServerName(serverName) {
|
if serverName != "" && !cfg.Matrix.IsLocalServerName(serverName) {
|
||||||
res, err := federation.GetPublicRoomsFiltered(
|
res, err := federation.GetPublicRoomsFiltered(
|
||||||
|
@ -97,7 +107,7 @@ func publicRooms(
|
||||||
response := gomatrixserverlib.RespPublicRooms{
|
response := gomatrixserverlib.RespPublicRooms{
|
||||||
Chunk: []gomatrixserverlib.PublicRoom{},
|
Chunk: []gomatrixserverlib.PublicRoom{},
|
||||||
}
|
}
|
||||||
var limit int16
|
var limit int64
|
||||||
var offset int64
|
var offset int64
|
||||||
limit = request.Limit
|
limit = request.Limit
|
||||||
if limit == 0 {
|
if limit == 0 {
|
||||||
|
@ -114,7 +124,7 @@ func publicRooms(
|
||||||
|
|
||||||
var rooms []gomatrixserverlib.PublicRoom
|
var rooms []gomatrixserverlib.PublicRoom
|
||||||
if request.Since == "" {
|
if request.Since == "" {
|
||||||
rooms = refreshPublicRoomCache(ctx, rsAPI, extRoomsProvider)
|
rooms = refreshPublicRoomCache(ctx, rsAPI, extRoomsProvider, request)
|
||||||
} else {
|
} else {
|
||||||
rooms = getPublicRoomsFromCache()
|
rooms = getPublicRoomsFromCache()
|
||||||
}
|
}
|
||||||
|
@ -176,7 +186,7 @@ func fillPublicRoomsReq(httpReq *http.Request, request *PublicRoomReq) *util.JSO
|
||||||
JSON: jsonerror.BadJSON("limit param is not a number"),
|
JSON: jsonerror.BadJSON("limit param is not a number"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request.Limit = int16(limit)
|
request.Limit = int64(limit)
|
||||||
request.Since = httpReq.FormValue("since")
|
request.Since = httpReq.FormValue("since")
|
||||||
request.Server = httpReq.FormValue("server")
|
request.Server = httpReq.FormValue("server")
|
||||||
} else {
|
} else {
|
||||||
|
@ -204,7 +214,7 @@ func fillPublicRoomsReq(httpReq *http.Request, request *PublicRoomReq) *util.JSO
|
||||||
// limit=3&since=6 => G (prev='3', next='')
|
// limit=3&since=6 => G (prev='3', next='')
|
||||||
//
|
//
|
||||||
// A value of '-1' for prev/next indicates no position.
|
// A value of '-1' for prev/next indicates no position.
|
||||||
func sliceInto(slice []gomatrixserverlib.PublicRoom, since int64, limit int16) (subset []gomatrixserverlib.PublicRoom, prev, next int) {
|
func sliceInto(slice []gomatrixserverlib.PublicRoom, since int64, limit int64) (subset []gomatrixserverlib.PublicRoom, prev, next int) {
|
||||||
prev = -1
|
prev = -1
|
||||||
next = -1
|
next = -1
|
||||||
|
|
||||||
|
@ -230,6 +240,7 @@ func sliceInto(slice []gomatrixserverlib.PublicRoom, since int64, limit int16) (
|
||||||
|
|
||||||
func refreshPublicRoomCache(
|
func refreshPublicRoomCache(
|
||||||
ctx context.Context, rsAPI roomserverAPI.ClientRoomserverAPI, extRoomsProvider api.ExtraPublicRoomsProvider,
|
ctx context.Context, rsAPI roomserverAPI.ClientRoomserverAPI, extRoomsProvider api.ExtraPublicRoomsProvider,
|
||||||
|
request PublicRoomReq,
|
||||||
) []gomatrixserverlib.PublicRoom {
|
) []gomatrixserverlib.PublicRoom {
|
||||||
cacheMu.Lock()
|
cacheMu.Lock()
|
||||||
defer cacheMu.Unlock()
|
defer cacheMu.Unlock()
|
||||||
|
@ -238,8 +249,17 @@ func refreshPublicRoomCache(
|
||||||
extraRooms = extRoomsProvider.Rooms()
|
extraRooms = extRoomsProvider.Rooms()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this is only here to make Sytest happy, for now.
|
||||||
|
ns := strings.Split(request.NetworkID, "|")
|
||||||
|
if len(ns) == 2 {
|
||||||
|
request.NetworkID = ns[1]
|
||||||
|
}
|
||||||
|
|
||||||
var queryRes roomserverAPI.QueryPublishedRoomsResponse
|
var queryRes roomserverAPI.QueryPublishedRoomsResponse
|
||||||
err := rsAPI.QueryPublishedRooms(ctx, &roomserverAPI.QueryPublishedRoomsRequest{}, &queryRes)
|
err := rsAPI.QueryPublishedRooms(ctx, &roomserverAPI.QueryPublishedRoomsRequest{
|
||||||
|
NetworkID: request.NetworkID,
|
||||||
|
IncludeAllNetworks: request.IncludeAllNetworks,
|
||||||
|
}, &queryRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Error("QueryPublishedRooms failed")
|
util.GetLogger(ctx).WithError(err).Error("QueryPublishedRooms failed")
|
||||||
return publicRoomsCache
|
return publicRoomsCache
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestSliceInto(t *testing.T) {
|
||||||
slice := []gomatrixserverlib.PublicRoom{
|
slice := []gomatrixserverlib.PublicRoom{
|
||||||
pubRoom("a"), pubRoom("b"), pubRoom("c"), pubRoom("d"), pubRoom("e"), pubRoom("f"), pubRoom("g"),
|
pubRoom("a"), pubRoom("b"), pubRoom("c"), pubRoom("d"), pubRoom("e"), pubRoom("f"), pubRoom("g"),
|
||||||
}
|
}
|
||||||
limit := int16(3)
|
limit := int64(3)
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
since int64
|
since int64
|
||||||
wantPrev int
|
wantPrev int
|
||||||
|
|
|
@ -480,7 +480,7 @@ func Setup(
|
||||||
return GetVisibility(req, rsAPI, vars["roomID"])
|
return GetVisibility(req, rsAPI, vars["roomID"])
|
||||||
}),
|
}),
|
||||||
).Methods(http.MethodGet, http.MethodOptions)
|
).Methods(http.MethodGet, http.MethodOptions)
|
||||||
// TODO: Add AS support
|
|
||||||
v3mux.Handle("/directory/list/room/{roomID}",
|
v3mux.Handle("/directory/list/room/{roomID}",
|
||||||
httputil.MakeAuthAPI("directory_list", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
httputil.MakeAuthAPI("directory_list", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
|
||||||
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
|
||||||
|
@ -490,6 +490,27 @@ func Setup(
|
||||||
return SetVisibility(req, rsAPI, device, vars["roomID"])
|
return SetVisibility(req, rsAPI, device, vars["roomID"])
|
||||||
}),
|
}),
|
||||||
).Methods(http.MethodPut, http.MethodOptions)
|
).Methods(http.MethodPut, http.MethodOptions)
|
||||||
|
v3mux.Handle("/directory/list/appservice/{networkID}/{roomID}",
|
||||||
|
httputil.MakeAuthAPI("directory_list", 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 SetVisibilityAS(req, rsAPI, device, vars["networkID"], vars["roomID"])
|
||||||
|
}),
|
||||||
|
).Methods(http.MethodPut, http.MethodOptions)
|
||||||
|
|
||||||
|
// Undocumented endpoint
|
||||||
|
v3mux.Handle("/directory/list/appservice/{networkID}/{roomID}",
|
||||||
|
httputil.MakeAuthAPI("directory_list", 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 SetVisibilityAS(req, rsAPI, device, vars["networkID"], vars["roomID"])
|
||||||
|
}),
|
||||||
|
).Methods(http.MethodDelete, http.MethodOptions)
|
||||||
|
|
||||||
v3mux.Handle("/publicRooms",
|
v3mux.Handle("/publicRooms",
|
||||||
httputil.MakeExternalAPI("public_rooms", func(req *http.Request) util.JSONResponse {
|
httputil.MakeExternalAPI("public_rooms", func(req *http.Request) util.JSONResponse {
|
||||||
return GetPostPublicRooms(req, rsAPI, extRoomsProvider, federation, cfg)
|
return GetPostPublicRooms(req, rsAPI, extRoomsProvider, federation, cfg)
|
||||||
|
|
|
@ -2,24 +2,29 @@ package routing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/httputil"
|
"github.com/matrix-org/dendrite/clientapi/httputil"
|
||||||
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
"github.com/matrix-org/dendrite/clientapi/jsonerror"
|
||||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
|
||||||
"github.com/matrix-org/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type PublicRoomReq struct {
|
type PublicRoomReq struct {
|
||||||
Since string `json:"since,omitempty"`
|
Since string `json:"since,omitempty"`
|
||||||
Limit int16 `json:"limit,omitempty"`
|
Limit int16 `json:"limit,omitempty"`
|
||||||
Filter filter `json:"filter,omitempty"`
|
Filter filter `json:"filter,omitempty"`
|
||||||
|
IncludeAllNetworks bool `json:"include_all_networks,omitempty"`
|
||||||
|
NetworkID string `json:"third_party_instance_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type filter struct {
|
type filter struct {
|
||||||
SearchTerms string `json:"generic_search_term,omitempty"`
|
SearchTerms string `json:"generic_search_term,omitempty"`
|
||||||
|
RoomTypes []string `json:"room_types,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetPostPublicRooms implements GET and POST /publicRooms
|
// GetPostPublicRooms implements GET and POST /publicRooms
|
||||||
|
@ -57,8 +62,14 @@ func publicRooms(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if request.IncludeAllNetworks && request.NetworkID != "" {
|
||||||
|
return nil, fmt.Errorf("include_all_networks and third_party_instance_id can not be used together")
|
||||||
|
}
|
||||||
|
|
||||||
var queryRes roomserverAPI.QueryPublishedRoomsResponse
|
var queryRes roomserverAPI.QueryPublishedRoomsResponse
|
||||||
err = rsAPI.QueryPublishedRooms(ctx, &roomserverAPI.QueryPublishedRoomsRequest{}, &queryRes)
|
err = rsAPI.QueryPublishedRooms(ctx, &roomserverAPI.QueryPublishedRoomsRequest{
|
||||||
|
NetworkID: request.NetworkID,
|
||||||
|
}, &queryRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.GetLogger(ctx).WithError(err).Error("QueryPublishedRooms failed")
|
util.GetLogger(ctx).WithError(err).Error("QueryPublishedRooms failed")
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -168,8 +168,10 @@ type PerformBackfillResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PerformPublishRequest struct {
|
type PerformPublishRequest struct {
|
||||||
RoomID string
|
RoomID string
|
||||||
Visibility string
|
Visibility string
|
||||||
|
AppserviceID string
|
||||||
|
NetworkID string
|
||||||
}
|
}
|
||||||
|
|
||||||
type PerformPublishResponse struct {
|
type PerformPublishResponse struct {
|
||||||
|
|
|
@ -21,8 +21,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// QueryLatestEventsAndStateRequest is a request to QueryLatestEventsAndState
|
// QueryLatestEventsAndStateRequest is a request to QueryLatestEventsAndState
|
||||||
|
@ -257,7 +258,9 @@ type QueryRoomVersionForRoomResponse struct {
|
||||||
|
|
||||||
type QueryPublishedRoomsRequest struct {
|
type QueryPublishedRoomsRequest struct {
|
||||||
// Optional. If specified, returns whether this room is published or not.
|
// Optional. If specified, returns whether this room is published or not.
|
||||||
RoomID string
|
RoomID string
|
||||||
|
NetworkID string
|
||||||
|
IncludeAllNetworks bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueryPublishedRoomsResponse struct {
|
type QueryPublishedRoomsResponse struct {
|
||||||
|
|
|
@ -30,7 +30,7 @@ func (r *Publisher) PerformPublish(
|
||||||
req *api.PerformPublishRequest,
|
req *api.PerformPublishRequest,
|
||||||
res *api.PerformPublishResponse,
|
res *api.PerformPublishResponse,
|
||||||
) error {
|
) error {
|
||||||
err := r.DB.PublishRoom(ctx, req.RoomID, req.Visibility == "public")
|
err := r.DB.PublishRoom(ctx, req.RoomID, req.AppserviceID, req.NetworkID, req.Visibility == "public")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.Error = &api.PerformError{
|
res.Error = &api.PerformError{
|
||||||
Msg: err.Error(),
|
Msg: err.Error(),
|
||||||
|
|
|
@ -702,7 +702,7 @@ func (r *Queryer) QueryPublishedRooms(
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rooms, err := r.DB.GetPublishedRooms(ctx)
|
rooms, err := r.DB.GetPublishedRooms(ctx, req.NetworkID, req.IncludeAllNetworks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,9 +139,9 @@ type Database interface {
|
||||||
// Returns an error if the retrieval went wrong.
|
// Returns an error if the retrieval went wrong.
|
||||||
EventsFromIDs(ctx context.Context, eventIDs []string) ([]types.Event, error)
|
EventsFromIDs(ctx context.Context, eventIDs []string) ([]types.Event, error)
|
||||||
// Publish or unpublish a room from the room directory.
|
// Publish or unpublish a room from the room directory.
|
||||||
PublishRoom(ctx context.Context, roomID string, publish bool) error
|
PublishRoom(ctx context.Context, roomID, appserviceID, networkID string, publish bool) error
|
||||||
// Returns a list of room IDs for rooms which are published.
|
// Returns a list of room IDs for rooms which are published.
|
||||||
GetPublishedRooms(ctx context.Context) ([]string, error)
|
GetPublishedRooms(ctx context.Context, networkID string, includeAllNetworks bool) ([]string, error)
|
||||||
// Returns whether a given room is published or not.
|
// Returns whether a given room is published or not.
|
||||||
GetPublishedRoom(ctx context.Context, roomID string) (bool, error)
|
GetPublishedRoom(ctx context.Context, roomID string) (bool, error)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
// 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 deltas
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UpPulishedAppservice(ctx context.Context, tx *sql.Tx) error {
|
||||||
|
_, err := tx.ExecContext(ctx, `ALTER TABLE roomserver_published ADD COLUMN IF NOT EXISTS appservice_id TEXT NOT NULL;`)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute upgrade: %w", err)
|
||||||
|
}
|
||||||
|
_, err = tx.ExecContext(ctx, `ALTER TABLE roomserver_published ADD COLUMN IF NOT EXISTS network_id TEXT NOT NULL;`)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute upgrade: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DownPublishedAppservice(ctx context.Context, tx *sql.Tx) error {
|
||||||
|
_, err := tx.ExecContext(ctx, `ALTER TABLE roomserver_published DROP COLUMN IF EXISTS appservice_id;`)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute downgrade: %w", err)
|
||||||
|
}
|
||||||
|
_, err = tx.ExecContext(ctx, `ALTER TABLE roomserver_published DROP COLUMN IF EXISTS network_id;`)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute downgrade: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
"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/roomserver/storage/postgres/deltas"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -27,31 +28,48 @@ const publishedSchema = `
|
||||||
-- Stores which rooms are published in the room directory
|
-- Stores which rooms are published in the room directory
|
||||||
CREATE TABLE IF NOT EXISTS roomserver_published (
|
CREATE TABLE IF NOT EXISTS roomserver_published (
|
||||||
-- The room ID of the room
|
-- The room ID of the room
|
||||||
room_id TEXT NOT NULL PRIMARY KEY,
|
room_id TEXT NOT NULL,
|
||||||
|
-- The appservice ID of the room
|
||||||
|
appservice_id TEXT NOT NULL,
|
||||||
|
-- The network_id of the room
|
||||||
|
network_id TEXT NOT NULL,
|
||||||
-- Whether it is published or not
|
-- Whether it is published or not
|
||||||
published BOOLEAN NOT NULL DEFAULT false
|
published BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
PRIMARY KEY (room_id, appservice_id, network_id)
|
||||||
);
|
);
|
||||||
`
|
`
|
||||||
|
|
||||||
const upsertPublishedSQL = "" +
|
const upsertPublishedSQL = "" +
|
||||||
"INSERT INTO roomserver_published (room_id, published) VALUES ($1, $2) " +
|
"INSERT INTO roomserver_published (room_id, appservice_id, network_id, published) VALUES ($1, $2, $3, $4) " +
|
||||||
"ON CONFLICT (room_id) DO UPDATE SET published=$2"
|
"ON CONFLICT (room_id, appservice_id, network_id) DO UPDATE SET published=$4"
|
||||||
|
|
||||||
const selectAllPublishedSQL = "" +
|
const selectAllPublishedSQL = "" +
|
||||||
"SELECT room_id FROM roomserver_published WHERE published = $1 ORDER BY room_id ASC"
|
"SELECT room_id FROM roomserver_published WHERE published = $1 AND CASE WHEN $2 THEN 1=1 ELSE network_id = '' END ORDER BY room_id ASC"
|
||||||
|
|
||||||
|
const selectNetworkPublishedSQL = "" +
|
||||||
|
"SELECT room_id FROM roomserver_published WHERE published = $1 AND network_id = $2 ORDER BY room_id ASC"
|
||||||
|
|
||||||
const selectPublishedSQL = "" +
|
const selectPublishedSQL = "" +
|
||||||
"SELECT published FROM roomserver_published WHERE room_id = $1"
|
"SELECT published FROM roomserver_published WHERE room_id = $1"
|
||||||
|
|
||||||
type publishedStatements struct {
|
type publishedStatements struct {
|
||||||
upsertPublishedStmt *sql.Stmt
|
upsertPublishedStmt *sql.Stmt
|
||||||
selectAllPublishedStmt *sql.Stmt
|
selectAllPublishedStmt *sql.Stmt
|
||||||
selectPublishedStmt *sql.Stmt
|
selectPublishedStmt *sql.Stmt
|
||||||
|
selectNetworkPublishedStmt *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePublishedTable(db *sql.DB) error {
|
func CreatePublishedTable(db *sql.DB) error {
|
||||||
_, err := db.Exec(publishedSchema)
|
_, err := db.Exec(publishedSchema)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m := sqlutil.NewMigrator(db)
|
||||||
|
m.AddMigrations(sqlutil.Migration{
|
||||||
|
Version: "roomserver: published appservice",
|
||||||
|
Up: deltas.UpPulishedAppservice,
|
||||||
|
})
|
||||||
|
return m.Up(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
func PreparePublishedTable(db *sql.DB) (tables.Published, error) {
|
func PreparePublishedTable(db *sql.DB) (tables.Published, error) {
|
||||||
|
@ -61,14 +79,15 @@ func PreparePublishedTable(db *sql.DB) (tables.Published, error) {
|
||||||
{&s.upsertPublishedStmt, upsertPublishedSQL},
|
{&s.upsertPublishedStmt, upsertPublishedSQL},
|
||||||
{&s.selectAllPublishedStmt, selectAllPublishedSQL},
|
{&s.selectAllPublishedStmt, selectAllPublishedSQL},
|
||||||
{&s.selectPublishedStmt, selectPublishedSQL},
|
{&s.selectPublishedStmt, selectPublishedSQL},
|
||||||
|
{&s.selectNetworkPublishedStmt, selectNetworkPublishedSQL},
|
||||||
}.Prepare(db)
|
}.Prepare(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *publishedStatements) UpsertRoomPublished(
|
func (s *publishedStatements) UpsertRoomPublished(
|
||||||
ctx context.Context, txn *sql.Tx, roomID string, published bool,
|
ctx context.Context, txn *sql.Tx, roomID, appserviceID, networkID string, published bool,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
stmt := sqlutil.TxStmt(txn, s.upsertPublishedStmt)
|
stmt := sqlutil.TxStmt(txn, s.upsertPublishedStmt)
|
||||||
_, err = stmt.ExecContext(ctx, roomID, published)
|
_, err = stmt.ExecContext(ctx, roomID, appserviceID, networkID, published)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,10 +103,18 @@ func (s *publishedStatements) SelectPublishedFromRoomID(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *publishedStatements) SelectAllPublishedRooms(
|
func (s *publishedStatements) SelectAllPublishedRooms(
|
||||||
ctx context.Context, txn *sql.Tx, published bool,
|
ctx context.Context, txn *sql.Tx, networkID string, published, includeAllNetworks bool,
|
||||||
) ([]string, error) {
|
) ([]string, error) {
|
||||||
stmt := sqlutil.TxStmt(txn, s.selectAllPublishedStmt)
|
var rows *sql.Rows
|
||||||
rows, err := stmt.QueryContext(ctx, published)
|
var err error
|
||||||
|
if networkID != "" {
|
||||||
|
stmt := sqlutil.TxStmt(txn, s.selectNetworkPublishedStmt)
|
||||||
|
rows, err = stmt.QueryContext(ctx, published, networkID)
|
||||||
|
} else {
|
||||||
|
stmt := sqlutil.TxStmt(txn, s.selectAllPublishedStmt)
|
||||||
|
rows, err = stmt.QueryContext(ctx, published, includeAllNetworks)
|
||||||
|
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -722,9 +722,9 @@ func (d *Database) storeEvent(
|
||||||
}, redactionEvent, redactedEventID, err
|
}, redactionEvent, redactedEventID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) PublishRoom(ctx context.Context, roomID string, publish bool) error {
|
func (d *Database) PublishRoom(ctx context.Context, roomID, appserviceID, networkID string, publish bool) error {
|
||||||
return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
return d.Writer.Do(d.DB, nil, func(txn *sql.Tx) error {
|
||||||
return d.PublishedTable.UpsertRoomPublished(ctx, txn, roomID, publish)
|
return d.PublishedTable.UpsertRoomPublished(ctx, txn, roomID, appserviceID, networkID, publish)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,8 +732,8 @@ func (d *Database) GetPublishedRoom(ctx context.Context, roomID string) (bool, e
|
||||||
return d.PublishedTable.SelectPublishedFromRoomID(ctx, nil, roomID)
|
return d.PublishedTable.SelectPublishedFromRoomID(ctx, nil, roomID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) GetPublishedRooms(ctx context.Context) ([]string, error) {
|
func (d *Database) GetPublishedRooms(ctx context.Context, networkID string, includeAllNetworks bool) ([]string, error) {
|
||||||
return d.PublishedTable.SelectAllPublishedRooms(ctx, nil, true)
|
return d.PublishedTable.SelectAllPublishedRooms(ctx, nil, networkID, true, includeAllNetworks)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Database) MissingAuthPrevEvents(
|
func (d *Database) MissingAuthPrevEvents(
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
// 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 deltas
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func UpPulishedAppservice(ctx context.Context, tx *sql.Tx) error {
|
||||||
|
_, err := tx.ExecContext(ctx, ` ALTER TABLE roomserver_published RENAME TO roomserver_published_tmp;
|
||||||
|
CREATE TABLE IF NOT EXISTS roomserver_published (
|
||||||
|
room_id TEXT NOT NULL,
|
||||||
|
appservice_id TEXT NOT NULL,
|
||||||
|
network_id TEXT NOT NULL,
|
||||||
|
published BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
CONSTRAINT unique_published_idx PRIMARY KEY (room_id, appservice_id, network_id)
|
||||||
|
);
|
||||||
|
INSERT
|
||||||
|
INTO roomserver_published (
|
||||||
|
room_id, published
|
||||||
|
) SELECT
|
||||||
|
room_id, published
|
||||||
|
FROM roomserver_published_tmp
|
||||||
|
;
|
||||||
|
DROP TABLE roomserver_published_tmp;`)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute upgrade: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DownPublishedAppservice(ctx context.Context, tx *sql.Tx) error {
|
||||||
|
_, err := tx.ExecContext(ctx, ` ALTER TABLE roomserver_published RENAME TO roomserver_published_tmp;
|
||||||
|
CREATE TABLE IF NOT EXISTS roomserver_published (
|
||||||
|
room_id TEXT NOT NULL PRIMARY KEY,
|
||||||
|
published BOOLEAN NOT NULL DEFAULT false
|
||||||
|
);
|
||||||
|
INSERT
|
||||||
|
INTO roomserver_published (
|
||||||
|
room_id, published
|
||||||
|
) SELECT
|
||||||
|
room_id, published
|
||||||
|
FROM roomserver_published_tmp
|
||||||
|
;
|
||||||
|
DROP TABLE roomserver_published_tmp;`)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to execute upgrade: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
"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/roomserver/storage/sqlite3/deltas"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -27,31 +28,49 @@ const publishedSchema = `
|
||||||
-- Stores which rooms are published in the room directory
|
-- Stores which rooms are published in the room directory
|
||||||
CREATE TABLE IF NOT EXISTS roomserver_published (
|
CREATE TABLE IF NOT EXISTS roomserver_published (
|
||||||
-- The room ID of the room
|
-- The room ID of the room
|
||||||
room_id TEXT NOT NULL PRIMARY KEY,
|
room_id TEXT NOT NULL,
|
||||||
|
-- The appservice ID of the room
|
||||||
|
appservice_id TEXT NOT NULL,
|
||||||
|
-- The network_id of the room
|
||||||
|
network_id TEXT NOT NULL,
|
||||||
-- Whether it is published or not
|
-- Whether it is published or not
|
||||||
published BOOLEAN NOT NULL DEFAULT false
|
published BOOLEAN NOT NULL DEFAULT false,
|
||||||
|
PRIMARY KEY (room_id, appservice_id, network_id)
|
||||||
);
|
);
|
||||||
`
|
`
|
||||||
|
|
||||||
const upsertPublishedSQL = "" +
|
const upsertPublishedSQL = "" +
|
||||||
"INSERT OR REPLACE INTO roomserver_published (room_id, published) VALUES ($1, $2)"
|
"INSERT INTO roomserver_published (room_id, appservice_id, network_id, published) VALUES ($1, $2, $3, $4)" +
|
||||||
|
" ON CONFLICT (room_id, appservice_id, network_id) DO UPDATE SET published = $4"
|
||||||
|
|
||||||
const selectAllPublishedSQL = "" +
|
const selectAllPublishedSQL = "" +
|
||||||
"SELECT room_id FROM roomserver_published WHERE published = $1 ORDER BY room_id ASC"
|
"SELECT room_id FROM roomserver_published WHERE published = $1 AND CASE WHEN $2 THEN 1=1 ELSE network_id = '' END ORDER BY room_id ASC"
|
||||||
|
|
||||||
|
const selectNetworkPublishedSQL = "" +
|
||||||
|
"SELECT room_id FROM roomserver_published WHERE published = $1 AND network_id = $2 ORDER BY room_id ASC"
|
||||||
|
|
||||||
const selectPublishedSQL = "" +
|
const selectPublishedSQL = "" +
|
||||||
"SELECT published FROM roomserver_published WHERE room_id = $1"
|
"SELECT published FROM roomserver_published WHERE room_id = $1"
|
||||||
|
|
||||||
type publishedStatements struct {
|
type publishedStatements struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
upsertPublishedStmt *sql.Stmt
|
upsertPublishedStmt *sql.Stmt
|
||||||
selectAllPublishedStmt *sql.Stmt
|
selectAllPublishedStmt *sql.Stmt
|
||||||
selectPublishedStmt *sql.Stmt
|
selectPublishedStmt *sql.Stmt
|
||||||
|
selectNetworkPublishedStmt *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePublishedTable(db *sql.DB) error {
|
func CreatePublishedTable(db *sql.DB) error {
|
||||||
_, err := db.Exec(publishedSchema)
|
_, err := db.Exec(publishedSchema)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m := sqlutil.NewMigrator(db)
|
||||||
|
m.AddMigrations(sqlutil.Migration{
|
||||||
|
Version: "roomserver: published appservice",
|
||||||
|
Up: deltas.UpPulishedAppservice,
|
||||||
|
})
|
||||||
|
return m.Up(context.Background())
|
||||||
}
|
}
|
||||||
|
|
||||||
func PreparePublishedTable(db *sql.DB) (tables.Published, error) {
|
func PreparePublishedTable(db *sql.DB) (tables.Published, error) {
|
||||||
|
@ -63,14 +82,15 @@ func PreparePublishedTable(db *sql.DB) (tables.Published, error) {
|
||||||
{&s.upsertPublishedStmt, upsertPublishedSQL},
|
{&s.upsertPublishedStmt, upsertPublishedSQL},
|
||||||
{&s.selectAllPublishedStmt, selectAllPublishedSQL},
|
{&s.selectAllPublishedStmt, selectAllPublishedSQL},
|
||||||
{&s.selectPublishedStmt, selectPublishedSQL},
|
{&s.selectPublishedStmt, selectPublishedSQL},
|
||||||
|
{&s.selectNetworkPublishedStmt, selectNetworkPublishedSQL},
|
||||||
}.Prepare(db)
|
}.Prepare(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *publishedStatements) UpsertRoomPublished(
|
func (s *publishedStatements) UpsertRoomPublished(
|
||||||
ctx context.Context, txn *sql.Tx, roomID string, published bool,
|
ctx context.Context, txn *sql.Tx, roomID, appserviceID, networkID string, published bool,
|
||||||
) error {
|
) error {
|
||||||
stmt := sqlutil.TxStmt(txn, s.upsertPublishedStmt)
|
stmt := sqlutil.TxStmt(txn, s.upsertPublishedStmt)
|
||||||
_, err := stmt.ExecContext(ctx, roomID, published)
|
_, err := stmt.ExecContext(ctx, roomID, appserviceID, networkID, published)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,10 +106,17 @@ func (s *publishedStatements) SelectPublishedFromRoomID(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *publishedStatements) SelectAllPublishedRooms(
|
func (s *publishedStatements) SelectAllPublishedRooms(
|
||||||
ctx context.Context, txn *sql.Tx, published bool,
|
ctx context.Context, txn *sql.Tx, networkID string, published, includeAllNetworks bool,
|
||||||
) ([]string, error) {
|
) ([]string, error) {
|
||||||
stmt := sqlutil.TxStmt(txn, s.selectAllPublishedStmt)
|
var rows *sql.Rows
|
||||||
rows, err := stmt.QueryContext(ctx, published)
|
var err error
|
||||||
|
if networkID != "" {
|
||||||
|
stmt := sqlutil.TxStmt(txn, s.selectNetworkPublishedStmt)
|
||||||
|
rows, err = stmt.QueryContext(ctx, published, networkID)
|
||||||
|
} else {
|
||||||
|
stmt := sqlutil.TxStmt(txn, s.selectAllPublishedStmt)
|
||||||
|
rows, err = stmt.QueryContext(ctx, published, includeAllNetworks)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,9 +146,9 @@ type Membership interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Published interface {
|
type Published interface {
|
||||||
UpsertRoomPublished(ctx context.Context, txn *sql.Tx, roomID string, published bool) (err error)
|
UpsertRoomPublished(ctx context.Context, txn *sql.Tx, roomID, appserviceID, networkID string, published bool) (err error)
|
||||||
SelectPublishedFromRoomID(ctx context.Context, txn *sql.Tx, roomID string) (published bool, err error)
|
SelectPublishedFromRoomID(ctx context.Context, txn *sql.Tx, roomID string) (published bool, err error)
|
||||||
SelectAllPublishedRooms(ctx context.Context, txn *sql.Tx, published bool) ([]string, error)
|
SelectAllPublishedRooms(ctx context.Context, txn *sql.Tx, networkdID string, published, includeAllNetworks bool) ([]string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RedactionInfo struct {
|
type RedactionInfo struct {
|
||||||
|
|
|
@ -2,16 +2,18 @@ package tables_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/internal/sqlutil"
|
"github.com/matrix-org/dendrite/internal/sqlutil"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage/postgres"
|
"github.com/matrix-org/dendrite/roomserver/storage/postgres"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage/sqlite3"
|
"github.com/matrix-org/dendrite/roomserver/storage/sqlite3"
|
||||||
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
"github.com/matrix-org/dendrite/roomserver/storage/tables"
|
||||||
"github.com/matrix-org/dendrite/setup/config"
|
"github.com/matrix-org/dendrite/setup/config"
|
||||||
"github.com/matrix-org/dendrite/test"
|
"github.com/matrix-org/dendrite/test"
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustCreatePublishedTable(t *testing.T, dbType test.DBType) (tab tables.Published, close func()) {
|
func mustCreatePublishedTable(t *testing.T, dbType test.DBType) (tab tables.Published, close func()) {
|
||||||
|
@ -46,10 +48,12 @@ func TestPublishedTable(t *testing.T) {
|
||||||
|
|
||||||
// Publish some rooms
|
// Publish some rooms
|
||||||
publishedRooms := []string{}
|
publishedRooms := []string{}
|
||||||
|
asID := ""
|
||||||
|
nwID := ""
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
room := test.NewRoom(t, alice)
|
room := test.NewRoom(t, alice)
|
||||||
published := i%2 == 0
|
published := i%2 == 0
|
||||||
err := tab.UpsertRoomPublished(ctx, nil, room.ID, published)
|
err := tab.UpsertRoomPublished(ctx, nil, room.ID, asID, nwID, published)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
if published {
|
if published {
|
||||||
publishedRooms = append(publishedRooms, room.ID)
|
publishedRooms = append(publishedRooms, room.ID)
|
||||||
|
@ -61,19 +65,36 @@ func TestPublishedTable(t *testing.T) {
|
||||||
sort.Strings(publishedRooms)
|
sort.Strings(publishedRooms)
|
||||||
|
|
||||||
// check that we get the expected published rooms
|
// check that we get the expected published rooms
|
||||||
roomIDs, err := tab.SelectAllPublishedRooms(ctx, nil, true)
|
roomIDs, err := tab.SelectAllPublishedRooms(ctx, nil, "", true, true)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, publishedRooms, roomIDs)
|
assert.Equal(t, publishedRooms, roomIDs)
|
||||||
|
|
||||||
// test an actual upsert
|
// test an actual upsert
|
||||||
room := test.NewRoom(t, alice)
|
room := test.NewRoom(t, alice)
|
||||||
err = tab.UpsertRoomPublished(ctx, nil, room.ID, true)
|
err = tab.UpsertRoomPublished(ctx, nil, room.ID, asID, nwID, true)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
err = tab.UpsertRoomPublished(ctx, nil, room.ID, false)
|
err = tab.UpsertRoomPublished(ctx, nil, room.ID, asID, nwID, false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// should now be false, due to the upsert
|
// should now be false, due to the upsert
|
||||||
publishedRes, err := tab.SelectPublishedFromRoomID(ctx, nil, room.ID)
|
publishedRes, err := tab.SelectPublishedFromRoomID(ctx, nil, room.ID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.False(t, publishedRes)
|
assert.False(t, publishedRes, fmt.Sprintf("expected room %s to be unpublished", room.ID))
|
||||||
|
|
||||||
|
// network specific test
|
||||||
|
nwID = "irc"
|
||||||
|
room = test.NewRoom(t, alice)
|
||||||
|
err = tab.UpsertRoomPublished(ctx, nil, room.ID, asID, nwID, true)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
publishedRooms = append(publishedRooms, room.ID)
|
||||||
|
sort.Strings(publishedRooms)
|
||||||
|
// should only return the room for network "irc"
|
||||||
|
allNWPublished, err := tab.SelectAllPublishedRooms(ctx, nil, nwID, true, true)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, []string{room.ID}, allNWPublished)
|
||||||
|
|
||||||
|
// check that we still get all published rooms regardless networkID
|
||||||
|
roomIDs, err = tab.SelectAllPublishedRooms(ctx, nil, "", true, true)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, publishedRooms, roomIDs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -758,3 +758,5 @@ Local device key changes appear in /keys/changes
|
||||||
Can get rooms/{roomId}/members at a given point
|
Can get rooms/{roomId}/members at a given point
|
||||||
Can filter rooms/{roomId}/members
|
Can filter rooms/{roomId}/members
|
||||||
Current state appears in timeline in private history with many messages after
|
Current state appears in timeline in private history with many messages after
|
||||||
|
AS can publish rooms in their own list
|
||||||
|
AS and main public room lists are separate
|
Loading…
Reference in a new issue