annotate authorize.php @ 0:ff03f76ab3fe

initial version
author danieleb <danielebarchiesi@me.com>
date Wed, 21 Aug 2013 18:51:11 +0100
parents
children
rev   line source
danielebarchiesi@0 1 <?php
danielebarchiesi@0 2
danielebarchiesi@0 3 /**
danielebarchiesi@0 4 * @file
danielebarchiesi@0 5 * Administrative script for running authorized file operations.
danielebarchiesi@0 6 *
danielebarchiesi@0 7 * Using this script, the site owner (the user actually owning the files on the
danielebarchiesi@0 8 * webserver) can authorize certain file-related operations to proceed with
danielebarchiesi@0 9 * elevated privileges, for example to deploy and upgrade modules or themes.
danielebarchiesi@0 10 * Users should not visit this page directly, but instead use an administrative
danielebarchiesi@0 11 * user interface which knows how to redirect the user to this script as part of
danielebarchiesi@0 12 * a multistep process. This script actually performs the selected operations
danielebarchiesi@0 13 * without loading all of Drupal, to be able to more gracefully recover from
danielebarchiesi@0 14 * errors. Access to the script is controlled by a global killswitch in
danielebarchiesi@0 15 * settings.php ('allow_authorize_operations') and via the 'administer software
danielebarchiesi@0 16 * updates' permission.
danielebarchiesi@0 17 *
danielebarchiesi@0 18 * There are helper functions for setting up an operation to run via this
danielebarchiesi@0 19 * system in modules/system/system.module. For more information, see:
danielebarchiesi@0 20 * @link authorize Authorized operation helper functions @endlink
danielebarchiesi@0 21 */
danielebarchiesi@0 22
danielebarchiesi@0 23 /**
danielebarchiesi@0 24 * Defines the root directory of the Drupal installation.
danielebarchiesi@0 25 */
danielebarchiesi@0 26 define('DRUPAL_ROOT', getcwd());
danielebarchiesi@0 27
danielebarchiesi@0 28 /**
danielebarchiesi@0 29 * Global flag to identify update.php and authorize.php runs.
danielebarchiesi@0 30 *
danielebarchiesi@0 31 * Identifies update.php and authorize.php runs, avoiding unwanted operations
danielebarchiesi@0 32 * such as hook_init() and hook_exit() invokes, css/js preprocessing and
danielebarchiesi@0 33 * translation, and solves some theming issues. The flag is checked in other
danielebarchiesi@0 34 * places in Drupal code (not just authorize.php).
danielebarchiesi@0 35 */
danielebarchiesi@0 36 define('MAINTENANCE_MODE', 'update');
danielebarchiesi@0 37
danielebarchiesi@0 38 /**
danielebarchiesi@0 39 * Renders a 403 access denied page for authorize.php.
danielebarchiesi@0 40 */
danielebarchiesi@0 41 function authorize_access_denied_page() {
danielebarchiesi@0 42 drupal_add_http_header('Status', '403 Forbidden');
danielebarchiesi@0 43 watchdog('access denied', 'authorize.php', NULL, WATCHDOG_WARNING);
danielebarchiesi@0 44 drupal_set_title('Access denied');
danielebarchiesi@0 45 return t('You are not allowed to access this page.');
danielebarchiesi@0 46 }
danielebarchiesi@0 47
danielebarchiesi@0 48 /**
danielebarchiesi@0 49 * Determines if the current user is allowed to run authorize.php.
danielebarchiesi@0 50 *
danielebarchiesi@0 51 * The killswitch in settings.php overrides all else, otherwise, the user must
danielebarchiesi@0 52 * have access to the 'administer software updates' permission.
danielebarchiesi@0 53 *
danielebarchiesi@0 54 * @return
danielebarchiesi@0 55 * TRUE if the current user can run authorize.php, and FALSE if not.
danielebarchiesi@0 56 */
danielebarchiesi@0 57 function authorize_access_allowed() {
danielebarchiesi@0 58 return variable_get('allow_authorize_operations', TRUE) && user_access('administer software updates');
danielebarchiesi@0 59 }
danielebarchiesi@0 60
danielebarchiesi@0 61 // *** Real work of the script begins here. ***
danielebarchiesi@0 62
danielebarchiesi@0 63 require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
danielebarchiesi@0 64 require_once DRUPAL_ROOT . '/includes/common.inc';
danielebarchiesi@0 65 require_once DRUPAL_ROOT . '/includes/file.inc';
danielebarchiesi@0 66 require_once DRUPAL_ROOT . '/includes/module.inc';
danielebarchiesi@0 67 require_once DRUPAL_ROOT . '/includes/ajax.inc';
danielebarchiesi@0 68
danielebarchiesi@0 69 // We prepare only a minimal bootstrap. This includes the database and
danielebarchiesi@0 70 // variables, however, so we have access to the class autoloader registry.
danielebarchiesi@0 71 drupal_bootstrap(DRUPAL_BOOTSTRAP_SESSION);
danielebarchiesi@0 72
danielebarchiesi@0 73 // This must go after drupal_bootstrap(), which unsets globals!
danielebarchiesi@0 74 global $conf;
danielebarchiesi@0 75
danielebarchiesi@0 76 // We have to enable the user and system modules, even to check access and
danielebarchiesi@0 77 // display errors via the maintenance theme.
danielebarchiesi@0 78 $module_list['system']['filename'] = 'modules/system/system.module';
danielebarchiesi@0 79 $module_list['user']['filename'] = 'modules/user/user.module';
danielebarchiesi@0 80 module_list(TRUE, FALSE, FALSE, $module_list);
danielebarchiesi@0 81 drupal_load('module', 'system');
danielebarchiesi@0 82 drupal_load('module', 'user');
danielebarchiesi@0 83
danielebarchiesi@0 84 // We also want to have the language system available, but we do *NOT* want to
danielebarchiesi@0 85 // actually call drupal_bootstrap(DRUPAL_BOOTSTRAP_LANGUAGE), since that would
danielebarchiesi@0 86 // also force us through the DRUPAL_BOOTSTRAP_PAGE_HEADER phase, which loads
danielebarchiesi@0 87 // all the modules, and that's exactly what we're trying to avoid.
danielebarchiesi@0 88 drupal_language_initialize();
danielebarchiesi@0 89
danielebarchiesi@0 90 // Initialize the maintenance theme for this administrative script.
danielebarchiesi@0 91 drupal_maintenance_theme();
danielebarchiesi@0 92
danielebarchiesi@0 93 $output = '';
danielebarchiesi@0 94 $show_messages = TRUE;
danielebarchiesi@0 95
danielebarchiesi@0 96 if (authorize_access_allowed()) {
danielebarchiesi@0 97 // Load both the Form API and Batch API.
danielebarchiesi@0 98 require_once DRUPAL_ROOT . '/includes/form.inc';
danielebarchiesi@0 99 require_once DRUPAL_ROOT . '/includes/batch.inc';
danielebarchiesi@0 100 // Load the code that drives the authorize process.
danielebarchiesi@0 101 require_once DRUPAL_ROOT . '/includes/authorize.inc';
danielebarchiesi@0 102
danielebarchiesi@0 103 // For the sake of Batch API and a few other low-level functions, we need to
danielebarchiesi@0 104 // initialize the URL path into $_GET['q']. However, we do not want to raise
danielebarchiesi@0 105 // our bootstrap level, nor do we want to call drupal_initialize_path(),
danielebarchiesi@0 106 // since that is assuming that modules are loaded and invoking hooks.
danielebarchiesi@0 107 // However, all we really care is if we're in the middle of a batch, in which
danielebarchiesi@0 108 // case $_GET['q'] will already be set, we just initialize it to an empty
danielebarchiesi@0 109 // string if it's not already defined.
danielebarchiesi@0 110 if (!isset($_GET['q'])) {
danielebarchiesi@0 111 $_GET['q'] = '';
danielebarchiesi@0 112 }
danielebarchiesi@0 113
danielebarchiesi@0 114 if (isset($_SESSION['authorize_operation']['page_title'])) {
danielebarchiesi@0 115 drupal_set_title($_SESSION['authorize_operation']['page_title']);
danielebarchiesi@0 116 }
danielebarchiesi@0 117 else {
danielebarchiesi@0 118 drupal_set_title(t('Authorize file system changes'));
danielebarchiesi@0 119 }
danielebarchiesi@0 120
danielebarchiesi@0 121 // See if we've run the operation and need to display a report.
danielebarchiesi@0 122 if (isset($_SESSION['authorize_results']) && $results = $_SESSION['authorize_results']) {
danielebarchiesi@0 123
danielebarchiesi@0 124 // Clear the session out.
danielebarchiesi@0 125 unset($_SESSION['authorize_results']);
danielebarchiesi@0 126 unset($_SESSION['authorize_operation']);
danielebarchiesi@0 127 unset($_SESSION['authorize_filetransfer_info']);
danielebarchiesi@0 128
danielebarchiesi@0 129 if (!empty($results['page_title'])) {
danielebarchiesi@0 130 drupal_set_title($results['page_title']);
danielebarchiesi@0 131 }
danielebarchiesi@0 132 if (!empty($results['page_message'])) {
danielebarchiesi@0 133 drupal_set_message($results['page_message']['message'], $results['page_message']['type']);
danielebarchiesi@0 134 }
danielebarchiesi@0 135
danielebarchiesi@0 136 $output = theme('authorize_report', array('messages' => $results['messages']));
danielebarchiesi@0 137
danielebarchiesi@0 138 $links = array();
danielebarchiesi@0 139 if (is_array($results['tasks'])) {
danielebarchiesi@0 140 $links += $results['tasks'];
danielebarchiesi@0 141 }
danielebarchiesi@0 142 else {
danielebarchiesi@0 143 $links = array_merge($links, array(
danielebarchiesi@0 144 l(t('Administration pages'), 'admin'),
danielebarchiesi@0 145 l(t('Front page'), '<front>'),
danielebarchiesi@0 146 ));
danielebarchiesi@0 147 }
danielebarchiesi@0 148
danielebarchiesi@0 149 $output .= theme('item_list', array('items' => $links, 'title' => t('Next steps')));
danielebarchiesi@0 150 }
danielebarchiesi@0 151 // If a batch is running, let it run.
danielebarchiesi@0 152 elseif (isset($_GET['batch'])) {
danielebarchiesi@0 153 $output = _batch_page();
danielebarchiesi@0 154 }
danielebarchiesi@0 155 else {
danielebarchiesi@0 156 if (empty($_SESSION['authorize_operation']) || empty($_SESSION['authorize_filetransfer_info'])) {
danielebarchiesi@0 157 $output = t('It appears you have reached this page in error.');
danielebarchiesi@0 158 }
danielebarchiesi@0 159 elseif (!$batch = batch_get()) {
danielebarchiesi@0 160 // We have a batch to process, show the filetransfer form.
danielebarchiesi@0 161 $elements = drupal_get_form('authorize_filetransfer_form');
danielebarchiesi@0 162 $output = drupal_render($elements);
danielebarchiesi@0 163 }
danielebarchiesi@0 164 }
danielebarchiesi@0 165 // We defer the display of messages until all operations are done.
danielebarchiesi@0 166 $show_messages = !(($batch = batch_get()) && isset($batch['running']));
danielebarchiesi@0 167 }
danielebarchiesi@0 168 else {
danielebarchiesi@0 169 $output = authorize_access_denied_page();
danielebarchiesi@0 170 }
danielebarchiesi@0 171
danielebarchiesi@0 172 if (!empty($output)) {
danielebarchiesi@0 173 print theme('update_page', array('content' => $output, 'show_messages' => $show_messages));
danielebarchiesi@0 174 }