kohana Auth with automodeler ORM - authentication

New to kohana here. I have a task from my internship to make login system with kohana framework 3.2 . I also did it to insert,update and delete stuff with auto modeler ORM. I have some trouble now with kohana auth. I already have the database structure Imported and inserted an user in the 'users' table and give him a role in the 'roles_user' table.
Also created an Auth.php file in APP/config/ :
return array(
'driver' => 'AutoModeler_ORM',
'hash_method' => 'sha256',
'hash_key' => 'Somebiglonghaskeyofmixedcharacters102345567709',
'lifetime' => 1209600,
'session_type' => Session::$default,
'session_key' => 'auth_user',
);
In my controller , I have a login function with the following code:
if ($_POST)
{
$post = $this->request->post();
$success = Auth::instance()->login($post['email'], $post['password']);
if ($success)
{
echo "Welcome!";
}
else
{
echo "Something goes wrong...";
}
}
I already have activated the modules in the bootstrap.
pastebin link to my role model : http://pastebin.com/bQYReETh
pastebin link to my user model : http://pastebin.com/ufzvKjmA
The problem is that I always come in the else.
Does somebody have an idea whats going on?
Do I miss something?

#Woodle,
Maybe adding a _constructor can help.
public function __construct($id = NULL)
{
if ($id !== NULL)
{
$this->load(db::select_array($this->fields())->where($this->_table_name.'.username', '=', $id));
}
elseif ($this->id) // We loaded this via mysql_result_object
{
parent::__construct($id);
}
}

Related

CakePHP 2 user database/password migration for Cakephp 4

