Index: bakery.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/bakery/bakery.module,v
retrieving revision 1.52.2.1
diff -u -p -r1.52.2.1 bakery.module
--- bakery.module	29 Apr 2010 23:52:19 -0000	1.52.2.1
+++ bakery.module	27 Aug 2010 15:10:21 -0000
@@ -36,6 +36,14 @@ function bakery_menu() {
       'type' => MENU_CALLBACK,
     );
   }
+  else {
+    $items['bakery'] = array(
+      'title' => 'Bakery create',
+      'access callback' => 'bakery_taste_gingerbread_cookie',
+      'page callback' => 'bakery_eat_gingerbread_cookie',
+      'type' => MENU_CALLBACK,
+    );
+  }
 
   return $items;
 }
@@ -601,6 +609,127 @@ function bakery_eat_stroopwafel_cookie()
 }
 
 /**
+ * Request account information from master to create account locally.
+ *
+ * @param string $name the username to request information for to create.
+ * @return The local UID or FALSE.
+ */
+function bakery_request_account($name) {
+  $existing_account = user_load(array('name' => $name));
+  if (!$existing_account) {
+    $master = variable_get('bakery_master', '');
+    $key = variable_get('bakery_key', '');
+
+    $payload = array();
+    $payload['name'] = $name;
+    $payload['timestamp'] = $_SERVER['REQUEST_TIME'];
+    $payload['signature'] = hash_hmac('sha256', $payload['name'] . '/' . $payload['timestamp'], $key);
+    $payload = drupal_query_string_encode(array('gingerbread' => bakery_mix(serialize($payload), 1)));
+    // Make request to master for account information.
+    $result = drupal_http_request($master . 'bakery', array('Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8'), 'POST', $payload);
+    // Parse result and create account
+    if ($result->code != 200) {
+      $message = $result->data;
+      watchdog('bakery', 'Received response !code from master with message !message', array('!code' => $result->code, '!message' => $message), WATCHDOG_ERROR);
+    }
+    else {
+      // Create account.
+      $cookie = unserialize(bakery_mix($result->data, 0));
+      $key = variable_get('bakery_key', '');
+      $signature = hash_hmac('sha256', $cookie['name'] . '/' . $cookie['timestamp'], $key);
+
+      if ($signature == $cookie['signature']) {
+        // Valid response.
+        $new_account = array(
+          'name' => $cookie['name'],
+          'pass' => user_password(),
+          'mail' => $cookie['mail'],
+          'status' => 1,
+          'init' => $master . 'user/' . $cookie['uid'] . '/edit',
+        );
+        // Add any supported sync fields.
+        foreach (variable_get('bakery_supported_fields', array('mail' => 'mail', 'name' => 'name')) as $type => $enabled) {
+          if ($enabled && isset($cookie[$type])) {
+            $new_account[$type] = $cookie[$type];
+          }
+        }
+        // Create account.
+        $account = user_save(NULL, $new_account);
+        if ($account) {
+          watchdog('bakery', 'Created account for !name', array('!name' => $name));
+          return $account->uid;
+        }
+        else {
+          watchdog('bakery', 'Unable to create account for !name', array('!name' => $name), WATCHDOG_ERROR);
+        }
+      }
+      else {
+        // Invalid response.
+        watchdog('bakery', 'Invalid response from master when attempting to create local account for !name', array('!name' => $name), WATCHDOG_ERROR);
+      }
+    }
+  }
+  return FALSE;
+}
+
+/**
+ * Validate the account information request.
+ */
+function bakery_taste_gingerbread_cookie() {
+  $payload = $_POST['gingerbread'];
+  $valid = FALSE;
+
+  if ($payload) {
+    $cookie = unserialize(bakery_mix($payload, 0));
+    $key = variable_get('bakery_key', '');
+    $signature = hash_hmac('sha256', $cookie['name'] . '/' . $cookie['timestamp'], $key);
+
+    if ($signature == $cookie['signature'] && $cookie['timestamp'] + variable_get('bakery_freshness', '3600') >= $_SERVER['REQUEST_TIME']) {
+      $valid = TRUE;
+      $_SESSION['bakery']['name'] = $cookie['name'];
+    }
+  }
+
+  return $valid;
+}
+
+/**
+ * Respond with account information.
+ */
+function bakery_eat_gingerbread_cookie() {
+  // Session was set in validate.
+  $name = $_SESSION['bakery']['name'];
+  unset($_SESSION['bakery']['name']);
+  $key = variable_get('bakery_key', '');
+
+  $account = user_load(array('name' => $name));
+  if ($account) {
+    $payload = array();
+    $payload['name'] = $account->name;
+    $payload['mail'] = $account->mail;
+    $payload['uid'] = $account->uid; // For use in slave init field.
+    // Add any synced fields.
+    foreach (variable_get('bakery_supported_fields', array('mail' => 'mail', 'name' => 'name')) as $type => $enabled) {
+      if ($enabled && $account->$type) {
+        $payload[$type] = $account->$type;
+      }
+    }
+    $payload['timestamp'] = $_SERVER['REQUEST_TIME'];
+    $payload['signature'] = hash_hmac('sha256', $payload['name'] . '/' . $payload['timestamp'], $key);
+
+    // Respond with encrypted and signed account information.
+    $message = bakery_mix(serialize($payload), 1);
+  }
+  else {
+    $message = t('No account found');
+    header('HTTP/1.1 409 Conflict');
+  }
+  module_invoke_all('exit');
+  print $message;
+  exit();
+}
+
+/**
  * Destroy unwanted cookies
  */
 function _bakery_eat_cookie($type = 'CHOCOLATECHIP') {
