magento password change with soap - php

I am connecting an other application to create and update customers in Magento 1.9 with SOAP. Because I want the passwords to stay exactly the same customers will be forced to change the password in the other application. After change I want the password to be changed in Magento Through the SOAP connection, but I can't get it working. After the request I am getting "bool(true)" but nothing seems to be changed.
Am I doing something wrong, or are there restrictions in Magento.
My code:
<?php
//ensure you are getting error output for debug
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors',1);
$client = new SoapClient('http://www.mymagentosite.com/api/v2_soap/?wsdl');
// If some stuff requires api authentification,
// then get a session token
$session = $client->login('apiuser', 'apikey');
// CustomerID search
$params = array('complex_filter'=>
array(
array('key'=>'email','value'=>array('key' =>'eq','value' => $email)),
),
);
$result = $client->customerCustomerList($session, $params);
var_dump ($result);
$customerID = $result[0]->customer_id;
// echo $customerID;
// Update Customer
$result2 = $client->customerCustomerUpdate($session, $customerID, array('password' => 'newpassword'));
var_dump ($result2);

It's very strange.
The doc (and the wsdl) wants you to pass the password parameter.
I've tried to investigate in the code (Magento 1.7 series).
Before setting the values you have passed through the API call, in the corresponding update() function of the app/code/core/Mage/Customer/Model/Customer/Api.php file, there is this code:
foreach ($this->getAllowedAttributes($customer) as $attributeCode=>$attribute) {
if (isset($customerData[$attributeCode])) {
$customer->setData($attributeCode, $customerData[$attributeCode]);
}
}
So, I've tried to print the allowed attributes, and password is not present. What is present is password_hash, but this field is not present in the doc, and, more important, is not present in the wsdl.
Just to make a test, I've tried to pass the md5 value of the password I wanted to pass as the password argument, then, in the _prepareData function that is called in the update function, I've added this line of code:
$data['password_hash'] = $data['password'];
The result is that the password is successfully changed, and I can login with the new password.
Now, of course this is not the way to proceed.
First of all, I'm changing a core file.
Then, probably, it's possible to update the list of the allowed attributes adding the password attribute, but you have to remember to build the md5 version of the password, not the "clear text" one, and in any case rename it to password_hash somewhere.
Another solution is to customize (not in core/, again) the wsdl parameters related to the complex type customerCustomerEntityToCreate, adding password_hash.

Related

Aauth - update_user() - Not sure how to use

Perhaps I'm just unsure on the documentation. I've tried to figure it out, but I've never used this Codeigniter library before (Aauth). I'm attempting to create a form / page that will allow a user to change their password. The form works fine, but it's not changing the users password in the database.
The documentation says this:
Please note that I am not sure what "FALSE" represents. I do not see a change password method in the documentation provided here.
update_user($user_id, $email = FALSE, $pass = FALSE, $name = FALSE)
Updates user by using user_id
I'm not seeing any errors.
I'm writing something like this:
// get user info for currently logged user (this part works)
$userdata = $this->aauth->get_user();
// Change Password (not currently changing the password for the user)
$this->aauth->update_user($userdata->id, $userdata->email, $_POST['formpassword']);
Whoops, didn't realize when it said "FALSE" it meant it was required.
The correct solution:
// I did not want to change email or name. Password only.
$this->aauth->update_user($userdata->id, FALSE, $_POST['formpassword'], FALSE);

User logs into frontend - plugin to automatically be logged into backend

