OK about a month ago I asked about this and got some useful info from the guys here and was asked to post my solution when it was done. Unfortunately due to other jobs this fell to the back burner a few times and just got it going. Original thread is here:
http://modxcms.com/forums/index.php/topic,56921.0.html
So here is my code. I hope you find it useful. It works on every test I have tried but always happy for feedback or suggestions.
A few things to note.
1) It uses OLD style sql code not XPDO. I need to get up to speed with XPDO but haven’t had the time to devote to it yet. If anyone wants to recast the old sql code here to XPDO style then PLEASE go ahead and post it back here! I (and plenty others) will be appreciative of it!
2) I don’t really need to invent a password when creating an account for someone coming in from janrain but I figured what the heck just give them a random password and then if they use the forgot password facility at least there is something there.
3) I put them in a user group "members" - you don’t have to do that, up to you to include them in a group or not.
4) Obviously you need a janrain account - they will provide you with a javascript that you place on the login page and you put this snippet on the destination page - the url of which you have to include in that javascript. You will need your own api key which you get on registering with janrain and obviously I have removed my references to the contexts I use here and my domain - just edit those.
That’s about it. Happy to answer any questions or if anyone has some feedback or suggestions over the way I have done things (ie there is a better way!) then happy to hear it.
Hope this is helpful.
<?php
#----check if logging in or prompting for new username this equates to the return from option 4) listed below after they
#----have tried a new username - checks for another clash and then prompts or registers them.
if (isset($_POST['username'])) {
$table = 'modxr_users';
$condition = '`username` = "'.$_POST['username'].'"';
$result = $modx->db->select( '*','`'. $table.'`',$condition,'`username` ASC','0,1');
if( $modx->db->getRecordCount( $result ) >= 1 ) { #username exists
$modx->toPlaceholder('error.username', 'Username already exists - please select another');
$refresh = '';
$lenth=8;
$aZ09 = array_merge(range('A', 'Z'), range('a', 'z'),range(0, 9));
$pwd ='';
for($c=0;$c < $lenth;$c++) {
$pwd .= $aZ09[mt_rand(0,count($aZ09)-1)];
}
$spinner = '<div class="register">
<div class="registerMessage">[[+error.message]]</div>
<form class="form" action="/[[~[[*id]]]]" method="post">
<table id="createAccount">
<input type="hidden" name="email" id="email" value="'.$_POST['email'].'" />
<input type="hidden" name="password" id="password" value="'.$_POST['pwd'].'" />
<tr>
<td class="first">
<label for="username">Username</label>
</td>
<td>
<input type="text" name="username" id="username" value="'.$_POST['username'].'" />
<span class="error">[[+error.username]]</span>
</td>
</tr>
<tr>
<td class="first">
</td>
<td>
<input type="submit" value="Login" class="button green big"/>
</td>
</tr>
</table>
</form>
<p>Already a member? <a href="/member/index.html"><strong>Sign In</strong></a></p>
</div>';
$modx->toPlaceholder('refresh', $refresh);
$modx->toPlaceholder('login_content', $spinner);
}
else {
// option 3 - create new user, I choose to assign random password.
$pwd = $_POST['pwd'];
$user = $modx->newObject('modUser');
$user->fromArray(array(
'username' => $_POST['username']
,'password' => md5($pwd)
,'active' => 1
));
$profile = $modx->newObject('modUserProfile');
$profile->fromArray(array(
'email' => $_POST['email']
));
$user->addOne($profile, 'Profile');
$saved = $user->save();
$user->addSessionContext('yourcontext');
#---- add to usergroup.
$table = 'modxr_users';
$condition = '`username` = "'.$_POST['username'].'"';
$result = $modx->db->select( '*','`'. $table.'`',$condition,'`username` ASC','0,1');
if( $modx->db->getRecordCount( $result ) >= 1 ) { #username exists
$row = $modx->db->getRow( $result );
$uid = $row['id'];
}
$table = 'modxr_member_groups';
$member_group = array();
$member_group['user_group'] = 5;
$member_group['member'] = $uid;
$member_group['role'] = 1;
$result = $modx->db->insert( $member_group,'`'. $table.'`', '');
$refresh = '<meta http-equiv="refresh" content="2;url=http://yourdomain.com/member/">';
$modx->toPlaceholder('refresh', $refresh);
}
}
else {
$refresh = '<meta http-equiv="refresh" content="2;url=http://yourdomain.com/member/">';
$spinner = '<center><img src="http://yourdomain.com/assets/img/load.gif"></center><br /><a href="/member/">Members page</a>';
$modx->toPlaceholder('refresh', $refresh);
$modx->toPlaceholder('login_content', $spinner);
#--- Default response from janrain - gives you their username and email and unique id info
#--- This code supplied by janrain --
$rpxApiKey = 'your api key goes here';
if(isset($_POST['token'])) {
/* STEP 1: Extract token POST parameter */
$token = $_POST['token'];
/* STEP 2: Use the token to make the auth_info API call */
$post_data = array('token' => $_POST['token'],
'apiKey' => $rpxApiKey,
'format' => 'json');
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, 'https://rpxnow.com/api/v2/auth_info');
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$raw_json = curl_exec($curl);
curl_close($curl);
/* STEP 3: Parse the JSON auth_info response */
$auth_info = json_decode($raw_json, true);
if ($auth_info['stat'] == 'ok') {
/* STEP 3 Continued: Extract the 'identifier' from the response */
$profile = $auth_info['profile'];
$identifier = $profile['identifier'];
if (isset($profile['photo'])) {
$photo_url = $profile['photo'];
}
if (isset($profile['displayName'])) {
$name = $profile['displayName'];
}
if (isset($profile['email'])) {
$email = $profile['email'];
}
//echo 'name = '.$name.'<br>email = '.$email.'<br>identifier = '.$identifier.'<br>';
/* STEP 4: Use the identifier as the unique key to sign the user into your system.
This will depend on your website implementation, and you should add your own
code here.
---- End of janrain code from here it is mine again ---
Check options for login:
1) identifier exists - log them in
2) identifier doesn't exist but email exists - add identifier and log them in
3) identifier and email don't exist and username doesn't exist - create account and log them in
4) identifier and email don't exist and username already exists - prompt for username and log them in
*/
//------- user check ------
// - Option 1)
$table = 'modxr_users';
$condition = '`remote_key` = "'.$identifier.'"';
$result = $modx->db->select( '*','`'. $table.'`',$condition,'`username` ASC','0,1');
if( $modx->db->getRecordCount( $result ) >= 1 ) { #they exist
#check if blocked
$row = $modx->db->getRow( $result );
$blocked = $row['blocked'];
$userid = $row['id'];
$username = $row['username'];
if ($blocked > 0) {
echo 'Blocked user';
exit;
}
$user = $modx->getObjectGraph('modUser', '{"Profile":{}}', array('remote_key:=' => $identifier, 'remote_key:!=' => null, 'class_key' => 'modUser'));
$user->addSessionContext('yourcontext');
}
else {
// - Option 2)
$table = 'modxr_user_attributes';
$condition = '`email` = "'.$email.'"';
$result = $modx->db->select( '*','`'. $table.'`',$condition,'`email` ASC','0,1');
if( $modx->db->getRecordCount( $result ) >= 1 ) { #they exist
#check if blocked
$row = $modx->db->getRow( $result );
$blocked = $row['blocked'];
$userid = $row['id'];
if ($blocked > 0) {
echo 'Blocked user';
exit;
}
#update modxr_users with key
$table = 'modxr_users';
$condition = '`id` = "'.$userid.'"';
$tabledata['remote_key'] = $identifier;
$result = $modx->db->update( $tabledata,'`'. $table.'`', $condition);
$user = $modx->getObjectGraph('modUser', '{"Profile":{}}', array('remote_key:=' => $identifier, 'remote_key:!=' => null, 'class_key' => 'modUser'));
$user->addSessionContext('yourcontext');
}
else { #--------- Duplicate username prompt for new username
$table = 'modxr_users';
$condition = '`username` = "'.$name.'"';
$result = $modx->db->select( '*','`'. $table.'`',$condition,'`username` ASC','0,1');
if( $modx->db->getRecordCount( $result ) >= 1 ) { #username exists
$modx->toPlaceholder('error.username', 'Username already exists - please select another');
$refresh = '';
$lenth=8;
$aZ09 = array_merge(range('A', 'Z'), range('a', 'z'),range(0, 9));
$pwd ='';
for($c=0;$c < $lenth;$c++) {
$pwd .= $aZ09[mt_rand(0,count($aZ09)-1)];
}
$spinner = '<div class="register">
<div class="registerMessage">[[+error.message]]</div>
<form class="form" action="/[[~[[*id]]]]" method="post">
<table id="createAccount">
<input type="hidden" name="email" id="email" value="'.$email.'" />
<input type="hidden" name="password" id="password" value="'.$pwd.'" />
<tr>
<td class="first">
<label for="username">Username</label>
</td>
<td>
<input type="text" name="username" id="username" value="'.$name.'" />
<span class="error">[[+error.username]]</span>
</td>
</tr>
<tr>
<td class="first">
</td>
<td>
<input type="submit" value="Login" class="button green big"/>
</td>
</tr>
</table>
</form>
<p>Already a member? <a href="/member/index.html"><strong>Sign In</strong></a></p>
</div>';
$modx->toPlaceholder('refresh', $refresh);
$modx->toPlaceholder('login_content', $spinner);
}
else {
// option 3 - create new user, I choose to assign random password.
$aZ09 = array_merge(range('A', 'Z'), range('a', 'z'),range(0, 9));
$pwd ='';
$lenth = 8;
for($c=0;$c < $lenth;$c++) {
$pwd .= $aZ09[mt_rand(0,count($aZ09)-1)];
}
$user = $modx->newObject('modUser');
$user->fromArray(array(
'username' => $name
,'password' => md5($pwd)
,'active' => 1
,'remote_key' => $identifier
));
$profile = $modx->newObject('modUserProfile');
$profile->fromArray(array(
'email' => $email
));
$user->addOne($profile, 'Profile');
$saved = $user->save();
$user->addSessionContext('yourcontext');
#---- add to usergroup.
$table = 'modxr_users';
$condition = '`username` = "'.$name.'"';
$result = $modx->db->select( '*','`'. $table.'`',$condition,'`username` ASC','0,1');
if( $modx->db->getRecordCount( $result ) >= 1 ) { #username exists
$row = $modx->db->getRow( $result );
$uid = $row['id'];
}
$table = 'modxr_member_groups';
$member_group = array();
$member_group['user_group'] = 5;
$member_group['member'] = $uid;
$member_group['role'] = 1;
}
} // else option 2)
} // else option 1)
//end:
/* an error occurred - janrain code, haven't done anything with this yet*/
} else {
// gracefully handle the error. Hook this into your native error handling system.
echo 'An error occured: ' . $auth_info['err']['msg'];
}
}
} #else (isset($_POST['username'])