Implement GET /rooms/{roomAlias} (#494)
* Query whether a room alias exists on app services Signed-off-by: Andrew Morgan <andrewm@matrix.org> * URL encode room alias before sending to AS * Add /room/ to path * Query AS /alias/ API at a lower level * Don't verify self-signed AS certificates * Don't skip cert validation on appservices, fix logging * Separate req.WithContext * Linting * Do not warn when an AS room alias does not existmain
parent
e05a31f4c2
commit
609646c19b
|
@ -18,16 +18,41 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
commonHTTP "github.com/matrix-org/dendrite/common/http"
|
||||||
|
opentracing "github.com/opentracing/opentracing-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RoomAliasExistsRequest is a request to an application service
|
||||||
|
// about whether a room alias exists
|
||||||
|
type RoomAliasExistsRequest struct {
|
||||||
|
// Alias we want to lookup
|
||||||
|
Alias string `json:"alias"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoomAliasExistsResponse is a response from an application service
|
||||||
|
// about whether a room alias exists
|
||||||
|
type RoomAliasExistsResponse struct {
|
||||||
|
AliasExists bool `json:"exists"`
|
||||||
|
}
|
||||||
|
|
||||||
// AppServiceQueryAPI is used to query user and room alias data from application
|
// AppServiceQueryAPI is used to query user and room alias data from application
|
||||||
// services
|
// services
|
||||||
type AppServiceQueryAPI interface {
|
type AppServiceQueryAPI interface {
|
||||||
// TODO: Check whether a room alias exists within any application service namespaces
|
// Check whether a room alias exists within any application service namespaces
|
||||||
|
RoomAliasExists(
|
||||||
|
ctx context.Context,
|
||||||
|
req *RoomAliasExistsRequest,
|
||||||
|
response *RoomAliasExistsResponse,
|
||||||
|
) error
|
||||||
// TODO: QueryUserIDExists
|
// TODO: QueryUserIDExists
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppServiceRoomAliasExistsPath is the HTTP path for the RoomAliasExists API
|
||||||
|
const AppServiceRoomAliasExistsPath = "/api/appservice/RoomAliasExists"
|
||||||
|
|
||||||
// httpAppServiceQueryAPI contains the URL to an appservice query API and a
|
// httpAppServiceQueryAPI contains the URL to an appservice query API and a
|
||||||
// reference to a httpClient used to reach it
|
// reference to a httpClient used to reach it
|
||||||
type httpAppServiceQueryAPI struct {
|
type httpAppServiceQueryAPI struct {
|
||||||
|
@ -47,3 +72,16 @@ func NewAppServiceQueryAPIHTTP(
|
||||||
}
|
}
|
||||||
return &httpAppServiceQueryAPI{appserviceURL, httpClient}
|
return &httpAppServiceQueryAPI{appserviceURL, httpClient}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RoomAliasExists implements AppServiceQueryAPI
|
||||||
|
func (h *httpAppServiceQueryAPI) RoomAliasExists(
|
||||||
|
ctx context.Context,
|
||||||
|
request *RoomAliasExistsRequest,
|
||||||
|
response *RoomAliasExistsResponse,
|
||||||
|
) error {
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "appserviceRoomAliasExists")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
apiURL := h.appserviceURL + AppServiceRoomAliasExistsPath
|
||||||
|
return commonHTTP.PostJSON(ctx, span, h.httpClient, apiURL, request, response)
|
||||||
|
}
|
||||||
|
|
|
@ -74,14 +74,12 @@ func SetupAppServiceAPIComponent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a HTTP client that this component will use for all outbound and
|
// Create appserivce query API with an HTTP client that will be used for all
|
||||||
// inbound requests (inbound only for the internal API)
|
// outbound and inbound requests (inbound only for the internal API)
|
||||||
httpClient := &http.Client{
|
|
||||||
Timeout: time.Second * 30,
|
|
||||||
}
|
|
||||||
|
|
||||||
appserviceQueryAPI := query.AppServiceQueryAPI{
|
appserviceQueryAPI := query.AppServiceQueryAPI{
|
||||||
HTTPClient: httpClient,
|
HTTPClient: &http.Client{
|
||||||
|
Timeout: time.Second * 30,
|
||||||
|
},
|
||||||
Cfg: base.Cfg,
|
Cfg: base.Cfg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,7 @@ func (s *OutputRoomEventConsumer) appserviceIsInterestedInEvent(ctx context.Cont
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check Room ID and Sender of the event
|
||||||
if appservice.IsInterestedInUserID(event.Sender()) ||
|
if appservice.IsInterestedInUserID(event.Sender()) ||
|
||||||
appservice.IsInterestedInRoomID(event.RoomID()) {
|
appservice.IsInterestedInRoomID(event.RoomID()) {
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -17,18 +17,118 @@
|
||||||
package query
|
package query
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/appservice/api"
|
||||||
|
"github.com/matrix-org/dendrite/common"
|
||||||
"github.com/matrix-org/dendrite/common/config"
|
"github.com/matrix-org/dendrite/common/config"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
opentracing "github.com/opentracing/opentracing-go"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const roomAliasExistsPath = "/rooms/"
|
||||||
|
|
||||||
// AppServiceQueryAPI is an implementation of api.AppServiceQueryAPI
|
// AppServiceQueryAPI is an implementation of api.AppServiceQueryAPI
|
||||||
type AppServiceQueryAPI struct {
|
type AppServiceQueryAPI struct {
|
||||||
HTTPClient *http.Client
|
HTTPClient *http.Client
|
||||||
Cfg *config.Dendrite
|
Cfg *config.Dendrite
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RoomAliasExists performs a request to '/room/{roomAlias}' on all known
|
||||||
|
// handling application services until one admits to owning the room
|
||||||
|
func (a *AppServiceQueryAPI) RoomAliasExists(
|
||||||
|
ctx context.Context,
|
||||||
|
request *api.RoomAliasExistsRequest,
|
||||||
|
response *api.RoomAliasExistsResponse,
|
||||||
|
) error {
|
||||||
|
span, ctx := opentracing.StartSpanFromContext(ctx, "ApplicationServiceRoomAlias")
|
||||||
|
defer span.Finish()
|
||||||
|
|
||||||
|
// Create an HTTP client if one does not already exist
|
||||||
|
if a.HTTPClient == nil {
|
||||||
|
a.HTTPClient = makeHTTPClient()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine which application service should handle this request
|
||||||
|
for _, appservice := range a.Cfg.Derived.ApplicationServices {
|
||||||
|
if appservice.URL != "" && appservice.IsInterestedInRoomAlias(request.Alias) {
|
||||||
|
// The full path to the rooms API, includes hs token
|
||||||
|
URL, err := url.Parse(appservice.URL + roomAliasExistsPath)
|
||||||
|
URL.Path += request.Alias
|
||||||
|
apiURL := URL.String() + "?access_token=" + appservice.HSToken
|
||||||
|
|
||||||
|
// Send a request to each application service. If one responds that it has
|
||||||
|
// created the room, immediately return.
|
||||||
|
req, err := http.NewRequest(http.MethodGet, apiURL, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
|
||||||
|
resp, err := a.HTTPClient.Do(req)
|
||||||
|
if resp != nil {
|
||||||
|
defer func() {
|
||||||
|
err = resp.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"appservice_id": appservice.ID,
|
||||||
|
"status_code": resp.StatusCode,
|
||||||
|
}).WithError(err).Error("Unable to close application service response body")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Errorf("Issue querying room alias on application service %s", appservice.ID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch resp.StatusCode {
|
||||||
|
case http.StatusOK:
|
||||||
|
// OK received from appservice. Room exists
|
||||||
|
response.AliasExists = true
|
||||||
|
return nil
|
||||||
|
case http.StatusNotFound:
|
||||||
|
// Room does not exist
|
||||||
|
default:
|
||||||
|
// Application service reported an error. Warn
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"appservice_id": appservice.ID,
|
||||||
|
"status_code": resp.StatusCode,
|
||||||
|
}).Warn("Application service responded with non-OK status code")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response.AliasExists = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeHTTPClient creates an HTTP client with certain options that will be used for all query requests to application services
|
||||||
|
func makeHTTPClient() *http.Client {
|
||||||
|
return &http.Client{
|
||||||
|
Timeout: time.Second * 30,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetupHTTP adds the AppServiceQueryPAI handlers to the http.ServeMux. This
|
// SetupHTTP adds the AppServiceQueryPAI handlers to the http.ServeMux. This
|
||||||
// handles and muxes incoming api requests the to internal AppServiceQueryAPI.
|
// handles and muxes incoming api requests the to internal AppServiceQueryAPI.
|
||||||
func (a *AppServiceQueryAPI) SetupHTTP(servMux *http.ServeMux) {
|
func (a *AppServiceQueryAPI) SetupHTTP(servMux *http.ServeMux) {
|
||||||
|
servMux.Handle(
|
||||||
|
api.AppServiceRoomAliasExistsPath,
|
||||||
|
common.MakeInternalAPI("appserviceRoomAliasExists", func(req *http.Request) util.JSONResponse {
|
||||||
|
var request api.RoomAliasExistsRequest
|
||||||
|
var response api.RoomAliasExistsResponse
|
||||||
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
if err := a.RoomAliasExists(req.Context(), &request, &response); err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
return util.JSONResponse{Code: http.StatusOK, JSON: &response}
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ package workers
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
@ -68,12 +67,6 @@ func worker(db *storage.Database, ws types.ApplicationServiceWorkerState) {
|
||||||
// Create a HTTP client for sending requests to app services
|
// Create a HTTP client for sending requests to app services
|
||||||
client := &http.Client{
|
client := &http.Client{
|
||||||
Timeout: transactionTimeout,
|
Timeout: transactionTimeout,
|
||||||
// TODO: Verify certificates
|
|
||||||
Transport: &http.Transport{
|
|
||||||
TLSClientConfig: &tls.Config{
|
|
||||||
InsecureSkipVerify: true, // nolint: gas
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initial check for any leftover events to send from last time
|
// Initial check for any leftover events to send from last time
|
||||||
|
|
|
@ -15,13 +15,14 @@
|
||||||
package routing
|
package routing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
||||||
"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"
|
||||||
"github.com/matrix-org/dendrite/common/config"
|
"github.com/matrix-org/dendrite/common/config"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/gomatrix"
|
"github.com/matrix-org/gomatrix"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
@ -33,7 +34,7 @@ func DirectoryRoom(
|
||||||
roomAlias string,
|
roomAlias string,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
cfg *config.Dendrite,
|
cfg *config.Dendrite,
|
||||||
aliasAPI api.RoomserverAliasAPI,
|
rsAPI roomserverAPI.RoomserverAliasAPI,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
_, domain, err := gomatrixserverlib.SplitID('#', roomAlias)
|
_, domain, err := gomatrixserverlib.SplitID('#', roomAlias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -43,51 +44,48 @@ func DirectoryRoom(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var resp gomatrixserverlib.RespDirectory
|
|
||||||
|
|
||||||
if domain == cfg.Matrix.ServerName {
|
if domain == cfg.Matrix.ServerName {
|
||||||
queryReq := api.GetRoomIDForAliasRequest{Alias: roomAlias}
|
// Query the roomserver API to check if the alias exists locally
|
||||||
var queryRes api.GetRoomIDForAliasResponse
|
queryReq := roomserverAPI.GetRoomIDForAliasRequest{Alias: roomAlias}
|
||||||
if err = aliasAPI.GetRoomIDForAlias(req.Context(), &queryReq, &queryRes); err != nil {
|
var queryRes roomserverAPI.GetRoomIDForAliasResponse
|
||||||
|
if err = rsAPI.GetRoomIDForAlias(req.Context(), &queryReq, &queryRes); err != nil {
|
||||||
return httputil.LogThenError(req, err)
|
return httputil.LogThenError(req, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// List any roomIDs found associated with this alias
|
||||||
if len(queryRes.RoomID) > 0 {
|
if len(queryRes.RoomID) > 0 {
|
||||||
// TODO: List servers that are aware of this room alias
|
|
||||||
resp = gomatrixserverlib.RespDirectory{
|
|
||||||
RoomID: queryRes.RoomID,
|
|
||||||
Servers: []gomatrixserverlib.ServerName{},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If the response doesn't contain a non-empty string, return an error
|
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusNotFound,
|
Code: http.StatusOK,
|
||||||
JSON: jsonerror.NotFound("Room alias " + roomAlias + " not found."),
|
JSON: queryRes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resp, err = federation.LookupRoomAlias(req.Context(), domain, roomAlias)
|
// Query the federation for this room alias
|
||||||
|
resp, err := federation.LookupRoomAlias(req.Context(), domain, roomAlias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch x := err.(type) {
|
switch err.(type) {
|
||||||
case gomatrix.HTTPError:
|
case gomatrix.HTTPError:
|
||||||
if x.Code == http.StatusNotFound {
|
default:
|
||||||
return util.JSONResponse{
|
|
||||||
Code: http.StatusNotFound,
|
|
||||||
JSON: jsonerror.NotFound("Room alias not found"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO: Return 502 if the remote server errored.
|
// TODO: Return 502 if the remote server errored.
|
||||||
// TODO: Return 504 if the remote server timed out.
|
// TODO: Return 504 if the remote server timed out.
|
||||||
return httputil.LogThenError(req, err)
|
return httputil.LogThenError(req, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if len(resp.RoomID) > 0 {
|
||||||
return util.JSONResponse{
|
return util.JSONResponse{
|
||||||
Code: http.StatusOK,
|
Code: http.StatusOK,
|
||||||
JSON: resp,
|
JSON: resp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusNotFound,
|
||||||
|
JSON: jsonerror.NotFound(
|
||||||
|
fmt.Sprintf("Room alias %s not found", roomAlias),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetLocalAlias implements PUT /directory/room/{roomAlias}
|
// SetLocalAlias implements PUT /directory/room/{roomAlias}
|
||||||
// TODO: Check if the user has the power level to set an alias
|
// TODO: Check if the user has the power level to set an alias
|
||||||
|
@ -96,7 +94,7 @@ func SetLocalAlias(
|
||||||
device *authtypes.Device,
|
device *authtypes.Device,
|
||||||
alias string,
|
alias string,
|
||||||
cfg *config.Dendrite,
|
cfg *config.Dendrite,
|
||||||
aliasAPI api.RoomserverAliasAPI,
|
aliasAPI roomserverAPI.RoomserverAliasAPI,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
_, domain, err := gomatrixserverlib.SplitID('#', alias)
|
_, domain, err := gomatrixserverlib.SplitID('#', alias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -138,12 +136,12 @@ func SetLocalAlias(
|
||||||
return *resErr
|
return *resErr
|
||||||
}
|
}
|
||||||
|
|
||||||
queryReq := api.SetRoomAliasRequest{
|
queryReq := roomserverAPI.SetRoomAliasRequest{
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
RoomID: r.RoomID,
|
RoomID: r.RoomID,
|
||||||
Alias: alias,
|
Alias: alias,
|
||||||
}
|
}
|
||||||
var queryRes api.SetRoomAliasResponse
|
var queryRes roomserverAPI.SetRoomAliasResponse
|
||||||
if err := aliasAPI.SetRoomAlias(req.Context(), &queryReq, &queryRes); err != nil {
|
if err := aliasAPI.SetRoomAlias(req.Context(), &queryReq, &queryRes); err != nil {
|
||||||
return httputil.LogThenError(req, err)
|
return httputil.LogThenError(req, err)
|
||||||
}
|
}
|
||||||
|
@ -167,13 +165,13 @@ func RemoveLocalAlias(
|
||||||
req *http.Request,
|
req *http.Request,
|
||||||
device *authtypes.Device,
|
device *authtypes.Device,
|
||||||
alias string,
|
alias string,
|
||||||
aliasAPI api.RoomserverAliasAPI,
|
aliasAPI roomserverAPI.RoomserverAliasAPI,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
queryReq := api.RemoveRoomAliasRequest{
|
queryReq := roomserverAPI.RemoveRoomAliasRequest{
|
||||||
Alias: alias,
|
Alias: alias,
|
||||||
UserID: device.UserID,
|
UserID: device.UserID,
|
||||||
}
|
}
|
||||||
var queryRes api.RemoveRoomAliasResponse
|
var queryRes roomserverAPI.RemoveRoomAliasResponse
|
||||||
if err := aliasAPI.RemoveRoomAlias(req.Context(), &queryReq, &queryRes); err != nil {
|
if err := aliasAPI.RemoveRoomAlias(req.Context(), &queryReq, &queryRes); err != nil {
|
||||||
return httputil.LogThenError(req, err)
|
return httputil.LogThenError(req, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/common"
|
"github.com/matrix-org/dendrite/common"
|
||||||
"github.com/matrix-org/dendrite/common/config"
|
"github.com/matrix-org/dendrite/common/config"
|
||||||
"github.com/matrix-org/dendrite/common/transactions"
|
"github.com/matrix-org/dendrite/common/transactions"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
@ -42,8 +42,9 @@ const pathPrefixUnstable = "/_matrix/client/unstable"
|
||||||
// to clients which need to make outbound HTTP requests.
|
// to clients which need to make outbound HTTP requests.
|
||||||
func Setup(
|
func Setup(
|
||||||
apiMux *mux.Router, cfg config.Dendrite,
|
apiMux *mux.Router, cfg config.Dendrite,
|
||||||
producer *producers.RoomserverProducer, queryAPI api.RoomserverQueryAPI,
|
producer *producers.RoomserverProducer,
|
||||||
aliasAPI api.RoomserverAliasAPI,
|
queryAPI roomserverAPI.RoomserverQueryAPI,
|
||||||
|
aliasAPI roomserverAPI.RoomserverAliasAPI,
|
||||||
accountDB *accounts.Database,
|
accountDB *accounts.Database,
|
||||||
deviceDB *devices.Database,
|
deviceDB *devices.Database,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
|
@ -142,7 +143,7 @@ func Setup(
|
||||||
})).Methods(http.MethodGet, http.MethodOptions)
|
})).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
|
||||||
r0mux.Handle("/directory/room/{roomAlias}",
|
r0mux.Handle("/directory/room/{roomAlias}",
|
||||||
common.MakeAuthAPI("directory_room", authData, func(req *http.Request, device *authtypes.Device) util.JSONResponse {
|
common.MakeExternalAPI("directory_room", func(req *http.Request) util.JSONResponse {
|
||||||
vars := mux.Vars(req)
|
vars := mux.Vars(req)
|
||||||
return DirectoryRoom(req, vars["roomAlias"], federation, &cfg, aliasAPI)
|
return DirectoryRoom(req, vars["roomAlias"], federation, &cfg, aliasAPI)
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -19,6 +19,8 @@ import (
|
||||||
"github.com/matrix-org/dendrite/common/basecomponent"
|
"github.com/matrix-org/dendrite/common/basecomponent"
|
||||||
"github.com/matrix-org/dendrite/common/keydb"
|
"github.com/matrix-org/dendrite/common/keydb"
|
||||||
"github.com/matrix-org/dendrite/common/transactions"
|
"github.com/matrix-org/dendrite/common/transactions"
|
||||||
|
"github.com/matrix-org/dendrite/typingserver"
|
||||||
|
"github.com/matrix-org/dendrite/typingserver/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -34,12 +36,11 @@ func main() {
|
||||||
keyRing := keydb.CreateKeyRing(federation.Client, keyDB)
|
keyRing := keydb.CreateKeyRing(federation.Client, keyDB)
|
||||||
|
|
||||||
alias, input, query := base.CreateHTTPRoomserverAPIs()
|
alias, input, query := base.CreateHTTPRoomserverAPIs()
|
||||||
typingInputAPI := base.CreateHTTPTypingServerAPIs()
|
typingInputAPI := typingserver.SetupTypingServerComponent(base, cache.NewTypingCache())
|
||||||
cache := transactions.New()
|
|
||||||
|
|
||||||
clientapi.SetupClientAPIComponent(
|
clientapi.SetupClientAPIComponent(
|
||||||
base, deviceDB, accountDB, federation, &keyRing,
|
base, deviceDB, accountDB, federation, &keyRing,
|
||||||
alias, input, query, typingInputAPI, cache,
|
alias, input, query, typingInputAPI, transactions.New(),
|
||||||
)
|
)
|
||||||
|
|
||||||
base.SetupAndServeHTTP(string(base.Cfg.Listen.ClientAPI))
|
base.SetupAndServeHTTP(string(base.Cfg.Listen.ClientAPI))
|
||||||
|
|
|
@ -18,7 +18,6 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/appservice"
|
|
||||||
"github.com/matrix-org/dendrite/clientapi"
|
"github.com/matrix-org/dendrite/clientapi"
|
||||||
"github.com/matrix-org/dendrite/common"
|
"github.com/matrix-org/dendrite/common"
|
||||||
"github.com/matrix-org/dendrite/common/basecomponent"
|
"github.com/matrix-org/dendrite/common/basecomponent"
|
||||||
|
@ -68,7 +67,6 @@ func main() {
|
||||||
mediaapi.SetupMediaAPIComponent(base, deviceDB)
|
mediaapi.SetupMediaAPIComponent(base, deviceDB)
|
||||||
publicroomsapi.SetupPublicRoomsAPIComponent(base, deviceDB)
|
publicroomsapi.SetupPublicRoomsAPIComponent(base, deviceDB)
|
||||||
syncapi.SetupSyncAPIComponent(base, deviceDB, accountDB, query)
|
syncapi.SetupSyncAPIComponent(base, deviceDB, accountDB, query)
|
||||||
appservice.SetupAppServiceAPIComponent(base, accountDB, deviceDB, federation, alias, query, transactions.New())
|
|
||||||
|
|
||||||
httpHandler := common.WrapHandlerInCORS(base.APIMux)
|
httpHandler := common.WrapHandlerInCORS(base.APIMux)
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
"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"
|
||||||
"github.com/matrix-org/dendrite/common/config"
|
"github.com/matrix-org/dendrite/common/config"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/gomatrix"
|
"github.com/matrix-org/gomatrix"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
@ -32,7 +32,7 @@ func RoomAliasToID(
|
||||||
httpReq *http.Request,
|
httpReq *http.Request,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
cfg config.Dendrite,
|
cfg config.Dendrite,
|
||||||
aliasAPI api.RoomserverAliasAPI,
|
aliasAPI roomserverAPI.RoomserverAliasAPI,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
roomAlias := httpReq.FormValue("room_alias")
|
roomAlias := httpReq.FormValue("room_alias")
|
||||||
if roomAlias == "" {
|
if roomAlias == "" {
|
||||||
|
@ -52,8 +52,8 @@ func RoomAliasToID(
|
||||||
var resp gomatrixserverlib.RespDirectory
|
var resp gomatrixserverlib.RespDirectory
|
||||||
|
|
||||||
if domain == cfg.Matrix.ServerName {
|
if domain == cfg.Matrix.ServerName {
|
||||||
queryReq := api.GetRoomIDForAliasRequest{Alias: roomAlias}
|
queryReq := roomserverAPI.GetRoomIDForAliasRequest{Alias: roomAlias}
|
||||||
var queryRes api.GetRoomIDForAliasResponse
|
var queryRes roomserverAPI.GetRoomIDForAliasResponse
|
||||||
if err = aliasAPI.GetRoomIDForAlias(httpReq.Context(), &queryReq, &queryRes); err != nil {
|
if err = aliasAPI.GetRoomIDForAlias(httpReq.Context(), &queryReq, &queryRes); err != nil {
|
||||||
return httputil.LogThenError(httpReq, err)
|
return httputil.LogThenError(httpReq, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/clientapi/producers"
|
"github.com/matrix-org/dendrite/clientapi/producers"
|
||||||
"github.com/matrix-org/dendrite/common"
|
"github.com/matrix-org/dendrite/common"
|
||||||
"github.com/matrix-org/dendrite/common/config"
|
"github.com/matrix-org/dendrite/common/config"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
@ -37,8 +37,8 @@ const (
|
||||||
func Setup(
|
func Setup(
|
||||||
apiMux *mux.Router,
|
apiMux *mux.Router,
|
||||||
cfg config.Dendrite,
|
cfg config.Dendrite,
|
||||||
query api.RoomserverQueryAPI,
|
query roomserverAPI.RoomserverQueryAPI,
|
||||||
aliasAPI api.RoomserverAliasAPI,
|
aliasAPI roomserverAPI.RoomserverAliasAPI,
|
||||||
producer *producers.RoomserverProducer,
|
producer *producers.RoomserverProducer,
|
||||||
keys gomatrixserverlib.KeyRing,
|
keys gomatrixserverlib.KeyRing,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
|
|
|
@ -21,9 +21,10 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
appserviceAPI "github.com/matrix-org/dendrite/appservice/api"
|
||||||
"github.com/matrix-org/dendrite/common"
|
"github.com/matrix-org/dendrite/common"
|
||||||
"github.com/matrix-org/dendrite/common/config"
|
"github.com/matrix-org/dendrite/common/config"
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
)
|
)
|
||||||
|
@ -44,19 +45,20 @@ type RoomserverAliasAPIDatabase interface {
|
||||||
RemoveRoomAlias(ctx context.Context, alias string) error
|
RemoveRoomAlias(ctx context.Context, alias string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// RoomserverAliasAPI is an implementation of api.RoomserverAliasAPI
|
// RoomserverAliasAPI is an implementation of alias.RoomserverAliasAPI
|
||||||
type RoomserverAliasAPI struct {
|
type RoomserverAliasAPI struct {
|
||||||
DB RoomserverAliasAPIDatabase
|
DB RoomserverAliasAPIDatabase
|
||||||
Cfg *config.Dendrite
|
Cfg *config.Dendrite
|
||||||
InputAPI api.RoomserverInputAPI
|
InputAPI roomserverAPI.RoomserverInputAPI
|
||||||
QueryAPI api.RoomserverQueryAPI
|
QueryAPI roomserverAPI.RoomserverQueryAPI
|
||||||
|
AppserviceAPI appserviceAPI.AppServiceQueryAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRoomAlias implements api.RoomserverAliasAPI
|
// SetRoomAlias implements alias.RoomserverAliasAPI
|
||||||
func (r *RoomserverAliasAPI) SetRoomAlias(
|
func (r *RoomserverAliasAPI) SetRoomAlias(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.SetRoomAliasRequest,
|
request *roomserverAPI.SetRoomAliasRequest,
|
||||||
response *api.SetRoomAliasResponse,
|
response *roomserverAPI.SetRoomAliasResponse,
|
||||||
) error {
|
) error {
|
||||||
// Check if the alias isn't already referring to a room
|
// Check if the alias isn't already referring to a room
|
||||||
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
||||||
|
@ -82,11 +84,11 @@ func (r *RoomserverAliasAPI) SetRoomAlias(
|
||||||
return r.sendUpdatedAliasesEvent(context.TODO(), request.UserID, request.RoomID)
|
return r.sendUpdatedAliasesEvent(context.TODO(), request.UserID, request.RoomID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRoomIDForAlias implements api.RoomserverAliasAPI
|
// GetRoomIDForAlias implements alias.RoomserverAliasAPI
|
||||||
func (r *RoomserverAliasAPI) GetRoomIDForAlias(
|
func (r *RoomserverAliasAPI) GetRoomIDForAlias(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.GetRoomIDForAliasRequest,
|
request *roomserverAPI.GetRoomIDForAliasRequest,
|
||||||
response *api.GetRoomIDForAliasResponse,
|
response *roomserverAPI.GetRoomIDForAliasResponse,
|
||||||
) error {
|
) error {
|
||||||
// Look up the room ID in the database
|
// Look up the room ID in the database
|
||||||
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
||||||
|
@ -94,15 +96,23 @@ func (r *RoomserverAliasAPI) GetRoomIDForAlias(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No rooms found locally, try our application services by making a call to
|
||||||
|
// the appservice component
|
||||||
|
aliasReq := appserviceAPI.RoomAliasExistsRequest{Alias: request.Alias}
|
||||||
|
var aliasResp appserviceAPI.RoomAliasExistsResponse
|
||||||
|
if err = r.AppserviceAPI.RoomAliasExists(ctx, &aliasReq, &aliasResp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
response.RoomID = roomID
|
response.RoomID = roomID
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAliasesForRoomID implements api.RoomserverAliasAPI
|
// GetAliasesForRoomID implements alias.RoomserverAliasAPI
|
||||||
func (r *RoomserverAliasAPI) GetAliasesForRoomID(
|
func (r *RoomserverAliasAPI) GetAliasesForRoomID(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.GetAliasesForRoomIDRequest,
|
request *roomserverAPI.GetAliasesForRoomIDRequest,
|
||||||
response *api.GetAliasesForRoomIDResponse,
|
response *roomserverAPI.GetAliasesForRoomIDResponse,
|
||||||
) error {
|
) error {
|
||||||
// Look up the aliases in the database for the given RoomID
|
// Look up the aliases in the database for the given RoomID
|
||||||
aliases, err := r.DB.GetAliasesForRoomID(ctx, request.RoomID)
|
aliases, err := r.DB.GetAliasesForRoomID(ctx, request.RoomID)
|
||||||
|
@ -114,11 +124,11 @@ func (r *RoomserverAliasAPI) GetAliasesForRoomID(
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveRoomAlias implements api.RoomserverAliasAPI
|
// RemoveRoomAlias implements alias.RoomserverAliasAPI
|
||||||
func (r *RoomserverAliasAPI) RemoveRoomAlias(
|
func (r *RoomserverAliasAPI) RemoveRoomAlias(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *api.RemoveRoomAliasRequest,
|
request *roomserverAPI.RemoveRoomAliasRequest,
|
||||||
response *api.RemoveRoomAliasResponse,
|
response *roomserverAPI.RemoveRoomAliasResponse,
|
||||||
) error {
|
) error {
|
||||||
// Look up the room ID in the database
|
// Look up the room ID in the database
|
||||||
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
roomID, err := r.DB.GetRoomIDForAlias(ctx, request.Alias)
|
||||||
|
@ -177,11 +187,11 @@ func (r *RoomserverAliasAPI) sendUpdatedAliasesEvent(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
req := api.QueryLatestEventsAndStateRequest{
|
req := roomserverAPI.QueryLatestEventsAndStateRequest{
|
||||||
RoomID: roomID,
|
RoomID: roomID,
|
||||||
StateToFetch: eventsNeeded.Tuples(),
|
StateToFetch: eventsNeeded.Tuples(),
|
||||||
}
|
}
|
||||||
var res api.QueryLatestEventsAndStateResponse
|
var res roomserverAPI.QueryLatestEventsAndStateResponse
|
||||||
if err = r.QueryAPI.QueryLatestEventsAndState(ctx, &req, &res); err != nil {
|
if err = r.QueryAPI.QueryLatestEventsAndState(ctx, &req, &res); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -213,16 +223,16 @@ func (r *RoomserverAliasAPI) sendUpdatedAliasesEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the request
|
// Create the request
|
||||||
ire := api.InputRoomEvent{
|
ire := roomserverAPI.InputRoomEvent{
|
||||||
Kind: api.KindNew,
|
Kind: roomserverAPI.KindNew,
|
||||||
Event: event,
|
Event: event,
|
||||||
AuthEventIDs: event.AuthEventIDs(),
|
AuthEventIDs: event.AuthEventIDs(),
|
||||||
SendAsServer: serverName,
|
SendAsServer: serverName,
|
||||||
}
|
}
|
||||||
inputReq := api.InputRoomEventsRequest{
|
inputReq := roomserverAPI.InputRoomEventsRequest{
|
||||||
InputRoomEvents: []api.InputRoomEvent{ire},
|
InputRoomEvents: []roomserverAPI.InputRoomEvent{ire},
|
||||||
}
|
}
|
||||||
var inputRes api.InputRoomEventsResponse
|
var inputRes roomserverAPI.InputRoomEventsResponse
|
||||||
|
|
||||||
// Send the request
|
// Send the request
|
||||||
return r.InputAPI.InputRoomEvents(ctx, &inputReq, &inputRes)
|
return r.InputAPI.InputRoomEvents(ctx, &inputReq, &inputRes)
|
||||||
|
@ -231,10 +241,10 @@ func (r *RoomserverAliasAPI) sendUpdatedAliasesEvent(
|
||||||
// SetupHTTP adds the RoomserverAliasAPI handlers to the http.ServeMux.
|
// SetupHTTP adds the RoomserverAliasAPI handlers to the http.ServeMux.
|
||||||
func (r *RoomserverAliasAPI) SetupHTTP(servMux *http.ServeMux) {
|
func (r *RoomserverAliasAPI) SetupHTTP(servMux *http.ServeMux) {
|
||||||
servMux.Handle(
|
servMux.Handle(
|
||||||
api.RoomserverSetRoomAliasPath,
|
roomserverAPI.RoomserverSetRoomAliasPath,
|
||||||
common.MakeInternalAPI("setRoomAlias", func(req *http.Request) util.JSONResponse {
|
common.MakeInternalAPI("setRoomAlias", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.SetRoomAliasRequest
|
var request roomserverAPI.SetRoomAliasRequest
|
||||||
var response api.SetRoomAliasResponse
|
var response roomserverAPI.SetRoomAliasResponse
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
return util.ErrorResponse(err)
|
return util.ErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
@ -245,10 +255,10 @@ func (r *RoomserverAliasAPI) SetupHTTP(servMux *http.ServeMux) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
servMux.Handle(
|
servMux.Handle(
|
||||||
api.RoomserverGetRoomIDForAliasPath,
|
roomserverAPI.RoomserverGetRoomIDForAliasPath,
|
||||||
common.MakeInternalAPI("GetRoomIDForAlias", func(req *http.Request) util.JSONResponse {
|
common.MakeInternalAPI("GetRoomIDForAlias", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.GetRoomIDForAliasRequest
|
var request roomserverAPI.GetRoomIDForAliasRequest
|
||||||
var response api.GetRoomIDForAliasResponse
|
var response roomserverAPI.GetRoomIDForAliasResponse
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
return util.ErrorResponse(err)
|
return util.ErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
@ -259,10 +269,10 @@ func (r *RoomserverAliasAPI) SetupHTTP(servMux *http.ServeMux) {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
servMux.Handle(
|
servMux.Handle(
|
||||||
api.RoomserverRemoveRoomAliasPath,
|
roomserverAPI.RoomserverRemoveRoomAliasPath,
|
||||||
common.MakeInternalAPI("removeRoomAlias", func(req *http.Request) util.JSONResponse {
|
common.MakeInternalAPI("removeRoomAlias", func(req *http.Request) util.JSONResponse {
|
||||||
var request api.RemoveRoomAliasRequest
|
var request roomserverAPI.RemoveRoomAliasRequest
|
||||||
var response api.RemoveRoomAliasResponse
|
var response roomserverAPI.RemoveRoomAliasResponse
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
return util.ErrorResponse(err)
|
return util.ErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/roomserver/api"
|
"github.com/matrix-org/dendrite/roomserver/api"
|
||||||
|
|
||||||
|
asQuery "github.com/matrix-org/dendrite/appservice/query"
|
||||||
"github.com/matrix-org/dendrite/common/basecomponent"
|
"github.com/matrix-org/dendrite/common/basecomponent"
|
||||||
"github.com/matrix-org/dendrite/roomserver/alias"
|
"github.com/matrix-org/dendrite/roomserver/alias"
|
||||||
"github.com/matrix-org/dendrite/roomserver/input"
|
"github.com/matrix-org/dendrite/roomserver/input"
|
||||||
|
@ -51,11 +52,14 @@ func SetupRoomServerComponent(
|
||||||
|
|
||||||
queryAPI.SetupHTTP(http.DefaultServeMux)
|
queryAPI.SetupHTTP(http.DefaultServeMux)
|
||||||
|
|
||||||
|
asAPI := asQuery.AppServiceQueryAPI{Cfg: base.Cfg}
|
||||||
|
|
||||||
aliasAPI := alias.RoomserverAliasAPI{
|
aliasAPI := alias.RoomserverAliasAPI{
|
||||||
DB: roomserverDB,
|
DB: roomserverDB,
|
||||||
Cfg: base.Cfg,
|
Cfg: base.Cfg,
|
||||||
InputAPI: &inputAPI,
|
InputAPI: &inputAPI,
|
||||||
QueryAPI: &queryAPI,
|
QueryAPI: &queryAPI,
|
||||||
|
AppserviceAPI: &asAPI,
|
||||||
}
|
}
|
||||||
|
|
||||||
aliasAPI.SetupHTTP(http.DefaultServeMux)
|
aliasAPI.SetupHTTP(http.DefaultServeMux)
|
||||||
|
|
Loading…
Reference in New Issue