fix: login refuses a not-activated account while require_activation is on

The refusal is the same 401 invalid-login answer as a wrong password and is counted by the login throttle.
The activation is checked after the password and before the deactivation restore, so a refused account stays deactivated.
require_activation false keeps the previous behaviour.
This commit is contained in:
Jakub Zych
2026-10-22 21:25:53 +02:00
parent 930b1587a0
commit 15ff9793ba
6 changed files with 287 additions and 23 deletions

View File

@@ -1000,7 +1000,18 @@ func TestAdminUserPassword(t *testing.T) {
} {
assertNoSecret(t, rec.Body.String(), first, user.Password)
}
// A request cannot turn the activation on, and cannot store a hash directly.
// Escalation G2: the account the administrator created is not activated,
// so its password does not sign it in while require_activation is on
// (the default); it gets the invalid-login answer of a wrong password.
// A request still cannot turn the activation on, and cannot store a hash
// directly. Once an administrator activates it, the password signs in.
refused := env.call(t, http.MethodPost, "/_user/api/v1/login", "", map[string]string{"email": email, "password": first})
if refused.Code != http.StatusUnauthorized || refused.Body.String() != invalidLoginBody {
t.Fatalf("login of the not-activated user = %d %s", refused.Code, refused.Body.String())
}
if rec := env.bulk(t, token, "activate", user); rec.Code != http.StatusOK {
t.Fatalf("activate = %d %s", rec.Code, rec.Body.String())
}
if status, _ := env.userLogin(t, email, first); status != http.StatusOK {
t.Fatalf("login with the created password = %d", status)
}
@@ -1094,8 +1105,8 @@ func TestAdminUserPassword(t *testing.T) {
if status, _ := env.userLogin(t, email, second); status != http.StatusOK {
t.Fatalf("the new password does not sign in: %d", status)
}
// The reset did not activate the user or touch anything else.
if after.IsActivated || after.Email != email {
// The reset kept the activation and the email.
if !after.IsActivated || after.Email != email {
t.Fatalf("the reset changed more than the password: %+v", after)
}
}