? 501704-4-openid_provider_ax_update_url.patch
? 501704-5-openid_provider_ax_update_url.patch
Index: openid_provider_ax.install
===================================================================
RCS file: openid_provider_ax.install
diff -N openid_provider_ax.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ openid_provider_ax.install	25 Oct 2010 15:30:27 -0000
@@ -0,0 +1,70 @@
+<?php
+// $Id$
+
+/**
+ * Implementation of hook_schema().
+ */
+function openid_provider_ax_schema() {
+  $schema['openid_provider_ax'] = array(
+    'description' => t('Connect profiles to the relying parties.'),
+    'fields' => array(
+      'uid' => array(
+        'description' => t('The user identifier.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'claimed_id' => array(
+        'description' => t('The OpenID the user claimed.'),
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'request' => array(
+        'description' => t('The attributes that were requested by the relying party.'),
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'response' => array(
+        'description' => t('The attributes that were the response to the relying party.'),
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+      'update_url' => array(
+        'description' => t('The URL of the relying party where the updated attributes should be sent to.'),
+        'type' => 'text',
+        'not null' => TRUE,
+      ),
+    ),
+    'unique keys' => array(
+      'claimed_id' => array('claimed_id')
+    ),
+    'indexes' => array(
+      'uid' => array('uid'),
+    ),
+  );
+  return $schema;
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function openid_provider_ax_install() {
+  drupal_install_schema('openid_provider_ax');
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function openid_provider_ax_uninstall() {
+  drupal_uninstall_schema('openid_provider_ax');
+}
+
+/**
+ * Implementation of hook_update_N().
+ */
+function openid_provider_ax_update_6001() {
+  return drupal_install_schema('openid_provider_ax');
+}
+
Index: openid_provider_ax.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/openid_provider_ax/openid_provider_ax.module,v
retrieving revision 1.3.2.6
diff -u -p -r1.3.2.6 openid_provider_ax.module
--- openid_provider_ax.module	8 Jul 2009 12:51:46 -0000	1.3.2.6
+++ openid_provider_ax.module	25 Oct 2010 15:30:28 -0000
@@ -23,11 +23,43 @@ function openid_provider_ax_xrds($accoun
 /**
  * Implementation of hook_openid_provider()
  */
-function openid_provider_ax_openid_provider($op = 'response', $response = array(), $request = array()) {
+function openid_provider_ax_openid_provider($op = 'response') {
+  $args = func_get_args();
   switch ($op) {
     case 'response':
-      return openid_provider_ax_response_process($response, $request);
+      if (count($args) < 3) {
+        return FALSE;
+      }
+      return openid_provider_ax_response_process($args[1], $args[2]);
       break;
+    case 'update':
+      module_load_include('inc', 'openid_provider', 'openid_provider');
+
+      $uid = array_pop($args);
+
+      //TODO: refactor into own function
+      $result = db_query("SELECT * FROM {openid_provider_ax} WHERE uid = %d", $uid);
+      $relying_parties = array();
+      while ($relying_party = db_fetch_array($result)) {
+        $relying_party['request'] = unserialize($relying_party['request']);
+        $relying_party['response'] = unserialize($relying_party['response']);
+        $relying_parties[] = $relying_party;
+      }
+
+      foreach ($relying_parties as $rp) {
+        $update_url = $rp['request']['openid.ax.update_url'];
+        unset($rp['request']['openid.ax.update_url']);
+        $response = openid_provider_ax_response_process($rp['response'], $rp['request'], $uid);
+        $response['openid.response_nonce'] = _openid_provider_nonce();
+        $response['openid.return_to'] = $update_url;
+        $response = array_merge($rp['response'], $response);
+
+        if (!openid_provider_unsolicited_assertion($response, $update_url)) {
+          // We got a 404 and need to remove the update_url
+          // TODO: Implement some kind of threshold (e.g. 5 times 404, then remove)
+          db_query("DELETE FROM {openid_provider_ax} WHERE update_url = '%s'", $update_url);
+        }
+      }
     case 'signed':
       break;
   }
@@ -41,7 +73,12 @@ function openid_provider_ax_openid_provi
  * @param $request
  *      Keyed array holding the request that was received
  */
-function openid_provider_ax_response_process($response = array(), $request = array()) {
+function openid_provider_ax_response_process($response = array(), $request = array(), $uid = FALSE) {
+  if (!$uid) {
+    global $user;
+    $uid = $user->uid;
+  }
+
   $processed = array();
   // OPENID Attribute Exchange was requested hence get the alias per
   // OPENID specification and then determine the type of request it was
@@ -55,8 +92,32 @@ function openid_provider_ax_response_pro
     $attributes = openid_provider_ax_parse_request($request, $alias);
     switch ($request_type) {
       case 'fetch_request':
-        $processed = array_merge($processed, module_invoke_all('openid_provider_ax', 'load', $attributes, $request));
+        $processed = array_merge($processed, module_invoke_all('openid_provider_ax', 'load', $attributes, $uid));
         $processed = array_merge($processed, array($alias_key => OPENID_PROVIDER_AX, sprintf('openid%smode', $alias) => 'fetch_response'));
+
+        // Relying Party asks for updates.
+        if (isset($request['openid.ax.update_url']) && valid_url($request['openid.ax.update_url'], TRUE)) {
+          // Verify realm with update_url
+          $realm_verified = ($request['openid.realm'] == substr($request[sprintf('openid%supdate_url', $alias)], 0, strlen($request['openid.realm']))) ? TRUE : FALSE;
+
+          if ($realm_verified) {
+            $claimed_id = $request['openid.claimed_id'];
+            $update_url = $request['openid.ax.update_url'];
+
+            $processed = array_merge($processed, array($alias_key => OPENID_PROVIDER_AX, sprintf('openid%supdate_url', $alias) => $update_url));
+            $update = array();
+            if (db_result(db_query("SELECT COUNT(uid) FROM {openid_provider_ax} WHERE claimed_id = '%s'", $claimed_id))) {
+              $update = array('claimed_id');
+            }
+            $record = new stdClass();
+            $record->uid = $uid;
+            $record->claimed_id = $claimed_id;
+            $record->request = serialize($request);
+            $record->response = serialize($response);
+            $record->update_url = $update_url;
+            drupal_write_record('openid_provider_ax', $record, $update);
+          }
+        }
         break;
       case 'store_request':
         break;
