summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon L <szaimen@e.mail.de>2022-12-03 20:00:36 +0100
committerGitHub <noreply@github.com>2022-12-03 20:00:36 +0100
commitc19e7a9b68c927bb6d241e02ff50932a1a4eaab1 (patch)
treeb25fe7a013a64b0da6c7f698294e1e27f676db5a
parent31ec83f2d82544741cb16836de60fc92072efca8 (diff)
parent77df92cabf9baf82e1d3fce39f7a27e842a1197d (diff)
downloadnextcloud-server-c19e7a9b68c927bb6d241e02ff50932a1a4eaab1.tar.gz
nextcloud-server-c19e7a9b68c927bb6d241e02ff50932a1a4eaab1.zip
Merge pull request #35345 from nextcloud/feat/add_event_for_failed_logins
feat: add event for failed logins
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/Authentication/Events/LoginFailed.php12
-rw-r--r--lib/private/Authentication/Listeners/LoginFailedListener.php3
-rw-r--r--lib/private/Authentication/Login/LoggedInCheckCommand.php3
-rw-r--r--lib/private/User/Session.php2
-rw-r--r--lib/public/Authentication/Events/AnyLoginFailedEvent.php62
7 files changed, 78 insertions, 6 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 90e7fe51fa7..53a957c419a 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -83,6 +83,7 @@ return array(
'OCP\\App\\AppPathNotFoundException' => $baseDir . '/lib/public/App/AppPathNotFoundException.php',
'OCP\\App\\IAppManager' => $baseDir . '/lib/public/App/IAppManager.php',
'OCP\\App\\ManagerEvent' => $baseDir . '/lib/public/App/ManagerEvent.php',
+ 'OCP\\Authentication\\Events\\AnyLoginFailedEvent' => $baseDir . '/lib/public/Authentication/Events/AnyLoginFailedEvent.php',
'OCP\\Authentication\\Events\\LoginFailedEvent' => $baseDir . '/lib/public/Authentication/Events/LoginFailedEvent.php',
'OCP\\Authentication\\Exceptions\\CredentialsUnavailableException' => $baseDir . '/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php',
'OCP\\Authentication\\Exceptions\\PasswordUnavailableException' => $baseDir . '/lib/public/Authentication/Exceptions/PasswordUnavailableException.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 8cef29efc39..a35df71e376 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -116,6 +116,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OCP\\App\\AppPathNotFoundException' => __DIR__ . '/../../..' . '/lib/public/App/AppPathNotFoundException.php',
'OCP\\App\\IAppManager' => __DIR__ . '/../../..' . '/lib/public/App/IAppManager.php',
'OCP\\App\\ManagerEvent' => __DIR__ . '/../../..' . '/lib/public/App/ManagerEvent.php',
+ 'OCP\\Authentication\\Events\\AnyLoginFailedEvent' => __DIR__ . '/../../..' . '/lib/public/Authentication/Events/AnyLoginFailedEvent.php',
'OCP\\Authentication\\Events\\LoginFailedEvent' => __DIR__ . '/../../..' . '/lib/public/Authentication/Events/LoginFailedEvent.php',
'OCP\\Authentication\\Exceptions\\CredentialsUnavailableException' => __DIR__ . '/../../..' . '/lib/public/Authentication/Exceptions/CredentialsUnavailableException.php',
'OCP\\Authentication\\Exceptions\\PasswordUnavailableException' => __DIR__ . '/../../..' . '/lib/public/Authentication/Exceptions/PasswordUnavailableException.php',
diff --git a/lib/private/Authentication/Events/LoginFailed.php b/lib/private/Authentication/Events/LoginFailed.php
index 138e567139a..ef702e40a59 100644
--- a/lib/private/Authentication/Events/LoginFailed.php
+++ b/lib/private/Authentication/Events/LoginFailed.php
@@ -28,17 +28,21 @@ namespace OC\Authentication\Events;
use OCP\EventDispatcher\Event;
class LoginFailed extends Event {
+ private string $loginName;
+ private ?string $password;
- /** @var string */
- private $loginName;
-
- public function __construct(string $loginName) {
+ public function __construct(string $loginName, ?string $password) {
parent::__construct();
$this->loginName = $loginName;
+ $this->password = $password;
}
public function getLoginName(): string {
return $this->loginName;
}
+
+ public function getPassword(): ?string {
+ return $this->password;
+ }
}
diff --git a/lib/private/Authentication/Listeners/LoginFailedListener.php b/lib/private/Authentication/Listeners/LoginFailedListener.php
index 12d5dd4c17e..f75ee51b287 100644
--- a/lib/private/Authentication/Listeners/LoginFailedListener.php
+++ b/lib/private/Authentication/Listeners/LoginFailedListener.php
@@ -27,6 +27,7 @@ declare(strict_types=1);
namespace OC\Authentication\Listeners;
use OC\Authentication\Events\LoginFailed;
+use OCP\Authentication\Events\AnyLoginFailedEvent;
use OCP\Authentication\Events\LoginFailedEvent;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventDispatcher;
@@ -55,6 +56,8 @@ class LoginFailedListener implements IEventListener {
return;
}
+ $this->dispatcher->dispatchTyped(new AnyLoginFailedEvent($event->getLoginName(), $event->getPassword()));
+
$uid = $event->getLoginName();
Util::emitHook(
'\OCA\Files_Sharing\API\Server2Server',
diff --git a/lib/private/Authentication/Login/LoggedInCheckCommand.php b/lib/private/Authentication/Login/LoggedInCheckCommand.php
index 0efd84adbf5..9f80d47a3d4 100644
--- a/lib/private/Authentication/Login/LoggedInCheckCommand.php
+++ b/lib/private/Authentication/Login/LoggedInCheckCommand.php
@@ -48,11 +48,12 @@ class LoggedInCheckCommand extends ALoginCommand {
public function process(LoginData $loginData): LoginResult {
if ($loginData->getUser() === false) {
$loginName = $loginData->getUsername();
+ $password = $loginData->getPassword();
$ip = $loginData->getRequest()->getRemoteAddress();
$this->logger->warning("Login failed: $loginName (Remote IP: $ip)");
- $this->dispatcher->dispatchTyped(new LoginFailed($loginName));
+ $this->dispatcher->dispatchTyped(new LoginFailed($loginName, $password));
return LoginResult::failure($loginData, LoginController::LOGIN_MSG_INVALIDPASSWORD);
}
diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php
index 203d755d0ab..c7b11e22504 100644
--- a/lib/private/User/Session.php
+++ b/lib/private/User/Session.php
@@ -458,7 +458,7 @@ class Session implements IUserSession, Emitter {
$throttler->registerAttempt('login', $request->getRemoteAddress(), ['user' => $user]);
- $this->dispatcher->dispatchTyped(new OC\Authentication\Events\LoginFailed($user));
+ $this->dispatcher->dispatchTyped(new OC\Authentication\Events\LoginFailed($user, $password));
if ($currentDelay === 0) {
$throttler->sleepDelay($request->getRemoteAddress(), 'login');
diff --git a/lib/public/Authentication/Events/AnyLoginFailedEvent.php b/lib/public/Authentication/Events/AnyLoginFailedEvent.php
new file mode 100644
index 00000000000..ddfec6d9da8
--- /dev/null
+++ b/lib/public/Authentication/Events/AnyLoginFailedEvent.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2022, Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+namespace OCP\Authentication\Events;
+
+use OCP\EventDispatcher\Event;
+
+/**
+ * Emitted when the authentication fails
+ *
+ * @since 26.0.0
+ */
+class AnyLoginFailedEvent extends Event {
+ private string $loginName;
+ private ?string $password;
+
+ /**
+ * @since 26.0.0
+ */
+ public function __construct(string $loginName, ?string $password) {
+ parent::__construct();
+
+ $this->loginName = $loginName;
+ $this->password = $password;
+ }
+
+ /**
+ * @since 26.0.0
+ */
+ public function geLoginName(): string {
+ return $this->loginName;
+ }
+
+ /**
+ * @since 26.0.0
+ */
+ public function getPassword(): ?string {
+ return $this->password;
+ }
+}