aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoeland Jago Douma <roeland@famdouma.nl>2022-11-22 22:43:01 +0100
committerRoeland Jago Douma <roeland@famdouma.nl>2022-11-24 21:24:21 +0100
commit77df92cabf9baf82e1d3fce39f7a27e842a1197d (patch)
tree550dd5db0b654be36e0dcab72eb889aa00851423
parent28f41059051afaf665e80e69ea2e90251aa1662e (diff)
downloadnextcloud-server-77df92cabf9baf82e1d3fce39f7a27e842a1197d.tar.gz
nextcloud-server-77df92cabf9baf82e1d3fce39f7a27e842a1197d.zip
feat: add event for failed logins
Apps might also like to know about failed logins. This adds that event. The private interface changes are backwards compatible so all should be fine. Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
-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 d8016e10b79..fc6fd6727c7 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 595c7ec3736..6ba5c4cf691 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;
+ }
+}