aboutsummaryrefslogtreecommitdiff
path: root/clientapi
diff options
context:
space:
mode:
authorTill <2353100+S7evinK@users.noreply.github.com>2022-10-27 14:40:35 +0200
committerGitHub <noreply@github.com>2022-10-27 14:40:35 +0200
commit444b4bbdb8ce6f26651c4516cb23828a65bdd065 (patch)
tree199b5d262c965acf1d885bafaa59549b3eafe0c2 /clientapi
parenta169a9121aa6b2ff3e3fba6ec9777227e349300f (diff)
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.
Diffstat (limited to 'clientapi')
-rw-r--r--clientapi/routing/directory.go45
-rw-r--r--clientapi/routing/directory_public.go40
-rw-r--r--clientapi/routing/directory_public_test.go2
-rw-r--r--clientapi/routing/routing.go23
4 files changed, 96 insertions, 14 deletions
diff --git a/clientapi/routing/directory.go b/clientapi/routing/directory.go
index 33bc63d1..ce14745a 100644
--- a/clientapi/routing/directory.go
+++ b/clientapi/routing/directory.go
@@ -18,14 +18,15 @@ import (
"fmt"
"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/jsonerror"
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
roomserverAPI "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/util"
)
type roomDirectoryResponse struct {
@@ -318,3 +319,43 @@ func SetVisibility(
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{}{},
+ }
+}
diff --git a/clientapi/routing/directory_public.go b/clientapi/routing/directory_public.go
index 4ebf2295..b1043e99 100644
--- a/clientapi/routing/directory_public.go
+++ b/clientapi/routing/directory_public.go
@@ -39,14 +39,17 @@ var (
)
type PublicRoomReq struct {
- Since string `json:"since,omitempty"`
- Limit int16 `json:"limit,omitempty"`
- Filter filter `json:"filter,omitempty"`
- Server string `json:"server,omitempty"`
+ Since string `json:"since,omitempty"`
+ Limit int64 `json:"limit,omitempty"`
+ Filter filter `json:"filter,omitempty"`
+ Server string `json:"server,omitempty"`
+ IncludeAllNetworks bool `json:"include_all_networks,omitempty"`
+ NetworkID string `json:"third_party_instance_id,omitempty"`
}
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
@@ -61,6 +64,13 @@ func GetPostPublicRooms(
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)
if serverName != "" && !cfg.Matrix.IsLocalServerName(serverName) {
res, err := federation.GetPublicRoomsFiltered(
@@ -97,7 +107,7 @@ func publicRooms(
response := gomatrixserverlib.RespPublicRooms{
Chunk: []gomatrixserverlib.PublicRoom{},
}
- var limit int16
+ var limit int64
var offset int64
limit = request.Limit
if limit == 0 {
@@ -114,7 +124,7 @@ func publicRooms(
var rooms []gomatrixserverlib.PublicRoom
if request.Since == "" {
- rooms = refreshPublicRoomCache(ctx, rsAPI, extRoomsProvider)
+ rooms = refreshPublicRoomCache(ctx, rsAPI, extRoomsProvider, request)
} else {
rooms = getPublicRoomsFromCache()
}
@@ -176,7 +186,7 @@ func fillPublicRoomsReq(httpReq *http.Request, request *PublicRoomReq) *util.JSO
JSON: jsonerror.BadJSON("limit param is not a number"),
}
}
- request.Limit = int16(limit)
+ request.Limit = int64(limit)
request.Since = httpReq.FormValue("since")
request.Server = httpReq.FormValue("server")
} else {
@@ -204,7 +214,7 @@ func fillPublicRoomsReq(httpReq *http.Request, request *PublicRoomReq) *util.JSO
// limit=3&since=6 => G (prev='3', next='')
//
// 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
next = -1
@@ -230,6 +240,7 @@ func sliceInto(slice []gomatrixserverlib.PublicRoom, since int64, limit int16) (
func refreshPublicRoomCache(
ctx context.Context, rsAPI roomserverAPI.ClientRoomserverAPI, extRoomsProvider api.ExtraPublicRoomsProvider,
+ request PublicRoomReq,
) []gomatrixserverlib.PublicRoom {
cacheMu.Lock()
defer cacheMu.Unlock()
@@ -238,8 +249,17 @@ func refreshPublicRoomCache(
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
- err := rsAPI.QueryPublishedRooms(ctx, &roomserverAPI.QueryPublishedRoomsRequest{}, &queryRes)
+ err := rsAPI.QueryPublishedRooms(ctx, &roomserverAPI.QueryPublishedRoomsRequest{
+ NetworkID: request.NetworkID,
+ IncludeAllNetworks: request.IncludeAllNetworks,
+ }, &queryRes)
if err != nil {
util.GetLogger(ctx).WithError(err).Error("QueryPublishedRooms failed")
return publicRoomsCache
diff --git a/clientapi/routing/directory_public_test.go b/clientapi/routing/directory_public_test.go
index bb3912b8..65ad392c 100644
--- a/clientapi/routing/directory_public_test.go
+++ b/clientapi/routing/directory_public_test.go
@@ -17,7 +17,7 @@ func TestSliceInto(t *testing.T) {
slice := []gomatrixserverlib.PublicRoom{
pubRoom("a"), pubRoom("b"), pubRoom("c"), pubRoom("d"), pubRoom("e"), pubRoom("f"), pubRoom("g"),
}
- limit := int16(3)
+ limit := int64(3)
testCases := []struct {
since int64
wantPrev int
diff --git a/clientapi/routing/routing.go b/clientapi/routing/routing.go
index e0e3e33d..22bc77a0 100644
--- a/clientapi/routing/routing.go
+++ b/clientapi/routing/routing.go
@@ -480,7 +480,7 @@ func Setup(
return GetVisibility(req, rsAPI, vars["roomID"])
}),
).Methods(http.MethodGet, http.MethodOptions)
- // TODO: Add AS support
+
v3mux.Handle("/directory/list/room/{roomID}",
httputil.MakeAuthAPI("directory_list", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
vars, err := httputil.URLDecodeMapValues(mux.Vars(req))
@@ -490,6 +490,27 @@ func Setup(
return SetVisibility(req, rsAPI, device, vars["roomID"])
}),
).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",
httputil.MakeExternalAPI("public_rooms", func(req *http.Request) util.JSONResponse {
return GetPostPublicRooms(req, rsAPI, extRoomsProvider, federation, cfg)