diff --git a/core/core.services.yml b/core/core.services.yml index e5fae05..eaa0607 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -607,8 +607,6 @@ services: site_status_negotiator: class: Drupal\Core\Site\StatusNegotiator arguments: ['@state', '@current_user'] - tags: - - { name: service_collector, tag: maintenance_mode_exemption, call: addExemption } maintenance_mode_subscriber: class: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber arguments: ['@site_status_negotiator', '@string_translation', '@url_generator', '@current_user'] diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php index fe595b1..f06dfe6 100644 --- a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php @@ -74,9 +74,9 @@ public function __construct(StatusNegotiatorInterface $status_negotiator, Transl * The event to process. */ public function onKernelRequestMaintenance(GetResponseEvent $event) { - if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST && $this->statusNegotiator->getStatus() != StatusNegotiatorInterface::SITE_ONLINE) { - $route_match = RouteMatch::createFromRequest($event->getRequest()); - if (!$this->statusNegotiator->exempt($route_match, $this->account)) { + $route_match = RouteMatch::createFromRequest($event->getRequest()); + if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST && $this->statusNegotiator->getStatus($route_match) != StatusNegotiatorInterface::SITE_ONLINE) { + if (!$this->statusNegotiator->exempt($this->account)) { // Deliver the 503 page if the site is in maintenance mode and the // logged in user is not allowed to bypass it. throw new ServiceUnavailableHttpException(); diff --git a/core/lib/Drupal/Core/Site/MaintenanceExemptionInterface.php b/core/lib/Drupal/Core/Site/MaintenanceExemptionInterface.php deleted file mode 100644 index 01a487f..0000000 --- a/core/lib/Drupal/Core/Site/MaintenanceExemptionInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -state = $state; - $this->exemptionHandlers = array(); } /** * {@inheritdoc} */ - public function getStatus() { - return $this->state->get('system.maintenance_mode') ? StatusNegotiatorInterface::SITE_OFFLINE : StatusNegotiatorInterface::SITE_ONLINE; - } + public function getStatus(RouteMatchInterface $route_match) { + if (!$this->state->get('system.maintenance_mode')) { + return StatusNegotiatorInterface::SITE_ONLINE; + } - /** - * {@inheritdoc} - */ - public function exempt(RouteMatchInterface $route_match, AccountInterface $account) { - foreach ($this->exemptionHandlers as $handler) { - if ($handler->exempt($route_match, $account)) { - return TRUE; + if ($route = $route_match->getRouteObject()) { + if ($route->getOption('_maintenance_access')) { + return StatusNegotiatorInterface::SITE_ONLINE; } } - return FALSE; + return StatusNegotiatorInterface::SITE_OFFLINE; } /** - * Add an exemption handler. - * - * @param \Drupal\Core\Site\MaintenanceExemptionInterface $handler - * A maintenance exemption handler. + * {@inheritdoc} */ - public function addExemption(MaintenanceExemptionInterface $handler) { - $this->exemptionHandlers[] = $handler; + public function exempt(AccountInterface $account) { + return $account->hasPermission('access site in maintenance mode'); } } diff --git a/core/lib/Drupal/Core/Site/StatusNegotiatorInterface.php b/core/lib/Drupal/Core/Site/StatusNegotiatorInterface.php index 0eabb49..7e72ebe 100644 --- a/core/lib/Drupal/Core/Site/StatusNegotiatorInterface.php +++ b/core/lib/Drupal/Core/Site/StatusNegotiatorInterface.php @@ -7,12 +7,14 @@ namespace Drupal\Core\Site; +use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Session\AccountInterface; use Drupal\Core\State\StateInterface; /** * Provides the default implementation of the site status negotiator. */ -interface StatusNegotiatorInterface extends MaintenanceExemptionInterface { +interface StatusNegotiatorInterface { /** * @defgroup menu_status_codes Menu status codes @@ -37,9 +39,23 @@ /** * Returns whether the site is in maintenance mode. * + * @param \Drupal\Core\Routing\RouteMatchInterface $route_match + * The current route match. + * * @return int * Either static::SITE_OFFLINE or static::SITE_ONLINE. */ - public function getStatus(); + public function getStatus(RouteMatchInterface $route_match); + + /** + * Returns TRUE if the given account should be exempted from maintenance mode. + * + * @param \Drupal\Core\Session\AccountInterface $account + * The logged in user. + * + * @return bool + * TRUE if the user should be exempted from maintenance mode. + */ + public function exempt(AccountInterface $account); } diff --git a/core/modules/system/src/Site/MaintenanceExemption.php b/core/modules/system/src/Site/MaintenanceExemption.php deleted file mode 100644 index 22036f5..0000000 --- a/core/modules/system/src/Site/MaintenanceExemption.php +++ /dev/null @@ -1,28 +0,0 @@ -hasPermission('access site in maintenance mode')) { - return TRUE; - } - } - -} diff --git a/core/modules/system/system.services.yml b/core/modules/system/system.services.yml index 9913425..2b7046c 100644 --- a/core/modules/system/system.services.yml +++ b/core/modules/system/system.services.yml @@ -33,7 +33,3 @@ services: arguments: ['@cron', '@config.factory', '@state'] tags: - { name: event_subscriber } - system.maintenance_mode_exemption: - class: Drupal\system\Site\MaintenanceExemption - tags: - - { name: maintenance_mode_exemption } diff --git a/core/modules/system/tests/modules/menu_test/menu_test.routing.yml b/core/modules/system/tests/modules/menu_test/menu_test.routing.yml index 6c3c106..7e6984d 100644 --- a/core/modules/system/tests/modules/menu_test/menu_test.routing.yml +++ b/core/modules/system/tests/modules/menu_test/menu_test.routing.yml @@ -20,6 +20,8 @@ menu_test.login_callback: _content: '\Drupal\menu_test\TestControllers::testLogin' requirements: _access: 'TRUE' + options: + _maintenance_access: TRUE menu_test.callback_description: path: '/menu_callback_description' diff --git a/core/modules/system/tests/modules/menu_test/menu_test.services.yml b/core/modules/system/tests/modules/menu_test/menu_test.services.yml index 951274f..8841320 100644 --- a/core/modules/system/tests/modules/menu_test/menu_test.services.yml +++ b/core/modules/system/tests/modules/menu_test/menu_test.services.yml @@ -1,9 +1,4 @@ services: - menu_test_maintenance_mode_exemption: - class: Drupal\menu_test\Site\MaintenanceExemption - tags: - - { name: maintenance_mode_exemption } - theme.negotiator.test_theme: class: Drupal\menu_test\Theme\TestThemeNegotiator tags: diff --git a/core/modules/system/tests/modules/menu_test/src/Site/MaintenanceExemption.php b/core/modules/system/tests/modules/menu_test/src/Site/MaintenanceExemption.php deleted file mode 100644 index 750a83a..0000000 --- a/core/modules/system/tests/modules/menu_test/src/Site/MaintenanceExemption.php +++ /dev/null @@ -1,29 +0,0 @@ -getRouteName() == 'menu_test.login_callback') { - return TRUE; - } - } - -} diff --git a/core/modules/user/src/EventSubscriber/MaintenanceModeSubscriber.php b/core/modules/user/src/EventSubscriber/MaintenanceModeSubscriber.php index 73d5c9e..62a5689 100644 --- a/core/modules/user/src/EventSubscriber/MaintenanceModeSubscriber.php +++ b/core/modules/user/src/EventSubscriber/MaintenanceModeSubscriber.php @@ -55,12 +55,12 @@ public function __construct(StatusNegotiatorInterface $status_negotiator, Accoun */ public function onKernelRequestMaintenance(GetResponseEvent $event) { $request = $event->getRequest(); - $site_status = $this->statusNegotiator->getStatus(); + $route_match = RouteMatch::createFromRequest($request); + $site_status = $this->statusNegotiator->getStatus($route_match); $path = $request->attributes->get('_system_path'); if ($site_status == StatusNegotiatorInterface::SITE_OFFLINE) { - $route_match = RouteMatch::createFromRequest($request); // If the site is offline, log out unprivileged users. - if ($this->account->isAuthenticated() && !$this->statusNegotiator->exempt($route_match, $this->account)) { + if ($this->account->isAuthenticated() && !$this->statusNegotiator->exempt($this->account)) { user_logout(); // Redirect to homepage. $event->setResponse(new RedirectResponse(url('', array('absolute' => TRUE)))); diff --git a/core/modules/user/src/Site/MaintenanceExemption.php b/core/modules/user/src/Site/MaintenanceExemption.php deleted file mode 100644 index 6e3ab4b..0000000 --- a/core/modules/user/src/Site/MaintenanceExemption.php +++ /dev/null @@ -1,27 +0,0 @@ -getRouteName(); - return in_array($route_name, ['user.login', 'user.pass', 'user.reset']); - } - -} diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml index 55c57d1..7e563f1 100644 --- a/core/modules/user/user.routing.yml +++ b/core/modules/user/user.routing.yml @@ -122,6 +122,8 @@ user.pass: _title: 'Request new password' requirements: _access: 'TRUE' + options: + _maintenance_access: TRUE user.page: path: '/user' @@ -146,6 +148,8 @@ user.login: _title: 'Log in' requirements: _access: 'TRUE' + options: + _maintenance_access: TRUE user.edit: path: '/user/{user}/edit' diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml index 74b68df..3a3e3a8 100644 --- a/core/modules/user/user.services.yml +++ b/core/modules/user/user.services.yml @@ -55,7 +55,3 @@ services: user.tempstore: class: Drupal\user\TempStoreFactory arguments: ['@serialization.phpserialize', '@database', '@lock'] - user.maintenance_mode_exemption: - class: Drupal\user\Site\MaintenanceExemption - tags: - - { name: maintenance_mode_exemption }