My customer has program which is made with CakePHP 2 (not my project) and he wants to upgrade it to newest CakePHP.
I noticed that there was tutorial for Custom Password Hasher (legacy / sha1 + blowfish) but it has been deprecated since 4.0 and should use authentication plugin.
How i can make that kind of procedure without touching core code which check if password needs rehash and then create new hash on database?
On loadAuthenticator i cannot put different hasher for that.
Yes but old valid user gives on login "Authentication\Authenticator\Result Object ( [_status:protected] => FAILURE_IDENTITY_NOT_FOUND [_data:protected] => [_errors:protected] => Array ( [Password] => Array ( ) ) )"
and newly created user with new has Authentication\Authenticator\Result Object ( [_status:protected] => SUCCESS etc..
I have made that check with that tutorial but how it can be valid if that not "exists"? SQL-query returns 1 row with old users email.
public function login() {
$this->viewBuilder()->setLayout('login');
if($this->request->is(['post','put'])) {
$result = $this->Authentication->getResult();
// regardless of POST or GET, redirect if user is logged in
if ($result->isValid()) {
$authService = $this->Authentication->getAuthenticationService();
// Assuming you are using the `Password` identifier.
if ($authService->identifiers()->get('Password')->needsPasswordRehash()) {
// Rehash happens on save.
$user = $this->Users->get($this->Authentication->getIdentityData('id'));
$user->password = $this->request->getData('password');
$this->Users->save($user);
}
// Redirect to a logged in page
return $this->redirect([
'controller' => 'Pages',
'action' => 'display',
'home'
]);
}
}
}
It will never goes inside "result->isvalid()" with old user.

Can't insert into database with save()

I am having an issue inserting a record into the database. I am a beginner with the Yii framework, so I may have made some stupid mistakes.
This is from the SiteController
public function actionCreatePost(){
$model = new PostForm();
$post = new Post();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$post->body = $model->body;
$post->title = $model->title;
$post->save();
return $this->redirect('index');
}else {
return $this->render('createPost', ['model' => $model]);
}
}
This is from the Post class
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => new Expression('NOW()'),
],
[
'class' => BlameableBehavior::className(),
'createdByAttribute' => 'id_author',
]
];
}
The issue is that you have created a PostForm class for the form (which is correct) but you are then trying to load the response into the Post class - a completely different class. This won’t work without modification.
If you have a look at the response:
var_dump(Yii:$app->request->post());
You will see the form data is located within the PostForm key. Yii will therefore only load the data into the PostForm class.
The correct solution is therefore to create a savePost() function within the PostForm eg:
public function savePost(){
$model = new Post();
$model->propertyABC = $this->propertyABC
...etc...
$model->save();
So the action would appear as follows:
$model = new PostForm();
If($model->load(Yii::$app->request->post()) && $model->validate()){
$model->savePost();
The other option is to rename the key from PostForm to Post. Yii will then load the data but this is not the best approach as it is a bit obscure.
Hope that helps
I would guess the issue is with the validation.
I can see several issues I will point out. First, I cannot figure out why are you creating a new PostForm, loading the data in it and verifying it, just to dump some values in a new Post and save it. Are there some functions, you are running in the PostForm model, that are triggered by load or verify? If that is not the case, I would suggest dropping one of the models, and using only the other. Usually, that is the Form model. It serves as a link between the ActiveForm and the model handling everything. You can do everything in the createPost() function in the Form model, and then in the controller it will look like
if ($model->load(Yii::$app->request->post())) {
$model->save();
return $this->redirect('index');
}
Second of all, you can dump post->getErrors() before the save to see if there are any errors with the validation. What you can also do, is call $post->save(false) instead. If you pass false to it, it will not trigger $post->validate(), and some errors can be neglected. Please, let me know if there is anything unclear.

Find() does not return result with cache

I am trying to implement memcache into my application, but I am running into some strange issues. If I run find() when there is no cache, then I get no results found. However, if I run the same query (refresh the page), then I get the results I expect.
Here is my code:
<?php
//Set the models cache service
$di->set('modelsCache', function(){
// Cache data for one day by default
$frontCache = new \Phalcon\Cache\Frontend\Data(array(
"lifetime" => 86400
));
// Memcached connection settings
$cache = new \Phalcon\Cache\Backend\Memcache($frontCache, array(
"host" => "localhost",
"port" => "11211"
));
return $cache;
});
<?php
class VideosController extends IndexController {
public function viewAction() {
/**
* This will always return an array;
* param 0 will always be the int
*/
$params = $this->dispatcher->getParams();
$id = $params[0];
$cacheName = 'videoForView_'.$id;
try {
$video = Videos::findFirst(array(
'id='.$id,
'cache' => array(
'key' => $this->router->getControllerName().'_'.$this->router->getActionName().'_'.$id
)
));
$this->view->setVar('video', $video);
} catch(Exception $e) {
echo '<pre>';
var_dump($e);
exit;
}
}
}
I am under the assumption that the Phalcon Model class would return me a database query, if there is no hit in the memcache server. It seems that the find() does find something and caches it, but it does not return me anything. Am I not understanding how the caching works in Phalcon? Or am I just doing something wrong?
The issue has been resolved. I worked with Andres (one of the developers of Phalcon), helping him resolve the issues I was having. Turns out it was deeper in the code than I would've expected.
The good news is it's resolved, and pushed up to the 0.8.0 branch on phalcon's github! Don't forget to recompile!

zfcUser getState in another module

how could i getState from zfcUser
in view/index.phtml i get it from $this->zfcUserIdentity()->getState();
but now i need to get this value ( state for this user who is logged in ), in other module /controller (this is my costum module controller)
so i need to get State from:
zfcUser/Entity/User
to
myModule/Controller
i watch this https://github.com/ZF-Commons/ZfcUser/wiki/How-to-check-if-the-user-is-logged-in but this solutons is not helpful
and this helps too, for me:
$sm = $this->getServiceLocator();
$auth = $sm->get('zfcuserauthservice');
if ($auth->hasIdentity()) {
$user_edit = $auth->getIdentity()->getPrem();
}
The state is a property from the user itself. So if you get the user throught the identification service, you can grab the state from there.
public function myFooAction()
{
if ($this->zfcUserAuthentication()->hasIdentity()) {
$user = $this->zfcUserAuthentication()->getIdentity();
$state = $user->getState();
}
}
Mind that when the user is not logged in, the if condition is false. Also the state can be null or any arbitrary value, so do not expect that every user returns a valid state (in other words, check the returned value!)
follow this code, I had same problem then I have manage how to use identity of logged in user via zfcUser
in other modules controller at topside,
use Zend\EventManager\EventManagerInterface;
then create this two function in the sameclass,
public function setEventManager(EventManagerInterface $events)
{
parent::setEventManager($events);
$controller = $this;
$events->attach('dispatch', function ($e) use ($controller) {
if (is_callable(array($controller, 'checkUserIdentity')))
{
call_user_func(array($controller, 'checkUserIdentity'));
}
}, 100);
}
public function checkUserIdentity()
{
if ($this->zfcUserAuthentication()->hasIdentity()) {
echo "<pre>"; print_r($this->zfcUserAuthentication()->getIdentity());die;
}
}
it will give this kind of output
Admin\Entity\User Object
(
[id:protected] => 2
[username:protected] =>
[email:protected] => rajat.modi#softwebsolutions.com
[displayName:protected] =>
[password:protected] => $2y$14$2WxYLE0DV0mH7txIRm7GkeVJB3mhD4FmnHmxmrkOXtUFL7S9PqWy6
[state:protected] =>
)
That's it you will automatically get Identity whether user is logged in if not then it will redirect to login page.
Hope this will helps

Saving data with cakephp won't work

I'm trying to load, edit and save a record with CakePHP 2.0 but I get a generic error during the save method that don't help me to understand where is the problem.
if I try with debug($this->User->invalidFields()); I get an empty array, but I get false from $this->User->save() condition.
Here is the controller action where I get the error:
public function activate ($code = false) {
if (!empty ($code)) {
// if I printr $user I get the right user
$user = $this->User->find('first', array('activation_key' => $code));
if (!empty($user)) {
$this->User->set(array (
'activation_key' => null,
'active' => 1
));
if ($this->User->save()) {
$this->render('activation_successful');
} else {
// I get this error
$this->set('status', 'Save error message');
$this->set('user_data', $user);
$this->render('activation_fail');
}
debug($this->User->invalidFields());
} else {
$this->set('status', 'Account not found for this key');
$this->render('activation_fail');
}
} else {
$this->set('status', 'Empty key');
$this->render('activation_fail');
}
}
When I try the action test.com/users/activate/hashedkey I get the activation_fail template page with Save error message message.
If I printr the $user var I get the right user from cake's find method.
Where I'm wrong?
I think the problem may be in the way you're querying for the User record. When you do this:
$user = $this->User->find('first', array('activation_key' => $code));
The variable $user is populated with the User record as an array. You check to ensure it's not empty, then proceed; but the problem is that $this->User hasn't been populated. I think if you tried debug($this->User->id) it would be empty. The read() method works the way you're thinking.
You could try using the ID from that $user array to set the Model ID first, like so:
if (!empty($user)) {
$this->User->id = $user['User']['id']; // ensure the Model has the ID to use
$this->User->set(array (
'activation_key' => null,
'active' => 1
));
if ($this->User->save()) {
...
Edit: Well another possible approach is to use the $user array instead of modifying the current model. You said that you get back a valid user if you debug($user), so if that's true you can do something like this:
if (!empty($user)) {
$user['User']['activation_key'] = null;
$user['User']['active'] = 1;
if ($this->User->save($user)) {
...
This method works in the same way as receiving form data from $this->request->data, and is described on the Saving Your Data part of the book.
I'm curious though if there's another part of your setup that's getting in the way. Can other parts of your app write to the database properly? You should also check to make sure you aren't having validation errors, like their example:
<?php
if ($this->Recipe->save($this->request->data)) {
// handle the success.
}
debug($this->Recipe->validationErrors);