Commit a9762cd3 authored by webchick's avatar webchick

#201415 by sun: Add a permission to access site in maintenance mode.

parent 4cbe60a5
......@@ -390,8 +390,8 @@ function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response
function drupal_site_offline() {
drupal_maintenance_theme();
drupal_set_header('503 Service unavailable');
drupal_set_title(t('Site offline'));
print theme('maintenance_page', filter_xss_admin(variable_get('site_offline_message',
drupal_set_title(t('Site under maintenance'));
print theme('maintenance_page', filter_xss_admin(variable_get('maintenance_mode_message',
t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal'))))));
}
......
......@@ -2744,32 +2744,37 @@ function menu_path_is_external($path) {
}
/**
* Checks whether the site is offline for maintenance.
* Checks whether the site is in maintenance mode.
*
* This function will log the current user out and redirect to front page
* if the current user has no 'administer site configuration' permission.
* if the current user has no 'access site in maintenance mode' permission.
*
* @return
* FALSE if the site is not offline or its the login page or the user has
* 'administer site configuration' permission.
* TRUE for anonymous users not on the login page if the site is offline.
* FALSE if the site is not in maintenance mode, the user login page is
* displayed, or the user has the 'access site in maintenance mode'
* permission. TRUE for anonymous users not being on the login page when the
* site is in maintenance mode.
*/
function _menu_site_is_offline() {
// Check if site is set to maintenance mode.
if (variable_get('site_offline', 0)) {
// Check if the user has administration privileges.
if (user_access('administer site configuration')) {
// Ensure that the offline message is displayed only once [allowing for
// page redirects], and specifically suppress its display on the site
// maintenance page.
if (drupal_get_normal_path($_GET['q']) != 'admin/config/development/maintenance') {
drupal_set_message(t('Operating in maintenance mode. <a href="@url">Go online.</a>', array('@url' => url('admin/config/development/maintenance'))), 'status', FALSE);
// Check if site is in maintenance mode.
if (variable_get('maintenance_mode', 0)) {
if (user_access('access site in maintenance mode')) {
// Ensure that the maintenance mode message is displayed only once
// (allowing for page redirects) and specifically suppress its display on
// the maintenance mode settings page.
if ($_GET['q'] != 'admin/config/development/maintenance') {
if (user_access('administer site configuration')) {
drupal_set_message(t('Operating in maintenance mode. <a href="@url">Go online.</a>', array('@url' => url('admin/config/development/maintenance'))), 'status', FALSE);
}
else {
drupal_set_message(t('Operating in maintenance mode.'), 'status', FALSE);
}
}
}
else {
// Anonymous users get a FALSE at the login prompt, TRUE otherwise.
if (user_is_anonymous()) {
return $_GET['q'] != 'user' && $_GET['q'] != 'user/login';
return ($_GET['q'] != 'user' && $_GET['q'] != 'user/login');
}
// Logged in users are unprivileged here, so they are logged out.
require_once DRUPAL_ROOT . '/' . drupal_get_path('module', 'user') . '/user.pages.inc';
......
......@@ -232,6 +232,7 @@ function update_prepare_d7_bootstrap() {
* made which make it impossible to continue using the prior version.
*/
function update_fix_d7_requirements() {
global $conf;
$ret = array();
// Rewrite the settings.php file if necessary.
......@@ -242,17 +243,24 @@ function update_fix_d7_requirements() {
file_put_contents(conf_path() . '/settings.php', "\n" . '$databases = ' . var_export($databases, TRUE) . ';', FILE_APPEND);
}
if (drupal_get_installed_schema_version('system') < 7000 && !variable_get('update_d7_requirements', FALSE)) {
// Add the cache_path table.
$schema['cache_path'] = drupal_get_schema_unprocessed('system', 'cache');
$schema['cache_path']['description'] = 'Cache table used for path alias lookups.';
db_create_table($ret, 'cache_path', $schema['cache_path']);
variable_set('update_d7_requirements', TRUE);
// Add column for locale context.
if (db_table_exists('locales_source')) {
db_add_field($ret, 'locales_source', 'context', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => 'The context this string applies to.'));
}
// Rename 'site_offline_message' variable to 'maintenance_mode_message'.
// Old variable is removed in update for system.module.
// @see system_update_7036().
if ($message = variable_get('site_offline_message', NULL)) {
variable_set('maintenance_mode_message', $message);
}
variable_set('update_d7_requirements', TRUE);
}
update_fix_d7_install_profile();
......@@ -423,9 +431,9 @@ function update_do_one($module, $number, &$context) {
function update_batch($start, $redirect = NULL, $url = NULL, $batch = array()) {
// During the update, bring the site offline so that schema changes do not
// affect visiting users.
$_SESSION['site_offline'] = variable_get('site_offline', FALSE);
if ($_SESSION['site_offline'] == FALSE) {
variable_set('site_offline', TRUE);
$_SESSION['maintenance_mode'] = variable_get('maintenance_mode', FALSE);
if ($_SESSION['maintenance_mode'] == FALSE) {
variable_set('maintenance_mode', TRUE);
}
$operations = array();
......@@ -480,10 +488,10 @@ function update_finished($success, $results, $operations) {
$_SESSION['updates_remaining'] = $operations;
// Now that the update is done, we can put the site back online if it was
// previously turned off.
if (isset($_SESSION['site_offline']) && $_SESSION['site_offline'] == FALSE) {
variable_set('site_offline', FALSE);
unset($_SESSION['site_offline']);
// previously in maintenance mode.
if (isset($_SESSION['maintenance_mode']) && $_SESSION['maintenance_mode'] == FALSE) {
variable_set('maintenance_mode', FALSE);
unset($_SESSION['maintenance_mode']);
}
}
......
......@@ -1808,18 +1808,15 @@ function system_date_time_lookup() {
* @see system_settings_form()
*/
function system_site_maintenance_mode() {
$form['site_offline'] = array(
'#type' => 'radios',
'#title' => t('Site status'),
$form['maintenance_mode'] = array(
'#type' => 'checkbox',
'#title' => t('Put site into maintenance mode'),
'#default_value' => 0,
'#options' => array(t('Online'), t('Offline')),
'#description' => t('When set to "Online", all visitors will be able to browse your site normally. When set to "Offline", only users with the "administer site configuration" permission will be able to access your site to perform maintenance; all other visitors will see the site offline message configured below. Authorized users can log in during "Offline" mode directly via the <a href="@user-login">user login</a> page.', array('@user-login' => url('user'))),
'#description' => t('When enabled, only users with the "Access site in maintenance mode" <a href="@permissions-url">permission</a> are able to access your site to perform maintenance; all other visitors see the maintenance mode message configured below. Authorized users can log in directly via the <a href="@user-login">user login</a> page.', array('@permissions-url' => url('admin/config/people/permissions'), '@user-login' => url('user'))),
);
$form['site_offline_message'] = array(
$form['maintenance_mode_message'] = array(
'#type' => 'textarea',
'#title' => t('Site offline message'),
'#title' => t('Maintenance mode message'),
'#default_value' => t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal'))),
'#description' => t('Message to show visitors when the site is in maintenance mode.')
);
......
......@@ -2428,6 +2428,33 @@ function system_update_7035() {
return $ret;
}
/**
* Split the 'access site in maintenance mode' permission from 'administer site configuration'.
*/
function system_update_7036() {
$ret = array();
// Get existing roles that can 'administer site configuration'.
$rids = db_query("SELECT rid FROM {role_permission} WHERE permission = :perm", array(':perm' => 'administer site configuration'))->fetchCol();
// None found.
if (empty($rids)) {
return $ret;
}
$insert = db_insert('role_permission')->fields(array('rid', 'permission'));
foreach ($rids as $rid) {
$insert->values(array(
'rid' => $rid,
'permission' => 'access site in maintenance mode',
));
}
$insert->execute();
// Remove obsolete variable 'site_offline_message'.
// @see update_fix_d7_requirements().
variable_del('site_offline_message');
return $ret;
}
/**
* @} End of "defgroup updates-6.x-to-7.x"
* The next series of updates should start at 8000.
......
......@@ -228,6 +228,10 @@ function system_permission() {
'title' => t('Access administration pages'),
'description' => t('View the administration panel and browse the help system.'),
),
'access site in maintenance mode' => array(
'title' => t('Access site in maintenance mode'),
'description' => t('Log in when the site is in maintenance mode.'),
),
'access site reports' => array(
'title' => t('Access site reports'),
'description' => t('View reports from system logs and other status information.'),
......
......@@ -647,6 +647,92 @@ class PageNotFoundTestCase extends DrupalWebTestCase {
}
}
/**
* Tests site maintenance functionality.
*/
class SiteMaintenanceTestCase extends DrupalWebTestCase {
protected $admin_user;
public static function getInfo() {
return array(
'name' => 'Site maintenance mode functionality',
'description' => 'Test access to site while in maintenance mode.',
'group' => 'System',
);
}
function setUp() {
parent::setUp();
// Create a user allowed to access site in maintenance mode.
$this->user = $this->drupalCreateUser(array('access site in maintenance mode'));
// Create an administrative user.
$this->admin_user = $this->drupalCreateUser(array('administer site configuration', 'access site in maintenance mode'));
$this->drupalLogin($this->admin_user);
}
/**
* Verify site maintenance mode functionality.
*/
function testSiteMaintenance() {
// Turn on maintenance mode.
$edit = array(
'maintenance_mode' => 1,
);
$this->drupalPost('admin/config/development/maintenance', $edit, t('Save configuration'));
$admin_message = t('Operating in maintenance mode. <a href="@url">Go online.</a>', array('@url' => url('admin/config/development/maintenance')));
$user_message = t('Operating in maintenance mode.');
$offline_message = t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')));
$this->drupalGet('');
$this->assertRaw($admin_message, t('Found the site maintenance mode message.'));
// Logout and verify that offline message is displayed.
$this->drupalLogout();
$this->drupalGet('');
$this->assertText($offline_message);
$this->drupalGet('node');
$this->assertText($offline_message);
$this->drupalGet('user/register');
$this->assertText($offline_message);
$this->drupalGet('user/password');
$this->assertText($offline_message);
// Verify that user is able to log in.
$this->drupalGet('user');
$this->assertNoText($offline_message);
$this->drupalGet('user/login');
$this->assertNoText($offline_message);
// Log in user and verify that maintenance mode message is displayed
// directly after login.
$edit = array(
'name' => $this->user->name,
'pass' => $this->user->pass_raw,
);
$this->drupalPost(NULL, $edit, t('Log in'));
$this->assertText($user_message);
// Log in administrative user and configure a custom site offline message.
$this->drupalLogout();
$this->drupalLogin($this->admin_user);
$this->drupalGet('admin/config/development/maintenance');
$this->assertNoRaw($admin_message, t('Site maintenance mode message not displayed.'));
$offline_message = 'Sorry, not online.';
$edit = array(
'maintenance_mode_message' => $offline_message,
);
$this->drupalPost(NULL, $edit, t('Save configuration'));
// Logout and verify that custom site offline message is displayed.
$this->drupalLogout();
$this->drupalGet('');
$this->assertRaw($offline_message, t('Found the site offline message.'));
}
}
/**
* Tests generic date and time handling capabilities of Drupal.
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment