dendrite/clientapi/clientapi_test.go
2023-03-29 12:17:39 +02:00

195 lines
6.2 KiB
Go

package clientapi
import (
"bytes"
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/matrix-org/dendrite/internal/caching"
"github.com/matrix-org/dendrite/internal/httputil"
"github.com/matrix-org/dendrite/internal/sqlutil"
"github.com/matrix-org/dendrite/roomserver"
"github.com/matrix-org/dendrite/roomserver/version"
"github.com/matrix-org/dendrite/setup/config"
"github.com/matrix-org/dendrite/setup/jetstream"
"github.com/matrix-org/dendrite/test"
"github.com/matrix-org/dendrite/test/testrig"
"github.com/matrix-org/dendrite/userapi"
"github.com/matrix-org/gomatrix"
"github.com/matrix-org/gomatrixserverlib"
"github.com/stretchr/testify/assert"
)
func TestCapabilities(t *testing.T) {
alice := test.NewUser(t)
ctx := context.Background()
// construct the expected result
versionsMap := map[gomatrixserverlib.RoomVersion]string{}
for v, desc := range version.SupportedRoomVersions() {
if desc.Stable {
versionsMap[v] = "stable"
} else {
versionsMap[v] = "unstable"
}
}
expectedMap := map[string]interface{}{
"capabilities": map[string]interface{}{
"m.change_password": map[string]bool{
"enabled": true,
},
"m.room_versions": map[string]interface{}{
"default": version.DefaultRoomVersion(),
"available": versionsMap,
},
},
}
expectedBuf := &bytes.Buffer{}
err := json.NewEncoder(expectedBuf).Encode(expectedMap)
assert.NoError(t, err)
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
cfg, processCtx, close := testrig.CreateConfig(t, dbType)
cfg.ClientAPI.RateLimiting.Enabled = false
defer close()
natsInstance := jetstream.NATSInstance{}
routers := httputil.NewRouters()
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
// Needed to create accounts
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, &natsInstance, nil, caching.DisableMetrics)
userAPI := userapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, rsAPI, nil)
// We mostly need the rsAPI/userAPI for this test, so nil for other APIs etc.
AddPublicRoutes(processCtx, routers, cfg, &natsInstance, nil, rsAPI, nil, nil, nil, userAPI, nil, nil, caching.DisableMetrics)
// Create the users in the userapi and login
accessTokens := map[*test.User]string{
alice: "",
}
createAccessTokens(t, accessTokens, userAPI, ctx, routers)
testCases := []struct {
name string
request *http.Request
}{
{
name: "can get capabilities",
request: httptest.NewRequest(http.MethodGet, "/_matrix/client/v3/capabilities", strings.NewReader("")),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
rec := httptest.NewRecorder()
tc.request.Header.Set("Authorization", "Bearer "+accessTokens[alice])
routers.Client.ServeHTTP(rec, tc.request)
assert.Equal(t, http.StatusOK, rec.Code)
assert.ObjectsAreEqual(expectedBuf.Bytes(), rec.Body.Bytes())
})
}
})
}
func TestTurnserver(t *testing.T) {
alice := test.NewUser(t)
ctx := context.Background()
cfg, processCtx, close := testrig.CreateConfig(t, test.DBTypeSQLite)
cfg.ClientAPI.RateLimiting.Enabled = false
defer close()
natsInstance := jetstream.NATSInstance{}
routers := httputil.NewRouters()
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
// Needed to create accounts
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, &natsInstance, nil, caching.DisableMetrics)
userAPI := userapi.NewInternalAPI(processCtx, cfg, cm, &natsInstance, rsAPI, nil)
//rsAPI.SetUserAPI(userAPI)
// We mostly need the rsAPI/userAPI for this test, so nil for other APIs etc.
AddPublicRoutes(processCtx, routers, cfg, &natsInstance, nil, rsAPI, nil, nil, nil, userAPI, nil, nil, caching.DisableMetrics)
// Create the users in the userapi and login
accessTokens := map[*test.User]string{
alice: "",
}
createAccessTokens(t, accessTokens, userAPI, ctx, routers)
testCases := []struct {
name string
turnConfig config.TURN
wantEmptyResponse bool
}{
{
name: "no turn server configured",
wantEmptyResponse: true,
},
{
name: "servers configured but not userLifeTime",
wantEmptyResponse: true,
turnConfig: config.TURN{URIs: []string{""}},
},
{
name: "missing sharedSecret/username/password",
wantEmptyResponse: true,
turnConfig: config.TURN{URIs: []string{""}, UserLifetime: "1m"},
},
{
name: "with shared secret",
turnConfig: config.TURN{URIs: []string{""}, UserLifetime: "1m", SharedSecret: "iAmSecret"},
},
{
name: "with username/password secret",
turnConfig: config.TURN{URIs: []string{""}, UserLifetime: "1m", Username: "username", Password: "iAmSecret"},
},
{
name: "only username set",
turnConfig: config.TURN{URIs: []string{""}, UserLifetime: "1m", Username: "username"},
wantEmptyResponse: true,
},
{
name: "only password set",
turnConfig: config.TURN{URIs: []string{""}, UserLifetime: "1m", Username: "username"},
wantEmptyResponse: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/_matrix/client/v3/voip/turnServer", strings.NewReader(""))
req.Header.Set("Authorization", "Bearer "+accessTokens[alice])
cfg.ClientAPI.TURN = tc.turnConfig
routers.Client.ServeHTTP(rec, req)
assert.Equal(t, http.StatusOK, rec.Code)
if tc.wantEmptyResponse && rec.Body.String() != "{}" {
t.Fatalf("expected an empty response, but got %s", rec.Body.String())
}
if !tc.wantEmptyResponse {
assert.NotEqual(t, "{}", rec.Body.String())
resp := gomatrix.RespTurnServer{}
err := json.NewDecoder(rec.Body).Decode(&resp)
assert.NoError(t, err)
duration, _ := time.ParseDuration(tc.turnConfig.UserLifetime)
assert.Equal(t, tc.turnConfig.URIs, resp.URIs)
assert.Equal(t, int(duration.Seconds()), resp.TTL)
if tc.turnConfig.Username != "" && tc.turnConfig.Password != "" {
assert.Equal(t, tc.turnConfig.Username, resp.Username)
assert.Equal(t, tc.turnConfig.Password, resp.Password)
}
}
})
}
}