mirror of
https://github.com/hoernschen/dendrite.git
synced 2024-12-27 07:28:27 +00:00
Implement /_synapse/admin/v1/register (#1911)
* Implement /_synapse/admin/v1/register This is implemented identically to Synapse, so scripts which work with Synapse should work with Dendrite. ``` Test 27 POST /_synapse/admin/v1/register with shared secret... OK Test 28 POST /_synapse/admin/v1/register admin with shared secret... OK Test 29 POST /_synapse/admin/v1/register with shared secret downcases capitals... OK Test 30 POST /_synapse/admin/v1/register with shared secret disallows symbols... OK ``` Sytest however has `implementation_specific => "synapse"` which stops these tests from running. * Add missing muxes to gobind * Linting
This commit is contained in:
parent
c8408a6387
commit
1ed732cc78
18 changed files with 220 additions and 66 deletions
|
@ -334,6 +334,7 @@ func (m *DendriteMonolith) Start() {
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
||||||
httpRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
|
httpRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
|
||||||
|
|
|
@ -173,6 +173,7 @@ func (m *DendriteMonolith) Start() {
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
||||||
httpRouter := mux.NewRouter()
|
httpRouter := mux.NewRouter()
|
||||||
|
|
|
@ -35,6 +35,7 @@ import (
|
||||||
// AddPublicRoutes sets up and registers HTTP handlers for the ClientAPI component.
|
// AddPublicRoutes sets up and registers HTTP handlers for the ClientAPI component.
|
||||||
func AddPublicRoutes(
|
func AddPublicRoutes(
|
||||||
router *mux.Router,
|
router *mux.Router,
|
||||||
|
synapseAdminRouter *mux.Router,
|
||||||
cfg *config.ClientAPI,
|
cfg *config.ClientAPI,
|
||||||
accountsDB accounts.Database,
|
accountsDB accounts.Database,
|
||||||
federation *gomatrixserverlib.FederationClient,
|
federation *gomatrixserverlib.FederationClient,
|
||||||
|
@ -56,7 +57,7 @@ func AddPublicRoutes(
|
||||||
}
|
}
|
||||||
|
|
||||||
routing.Setup(
|
routing.Setup(
|
||||||
router, cfg, eduInputAPI, rsAPI, asAPI,
|
router, synapseAdminRouter, cfg, eduInputAPI, rsAPI, asAPI,
|
||||||
accountsDB, userAPI, federation,
|
accountsDB, userAPI, federation,
|
||||||
syncProducer, transactionsCache, fsAPI, keyAPI, extRoomsProvider, mscCfg,
|
syncProducer, transactionsCache, fsAPI, keyAPI, extRoomsProvider, mscCfg,
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,10 +17,7 @@ package routing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/sha1"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -594,7 +591,6 @@ func handleRegistrationFlow(
|
||||||
accessToken string,
|
accessToken string,
|
||||||
accessTokenErr error,
|
accessTokenErr error,
|
||||||
) util.JSONResponse {
|
) util.JSONResponse {
|
||||||
// TODO: Shared secret registration (create new user scripts)
|
|
||||||
// TODO: Enable registration config flag
|
// TODO: Enable registration config flag
|
||||||
// TODO: Guest account upgrading
|
// TODO: Guest account upgrading
|
||||||
|
|
||||||
|
@ -643,20 +639,6 @@ func handleRegistrationFlow(
|
||||||
// Add Recaptcha to the list of completed registration stages
|
// Add Recaptcha to the list of completed registration stages
|
||||||
AddCompletedSessionStage(sessionID, authtypes.LoginTypeRecaptcha)
|
AddCompletedSessionStage(sessionID, authtypes.LoginTypeRecaptcha)
|
||||||
|
|
||||||
case authtypes.LoginTypeSharedSecret:
|
|
||||||
// Check shared secret against config
|
|
||||||
valid, err := isValidMacLogin(cfg, r.Username, r.Password, r.Admin, r.Auth.Mac)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
util.GetLogger(req.Context()).WithError(err).Error("isValidMacLogin failed")
|
|
||||||
return jsonerror.InternalServerError()
|
|
||||||
} else if !valid {
|
|
||||||
return util.MessageResponse(http.StatusForbidden, "HMAC incorrect")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add SharedSecret to the list of completed registration stages
|
|
||||||
AddCompletedSessionStage(sessionID, authtypes.LoginTypeSharedSecret)
|
|
||||||
|
|
||||||
case authtypes.LoginTypeDummy:
|
case authtypes.LoginTypeDummy:
|
||||||
// there is nothing to do
|
// there is nothing to do
|
||||||
// Add Dummy to the list of completed registration stages
|
// Add Dummy to the list of completed registration stages
|
||||||
|
@ -849,49 +831,6 @@ func completeRegistration(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used for shared secret registration.
|
|
||||||
// Checks if the username, password and isAdmin flag matches the given mac.
|
|
||||||
func isValidMacLogin(
|
|
||||||
cfg *config.ClientAPI,
|
|
||||||
username, password string,
|
|
||||||
isAdmin bool,
|
|
||||||
givenMac []byte,
|
|
||||||
) (bool, error) {
|
|
||||||
sharedSecret := cfg.RegistrationSharedSecret
|
|
||||||
|
|
||||||
// Check that shared secret registration isn't disabled.
|
|
||||||
if cfg.RegistrationSharedSecret == "" {
|
|
||||||
return false, errors.New("Shared secret registration is disabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Double check that username/password don't contain the HMAC delimiters. We should have
|
|
||||||
// already checked this.
|
|
||||||
if strings.Contains(username, "\x00") {
|
|
||||||
return false, errors.New("Username contains invalid character")
|
|
||||||
}
|
|
||||||
if strings.Contains(password, "\x00") {
|
|
||||||
return false, errors.New("Password contains invalid character")
|
|
||||||
}
|
|
||||||
if sharedSecret == "" {
|
|
||||||
return false, errors.New("Shared secret registration is disabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
adminString := "notadmin"
|
|
||||||
if isAdmin {
|
|
||||||
adminString = "admin"
|
|
||||||
}
|
|
||||||
joined := strings.Join([]string{username, password, adminString}, "\x00")
|
|
||||||
|
|
||||||
mac := hmac.New(sha1.New, []byte(sharedSecret))
|
|
||||||
_, err := mac.Write([]byte(joined))
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
expectedMAC := mac.Sum(nil)
|
|
||||||
|
|
||||||
return hmac.Equal(givenMac, expectedMAC), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkFlows checks a single completed flow against another required one. If
|
// checkFlows checks a single completed flow against another required one. If
|
||||||
// one contains at least all of the stages that the other does, checkFlows
|
// one contains at least all of the stages that the other does, checkFlows
|
||||||
// returns true.
|
// returns true.
|
||||||
|
@ -995,3 +934,34 @@ func RegisterAvailable(
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleSharedSecretRegistration(userAPI userapi.UserInternalAPI, sr *SharedSecretRegistration, req *http.Request) util.JSONResponse {
|
||||||
|
ssrr, err := NewSharedSecretRegistrationRequest(req.Body)
|
||||||
|
if err != nil {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 400,
|
||||||
|
JSON: jsonerror.BadJSON(fmt.Sprintf("malformed json: %s", err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
valid, err := sr.IsValidMacLogin(ssrr.Nonce, ssrr.User, ssrr.Password, ssrr.Admin, ssrr.MacBytes)
|
||||||
|
if err != nil {
|
||||||
|
return util.ErrorResponse(err)
|
||||||
|
}
|
||||||
|
if !valid {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 403,
|
||||||
|
JSON: jsonerror.Forbidden("bad mac"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// downcase capitals
|
||||||
|
ssrr.User = strings.ToLower(ssrr.User)
|
||||||
|
|
||||||
|
if resErr := validateUsername(ssrr.User); resErr != nil {
|
||||||
|
return *resErr
|
||||||
|
}
|
||||||
|
if resErr := validatePassword(ssrr.Password); resErr != nil {
|
||||||
|
return *resErr
|
||||||
|
}
|
||||||
|
deviceID := "shared_secret_registration"
|
||||||
|
return completeRegistration(req.Context(), userAPI, ssrr.User, ssrr.Password, "", req.RemoteAddr, req.UserAgent(), false, &ssrr.User, &deviceID)
|
||||||
|
}
|
||||||
|
|
99
clientapi/routing/register_secret.go
Normal file
99
clientapi/routing/register_secret.go
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
package routing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha1"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/matrix-org/dendrite/internal"
|
||||||
|
"github.com/matrix-org/util"
|
||||||
|
cache "github.com/patrickmn/go-cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SharedSecretRegistrationRequest struct {
|
||||||
|
User string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Nonce string `json:"nonce"`
|
||||||
|
MacBytes []byte
|
||||||
|
MacStr string `json:"mac"`
|
||||||
|
Admin bool `json:"admin"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSharedSecretRegistrationRequest(reader io.ReadCloser) (*SharedSecretRegistrationRequest, error) {
|
||||||
|
defer internal.CloseAndLogIfError(context.Background(), reader, "NewSharedSecretRegistrationRequest: failed to close request body")
|
||||||
|
var ssrr SharedSecretRegistrationRequest
|
||||||
|
err := json.NewDecoder(reader).Decode(&ssrr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ssrr.MacBytes, err = hex.DecodeString(ssrr.MacStr)
|
||||||
|
return &ssrr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type SharedSecretRegistration struct {
|
||||||
|
sharedSecret string
|
||||||
|
nonces *cache.Cache
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSharedSecretRegistration(sharedSecret string) *SharedSecretRegistration {
|
||||||
|
return &SharedSecretRegistration{
|
||||||
|
sharedSecret: sharedSecret,
|
||||||
|
// nonces live for 5mins, purge every 10mins
|
||||||
|
nonces: cache.New(5*time.Minute, 10*time.Minute),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SharedSecretRegistration) GenerateNonce() string {
|
||||||
|
nonce := util.RandomString(16)
|
||||||
|
r.nonces.Set(nonce, true, cache.DefaultExpiration)
|
||||||
|
return nonce
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SharedSecretRegistration) validNonce(nonce string) bool {
|
||||||
|
_, exists := r.nonces.Get(nonce)
|
||||||
|
return exists
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *SharedSecretRegistration) IsValidMacLogin(
|
||||||
|
nonce, username, password string,
|
||||||
|
isAdmin bool,
|
||||||
|
givenMac []byte,
|
||||||
|
) (bool, error) {
|
||||||
|
// Check that shared secret registration isn't disabled.
|
||||||
|
if r.sharedSecret == "" {
|
||||||
|
return false, errors.New("Shared secret registration is disabled")
|
||||||
|
}
|
||||||
|
if !r.validNonce(nonce) {
|
||||||
|
return false, fmt.Errorf("Incorrect or expired nonce: %s", nonce)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that username/password don't contain the HMAC delimiters.
|
||||||
|
if strings.Contains(username, "\x00") {
|
||||||
|
return false, errors.New("Username contains invalid character")
|
||||||
|
}
|
||||||
|
if strings.Contains(password, "\x00") {
|
||||||
|
return false, errors.New("Password contains invalid character")
|
||||||
|
}
|
||||||
|
|
||||||
|
adminString := "notadmin"
|
||||||
|
if isAdmin {
|
||||||
|
adminString = "admin"
|
||||||
|
}
|
||||||
|
joined := strings.Join([]string{nonce, username, password, adminString}, "\x00")
|
||||||
|
|
||||||
|
mac := hmac.New(sha1.New, []byte(r.sharedSecret))
|
||||||
|
_, err := mac.Write([]byte(joined))
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
expectedMAC := mac.Sum(nil)
|
||||||
|
|
||||||
|
return hmac.Equal(givenMac, expectedMAC), nil
|
||||||
|
}
|
43
clientapi/routing/register_secret_test.go
Normal file
43
clientapi/routing/register_secret_test.go
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
package routing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/patrickmn/go-cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSharedSecretRegister(t *testing.T) {
|
||||||
|
// these values have come from a local synapse instance to ensure compatibility
|
||||||
|
jsonStr := []byte(`{"admin":false,"mac":"f1ba8d37123866fd659b40de4bad9b0f8965c565","nonce":"759f047f312b99ff428b21d581256f8592b8976e58bc1b543972dc6147e529a79657605b52d7becd160ff5137f3de11975684319187e06901955f79e5a6c5a79","password":"wonderland","username":"alice"}`)
|
||||||
|
sharedSecret := "dendritetest"
|
||||||
|
|
||||||
|
req, err := NewSharedSecretRegistrationRequest(ioutil.NopCloser(bytes.NewBuffer(jsonStr)))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read request: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r := NewSharedSecretRegistration(sharedSecret)
|
||||||
|
|
||||||
|
// force the nonce to be known
|
||||||
|
r.nonces.Set(req.Nonce, true, cache.DefaultExpiration)
|
||||||
|
|
||||||
|
valid, err := r.IsValidMacLogin(req.Nonce, req.User, req.Password, req.Admin, req.MacBytes)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to check for valid mac: %s", err)
|
||||||
|
}
|
||||||
|
if !valid {
|
||||||
|
t.Errorf("mac login failed, wanted success")
|
||||||
|
}
|
||||||
|
|
||||||
|
// modify the mac so it fails
|
||||||
|
req.MacBytes[0] = 0xff
|
||||||
|
valid, err = r.IsValidMacLogin(req.Nonce, req.User, req.Password, req.Admin, req.MacBytes)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to check for valid mac: %s", err)
|
||||||
|
}
|
||||||
|
if valid {
|
||||||
|
t.Errorf("mac login succeeded, wanted failure")
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ import (
|
||||||
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
"github.com/matrix-org/dendrite/userapi/storage/accounts"
|
||||||
"github.com/matrix-org/gomatrixserverlib"
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
"github.com/matrix-org/util"
|
"github.com/matrix-org/util"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Setup registers HTTP handlers with the given ServeMux. It also supplies the given http.Client
|
// Setup registers HTTP handlers with the given ServeMux. It also supplies the given http.Client
|
||||||
|
@ -46,7 +47,7 @@ import (
|
||||||
// applied:
|
// applied:
|
||||||
// nolint: gocyclo
|
// nolint: gocyclo
|
||||||
func Setup(
|
func Setup(
|
||||||
publicAPIMux *mux.Router, cfg *config.ClientAPI,
|
publicAPIMux, synapseAdminRouter *mux.Router, cfg *config.ClientAPI,
|
||||||
eduAPI eduServerAPI.EDUServerInputAPI,
|
eduAPI eduServerAPI.EDUServerInputAPI,
|
||||||
rsAPI roomserverAPI.RoomserverInternalAPI,
|
rsAPI roomserverAPI.RoomserverInternalAPI,
|
||||||
asAPI appserviceAPI.AppServiceQueryAPI,
|
asAPI appserviceAPI.AppServiceQueryAPI,
|
||||||
|
@ -88,6 +89,32 @@ func Setup(
|
||||||
}),
|
}),
|
||||||
).Methods(http.MethodGet, http.MethodOptions)
|
).Methods(http.MethodGet, http.MethodOptions)
|
||||||
|
|
||||||
|
if cfg.RegistrationSharedSecret != "" {
|
||||||
|
logrus.Info("Enabling shared secret registration at /_synapse/admin/v1/register")
|
||||||
|
sr := NewSharedSecretRegistration(cfg.RegistrationSharedSecret)
|
||||||
|
synapseAdminRouter.Handle("/admin/v1/register",
|
||||||
|
httputil.MakeExternalAPI("shared_secret_registration", func(req *http.Request) util.JSONResponse {
|
||||||
|
if req.Method == http.MethodGet {
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: 200,
|
||||||
|
JSON: struct {
|
||||||
|
Nonce string `json:"nonce"`
|
||||||
|
}{
|
||||||
|
Nonce: sr.GenerateNonce(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.Method == http.MethodPost {
|
||||||
|
return handleSharedSecretRegistration(userAPI, sr, req)
|
||||||
|
}
|
||||||
|
return util.JSONResponse{
|
||||||
|
Code: http.StatusMethodNotAllowed,
|
||||||
|
JSON: jsonerror.NotFound("unknown method"),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
).Methods(http.MethodGet, http.MethodPost, http.MethodOptions)
|
||||||
|
}
|
||||||
|
|
||||||
r0mux := publicAPIMux.PathPrefix("/r0").Subrouter()
|
r0mux := publicAPIMux.PathPrefix("/r0").Subrouter()
|
||||||
unstableMux := publicAPIMux.PathPrefix("/unstable").Subrouter()
|
unstableMux := publicAPIMux.PathPrefix("/unstable").Subrouter()
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,7 @@ func main() {
|
||||||
base.Base.PublicFederationAPIMux,
|
base.Base.PublicFederationAPIMux,
|
||||||
base.Base.PublicKeyAPIMux,
|
base.Base.PublicKeyAPIMux,
|
||||||
base.Base.PublicMediaAPIMux,
|
base.Base.PublicMediaAPIMux,
|
||||||
|
base.Base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
if err := mscs.Enable(&base.Base, &monolith); err != nil {
|
if err := mscs.Enable(&base.Base, &monolith); err != nil {
|
||||||
logrus.WithError(err).Fatalf("Failed to enable MSCs")
|
logrus.WithError(err).Fatalf("Failed to enable MSCs")
|
||||||
|
|
|
@ -210,6 +210,7 @@ func main() {
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
||||||
wsUpgrader := websocket.Upgrader{
|
wsUpgrader := websocket.Upgrader{
|
||||||
|
|
|
@ -154,6 +154,7 @@ func main() {
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
if err := mscs.Enable(base, &monolith); err != nil {
|
if err := mscs.Enable(base, &monolith); err != nil {
|
||||||
logrus.WithError(err).Fatalf("Failed to enable MSCs")
|
logrus.WithError(err).Fatalf("Failed to enable MSCs")
|
||||||
|
|
|
@ -149,6 +149,7 @@ func main() {
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(base.Cfg.MSCs.MSCs) > 0 {
|
if len(base.Cfg.MSCs.MSCs) > 0 {
|
||||||
|
|
|
@ -33,7 +33,7 @@ func ClientAPI(base *setup.BaseDendrite, cfg *config.Dendrite) {
|
||||||
keyAPI := base.KeyServerHTTPClient()
|
keyAPI := base.KeyServerHTTPClient()
|
||||||
|
|
||||||
clientapi.AddPublicRoutes(
|
clientapi.AddPublicRoutes(
|
||||||
base.PublicClientAPIMux, &base.Cfg.ClientAPI, accountDB, federation,
|
base.PublicClientAPIMux, base.SynapseAdminMux, &base.Cfg.ClientAPI, accountDB, federation,
|
||||||
rsAPI, eduInputAPI, asQuery, transactions.New(), fsAPI, userAPI, keyAPI, nil,
|
rsAPI, eduInputAPI, asQuery, transactions.New(), fsAPI, userAPI, keyAPI, nil,
|
||||||
&cfg.MSCs,
|
&cfg.MSCs,
|
||||||
)
|
)
|
||||||
|
|
|
@ -215,6 +215,7 @@ func main() {
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
||||||
httpRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
|
httpRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
|
||||||
|
|
|
@ -236,6 +236,7 @@ func main() {
|
||||||
base.PublicFederationAPIMux,
|
base.PublicFederationAPIMux,
|
||||||
base.PublicKeyAPIMux,
|
base.PublicKeyAPIMux,
|
||||||
base.PublicMediaAPIMux,
|
base.PublicMediaAPIMux,
|
||||||
|
base.SynapseAdminMux,
|
||||||
)
|
)
|
||||||
|
|
||||||
httpRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
|
httpRouter := mux.NewRouter().SkipClean(true).UseEncodedPath()
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -39,6 +39,7 @@ require (
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/ngrok/sqlmw v0.0.0-20200129213757-d5c93a81bec6
|
github.com/ngrok/sqlmw v0.0.0-20200129213757-d5c93a81bec6
|
||||||
github.com/opentracing/opentracing-go v1.2.0
|
github.com/opentracing/opentracing-go v1.2.0
|
||||||
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pressly/goose v2.7.0+incompatible
|
github.com/pressly/goose v2.7.0+incompatible
|
||||||
github.com/prometheus/client_golang v1.9.0
|
github.com/prometheus/client_golang v1.9.0
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -1256,6 +1256,8 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
|
||||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
|
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||||
|
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
|
||||||
|
|
|
@ -77,6 +77,7 @@ type BaseDendrite struct {
|
||||||
PublicKeyAPIMux *mux.Router
|
PublicKeyAPIMux *mux.Router
|
||||||
PublicMediaAPIMux *mux.Router
|
PublicMediaAPIMux *mux.Router
|
||||||
InternalAPIMux *mux.Router
|
InternalAPIMux *mux.Router
|
||||||
|
SynapseAdminMux *mux.Router
|
||||||
UseHTTPAPIs bool
|
UseHTTPAPIs bool
|
||||||
apiHttpClient *http.Client
|
apiHttpClient *http.Client
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
|
@ -199,6 +200,7 @@ func NewBaseDendrite(cfg *config.Dendrite, componentName string, useHTTPAPIs boo
|
||||||
PublicKeyAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicKeyPathPrefix).Subrouter().UseEncodedPath(),
|
PublicKeyAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicKeyPathPrefix).Subrouter().UseEncodedPath(),
|
||||||
PublicMediaAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicMediaPathPrefix).Subrouter().UseEncodedPath(),
|
PublicMediaAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.PublicMediaPathPrefix).Subrouter().UseEncodedPath(),
|
||||||
InternalAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.InternalPathPrefix).Subrouter().UseEncodedPath(),
|
InternalAPIMux: mux.NewRouter().SkipClean(true).PathPrefix(httputil.InternalPathPrefix).Subrouter().UseEncodedPath(),
|
||||||
|
SynapseAdminMux: mux.NewRouter().SkipClean(true).PathPrefix("/_synapse/").Subrouter().UseEncodedPath(),
|
||||||
apiHttpClient: &apiClient,
|
apiHttpClient: &apiClient,
|
||||||
httpClient: &client,
|
httpClient: &client,
|
||||||
}
|
}
|
||||||
|
@ -391,6 +393,7 @@ func (b *BaseDendrite) SetupAndServeHTTP(
|
||||||
externalRouter.PathPrefix(httputil.PublicKeyPathPrefix).Handler(b.PublicKeyAPIMux)
|
externalRouter.PathPrefix(httputil.PublicKeyPathPrefix).Handler(b.PublicKeyAPIMux)
|
||||||
externalRouter.PathPrefix(httputil.PublicFederationPathPrefix).Handler(federationHandler)
|
externalRouter.PathPrefix(httputil.PublicFederationPathPrefix).Handler(federationHandler)
|
||||||
}
|
}
|
||||||
|
externalRouter.PathPrefix("/_synapse/").Handler(b.SynapseAdminMux)
|
||||||
externalRouter.PathPrefix(httputil.PublicMediaPathPrefix).Handler(b.PublicMediaAPIMux)
|
externalRouter.PathPrefix(httputil.PublicMediaPathPrefix).Handler(b.PublicMediaAPIMux)
|
||||||
|
|
||||||
if internalAddr != NoListener && internalAddr != externalAddr {
|
if internalAddr != NoListener && internalAddr != externalAddr {
|
||||||
|
|
|
@ -57,9 +57,9 @@ type Monolith struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddAllPublicRoutes attaches all public paths to the given router
|
// AddAllPublicRoutes attaches all public paths to the given router
|
||||||
func (m *Monolith) AddAllPublicRoutes(process *process.ProcessContext, csMux, ssMux, keyMux, mediaMux *mux.Router) {
|
func (m *Monolith) AddAllPublicRoutes(process *process.ProcessContext, csMux, ssMux, keyMux, mediaMux, synapseMux *mux.Router) {
|
||||||
clientapi.AddPublicRoutes(
|
clientapi.AddPublicRoutes(
|
||||||
csMux, &m.Config.ClientAPI, m.AccountDB,
|
csMux, synapseMux, &m.Config.ClientAPI, m.AccountDB,
|
||||||
m.FedClient, m.RoomserverAPI,
|
m.FedClient, m.RoomserverAPI,
|
||||||
m.EDUInternalAPI, m.AppserviceAPI, transactions.New(),
|
m.EDUInternalAPI, m.AppserviceAPI, transactions.New(),
|
||||||
m.FederationSenderAPI, m.UserAPI, m.KeyAPI, m.ExtPublicRoomsProvider,
|
m.FederationSenderAPI, m.UserAPI, m.KeyAPI, m.ExtPublicRoomsProvider,
|
||||||
|
|
Loading…
Reference in a new issue