Hi,
I'm trying to combine a whole lot of web services (mediawiki and SMF among others) in my website. I want to use OpenID for the authentication, but new users still would need to register an account with all components before being able to use them.
To make it easier for the user, I would like to create a single registration page that will create accounts on all of these subsystems automatically. For that, I need to know how to create OpenID-enabled accounts on all these subsystems, directly into their backend or by using some form of API.
In the case of SMF, is it possible to use some form of API to register a user ? Is it possible to block online account registrations, so all registrations would have to go through the central registration system ? Is it possible to disable the password-changing functionality in SMF (all users will use OpenID anyway, I don't want to store passwords)
Has anyone tried to build a central registration system like this ? It would seem more efficient than building O(n^2) bridges between n web services...
smf 2.0 supports openID
Yes it does, and so does mediawiki. But both software systems still require you to create an account. With N systems, that means N registrations.
I would like to have a central system to create these accounts directly in the SMF backend. For that I need an API or some other way of doing that.
ah... then you need to look at the integration arrays sticky at the top of this board.
As I understand it, the integration array is used to allow SMF to do all kinds of things when I register a new account in it. But then I need to make SMF the master in this process and I don't want to do that, I want something generic where SMF is "just another" subsystem where I need to create an account in.
Have a read of the topic below:
http://www.simplemachines.org/community/index.php?topic=265568.0
You should be able to use SMF's 'registerMember()' function to do what you want.
I've tried using registerMember(), but I can't get it to work. I followed the instructions as best as I could but no new user gets registered.
This is the (only) code I use:
Quote
<?
require_once('/var/www/smf/SSI.php');
function smf_register($vars) {
global $db_name, $db_prefix, $sourcedir, $boarddir;
mysql_select_db($db_name); //switch to SMF's database, in case these softwares are in different databases.
foreach($vars as $var => $val) {
$escvars[$var] = mysql_real_escape_string($val);
}
$regOptions = array(
'interface' => 'admin',
'password' => '',
'password_check' => '',
'check_reserved_name' => false,
'check_password_strength' => false,
'check_email_ban' => false,
'send_welcome_email' => false,
'require' => 'nothing',
'extra_register_vars' => array(),
'theme_vars' => array(),
'auth_method' => 'openid',
'username' => $escvars['username'],
'email' => $escvars['email'],
'openid' => $escvars['openid'],
);
require_once($sourcedir . '/Subs-Members.php'); //require the file, so that we can call the function
$memberID = registerMember($regOptions); //call the function. $memberID should return a value.
mysql_select_db($config["db_database"]); //back to the parent software's database...
}
$myvars['username'] = "SomeUser";
$myvars['email'] = "[email protected]";
$myvars['openid'] = "http://whatever.myopenid.com";
smf_register($myvars);
When I run this code, no user is created. Even worse, instead of the empty page I expect to see, I'm seeing a fullfletched SMF-themed login page with the warning "Only registered members are allowed to access this section. Please login below or register an account with MyForum Forum".
Is there a way to register a new member silently, meaning nothing is printed or displayed ? If so, how do I do that ? Where are errors logged, if any are logged at all ?
QuoteWhen I run this code, no user is created. Even worse, instead of the empty page I expect to see, I'm seeing a fullfletched SMF-themed login page with the warning "Only registered members are allowed to access this section. Please login below or register an account with MyForum Forum".
This is because you have defined the interface as the SMF admin panel:
$regOptions = array(
'interface' => 'admin',
thanks for the tip. I changed my code, and the output no longer shows. However, the registration fails because the API claims OpenID authentication failed. It would be nice if it didn't require me to be authenticated with OpenID, especially because the user I'm creating will never authenticate with my own OpenID account.
Quote
An Error Has Occurred!
The OpenID address given has not been verified yet. Please log in to verify.
Maybe this is a bug ? I'm running SMF 2.0 beta 4.
Remove this:
'openid' => $escvars['openid'],
I'm not sure what the would accomplish. I removed that field, it gave the same error.
So I also removed " 'auth_method' => 'openid',", which worked.
But as I understand it, this will not create an OpenID account but a regular account ?
I traced the problem to Sources/Subs-Members.php in registerMember()
Quote
// If they are using an OpenID that hasn't been verified yet error out.
// !!! Change this so they can register without having to attempt a login first
if ($regOptions['auth_method'] == 'openid' && (empty($_SESSION['openid']['verified']) || $_SESSION['openid']['openid_uri'] != $regOptions['openid']))
$reg_errors[] = array('lang', 'openid_not_verified');
So this is a known bug :)
why would you call it a bug?
If someone registers with an OpenID account, but does not verify it, then it indeed should error out.
true, if someone were to register his own account.
But I'm trying to use the SMF API. I assumed I could create accounts for other people using that API. I can't be logged in with their OpenID because I don't know the password.
but, if you have openID associated to the account, then you have to be able to validate the OpenID.
You specified "authentication method = openID" which means that they system is going to TRY to authenticate the open ID on your registration of the user account
As I said, it's not a bug.
Maybe I should be more clear about what I plan to do with the SMF API.
Suppose I want to register 5000 users, all whom are using OpenID. What I want to do, is call registerMember 5000 times to create 5000 users. What I don't want to do, is authenticate with OpenID 5000 times, just so I can create those users.
So the question is still: how can I create a user using the SMF API ?
register them all and then turn on OpenID?
Ah, that could work. I'll give it a try, thanks.
Is there also a way to keep the SMF API from printing anything out, including errors ?
I've successfully created an account with OpenID enabled using the API with the following code:
Quote
<?
require_once('/var/www/smf/SSI.php');
function smf_register($vars) {
global $db_name, $db_prefix, $sourcedir, $boarddir;
mysql_select_db($db_name); //switch to SMF's database, in case these softwares are in different databases.
foreach($vars as $var => $val) {
$escvars[$var] = mysql_real_escape_string($val);
}
#$newPassword = substr(preg_replace('/\W/', '', md5(mt_rand())), 0, 10);
$newPassword_sha1 = "xxx"; #sha1($newPassword);
$regOptions = array(
'interface' => 'guest',
'password' => $newPassword_sha1,
'password_check' => $newPassword_sha1,
'check_reserved_name' => false,
'check_password_strength' => false,
'check_email_ban' => false,
'send_welcome_email' => false,
'require' => 'nothing',
'extra_register_vars' => array(),
'theme_vars' => array(),
'auth_method' => 'password',
'username' => $escvars['username'],
'email' => $escvars['email'],
);
require_once($sourcedir . '/Subs-Members.php'); //require the file, so that we can call the function
require_once($sourcedir . '/Subs.php'); //require the file, so that we can call the function
$memberID = registerMember($regOptions); //call the function. $memberID should return a value.
updateMemberData($memberID, array('openid_uri' => $escvars['openid'], 'last_login' => 12345, 'hide_email' => 1, 'id_msg_last_visit' => 1));
mysql_select_db($config["db_database"]); //back to the parent software's database...
}
$myvars['username'] = "SomeUser";
$myvars['email'] = "[email protected]";
$myvars['openid'] = "http://username.myopenid.net";
smf_register($myvars);
session_destroy();
?>
When I now try to login with that user using OpenID, SMF thinks the user doesn't exist and wants me to register a new account. I'm not sure why that is or how to get around it.
The user I created has the exact same values in the database table as one created using the SMF registration form.
Besides some new entries in the log tables (which I assume are not checked when a user registers?)
, the following tables are also altered when doing a normal registration instead of an API register:
- smf_scheduled_tasks
- smf_openid_assoc
- smf_sessions
Even after setting an entry in smf_openid_assoc manually, SMF still thinks the user doesn't exist.
What am I doing wrong ?
Has anyone else tried to create an OpenID account through the API ? Ran into similar problems ? I'm interested in knowing how this was solved, if it can be solved...