mirror of
https://github.com/Icinga/icingaweb2.git
synced 2026-05-28 04:02:39 -04:00
Migrate AuthenticationController to CompatController
Convert `AuthenticationController` from the legacy Zend Controller to `CompatController`, dropping `login.phtml` in favour of the new `LoginPage` widget and `addContent()`. The view variable assignments are replaced by `setTitle()` and `addContent(new LoginPage(...))`. Improve `httpBadRequest()` message for external redirect attempts. In `CompatController`, `$this->controls` is the tab bar area rendered above the page content. When no tabs are added it still emits an empty `<div class="controls">` wrapper. Setting `$this->view->compact = true` suppresses that wrapper entirely, keeping the login page markup clean. Handle the redirect on success in an `ON_SUBMIT` event handler. Delegate the external-backend-only check to `LoginForm::onRequest()` via `ON_REQUEST`. Use `$this->getServerRequest()` instead of `ServerRequest::fromGlobals()`. Two structural fixes required by the changed DOM nesting: - `login.less`: height `100%` -> `100vh` (`#login` is now inside `.content` which has no explicit height, so percentage inheritance breaks) - `history.js`: `#layout > #login` -> `#layout #login` (direct-child selector breaks because `#login` is now a grandchild of `#layout` through `.content`)
This commit is contained in:
parent
1dd503e9af
commit
650ea2b597
4 changed files with 27 additions and 77 deletions
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
namespace Icinga\Controllers;
|
||||
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Icinga\Application\ClassLoader;
|
||||
use Icinga\Application\Hook\AuthenticationHook;
|
||||
use Icinga\Application\Hook\LoginButtonHook;
|
||||
|
|
@ -16,17 +15,20 @@ use Icinga\Authentication\LoginButtonForm;
|
|||
use Icinga\Common\Database;
|
||||
use Icinga\Exception\AuthenticationException;
|
||||
use Icinga\Forms\Authentication\LoginForm;
|
||||
use Icinga\Web\Controller;
|
||||
use Icinga\Web\Helper\CookieHelper;
|
||||
use Icinga\Web\RememberMe;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Web\Widget\LoginPage;
|
||||
use ipl\Html\Contract\Form;
|
||||
use ipl\Web\Compat\CompatController;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Application wide controller for authentication
|
||||
*/
|
||||
class AuthenticationController extends Controller
|
||||
class AuthenticationController extends CompatController
|
||||
{
|
||||
use Database;
|
||||
|
||||
|
|
@ -49,7 +51,17 @@ class AuthenticationController extends Controller
|
|||
if (($requiresSetup = $icinga->requiresSetup()) && $icinga->setupTokenExists()) {
|
||||
$this->redirectNow(Url::fromPath('setup'));
|
||||
}
|
||||
$form = new LoginForm();
|
||||
|
||||
$form = (new LoginForm())
|
||||
->setAction(Url::fromRequest()->getAbsoluteUrl())
|
||||
->on(Form::ON_SUBMIT, function (LoginForm $form) {
|
||||
if ($redirectUrl = $form->getRedirectUrl()) {
|
||||
$this->redirectNow($redirectUrl);
|
||||
}
|
||||
})
|
||||
->on(Form::ON_REQUEST, function (ServerRequestInterface $_, LoginForm $form) {
|
||||
$form->onRequest();
|
||||
});
|
||||
|
||||
if (RememberMe::hasCookie() && $this->hasDb()) {
|
||||
$authenticated = false;
|
||||
|
|
@ -81,14 +93,16 @@ class AuthenticationController extends Controller
|
|||
if ($redirect) {
|
||||
$redirectUrl = Url::fromPath($redirect, [], $this->getRequest());
|
||||
if ($redirectUrl->isExternal()) {
|
||||
$this->httpBadRequest('nope');
|
||||
$this->httpBadRequest('Redirect to an external host is not allowed');
|
||||
}
|
||||
} else {
|
||||
$redirectUrl = $form->getRedirectUrl();
|
||||
$redirectUrl = $form->createRedirectUrl();
|
||||
}
|
||||
|
||||
$this->redirectNow($redirectUrl);
|
||||
}
|
||||
|
||||
$request = $this->getServerRequest();
|
||||
if (! $requiresSetup) {
|
||||
$cookies = new CookieHelper($this->getRequest());
|
||||
if (! $cookies->isSupported()) {
|
||||
|
|
@ -99,11 +113,10 @@ class AuthenticationController extends Controller
|
|||
->sendResponse();
|
||||
exit;
|
||||
}
|
||||
$form->handleRequest();
|
||||
$form->handleRequest($request);
|
||||
}
|
||||
|
||||
$loginButtons = [];
|
||||
$request = ServerRequest::fromGlobals();
|
||||
|
||||
foreach (LoginButtonHook::all() as $class => $hook) {
|
||||
try {
|
||||
|
|
@ -126,10 +139,10 @@ class AuthenticationController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
$this->view->form = $form;
|
||||
$this->view->loginButtons = $loginButtons;
|
||||
$this->view->defaultTitle = $this->translate('Icinga Web 2 Login');
|
||||
$this->view->requiresSetup = $requiresSetup;
|
||||
// Suppress the rendering of controls bar
|
||||
$this->view->compact = true;
|
||||
$this->setTitle($this->translate('Icinga Web 2 Login'));
|
||||
$this->addContent(new LoginPage($form, $loginButtons, $requiresSetup));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
<div id="login">
|
||||
<div class="login-form" data-base-target="layout">
|
||||
<div role="status" class="sr-only">
|
||||
<?= $this->translate(
|
||||
'Welcome to Icinga Web 2. For users of the screen reader Jaws full and expectant compliant'
|
||||
. ' accessibility is possible only with use of the Firefox browser. VoiceOver on Mac OS X is tested on'
|
||||
. ' Chrome, Safari and Firefox.'
|
||||
) ?>
|
||||
</div>
|
||||
<div class="logo-wrapper"><div id="icinga-logo" aria-hidden="true"></div></div>
|
||||
<?php if ($requiresSetup): ?>
|
||||
<p class="config-note"><?= sprintf(
|
||||
$this->translate(
|
||||
'It appears that you did not configure Icinga Web 2 yet so it\'s not possible to log in without any defined '
|
||||
. 'authentication method. Please define a authentication method by following the instructions in the'
|
||||
. ' %1$sdocumentation%3$s or by using our %2$sweb-based setup-wizard%3$s.'
|
||||
),
|
||||
'<a href="https://icinga.com/docs/icinga-web-2/latest/doc/05-Authentication/#authentication" title="'
|
||||
. $this->translate('Icinga Web 2 Documentation') . '">',
|
||||
'<a href="' . $this->href('setup') . '" title="' . $this->translate('Icinga Web 2 Setup-Wizard') . '">',
|
||||
'</a>'
|
||||
) ?></p>
|
||||
<?php endif ?>
|
||||
<?= $this->form ?>
|
||||
<?= implode('', $this->loginButtons) ?>
|
||||
<div id="login-footer">
|
||||
<p>Icinga Web 2 © 2013-<?= date('Y') ?></p>
|
||||
<?= $this->qlink($this->translate('icinga.com'), 'https://icinga.com') ?>
|
||||
</div>
|
||||
</div>
|
||||
<ul id="social">
|
||||
<li>
|
||||
<?= $this->qlink(
|
||||
null,
|
||||
'https://www.facebook.com/icinga',
|
||||
null,
|
||||
array(
|
||||
'target' => '_blank',
|
||||
'icon' => 'facebook-squared',
|
||||
'title' => $this->translate('Icinga on Facebook')
|
||||
)
|
||||
) ?>
|
||||
</li>
|
||||
<li><?= $this->qlink(
|
||||
null,
|
||||
'https://github.com/Icinga',
|
||||
null,
|
||||
array(
|
||||
'target' => '_blank',
|
||||
'icon' => 'github-circled',
|
||||
'title' => $this->translate('Icinga on GitHub')
|
||||
)
|
||||
) ?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="orb-analytics" class="orb" ><?= $this->img('img/orb-analytics.png'); ?></div>
|
||||
<div id="orb-automation" class="orb"><?= $this->img('img/orb-automation.png'); ?></div>
|
||||
<div id="orb-cloud" class="orb"><?= $this->img('img/orb-cloud.png'); ?></div>
|
||||
<div id="orb-icinga" class="orb"><?= $this->img('img/orb-icinga.png'); ?></div>
|
||||
<div id="orb-infrastructure" class="orb"><?= $this->img('img/orb-infrastructure.png'); ?></div>
|
||||
<div id="orb-metrics" class="orb" ><?= $this->img('img/orb-metrics.png'); ?></div>
|
||||
<div id="orb-notifactions" class="orb"><?= $this->img('img/orb-notifications.png'); ?></div>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
// Login page styles
|
||||
|
||||
#login {
|
||||
height: 100%;
|
||||
height: 100vh;
|
||||
background-color: @menu-bg-color;
|
||||
background-image: url(../img/icingaweb2-background-orbs.jpg);
|
||||
background-repeat: no-repeat;
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@
|
|||
applyLocationBar: function (onload = false) {
|
||||
let col2State = this.getCol2State();
|
||||
|
||||
if (onload && document.querySelector('#layout > #login')) {
|
||||
if (onload && document.querySelector('#layout #login')) {
|
||||
// The user landed on the login
|
||||
let redirectInput = document.querySelector('#login form input[name=redirect]');
|
||||
redirectInput.value = redirectInput.value + col2State;
|
||||
|
|
|
|||
Loading…
Reference in a new issue