Project

General

Profile

Paste
Download (6.45 KB) Statistics
| Branch: | Revision:

root / drupal7 / authorize.php @ master

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
}