Index: authorize.php
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/authorize.php,v
retrieving revision 1.3
diff -u -p -r1.3 authorize.php
--- authorize.php	24 Oct 2009 05:13:43 -0000	1.3
+++ authorize.php	27 Oct 2009 10:02:26 -0000
@@ -14,7 +14,7 @@
  * global killswitch in settings.php ('allow_authorize_operations') and via
  * the 'administer software updates' permission.
  *
- * @see system_run_authorized()
+ * @see system_authorized_run()
  */
 
 /**
Index: modules/system/system.module
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/system/system.module,v
retrieving revision 1.827
diff -u -p -r1.827 system.module
--- modules/system/system.module	27 Oct 2009 04:16:39 -0000	1.827
+++ modules/system/system.module	27 Oct 2009 10:01:25 -0000
@@ -1450,14 +1450,54 @@ function _system_themes_access($theme) {
 }
 
 /**
- * Invoke a given callback via authorize.php to run with elevated privileges.
- *
- * To use authorize.php, certain variables must be stashed into
- * $_SESSION. This function sets up all the necessary $_SESSION variables,
- * then redirects to authorize.php to initiate the workflow that will
- * eventually lead to the callback being invoked. The callback will be invoked
- * at a low bootstrap level, without all modules being invoked, so it needs to
- * be careful not to assume any code exists.
+ * @defgroup authorized-operations Authorized operations
+ * @{
+ * Because of the Update manager functionality included in Drupal core, there
+ * is a mechanism for running operations with elevated file system privileges,
+ * the top-level authorize.php script. This script runs at a reduced Drupal
+ * bootstrap level so that it is not reliant on the entire site being
+ * functional. The operations use a FileTransfer class to manipulate code
+ * installed on the system as the user that owns the files, not the user that
+ * the httpd is running as.
+ *
+ * The first setup is to define a callback function that should be authorized
+ * to run with the elevated privileges. This callback should take a
+ * FileTransfer as its first argument, although you can define an array of
+ * other arguments it should be invoked with. The callback should be placed in
+ * a separate .inc file that will be included by authorize.php.
+ *
+ * To run the operation, certain data must be saved into the SESSION, and then
+ * the flow of control should be redirected to the authorize.php script. There
+ * are two ways to do this, either to call system_authorized_run() directly,
+ * or to call system_authorized_setup() and then redirect to authorize.php,
+ * using the URL from system_authorized_get_url(). Redirecting yourself is
+ * necessary when your authorized operation is being triggered by a form
+ * submit handler, since calling drupal_goto() in a submit handler is a bad
+ * idea, and you should instead set $form_state['redirect'].
+ *
+ * Once the SESSION is setup for the operation and the user is redirected to
+ * authorize.php, they will be prompted for their connection credentials (core
+ * provides FTP and SSH by default, although other connection classes can be
+ * added via contributed modules). With valid credentials, authorize.php will
+ * instantiate the appropriate FileTransfer object, and then invoke the
+ * desired operation passing in that object. The authorize.php script can act
+ * as a Batch API processing page, if the operation requires a batch.
+ *
+ * @see authorize.php
+ * @see FileTransfer
+ * @see hook_filetransfer_backends()
+ */
+
+/**
+ * Setup a given callback to run via authorize.php with elevated privileges.
+ *
+ * To use authorize.php, certain variables must be stashed into $_SESSION.
+ * This function sets up all the necessary $_SESSION variables, then returns
+ * the full path to authorize.php so the caller can redirect to authorize.php.
+ * That initiates the workflow that will eventually lead to the callback being
+ * invoked. The callback will be invoked at a low bootstrap level, without all
+ * modules being invoked, so it needs to be careful not to assume any code
+ * exists.
  *
  * @param $callback
  *   The name of the function to invoke one the user authorizes the operation.
@@ -1470,11 +1510,9 @@ function _system_themes_access($theme) {
  * @param $page_title
  *   Optional string to use as the page title once redirected to authorize.php.
  * @return
- *   Nothing. This function redirects to authorize.php and does not return.
+ *   The path to authorize.php that the caller should redirect to.
  */
