mirror of
https://github.com/matrix-org/dendrite.git
synced 2024-11-30 02:01:56 -06:00
5e85a00cb3
Removes `BaseDendrite` to, hopefully, make testing and composing of components easier in the future.
148 lines
5.6 KiB
Go
148 lines
5.6 KiB
Go
package routing
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/matrix-org/dendrite/clientapi/auth/authtypes"
|
|
"github.com/matrix-org/dendrite/setup/config"
|
|
)
|
|
|
|
func Test_AuthFallback(t *testing.T) {
|
|
cfg := config.Dendrite{}
|
|
cfg.Defaults(config.DefaultOpts{Generate: true, SingleDatabase: true})
|
|
for _, useHCaptcha := range []bool{false, true} {
|
|
for _, recaptchaEnabled := range []bool{false, true} {
|
|
for _, wantErr := range []bool{false, true} {
|
|
t.Run(fmt.Sprintf("useHCaptcha(%v) - recaptchaEnabled(%v) - wantErr(%v)", useHCaptcha, recaptchaEnabled, wantErr), func(t *testing.T) {
|
|
// Set the defaults for each test
|
|
cfg.ClientAPI.Defaults(config.DefaultOpts{Generate: true, SingleDatabase: true})
|
|
cfg.ClientAPI.RecaptchaEnabled = recaptchaEnabled
|
|
cfg.ClientAPI.RecaptchaPublicKey = "pub"
|
|
cfg.ClientAPI.RecaptchaPrivateKey = "priv"
|
|
if useHCaptcha {
|
|
cfg.ClientAPI.RecaptchaSiteVerifyAPI = "https://hcaptcha.com/siteverify"
|
|
cfg.ClientAPI.RecaptchaApiJsUrl = "https://js.hcaptcha.com/1/api.js"
|
|
cfg.ClientAPI.RecaptchaFormField = "h-captcha-response"
|
|
cfg.ClientAPI.RecaptchaSitekeyClass = "h-captcha"
|
|
}
|
|
cfgErrs := &config.ConfigErrors{}
|
|
cfg.ClientAPI.Verify(cfgErrs)
|
|
if len(*cfgErrs) > 0 {
|
|
t.Fatalf("(hCaptcha=%v) unexpected config errors: %s", useHCaptcha, cfgErrs.Error())
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/?session=1337", nil)
|
|
rec := httptest.NewRecorder()
|
|
|
|
AuthFallback(rec, req, authtypes.LoginTypeRecaptcha, &cfg.ClientAPI)
|
|
if !recaptchaEnabled {
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("unexpected response code: %d, want %d", rec.Code, http.StatusBadRequest)
|
|
}
|
|
if rec.Body.String() != "Recaptcha login is disabled on this Homeserver" {
|
|
t.Fatalf("unexpected response body: %s", rec.Body.String())
|
|
}
|
|
} else {
|
|
if !strings.Contains(rec.Body.String(), cfg.ClientAPI.RecaptchaSitekeyClass) {
|
|
t.Fatalf("body does not contain %s: %s", cfg.ClientAPI.RecaptchaSitekeyClass, rec.Body.String())
|
|
}
|
|
}
|
|
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if wantErr {
|
|
_, _ = w.Write([]byte(`{"success":false}`))
|
|
return
|
|
}
|
|
_, _ = w.Write([]byte(`{"success":true}`))
|
|
}))
|
|
defer srv.Close() // nolint: errcheck
|
|
|
|
cfg.ClientAPI.RecaptchaSiteVerifyAPI = srv.URL
|
|
|
|
// check the result after sending the captcha
|
|
req = httptest.NewRequest(http.MethodPost, "/?session=1337", nil)
|
|
req.Form = url.Values{}
|
|
req.Form.Add(cfg.ClientAPI.RecaptchaFormField, "someRandomValue")
|
|
rec = httptest.NewRecorder()
|
|
AuthFallback(rec, req, authtypes.LoginTypeRecaptcha, &cfg.ClientAPI)
|
|
if recaptchaEnabled {
|
|
if !wantErr {
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("unexpected response code: %d, want %d", rec.Code, http.StatusOK)
|
|
}
|
|
if rec.Body.String() != successTemplate {
|
|
t.Fatalf("unexpected response: %s, want %s", rec.Body.String(), successTemplate)
|
|
}
|
|
} else {
|
|
if rec.Code != http.StatusUnauthorized {
|
|
t.Fatalf("unexpected response code: %d, want %d", rec.Code, http.StatusUnauthorized)
|
|
}
|
|
wantString := "Authentication"
|
|
if !strings.Contains(rec.Body.String(), wantString) {
|
|
t.Fatalf("expected response to contain '%s', but didn't: %s", wantString, rec.Body.String())
|
|
}
|
|
}
|
|
} else {
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("unexpected response code: %d, want %d", rec.Code, http.StatusBadRequest)
|
|
}
|
|
if rec.Body.String() != "Recaptcha login is disabled on this Homeserver" {
|
|
t.Fatalf("unexpected response: %s, want %s", rec.Body.String(), "successTemplate")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
t.Run("unknown fallbacks are handled correctly", func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodPost, "/?session=1337", nil)
|
|
rec := httptest.NewRecorder()
|
|
AuthFallback(rec, req, "DoesNotExist", &cfg.ClientAPI)
|
|
if rec.Code != http.StatusNotImplemented {
|
|
t.Fatalf("unexpected http status: %d, want %d", rec.Code, http.StatusNotImplemented)
|
|
}
|
|
})
|
|
|
|
t.Run("unknown methods are handled correctly", func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodDelete, "/?session=1337", nil)
|
|
rec := httptest.NewRecorder()
|
|
AuthFallback(rec, req, authtypes.LoginTypeRecaptcha, &cfg.ClientAPI)
|
|
if rec.Code != http.StatusMethodNotAllowed {
|
|
t.Fatalf("unexpected http status: %d, want %d", rec.Code, http.StatusMethodNotAllowed)
|
|
}
|
|
})
|
|
|
|
t.Run("missing session parameter is handled correctly", func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
rec := httptest.NewRecorder()
|
|
AuthFallback(rec, req, authtypes.LoginTypeRecaptcha, &cfg.ClientAPI)
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("unexpected http status: %d, want %d", rec.Code, http.StatusBadRequest)
|
|
}
|
|
})
|
|
|
|
t.Run("missing session parameter is handled correctly", func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
|
rec := httptest.NewRecorder()
|
|
AuthFallback(rec, req, authtypes.LoginTypeRecaptcha, &cfg.ClientAPI)
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("unexpected http status: %d, want %d", rec.Code, http.StatusBadRequest)
|
|
}
|
|
})
|
|
|
|
t.Run("missing 'response' is handled correctly", func(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodPost, "/?session=1337", nil)
|
|
rec := httptest.NewRecorder()
|
|
AuthFallback(rec, req, authtypes.LoginTypeRecaptcha, &cfg.ClientAPI)
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("unexpected http status: %d, want %d", rec.Code, http.StatusBadRequest)
|
|
}
|
|
})
|
|
}
|