mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-06-10 16:38:18 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dc32dd2954 |
@@ -29,6 +29,9 @@ function showPassword(id) {
|
|||||||
const xhr = e.target;
|
const xhr = e.target;
|
||||||
if (xhr.status === 201) {
|
if (xhr.status === 201) {
|
||||||
window.location.replace(xhr.getResponseHeader('Location'));
|
window.location.replace(xhr.getResponseHeader('Location'));
|
||||||
|
} else if ([422, 429].includes(xhr.status)) {
|
||||||
|
disableSpinner()
|
||||||
|
showError(xhr.response);
|
||||||
} else if (xhr.status === 422) {
|
} else if (xhr.status === 422) {
|
||||||
disableSpinner()
|
disableSpinner()
|
||||||
showError(xhr.response);
|
showError(xhr.response);
|
||||||
|
|||||||
@@ -11,23 +11,52 @@ use Psr\Http\Message\ResponseInterface as Response;
|
|||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
|
|
||||||
readonly class LoginController {
|
readonly class LoginController {
|
||||||
|
private const int MAX_LOGIN_ATTEMPTS_PER_TTL = 5;
|
||||||
|
private const int LOGIN_COUNTER_TTL = 300;
|
||||||
|
private const string RATE_LIMIT_CACHE_KEY = 'login_failed_attempts';
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private AuthManager $authManager,
|
private AuthManager $authManager,
|
||||||
private DockerActionManager $dockerActionManager,
|
private DockerActionManager $dockerActionManager,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getFailedLoginCount() : int {
|
||||||
|
$count = apcu_fetch(self::RATE_LIMIT_CACHE_KEY);
|
||||||
|
return $count !== false ? (int)$count : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function incrementFailedLoginCount() : void {
|
||||||
|
if (!apcu_exists(self::RATE_LIMIT_CACHE_KEY)) {
|
||||||
|
apcu_store(self::RATE_LIMIT_CACHE_KEY, 1, self::LOGIN_COUNTER_TTL);
|
||||||
|
} else {
|
||||||
|
apcu_inc(self::RATE_LIMIT_CACHE_KEY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function resetFailedLoginCount() : void {
|
||||||
|
apcu_delete(self::RATE_LIMIT_CACHE_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
public function TryLogin(Request $request, Response $response, array $args) : Response {
|
public function TryLogin(Request $request, Response $response, array $args) : Response {
|
||||||
if (!$this->dockerActionManager->isLoginAllowed()) {
|
if (!$this->dockerActionManager->isLoginAllowed()) {
|
||||||
$response->getBody()->write("The login is blocked since Nextcloud is running.");
|
$response->getBody()->write("The login is blocked since Nextcloud is running.");
|
||||||
return $response->withHeader('Location', '.')->withStatus(422);
|
return $response->withHeader('Location', '.')->withStatus(422);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->getFailedLoginCount() >= self::MAX_LOGIN_ATTEMPTS_PER_TTL) {
|
||||||
|
$response->getBody()->write("Too many failed login attempts. Please try again in some minutes.");
|
||||||
|
return $response->withHeader('Location', '.')->withStatus(429);
|
||||||
|
}
|
||||||
|
|
||||||
$password = $request->getParsedBody()['password'] ?? '';
|
$password = $request->getParsedBody()['password'] ?? '';
|
||||||
if($this->authManager->CheckCredentials($password)) {
|
if($this->authManager->CheckCredentials($password)) {
|
||||||
|
$this->resetFailedLoginCount();
|
||||||
$this->authManager->SetAuthState(true);
|
$this->authManager->SetAuthState(true);
|
||||||
return $response->withHeader('Location', '.')->withStatus(201);
|
return $response->withHeader('Location', '.')->withStatus(201);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->incrementFailedLoginCount();
|
||||||
$response->getBody()->write("The password is incorrect.");
|
$response->getBody()->write("The password is incorrect.");
|
||||||
return $response->withHeader('Location', '.')->withStatus(422);
|
return $response->withHeader('Location', '.')->withStatus(422);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user