-function system_run_authorized($callback, $file, $arguments = array(), $page_title = NULL) {
-  global $base_url;
-
+function system_authorized_setup($callback, $file, $arguments = array(), $page_title = NULL) {
   // First, figure out what file transfer backends the site supports, and put
   // all of those in the SESSION so that authorize.php has access to all of
   // them via the class autoloader, even without a full bootstrap.
@@ -1490,12 +1528,31 @@ function system_run_authorized($callback
   if (isset($page_title)) {
     $_SESSION['authorize_operation']['page_title'] = $page_title;
   }
+}
+
+/**
+ * Return the URL for the authorize.php script.
+ */
+function system_authorized_get_url() {
+  global $base_url;
+  return $base_url . '/authorize.php';
+}
 
-  // Finally, redirect to authorize.php.
-  drupal_goto($base_url . '/authorize.php');
+/**
+ * Setup and invoke an operation using authorize.php.
+ *
+ * @see system_authorized_setup
+ */
+function system_authorized_run($callback, $file, $arguments = array(), $page_title = NULL) {
+  system_authorized_setup($callback, $file, $arguments, $page_title);
+  drupal_goto(system_authorized_get_url());
 }
 
 /**
+ * @} End of "defgroup authorized-operations".
+ */
+
+/**
  * Implement hook_updater_info().
  */
 function system_updater_info() {
Index: modules/update/update.manager.inc
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/update/update.manager.inc,v
retrieving revision 1.8
diff -u -p -r1.8 update.manager.inc
--- modules/update/update.manager.inc	27 Oct 2009 03:34:01 -0000	1.8
+++ modules/update/update.manager.inc	27 Oct 2009 10:01:25 -0000
@@ -396,9 +396,11 @@ function update_manager_confirm_update_f
  * update, do so now. Otherwise, pull information about all the required
  * updates out of the SESSION, figure out what Updater class is needed for
  * each one, generate an array of update operations to perform, and hand it
- * all off to system_run_authorized() where we redirect to authorize.php.
+ * all off to system_authorized_setup(), then redirect to authorize.php.
  *
- * @see system_run_authorized()
+ * @see update_authorize_run_update()
+ * @see system_authorized_setup()
+ * @see system_authorized_get_url()
  */
 function update_manager_confirm_update_form_submit($form, &$form_state) {
   if ($form_state['values']['site_offline'] == TRUE) {
@@ -440,7 +442,8 @@ function update_manager_confirm_update_f
     // credentials and invoke update_authorize_run_update() indirectly with
     // whatever FileTransfer object authorize.php creates for us.
     else {
-      system_run_authorized('update_authorize_run_update', drupal_get_path('module', 'update') . '/update.authorize.inc', array($updates));
+      system_authorized_setup('update_authorize_run_update', drupal_get_path('module', 'update') . '/update.authorize.inc', array($updates));
+      $form_state['redirect'] = system_authorized_get_url();
     }
   }
 }
@@ -536,6 +539,10 @@ function update_manager_install_form_val
  * the live webroot. If everything is successful, setup an operation to run
  * via authorize.php which will copy the extracted files from the temporary
  * location into the live site.
+ *
+ * @see update_authorize_run_install()
+ * @see system_authorized_setup()
+ * @see system_authorized_get_url()
  */
 function update_manager_install_form_submit($form, &$form_state) {
   if ($form_state['values']['project_url']) {
@@ -616,7 +623,8 @@ function update_manager_install_form_sub
   // credentials and invoke update_authorize_run_install() indirectly with
   // whatever FileTransfer object authorize.php creates for us.
   else {
-    system_run_authorized('update_authorize_run_install', drupal_get_path('module', 'update') . '/update.authorize.inc', $arguments);
+    system_authorized_setup('update_authorize_run_install', drupal_get_path('module', 'update') . '/update.authorize.inc', $arguments);
+    $form_state['redirect'] = system_authorized_get_url();
   }
 }
 
