NEW FEATURE: added OpenID support
authorArun Persaud <arun@nubati.net>
Sat, 25 Apr 2009 07:33:14 +0000 (00:33 -0700)
committerArun Persaud <arun@nubati.net>
Sat, 25 Apr 2009 18:32:25 +0000 (11:32 -0700)
Users can add and delete OpenIDs on the settings page and then log in
user those OpenIds.

They can also use their OpenIDs to register.

config.php_template
create_database.sql
css/openid-icon-small.gif [new file with mode: 0644]
css/standard020.css
include/login.php
include/openid.php [new file with mode: 0644]
include/preferences.php
include/register.php
include/welcome.php

index 50f731ae174ce867f5374c239b088d3f9cef498b..93e951cf68f9dc491a55c5808f4420d5127590d9 100644 (file)
@@ -28,7 +28,7 @@
     $EMAIL_REPLY="";
 
     /* this should point to your index.file and to your domain.
-     * The HOST variable is also used to test, if files are called 
+     * The HOST variable is also used to test, if files are called
      * from within e-DoKo, so it needs to be set.
      */
     $INDEX = "/index.php";
 
     /* the default timezone for you domain */
     $defaulttimezone = date_default_timezone_get();
+
+    /* OpenId
+     *
+     * we use the php-openid library (tested with version 2.1.3)
+     * E-DoKo needs to know where to find the file examples/consumer/common.php
+     * that comes with the library. That file also needs to be modified the
+     * function getReturnTo(), change:
+     -    return sprintf("%s://%s:%s%s/finish_auth.php",
+     +    return sprintf("%s://%s:%s%s/index.php?action=login",
+
+    */
+
+    /* Openidpath that points to the top php-openid directory */
+    //$OPENIDPATH = "..fill in correct path here.../openid/php-openid-2.1.3/"
+    // leave empty if not used.
+    $OPENIDPATH = '';
 ?>
\ No newline at end of file
index 319cdd356fd6108db0a8c3fd501f4257716bdc4b..339c3371d30f07d0d1efdb03a95635120f38feed 100644 (file)
@@ -457,3 +457,11 @@ UNLOCK TABLES;
 /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
 /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
 
+DROP TABLE IF EXISTS `user_openids`;
+create table user_openids (
+  openid_url varchar(255) not null,
+  primary key (openid_url),
+
+  user_id int not null,
+  index (user_id)
+);
diff --git a/css/openid-icon-small.gif b/css/openid-icon-small.gif
new file mode 100644 (file)
index 0000000..cde836c
Binary files /dev/null and b/css/openid-icon-small.gif differ
index cb1e1c05ed74159dd9d634da4d1ce688c1eaab2d..6488b8fd5c7063dc9d2107facecee85a228c0873 100644 (file)
@@ -618,6 +618,15 @@ fieldset {
 .login .submitbutton { background-color: #fff;}
 .login .submitbutton:hover { background-color: #aaa;}
 
+#openid_url {
+  background: #FFFFFF url('openid-icon-small.gif') no-repeat scroll 0pt 50%;
+  padding-left: 18px;
+}
+
+table.openid td, table.openid th{
+    padding: 0.0em 0.3em;;
+}
+
 .newbiehint {
     background-color: #fee;
 }
index c1a0e42029c6e1b5ffd2579524082a6a365c703d..3c3f6be51add51387d1a740fea2c66dc350671ba 100644 (file)
@@ -5,12 +5,62 @@
 if(!isset($HOST))
   exit;
 
-/* check if login information is present */
-if(!myisset('email','password'))
+include_once('openid.php');
+
+function escape($thing) {
+    return htmlentities($thing);
+}
+
+/* check for openid stuff */
+if($OPENIDPATH && myisset('openid_identity') && $_REQUEST['openid_identity']!='')
   {
-    echo "can't log you in... missing login information.";
+    /* what openid is being used? */
+    $openid_url = OpenIDUrlEncode($_REQUEST['openid_identity']);
+    /* get the userid from the database, openids need to be registered within E-DoKo */
+    $data = OpenIDVerify();
+    $ok  = 0;
+
+    /* verify ok? */
+    if($data)
+      {
+       /* do we know this openid?*/
+       $myid = DB_GetUserId($openid_url);
+
+       if(!$myid)
+         {
+           /* openid unknown, perhaps not registered? */
+           echo "<p>Openid ok, but not registered with any account. If you have an account ".
+             "on E-DoKo, please log in and add your openid in your preferences first. </p>\n";
+
+
+           /* or perhaps a new user...*/
+           $email = $data['email'];
+           $name  = $data['fullname'];
+           echo "<p>If you wan to register a new account with this OpenID, please follow this ".
+             "<a href=\"index.php?action=register&amp;openid_url=".$openid_url.
+             "&amp;openidname=$name&amp;openidemail=$email\">link</a>.</p>";
+         }
+       else
+         $ok=1;
+      }
+
+    if($ok)
+      {
+       /* user information is ok, set session variabel */
+       $email  = DB_get_email('userid',$myid);
+       $myname = DB_get_name('email',$email);
+       $password =  DB_get_passwd_by_userid($myid);
+       $_SESSION['name'] = $myname;
+       $_SESSION['id']   = $myid;
+       $_SESSION['pass'] = $password;
+      }
   }
-else
+else if($OPENIDPATH && myisset('openid_url') && $_REQUEST['openid_url']!='')
+  {
+    OpenIDAskForVerification(OpenIDUrlEncode($_REQUEST['openid_url']));
+  }
+/* check if normal login information is present */
+else if(myisset('email','password'))
   {
     $email     = $_REQUEST['email'];
     $password  = $_REQUEST['password'];
@@ -33,4 +83,8 @@ else
        $_SESSION['pass'] = $password;
       }
   }
+else
+  {
+    echo "can't log you in... missing login information.";
+  }
 ?>
\ No newline at end of file
diff --git a/include/openid.php b/include/openid.php
new file mode 100644 (file)
index 0000000..6ad5fed
--- /dev/null
@@ -0,0 +1,162 @@
+<?php
+require_once("db.php");
+
+  /* provide OpenID support
+   *
+   * taken from http://www.plaxo.com/api/openid_recipe
+   */
+
+function OpenIDVerify()
+{
+  global $OPENIDPATH;
+
+  /* need the openip library */
+  require_once $OPENIDPATH."examples/consumer/common.php";
+
+  $consumer = getConsumer();
+
+  $return_to = getReturnTo();
+  $response = $consumer->complete($return_to);
+
+  // Check the response status.
+  if ($response->status == Auth_OpenID_CANCEL) {
+    // This means the authentication was cancelled.
+    echo 'Verification cancelled.';
+    return False;
+  } else if ($response->status == Auth_OpenID_FAILURE) {
+    // Authentication failed; display the error message.
+    echo "OpenID authentication failed: " . $response->message;
+    return False;
+  } else if ($response->status == Auth_OpenID_SUCCESS) {
+    // This means the authentication succeeded; extract the
+    // identity URL and Simple Registration data (if it was
+    // returned).
+    $openid = $response->getDisplayIdentifier();
+
+    $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
+    $sreg = $sreg_resp->contents();
+  }
+
+  if(isset($sreg))
+    return $sreg;
+  else
+    return "ok";
+}
+
+function OpenIDAskForVerification($openid_url)
+{
+  global $OPENIDPATH;
+
+  /* ask for openid verification */
+  require_once $OPENIDPATH."examples/consumer/common.php";
+
+  $openid =$_REQUEST['openid_url'];
+  $consumer = getConsumer();
+
+  /* check for authentication */
+  // Begin the OpenID authentication process.
+  $auth_request = $consumer->begin($openid);
+
+  // No auth request means we can't begin OpenID.
+  if (!$auth_request) {
+    echo "Authentication error; not a valid OpenID.";
+    }
+
+  $sreg_request = Auth_OpenID_SRegRequest::build(array(),array('fullname','email', 'nickname'));
+
+  if ($sreg_request) {
+    $auth_request->addExtension($sreg_request);
+  }
+
+  // Redirect the user to the OpenID server for authentication.
+  // Store the token for this authentication so we can verify the
+  // response.
+
+  // For OpenID 1, send a redirect.  For OpenID 2, use a Javascript
+  // form to send a POST request to the server.
+  if ($auth_request->shouldSendRedirect()) {
+    $redirect_url = $auth_request->redirectURL(getTrustRoot(),
+                                              getReturnTo());
+
+    // If the redirect URL can't be built, display an error
+    // message.
+    if (Auth_OpenID::isFailure($redirect_url)) {
+      displayError("Could not redirect to server: " . $redirect_url->message);
+    } else {
+       // Send redirect.
+      header("Location: ".$redirect_url);
+      }
+  } else {
+    // Generate form markup and render it.
+    $form_id = 'openid_message';
+    $form_html = $auth_request->htmlMarkup(getTrustRoot(), getReturnTo(),
+                                          false, array('id' => $form_id));
+
+    // Display an error if the form markup couldn't be generated;
+    // otherwise, render the HTML.
+    if (Auth_OpenID::isFailure($form_html)) {
+       displayError("Could not redirect to server: " . $form_html->message);
+    } else {
+      print $form_html;
+    }
+  }
+}
+
+function OpenIDUrlEncode($openid_url)
+{
+  /* this converts each url to a standard form
+   * (domain lowercase and http at the beginning)
+   */
+
+  $return = "";
+
+  $parts = explode("/",$openid_url);
+  $return .= "http://";
+
+  /* check for http:// */
+  if( strtolower($parts[0]) == "http:" )
+    array_shift($parts);
+  if( $parts[0] == "")
+    array_shift($parts);
+
+  /* next part is the server*/
+  $return .= strtolower( $parts[0] );
+  array_shift($parts);
+
+  foreach ($parts as $t)
+    $return .= "/$t";
+
+  return $return;
+}
+
+function DB_GetUserId($openid_url)
+{
+  $result = DB_query_array("SELECT user_id FROM user_openids WHERE openid_url = ".DB_quote_smart(OpenIDUrlEncode($openid_url)));
+
+  if($result)
+    return $result[0];
+  else
+    return False;
+}
+
+function DB_GetOpenIDsByUser($user_id)
+{
+  return DB_query_array_all("SELECT openid_url FROM user_openids WHERE user_id = '$user_id'");
+}
+
+function DB_AttachOpenID($openid_url, $user_id)
+{
+  DB_query("INSERT INTO user_openids VALUES (".DB_quote_smart(OpenIDUrlEncode($openid_url)).", '$user_id')");
+}
+
+function DB_DetachOpenID($openid_url, $user_id)
+{
+  DB_query("DELETE FROM user_openids WHERE openid_url = ".DB_quote_smart(OpenIDUrlEncode($openid_url))." AND user_id = '$user_id'");
+}
+
+function DB_DetachOpenIDsByUser($user_id)
+{
+  DB_query("DELETE FROM user_openids WHERE user_id = '$user_id'");
+}
+
+?>
\ No newline at end of file
index f42ae82a19aa8385418bcba2c46fdbae47600f90..4abaf3b9522883bf6a18037def1432190734ff5b 100644 (file)
@@ -5,6 +5,8 @@
 if(!isset($HOST))
   exit;
 
+include_once('openid.php');
+
 $name  = $_SESSION["name"];
 $email = DB_get_email('name',$name);
 $myid  = DB_get_userid('email',$email);
@@ -20,6 +22,7 @@ $changed_autosetup    = 0;
 $changed_sorting      = 0;
 $changed_openforgames = 0;
 $changed_vacation     = 0;
+$changed_openid       = 0;
 
 display_user_menu($myid);
 
@@ -33,6 +36,20 @@ DB_update_user_timestamp($myid);
  * update the database and track changes with a variable, so that
  * we can later highlight the changed value
  */
+
+/* check for deleted openids */
+foreach($_REQUEST as $key=>$value)
+{
+  if(strstr($key,"delete-openid-"))
+    {
+      /* found and openid to delete */
+      $DelOpenID = substr(str_replace("_",".",$key),14);
+      DB_DetachOpenID($DelOpenID, $myid);
+      $changed_openid = 1;
+    }
+}
+
+
 if(myisset('vacation_start','vacation_stop','vacation_comment') &&
    ($_REQUEST['vacation_start']!='' || $_REQUEST['vacation_stop']!='')
    )
@@ -236,6 +253,12 @@ if(myisset("password0") &&  $_REQUEST["password0"]!="" )
     /* error output below */
   }
 
