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