Use Middleware to intercept login page
Signed-off-by: Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
This commit is contained in:
Родитель
d13795bdd6
Коммит
96de09e1d0
|
@ -25,14 +25,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace OCA\LimitLoginToIp\AppInfo;
|
||||
|
||||
use OCA\LimitLoginToIp\IsRequestAllowed;
|
||||
use OCA\LimitLoginToIp\LoginHookListener;
|
||||
use OCA\LimitLoginToIp\Middleware\CanSeeLoginPageMiddleware;
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\Bootstrap\IBootContext;
|
||||
use OCP\AppFramework\Bootstrap\IBootstrap;
|
||||
use OCP\AppFramework\Bootstrap\IRegistrationContext;
|
||||
use OCP\IRequest;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\User\Events\BeforeUserLoggedInEvent;
|
||||
|
||||
/**
|
||||
|
@ -41,11 +39,12 @@ use OCP\User\Events\BeforeUserLoggedInEvent;
|
|||
class Application extends App implements IBootstrap {
|
||||
public const APP_ID = 'limit_login_to_ip';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(self::APP_ID);
|
||||
public function __construct(array $urlParams = []) {
|
||||
parent::__construct(self::APP_ID, $urlParams);
|
||||
}
|
||||
|
||||
public function register(IRegistrationContext $context): void {
|
||||
$context->registerMiddleware(CanSeeLoginPageMiddleware::class, true);
|
||||
$context->registerEventListener(
|
||||
BeforeUserLoggedInEvent::class,
|
||||
LoginHookListener::class,
|
||||
|
@ -54,23 +53,5 @@ class Application extends App implements IBootstrap {
|
|||
}
|
||||
|
||||
public function boot(IBootContext $context): void {
|
||||
$server = $context->getServerContainer();
|
||||
/** @var IURLGenerator */
|
||||
$urlGenerator = $server->get(IURLGenerator::class);
|
||||
/** @var IRequest */
|
||||
$request = $server->get(IRequest::class);
|
||||
|
||||
// Special behaviour for login page
|
||||
// Block page before displaying form
|
||||
$currentPath = parse_url($request->getRequestUri(), PHP_URL_PATH);
|
||||
$loginPath = $urlGenerator->linkToRoute('core.login.showLoginForm');
|
||||
/** @var IsRequestAllowed */
|
||||
$isRequestAllowed = $server->get(IsRequestAllowed::class);
|
||||
if ($currentPath === $loginPath && !$isRequestAllowed()) {
|
||||
http_response_code(403);
|
||||
$forbiddenLoginPath = $urlGenerator->linkToRouteAbsolute('limit_login_to_ip.LoginDenied.showErrorPage');
|
||||
header('Location: '. $forbiddenLoginPath);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
|
||||
*
|
||||
* @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 OCA\LimitLoginToIp\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
final class ForbiddenLoginException extends Exception {
|
||||
public function __construct() {
|
||||
parent::__construct('Login denied', 403);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* @copyright Copyright (c) 2023 Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
|
||||
*
|
||||
* @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 OCA\LimitLoginToIp\Middleware;
|
||||
|
||||
use Exception;
|
||||
use OC\Core\Controller\LoginController;
|
||||
use OCA\LimitLoginToIp\Exception\ForbiddenLoginException;
|
||||
use OCA\LimitLoginToIp\IsRequestAllowed;
|
||||
use OCP\AppFramework\Middleware;
|
||||
use OCP\IURLGenerator;
|
||||
|
||||
/**
|
||||
* Checks whether the "sharing check" is enabled
|
||||
*
|
||||
* @package OCA\LimitLoginToIp\Middleware
|
||||
* @psalm-api
|
||||
*/
|
||||
class CanSeeLoginPageMiddleware extends Middleware {
|
||||
private const LOGIN_METHOD_NAMES = [
|
||||
'tryLogin',
|
||||
'confirmPassword',
|
||||
'showLoginForm',
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
private IsRequestAllowed $isRequestAllowed,
|
||||
private IURLGenerator $urlGenerator,
|
||||
) {
|
||||
}
|
||||
|
||||
public function beforeController($controller, $methodName): void {
|
||||
// Only filter login actions
|
||||
/** @psalm-suppress all */
|
||||
if (!$controller instanceof LoginController || !in_array($methodName, self::LOGIN_METHOD_NAMES, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!($this->isRequestAllowed)()) {
|
||||
throw new ForbiddenLoginException();
|
||||
}
|
||||
}
|
||||
|
||||
public function afterException($controller, $methodName, Exception $exception): void {
|
||||
if (!$exception instanceof ForbiddenLoginException) {
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
$forbiddenLoginPath = $this->urlGenerator->linkToRouteAbsolute('limit_login_to_ip.LoginDenied.showErrorPage');
|
||||
header('Location: '. $forbiddenLoginPath);
|
||||
exit;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<files psalm-version="5.14.1@b9d355e0829c397b9b3b47d0c0ed042a8a70284d">
|
||||
<file src="lib/AppInfo/Application.php">
|
||||
<DeprecatedInterface>
|
||||
<code><![CDATA[$context->getServerContainer()]]></code>
|
||||
</DeprecatedInterface>
|
||||
</file>
|
||||
<files psalm-version="5.15.0@5c774aca4746caf3d239d9c8cadb9f882ca29352">
|
||||
<file src="lib/IsRequestAllowed.php">
|
||||
<PossiblyUnusedMethod>
|
||||
<code>__construct</code>
|
||||
|
|
Загрузка…
Ссылка в новой задаче