+if(myisset("openid_url") && $_REQUEST['openid_url']!='')
+  {
+    $openid_url = OpenIDUrlEncode($_REQUEST['openid_url']);
+    DB_AttachOpenID($openid_url, $myid);
+  }
+
 /* get infos again in case they have changed */
 $PREF     = DB_get_PREF($myid);
 $timezone = DB_get_user_timezone($myid);
@@ -386,6 +409,31 @@ echo "        <tr><td>Password(new, retype): </td><td>",
   " </td></tr>\n";
 echo "      </table>\n";
 echo "    </fieldset>\n";
+echo "    <fieldset>\n";
+echo "      <legend>OpenID</legend>\n";
+
+$openids = array();
+$openids = DB_GetOpenIDsByUser($myid);
+
+if(sizeof($openids))
+  {
+    echo "     <table class=\"openid\">\n";
+    echo "     <thead><tr><th>Delete?</th><th>OpenId</th></tr></thead>\n";
+    echo "     <tbody>\n";
+    foreach ($openids as $ids)
+      {
+       $id=($ids[0]);
+       echo "        <tr><td><input type=\"checkbox\" name=\"delete-openid-$id\" /></td><td>",$id, "</td></tr>\n";
+      }
+    echo "     </tbody>\n";
+    echo "     </table>\n";
+  }
+
+echo "        add OpenID: ",
+  "<input type=\"text\" id=\"openid_url\" name=\"openid_url\" size=\"20\" maxlength=\"50\" />";
+if($changed_openid)
+  echo "   Deleted some OpenIDs! <br />\n";
+echo "    </fieldset>\n";
 echo "    <fieldset><legend>Submit</legend><input type=\"submit\"  name=\"passwd\" value=\"set\" /></fieldset>\n";
 echo "  </form>\n";
 echo "</div>\n";
