? modules/xrds
? modules/simpletest/tests/url-tests.chsc
Index: modules/openid/openid.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/openid/openid.pages.inc,v
retrieving revision 1.18
diff -u -9 -p -r1.18 openid.pages.inc
--- modules/openid/openid.pages.inc	25 May 2009 10:43:52 -0000	1.18
+++ modules/openid/openid.pages.inc	11 Jun 2009 16:46:09 -0000
@@ -29,26 +29,37 @@ function openid_authentication_page() {
  */
 function openid_user_identities($account) {
   drupal_set_title($account->name);
   drupal_add_css(drupal_get_path('module', 'openid') . '/openid.css');
 
   // Check to see if we got a response
   $result = openid_complete();
   if ($result['status'] == 'success') {
     $identity = $result['openid.claimed_id'];
-    $query = db_insert('authmap')
-      ->fields(array(
-        'uid' => $account->uid,
-        'authname' => $identity,
-        'module' => 'openid',
-      ))
-      ->execute();
-    drupal_set_message(t('Successfully added %identity', array('%identity' => $identity)));
+    try {
+      db_insert('authmap')
+        ->fields(array(
+          'uid' => $account->uid,
+          'authname' => $identity,
+          'module' => 'openid',
+        ))->execute();
+      drupal_set_message(t('Successfully added %identity', array('%identity' => $identity)));
+    }
+    catch (PDOException $e) {
+      // 23000 means "Integrity constraint violation", i.e. violation of the
+      // unique key on the authname column.
+      if ($e->errorInfo[0] == 23000) {
+        form_set_error('openid_identifier', t('The OpenID identity %identity is already in use on this site.', array('%identity' => $identity)));
+      }
+      else {
+        throw $e;
+      }
+    }
   }
 
   $header = array(t('OpenID'), t('Operations'));
   $rows = array();
 
   $result = db_query("SELECT * FROM {authmap} WHERE module='openid' AND uid=:uid", array(':uid' => $account->uid));
   foreach ($result as $identity) {
     $rows[] = array(check_plain($identity->authname), l(t('Delete'), 'user/' . $account->uid . '/openid/delete/' . $identity->aid));
   }
@@ -67,28 +78,21 @@ function openid_user_identities($account
 function openid_user_add() {
   $form['openid_identifier'] = array(
     '#type' => 'textfield',
     '#title' => t('OpenID'),
   );
   $form['submit'] = array('#type' => 'submit', '#value' => t('Add an OpenID'));
   return $form;
 }
 
-function openid_user_add_validate($form, &$form_state) {
-  // Check for existing entries.
-  $claimed_id = _openid_normalize($form_state['values']['openid_identifier']);
-  if (db_query("SELECT authname FROM {authmap} WHERE authname = :authname", (array(':authname' => $claimed_id)))->fetchField()) {
-    form_set_error('openid_identifier', t('That OpenID is already in use on this site.'));
-  }
-  else {
-    $return_to = url('user/' . arg(1) . '/openid', array('absolute' => TRUE));
-    openid_begin($form_state['values']['openid_identifier'], $return_to);
-  }
+function openid_user_add_submit($form, &$form_state) {
+  $return_to = url('user/' . arg(1) . '/openid', array('absolute' => TRUE));
+  openid_begin($form_state['values']['openid_identifier'], $return_to);
 }
 
 /**
  * Menu callback; Delete the specified OpenID identity from the system.
  */
 function openid_user_delete_form($form_state, $account, $aid = 0) {
   $authname = db_query("SELECT authname FROM {authmap} WHERE uid = :uid AND aid = :aid AND module = 'openid'", array(
     ':uid' => $account->uid,
     ':aid' => $aid,
Index: modules/openid/openid.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/openid/openid.test,v
retrieving revision 1.2
diff -u -9 -p -r1.2 openid.test
--- modules/openid/openid.test	6 May 2009 19:56:21 -0000	1.2
+++ modules/openid/openid.test	11 Jun 2009 16:46:09 -0000
@@ -105,18 +105,48 @@ class OpenIDFunctionalTest extends Drupa
     // Delete the newly added identity.
     $this->clickLink(t('Delete'));
     $this->drupalPost(NULL, array(), t('Confirm'));
 
     $this->assertText(t('OpenID deleted.'), t('Identity deleted'));
     $this->assertNoText($identity, t('Identity no longer appears in list.'));
   }
 
   /**
+   * Try to add the same identity to two different users.
+   */
+  function testIdentityConflict() {
+    // Use a User-supplied Identity that is the URL of an XRDS document.
+    $identity = url('openid-test/yadis/xrds', array('absolute' => TRUE));
+
+    $this->drupalLogin($this->web_user);
+    $this->addIdentity($identity);
+    $this->drupalLogout();
+
+    $web_user2 = $this->drupalCreateUser(array());
+    $this->drupalLogin($web_user2);
+
+    // Instruct openid_test module to return the same identity, even though we
+    // claim it using a different URL.
+    variable_set('openid_test_response', array('openid.claimed_id' => $identity));
+
+    // Use same identity but with a dummy parameter added to the URL.
+    $identity2 = url('openid-test/yadis/xrds', array('absolute' => TRUE, 'query' => 'foo=bar'));
+
+    $this->drupalGet('user/' . $web_user2->uid . '/openid');
+    $edit = array('openid_identifier' => $identity2);
+    $this->drupalPost(NULL, $edit, t('Add an OpenID'));
+
+    // Submit form to the OpenID Provider Endpoint.
+    $this->drupalPost(NULL, array(), t('Send'));
+    $this->assertRaw(t('The OpenID identity %identity is already in use on this site.', array('%identity' => $identity)));
+  }
+
+  /**
    * Add OpenID identity to user's profile.
    */
   function addIdentity($identity, $version = 2) {
     $this->drupalGet('user/' . $this->web_user->uid . '/openid');
     $edit = array('openid_identifier' => $identity);
     $this->drupalPost(NULL, $edit, t('Add an OpenID'));
 
     // OpenID 1 used a HTTP redirect, OpenID 2 uses a HTML form that is submitted automatically using JavaScript.
     if ($version == 2) {
Index: modules/openid/tests/openid_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/openid/tests/openid_test.module,v
retrieving revision 1.3
diff -u -9 -p -r1.3 openid_test.module
--- modules/openid/tests/openid_test.module	10 Jun 2009 20:13:20 -0000	1.3
+++ modules/openid/tests/openid_test.module	11 Jun 2009 16:46:09 -0000
@@ -199,19 +199,19 @@ function _openid_test_endpoint_authentic
 
   module_load_include('inc', 'openid');
 
   // Generate unique identifier for this authentication.
   $nonce = _openid_nonce();
 
   // Generate response containing the user's identity. The openid.sreg.xxx
   // entries contain profile data stored by the OpenID Provider (see OpenID
   // Simple Registration Extension 1.0).
-  $response = array(
+  $response = variable_get('openid_test_response', array()) + array(
     'openid.ns' => OPENID_NS_2_0,
     'openid.mode' => 'id_res',
     'openid.op_endpoint' => $base_url . url('openid/provider'),
     // openid.claimed_id is not sent by OpenID 1 clients.
     'openid.claimed_id' => isset($_REQUEST['openid_claimed_id']) ? $_REQUEST['openid_claimed_id'] : '',
     'openid.identity' => $_REQUEST['openid_identity'],
     'openid.return_to' => $_REQUEST['openid_return_to'],
     'openid.response_nonce' => $nonce,
     'openid.assoc_handle' => 'openid-test',
