Merge pull request #35345 from nextcloud/feat/add_event_for_failed_logins

feat: add event for failed logins
pull/35580/head
Simon L 3 years ago committed by GitHub
commit c19e7a9b68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      lib/composer/composer/autoload_classmap.php
  2. 1
      lib/composer/composer/autoload_static.php
  3. 12
      lib/private/Authentication/Events/LoginFailed.php
  4. 3
      lib/private/Authentication/Listeners/LoginFailedListener.php
  5. 3
      lib/private/Authentication/Login/LoggedInCheckCommand.php
  6. 2
      lib/private/User/Session.php
  7. 62
      lib/public/Authentication/Events/AnyLoginFailedEvent.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',

@ -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',

@ -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;
}
}

@ -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',

@ -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);
}

@ -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');

@ -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;
}
}
Loading…
Cancel
Save