Create mytut_service.info and put following code in file. I am assuming you know how to create module.
Put following code in mytut_service.module file.
Enable the module.
Now Create a service endpoint as shown in the following image
Now go to resources and there you will find a new endpoint exposed by "Mytut service" module. Check it and save.
Now its time to test our end point. So proper url to use this endpoint will be
YOUR_DOMAIN_NAME/?q=data/mytut_service_service/retrieve?&ts=1432539547&hpwd=IyHk9GeJS03Eu7ZQwr9G2Ob8JUCn7Lbeu6Or9S_x4wY&uid=230
In above url i am passing three parameter. Timestamp , hashed password , user id all these parameter are passed as a one time login link to registered user.
To test we can use drush to create one time login link for current user as well. Drush command for generating one time login link is :
drush uli some-username
This will give us a result like this :
Now all the three parametes userid,timestamp and hashed password can be get and replace with the service end point mentioned above. And if all the parameters are correct we get response shown in image
name = Mytut service
description = My custom Service.
package = Other
core = 7.x
dependencies[] = services
dependencies[] = rest_server
Put following code in mytut_service.module file.
function mytut_service_services_resources() {
$api = array(
'mytut_service_service' => array(
'operations' => array(
'retrieve' => array(
'help' => 'Retrieves story by nid',
'callback' => 'mycallback',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'access arguments append' => FALSE,
'args' => array(
array(
'name' => 'fn',
'type' => 'string',
'description' => 'Function to perform',
'source' => array('path' => '0'),
'optional' => TRUE,
'default' => '0',
),
array(
'name' => 'ts',
'type' => 'int',
'description' => 'timestamp',
'source' => array('param' => 'ts'),
'optional' => TRUE,
'default' => '0',
),
array(
'name' => 'hpwd',
'type' => 'string',
'description' => 'hashed password',
'source' => array('param' => 'hpwd'),
'optional' => TRUE,
'default' => '0',
),
array(
'name' => 'uid',
'type' => 'int',
'description' => 'user id',
'source' => array('param' => 'uid'),
'optional' => TRUE,
'default' => '0',
),
),
),
),
),
);
return $api;
}
/**
* Callback function
*/
function mycallback($fn, $ts, $hpwd, $uid) {
global $user;
$timestamp = $ts;
$hashed_pass = $hpwd;
// When processing the one-time login link, we have to make sure that a user
// isn't already logged in.
if ($user->uid) {
// The existing user is already logged in.
if ($user->uid == $uid) {
services_error('you are already loggedin', 202);
}
// A different user is already logged in on the computer.
else {
$reset_link_account = user_load($uid);
if (!empty($reset_link_account)) {
services_error('Another user is already login from this computer', 202);
} else {
// Invalid one-time link specifies an unknown user.
services_error('The one-time login link you clicked is invalid.', 202);
}
}
} else {
// Time out, in seconds, until login URL expires. Defaults to 24 hours =
// 86400 seconds.
$timeout = variable_get('user_password_reset_timeout', 86400);
$current = REQUEST_TIME;
// Some redundant checks for extra security ?
$users = user_load_multiple(array($uid), array('status' => '1'));
if ($timestamp <= $current && $account = reset($users)) {
// No time out for first time login.
if ($account->login && $current - $timestamp > $timeout) {
services_error(t('One time login link expired'));
} elseif ($account->uid && $timestamp >= $account->login && $timestamp <= $current && $hashed_pass == user_pass_rehash($account->pass, $timestamp, $account->login, $account->uid)) {
// First stage is a confirmation form, then login
// Set the new user.
$user = $account;
// user_login_finalize() also updates the login timestamp of the
// user, which invalidates further use of the one-time login link.
user_login_finalize();
watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $account->name, '%timestamp' => $timestamp));
// Let the user's password be changed without the current password check.
$token = drupal_random_key();
$_SESSION['pass_reset_' . $user->uid] = $token;
return array('Valid one time link');
} else {
services_error(t('Link has been used'));
}
} else {
services_error('Deny access, no more clues.');
}
}
}
Enable the module.
Now Create a service endpoint as shown in the following image
Now go to resources and there you will find a new endpoint exposed by "Mytut service" module. Check it and save.
Now its time to test our end point. So proper url to use this endpoint will be
YOUR_DOMAIN_NAME/?q=data/mytut_service_service/retrieve?&ts=1432539547&hpwd=IyHk9GeJS03Eu7ZQwr9G2Ob8JUCn7Lbeu6Or9S_x4wY&uid=230
In above url i am passing three parameter. Timestamp , hashed password , user id all these parameter are passed as a one time login link to registered user.
To test we can use drush to create one time login link for current user as well. Drush command for generating one time login link is :
drush uli some-username
This will give us a result like this :
Hey, Nice blog. But I have a question here. How do we get uid, timestamp and password hash from the one time login link ? The problem what I am facing is If I try to request a new password using endpoint/user/request_new_password. I'll get one time login link through mail but the login link base_url is the site domain name not the servoce END POINT.
ReplyDelete