index 7f3266bba19d0fa4885a60d73f3758a5d6f038ac..75ec309e98664158c52abca1332ddf87c7278283 100644 (file)
@@ -6,7 +6,7 @@ if(!isset($HOST))
   exit;
 
 /* new user wants to register */
-if(myisset("Rfullname","Remail","Rpassword","Rtimezone") )
+if(myisset("Rfullname","Remail","Rtimezone") )
   {
     global $HOST,$INDEX;
 
@@ -23,6 +23,13 @@ if(myisset("Rfullname","Remail","Rpassword","Rtimezone") )
        echo "this email address is already used ?!<br />";
        $ok=0;
       }
+    /* need either openid or password */
+    if(!myisset('Rpassword')  &&  !myisset('Ropenid'))
+      {
+       echo "I need either a Password or an Openid url.<br />";
+       $ok=0;
+      }
+
     /* check against robots */
     $robots=0; /* at least one anti-robot question needs to be answered */
     if(myisset('Robotproof0'))
@@ -65,15 +72,34 @@ if(myisset("Rfullname","Remail","Rpassword","Rtimezone") )
        echo "You answered the math question wrong. <br />\n";
        $ok=0;
       }
-
     /* everything ok, go ahead and create user */
     if($ok)
       {
-       $r=DB_query("INSERT INTO User VALUES(NULL,".DB_quote_smart($_REQUEST["Rfullname"]).
-                   ",".DB_quote_smart($_REQUEST["Remail"]).
-                   ",".DB_quote_smart(md5($_REQUEST["Rpassword"])).
-                   ",".DB_quote_smart($_REQUEST["Rtimezone"]).",NULL,NULL)");
-
+       if(myisset('Rpassword'))
+         {
+           $r=DB_query("INSERT INTO User VALUES(NULL,".DB_quote_smart($_REQUEST["Rfullname"]).
+                       ",".DB_quote_smart($_REQUEST["Remail"]).
+                       ",".DB_quote_smart(md5($_REQUEST["Rpassword"])).
+                       ",".DB_quote_smart($_REQUEST["Rtimezone"]).",NULL,NULL)");
+         }
+       else if(myisset('Ropenid'))
+         {
+           $password = $_REQUEST["Rfullname"].preg_replace('/([ ])/e', 'chr(rand(33,122))', '               ');
+           $r=DB_query("INSERT INTO User VALUES(NULL,".DB_quote_smart($_REQUEST["Rfullname"]).
+                       ",".DB_quote_smart($_REQUEST["Remail"]).
+                       ",".DB_quote_smart(md5($password)).
+                       ",".DB_quote_smart($_REQUEST["Rtimezone"]).",NULL,NULL)");
+           if($r)
+             {
+               include_once('openid.php');
+               $myid = DB_get_userid('email',$_REQUEST['Remail']);
+               DB_AttachOpenID($_REQUEST['Ropenid'], $myid);
+             }
+         }
+       else
+         {
+           echo 'Error during registration, please contact '.$ADMIN_NAME.' at '.$ADMIN_EMAIL;
+         }
        if($r)
          {
            /* Set session, so that new user doesn't need to log in */
@@ -94,29 +120,50 @@ if(myisset("Rfullname","Remail","Rpassword","Rtimezone") )
  else
    {
      /* No information for new user given, ouput a page for registration */
-     echo "<p><br /><strong> IMPORTANT: passwords are going over the net as clear text, so pick an easy password. ".
-       "No need to pick anything complicated here ;)<br />";
+
+     /* check for openid information */
+     $openid_url = '';
+     $name      = '';
+     $email     = '';
+     if(myisset('openid_url'))
+       $openid_url = $_REQUEST['openid_url'];
+     if(myisset('openidname'))
+       $name       = $_REQUEST['openidname'];
+     if(myisset('openidemail'))
+       $email      = $_REQUEST['openidemail'];
+
+     if($openid_url=='')
+       echo "<p><br /><strong> IMPORTANT: passwords are going over the net as clear text, so pick an easy password. ".
+        "No need to pick anything complicated here ;)<br />";
      echo "N.B. Your email address will be exposed to other players whom you play games with. ";
      echo "<br /><br /></strong></p>";
-     ?>
-        <form action="index.php?action=register" method="post">
-          <fieldset>
-            <legend>Register</legend>
-             <table>
-              <tr>
-               <td><label for="Rfullname">Full name:</label></td>
-              <td><input type="text" id="Rfullname" name="Rfullname" size="20" maxlength="30" /> </td>
-              </tr><tr>
-               <td><label for="Remail">Email:</label></td>
-              <td><input type="text" id="Remail" name="Remail" size="20" maxlength="30" /></td>
-              </tr><tr>
-              <td><label for="Rpassword">Password(will be displayed in cleartext on the next page):</label></td>
-               <td><input type="password" id="Rpassword" name="Rpassword" size="20" maxlength="30" /></td>
-              </tr><tr>
-              <td><label for="Rtimezone">Timezone:</label></td>
-               <td>
-<?php
-               output_select_timezone("Rtimezone");
+     echo '        <form action="index.php?action=register" method="post">';
+     echo '          <fieldset>';
+     echo '            <legend>Register</legend>';
+     echo '             <table>';
+     echo '              <tr>';
+     echo '               <td><label for="Rfullname">Full name:</label></td>';
+     echo "           <td><input type=\"text\" id=\"Rfullname\" name=\"Rfullname\" size=\"20\" maxlength=\"30\" value=\"$name\" /> </td>";
+     echo '              </tr><tr>';
+     echo '               <td><label for="Remail">Email:</label></td>';
+     echo "           <td><input type=\"text\" id=\"Remail\" name=\"Remail\" size=\"20\" maxlength=\"30\" value=\"$email\" /></td>";
+     echo '              </tr><tr>';
+     if($openid_url=='')
+       {
+        echo '        <td><label for="Rpassword">Password(will be displayed in cleartext on the next page):</label></td>';
+        echo '               <td><input type="password" id="Rpassword" name="Rpassword" size="20" maxlength="30" /></td>';
+        echo '              </tr><tr>';
+       }
+     else
+       {
+        echo '        <td><label for="Ropenid">OpenId:</label></td>';
+        echo '               <td><input type="text" id="Ropenid" name="Ropenid" size="20" maxlength="50" value="'.htmlentities($openid_url).'" /></td>';
+        echo '              </tr><tr>';
+       }
+     echo '           <td><label for="Rtimezone">Timezone:</label></td>';
+     echo '               <td>';
+
+     output_select_timezone("Rtimezone");
 ?>
               </td>
               </tr><tr>
index 5dd267c2741832aa2122cffbf49049080c231c97..2ff4fdfa2c572a4f2274b39c3fb445e1fadd31cc 100644 (file)
@@ -77,6 +77,15 @@ if($done==0)
     <input type="password" id="password" name="password" size="20" maxlength="30" /> <br />
     <input type="submit" class="submitbutton" name="login" value="login" />
     <input type="submit" class="submitbutton" name="forgot" value="Forgot your password?" />
+<?php
+  if($OPENIDPATH)
+    {?>
+    <hr>
+    <p> Have an OpenID account? Sign in below <br />
+    <input type="text" id="openid_url" name="openid_url" size="20" maxlength="50" />
+    <input type="submit" class="submitbutton" name="login" value="Sign in" /><br />
+     e.g. http://username.openid.net. See <a href="http://openid.net">openid.net</a> for more information.</p>
+<?php }?>
   </fieldset>
   </form>
 </div>