I need to create a system plugin (no auth plugin!) where a user which logges into the frontend automaticaly gets logged in the backend too.
(The user has the rights to log into the backend via /administrator.)
I try to do it via the very basic code you see below, the result is positive, but if i go to the backend the user still needs to log in.
In the session table the backend session row is set, but the "guest" field is set to 1 instead of 0 and the userid is set to 0 instead of the correct id.
How can this be done?
function onAfterInitialise() {
if(JFactory::getUser()->get('id')) { // logged in?
$credentials = array();
$credentials['username'] = "walter"; // hardcoded first
$credentials['password'] = "123"; // hardcoded first
$options = array();
$options['action'] = 'core.login.admin';
$result = $app->login($credentials, $options); // this seams to work
if (!($result instanceof Exception)) {
$app->redirect("www.bummer.de");
}
}
Apart from this being a very bad idea, as mentioned in this question Joomla! is implemented as two applications a front-end (/index.php) and back-end application (/administrator/index.php).
In the code provided you don't show where $app is initialised so I'm guessing that it's probably something like $app->JFactory::getApplication('site');.
To login to the admin app you need to get it rather than the front-end client app e.g.
$adminApp->JFactory::getApplication('administrator');
$result = $adminApp->login($credentials, $options);
n.b. this is untested code just typed in to stack overflow... it should be right.

kohana2 auth - login problem

I'm trying to make a login form for my kohana2 app using ORM example presented in kohana2 docs ( http://docs.kohanaphp.com/addons/auth ). I've done everything like in the wiki but after providing username, password and sending a form, nothing happens. No error, no exception, nothing! just the same form without any errors.
Here is the controller action, the only thing i've changed was adding a template functionality: http://pastebin.com/jEc4nqSP
There is a die() function in line 42, it's there for debug purposes. After sending a form, it displays Array ( [username] => invalid ) 1. I'm sure i have that user data in database and i'm providing a proper username and password. Roles are set to login. Have you any idea what am i doing wrong ?
Thanks.
On line 39 you are creating an empty ORM user object. At a minimum, surely you want:
ORM::factory('user', $post['username'])
Although you probably want to refactor that, so it actually checks that the username value is set.
Ok problem solved! All we need to do is to create a new user with this code (registration controller from kohana2 docs):
<?php
// grab relevant $_POST data
$username = $this->input->post('username');
$password = $this->input->post('password');
// instantiate User_Model and set attributes to the $_POST data
$user = ORM::factory('user');
$user->username = $username;
$user->password = Auth::instance()->hash_password($password);
// if the user was successfully created...
if ($user->add(ORM::factory('role', 'login')) AND $user->save()) {
// login using the collected data
Auth::instance()->login($username, $password);
// redirect to somewhere
url::redirect('user/profile');
}
The previous admin login data was not working cause the password was not hashed properly.

PHP -> SOAP -> Magento Webservice: get Cookies set by Magento

I am new to Magento Web-Service and have to expand it.
The Webservice shell be able to login an customer, give me the session cookie back so that I can redirect to a file that sets the cookie again, redirects me and I can see my cart and proceed to checkout on the Magento Store.
The Problem:
Magento creates a cookie (that contains the session id or whatever, ive tried to set this cookie manual and them im logged in) instead of setting a session when the customer logs in.
I've tried now for several hours to get this cookie that is set by magento in my magento web-service. It seems the cookie isn't set when i call
$session = Mage::getSingleton('customer/session');
return $session->getCookie()->get('frontend');
Heres my complete Code:
Magento Webservice Api:
<?php
class Customapi_Model_Core_Api
{
public function __construct()
{
}
public function checkout($user, $cart)
{
$ret['cookie'] = $this->login($user);
//$coreCookie = Mage::getSingleton('core/cookie');
//$ret['cookie'] = $_COOKIE['frontend'];
return $ret;
}
function login($user)
{
Mage::getSingleton('core/session', array('name'=>'frontend'));
$session = Mage::getSingleton('customer/session');
try
{
$session->loginById($user['id']);
}
catch (Exception $e)
{
}
return $session->getCookie()->get('frontend');
}
}
?>
Heres my Api Call in Php:
<?php
$teambook_path = 'http://localhost/magento/';
$soap = new SoapClient('http://localhost/magento/api/?wsdl');
$soap->startSession();
$sessionId = $soap->login('ApiUser', 'ApiKey');
$userSession = $soap->call(
$sessionId,
'customapi.checkout',
array(
array(
'id' => 1,
'username' => 'Ruf_Michael#gmx.de',
'password' => '***'
),
array(
)
)
);
echo '<pre>';
var_dump($userSession)."\n";
if(isset($userSession['sid']))
echo ''.$userSession['sid'].''."\n";
echo '</pre>';
$soap->endSession($sessionId);
?>
Thanks for every help!
MRu
Sorry i am writing an answer but the comment box denied me to write more than ... letters.
I've tried both codes you posted and all I get is an empty Array or Bool false.
I wrote a static function:
private static $cookie = array();
public static function cookie($key, $value)
{
if($key == 'frontend') {
self::$cookie['key'] = $key;
self::$cookie['value'] = $value;
}
}
that is called in Mage_Core_Model_Session_Abstract_Varien::start and I got the frontend cookie value:
Customapi_Model_Core_Api::cookie($sessionName, $this->getSessionId());
in line 125.
But that didnt solve my basic Problem:
The Session created in the Api call can't be restored, although it is set to the correct value.
Thanks for your help!
You can get an array of all your cookies with the following command:
Mage::getModel('core/cookie')->get();
The frontend cookie can be retrieved like this:
Mage::getModel('core/cookie')->get('frontend');
From your commented code I can see that you already knew that.
As far as I know, when you log in a user, Magento doesn't just create a new session id, it uses the session id of the active connection (which is generated by PHP itself). You are logging in the user and associating him to the session that your API client just created with Magento. Thus, the code that you have commented seems to be correct for what you are trying to achieve.
Now you should just need to get the returned session id and use it in your new request as the 'frontend' cookie.
Edit (a second time)
Magento has different sessions inside a single PHP session which it uses for different scopes. For instance, there is the core scope, the customer scope, etc. However, the customer scope is also specific to a given website. So, you can have a customer_website_one and a customer_website_two scope.
If you want to log in your user, you have to tell Magento in which website that is. Take the following code as an example
// This code goes inside your Magento API class method
// These two lines get your website code for the website with id 1
// You can obviously simply hardcode the $code variable if you prefer
// It must obviously be the website code to which your users will be redirected in the end
$webSites = Mage::app()->getWebsites();
$code = $webSites[1]->getCode();
$session = Mage::getSingleton("customer/session"); // This initiates the PHP session
// The following line is the trick here. You simulate that you
// entered Magento through a website (instead of the API) so if you log in your user
// his info will be stored in the customer_your_website scope
$session->init('customer_' . $code);
$session->loginById(4); // Just logging in some example user
return session_id(); // this holds your session id
If I understand you correctly, you now want to let the user open a PHP script in your server that sets the Magento Cookie to what you just returned in your API method. I wrote the following example which you would access like this: example.com/set_cookie.php?session=THE_RETURNED_SESSION_ID
<?php
// Make sure you match the cookie path magento is setting
setcookie('frontend', $_GET['session'], 0, '/your/magento/cookie/path');
header('Location: http://example.com');
?>
That should do it. Your user is now logged in (at least I got it to work in my test environment). One thing you should keep in mind is that Magento has a Session Validation Mechanism which will fail if enabled. That's because your session stores info about which browser you are using, the IP from which you are connecting, etc. These data will not match between calls through the API methods and the browser later. Here is an example output of the command print_r($session->getData()) after setting the session in the API method
[_session_validator_data] => Array
(
[remote_addr] => 172.20.1.1
[http_via] =>
[http_x_forwarded_for] =>
[http_user_agent] => PHP-SOAP/5.3.5
)
Make sure you turn of the validation in the Magento Admin in Settings > Configuration > General > Web > Session Validation Settings

Why is the CakePHP password field is empty when trying to access it using $this->data?

I am implementing an authentication component,
This is my registration page
create('User',array('action' => 'login'));
echo $form->input('primary_email',array('size'=> 32));
echo $form->input('password',array('label' => 'Password'));
echo $form->input('remember_me',array('label' => 'Remember Me','type'=>'checkbox','checked' => 'false'));
echo $html->link('Forgot Password','/users/forgot/');
echo $form->end('Login');
// Javascripts
echo $javascript->link('jquery',false);
//echo $javascript->link('jquery.validate.js',false);
//echo $javascript->codeBlock($code, array('inline' => false));
?>
When I print the contents of $this->data the password field turns up empty.
How can I resolve this?
When I rename password to password2 or something else it works !!! Strange
this is because the Auth component removes the password from the data array (for security purposes). why would you want it to contain the password anyway? the remember me logic (which I assume you are using from the form fields) will handle logging someone in without the password.
I had the same issue and mrlanrat's suggestion worked for me.
Instead of trying to access $this->data['password'], you will need to access $this->Auth->data['password']
What basically happens is that the Auth component hashes the password and moves the hashed version into $this->Auth->data. The non-hashed version is deleted for security purposes.
So whenever you need to deal with data related to Auth component, make sure you're using $this->Auth->data and not $this->data.
I would like to see your login() function as well but indeed this problem seems weird. You can work around this by renaming your password field and then inside your login function do something like:
$this->data['password']=$this->Auth->password($this->data['User']['pwd']);
//now you can call $this->Auth->login and it will work
One thing you may be able to do is have the user confirm their password, and use it for the login function. I may be completely mis-reading what you're trying to accomplish, but if you have the user Confirm their password w/ a password 2 field, you can compare the two, and also use the starting state of the confirmation password for whatever it is that you're wanting to do.
So:
echo $form->input('password', array('label' => 'password'));
echo $form->input('password2', array('label' => 'Confirm Password'));
Inside of your logic for whatever you're wanting to accomplish, you can just put:
$morePermanentDataStorage = $this->data['User']['password2'];
if($this->data['User']['password'] == $this->Auth->password($this->data['User']['password2']) {
//function logic here
}
I am also assuming that your form logic from above actually starts with:
echo $form->create('User');
I had the same problem, Using $this->Auth->data['User']['user'] and $this->Auth->data['User']['password'] fixed it.
It looks like the auth controller removed the password from the data when it does its automagic.
I had the same problem and it was related to using the email field for login thru this method
$this->Auth->fields = array('username' => 'email', 'password' => 'password');
I couldn't resolve it, so I opted to include a username field on my database and now it works perfectly.
I had the same problem with some ExtJS authentication I was working on some weeks back.
A weird workaround is to go to /config/core.php and change the debug level temporarily e.g. change from Configure::write('debug', 0); to Configure::write('debug', 1); and then run your code - not necessarily the part with the Auth component - (and afterwards change the debug level back if you wish). $this->data['User']['password'] will now be populated with the hash value as intended.
What causes this in the first place still beats me :)
First of all, you need to comment the code Configure::write('Cache.disable', true); in the file core.php

Categories