59 lines
2.2 KiB
Go
59 lines
2.2 KiB
Go
package controllers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestPublicRecoveryFlowHTTP(t *testing.T) {
|
|
enablePublicRecoveryForTest(t)
|
|
s, _, _, user, super := newPublicSecurityFixture(t)
|
|
previous := currentSecurityRuntime()
|
|
ConfigureSecurityRuntime(nil, nil, s, nil)
|
|
oldBegin, oldFailure := emailRecoveryBeginIPAttempts, emailRecoveryFailureIPAttempts
|
|
emailRecoveryBeginIPAttempts, emailRecoveryFailureIPAttempts = newLoginLimiter(100), newLoginLimiter(100)
|
|
t.Cleanup(func() {
|
|
ConfigureSecurityRuntime(previous.verification, previous.external, previous.recovery, previous.credentials)
|
|
emailRecoveryBeginIPAttempts, emailRecoveryFailureIPAttempts = oldBegin, oldFailure
|
|
})
|
|
invoke := func(endpoint, body string) (int, map[string]any) {
|
|
t.Helper()
|
|
r := httptest.NewRequest(http.MethodPost, "https://example.com/rest/api/recovery/"+endpoint, strings.NewReader(body))
|
|
r.RemoteAddr = "192.0.2.70:12345"
|
|
w := httptest.NewRecorder()
|
|
PublicPasswordRecoveryFlow(w, r)
|
|
var data map[string]any
|
|
if err := json.Unmarshal(w.Body.Bytes(), &data); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if w.Header().Get("Cache-Control") != "no-store" {
|
|
t.Fatal("recovery response cached")
|
|
}
|
|
return w.Code, data
|
|
}
|
|
status, data := invoke("begin", `{"identifier":"`+super.Account+`"}`)
|
|
if status != 200 || data["role"] != "super_admin" || data["token"] != nil {
|
|
t.Fatalf("super response: %v", data)
|
|
}
|
|
status, data = invoke("begin", `{"identifier":"`+user.Account+`"}`)
|
|
if status != 200 || data["email"] != "a***@example.com" {
|
|
t.Fatalf("identity response: %v", data)
|
|
}
|
|
token := data["token"].(string)
|
|
if status, _ := invoke("reset", `{"token":"`+token+`","new_password":"NewPass123"}`); status == 200 {
|
|
t.Fatal("unverified reset accepted")
|
|
}
|
|
if status, _ := invoke("verify", `{"token":"`+token+`","method":"email","code":"12345678"}`); status == 200 {
|
|
t.Fatal("unsent code accepted")
|
|
}
|
|
if status, _ := invoke("begin", `{"identifier":"missing"}`); status == 200 {
|
|
t.Fatal("missing user accepted")
|
|
}
|
|
if status, _ := invoke("begin", `{"identifier":"alice","role":"super_admin"}`); status == 200 {
|
|
t.Fatal("client role accepted")
|
|
}
|
|
}
|