views:

49

answers:

3

We have to have a "register" method available via web service that is written in java so hence forth we do not have access to the Drupal API. But we need to be able to register a user successfully. Simply adding a user to the users table will not do it as the newly created users are never able to login successfully. Again I love the Drupal API and would always use that as that is the "correct" way to do it but in this case we just dont have the faculty to do that. Any insights to this dilemma ?

+2  A: 

You'll want to step through the user_save() API function to get an idea of what Drupal does when creating a new user.

There isn't any deep magic to what Drupal does with saving that type of data: it's all in the database. So, while it's not ideal that you can't use the Drupal API, you're really only dealing with two database inserts: the {user} table insert (which you've already done), and the {users_roles} table insert.

Based on your info, I suspect the missing link is that you're not adding a row to the {users_roles} table for your new user's UID. The relevant line in user_save():

db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $account->uid, $rid);

Where $account->uid is the UID of the newly created user, and $rid is the ID of the role you want to give the user. A new user needs at least the authenticated user role.

Everything else in user_save() is mainly sanity checking (user_save() handles updating a user in addition to creating a new one) and hook firing, which you likely don't need to worry about for this use-case.

Mark Trapp
Mark, any time the user is created, they are then taken to the "accept terms and conditions page". They cant seem to go any further no matter if they accept or not.
jini
@jini, Drupal core doesn't have a terms and conditions system: it sounds like a contrib module is blocking the login. You'll want to look through their code to see how it's validating that. Likely, you'll need to add a row to that module's table with the new user's UID.
Mark Trapp
+1  A: 

While Mark's method is probably the most efficient, it's not the easiest to implement or maintain. Contrib modules can react to when users are being inserted in the database, and without Drupal you'll miss this and would need to implement each module by hand.

A simpler solution would be to create a menu callback you can call from your Java implementation. All you really need to do, is to post the relevant info and to Drupal and let it call user_save. It requires an extra request, but instead you get the Drupal hook system and a more maintainable solution that wont break if new modules are added.

To avoid letting anybody create users this way, you can create a setting for allowed IPs and check that requestee's IP in the access callback. That should be the easiest and most secure solution, since only the server(s) will be able to create users, and a brute force attack won't be able to succeed.

googletorp
+1  A: 

The easier solution would be to create a custom module that implement hook_menu() to add a menu callback that is called from the Java application.
The problem with this solution is that is not secure, as the menu callback should be accessible from the anonymous users; this means that if the menu callback entry is found by somebody, they could create new users bypassing the checking done by Drupal when users create a new account (in example, Drupal can verify the email address they use is one they can use). That is the same reason why you should never have a phpinfo.php file that returns the output of phpinfo(), and that is accessible to everybody.
The solution is to pass to the menu callback you created a parameter that other users cannot guess; Drupal 7 does this to avoid that cron.php is invoked by random users, with the effect of making the Drupal-powered site slower, or cause other problems. Drupal has a function that returns a not predictable value that depends from the Drupal installation (drupal_get_token()).

The other alternative is to implement hook_xmlrpc() in the custom code, and expose a new RPC function that accepts a parameter to verify who is invoking it, as in the previous case.

kiamlaluno

related questions