yii generatepasswordhash not working - passwords

For some strange reasons, i am finding it difficult to login with yii->$app->generatePasswordhash($password.) I have a backedn where i register users and also change password. Users can login successfully when i created them but when i edit user password, the system keeps telling me invalid username or password. Below is my code.
//Model
Class Adminuser extends ActiveRecord
{
public $resetpassword
public function activateuser($id,$newpassword)
{
//echo Yii::$app->security->generatePasswordHash($newpassword); exit;
$user = Adminuser::find()->where(['id' =>$id])->one();
$user->status = self::SET_STATUS;
$user->password_reset_token = null;
$user->password = Admin::genPassword($this->resetpassword); // this returns yii::$app->security->generatePasswordHash($password)
return $user->save();
}
}
//controller action
public function actionActivate($id)
{
$model = new Adminuser();
$model->scenario = 'adminactivate';
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if($model->activateuser($id,$model->password))
{
//send a mail
Yii::$app->session->setFlash('success', 'New user has been activated.');
return $this->redirect(['index']);
}
else
$errors = $model->errors;
}
return $this->render('activate', [
'model' => $model,
]);
}
Please i need help

Your activateuser() method has $newpassword as an incoming parameter. Anyway you are using $this->resetpassword in Admin::genPassword(). Looks like that is the reason of the problem and all your passwords are generated based on null value. So try to use $user->password = Admin::genPassword($newpassword); instead.

Related

How to login using sql password() function in laravel?

I want to login using the sql password() function in laravel. This is because the master database of employee table contains password in the format insert into tbl_name(' ') values (' ', password('abc'));
So I need to use this master table for login so can anyone suggest me as to how can this be possible?
public function login(Request $request) {
// dd($request->all());
if(Auth::attempt([
'tgi' => $request->tgi,
'password' => $request->password
]))
{
// $user = \DB::where('tgi', $request->tgi)->first();
$user = MasterLogin::where('tgi', $request->tgi)->first();
if($user->is_admin() == '1') {
return redirect()->route('dashboard');
}
elseif($user->is_admin() == '0'){
return redirect()->route('home');
}
elseif($user->is_admin() == '3'){
return redirect()->route('manager');
}
}
return redirect()->back();
}
public function validateCredentials(UserContract $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
In validateCredentials i would like to know how can I pass the password here.
As of now I tried this as said:
public function login(Request $request) {
// dd($request->all());
if(Auth::attempt([
'tgi' => $request->tgi,
'password' => sha1($request->password)
]))
{
$user = User::select("SELECT * FROM emp_username_db WHERE tgi = $request->tgi AND password = sha1('$request->password')");
if (Hash::check(sha1($request->password), $user['password'])) {
// The passwords match...
return redirect()->route('dashboard');
}
}
return redirect()->back();
}
My code that I am working on
class LoginController extends Controller
{
public function login(Request $request) {
//$user = User::where('tgi', $request->tgi)->first();
$result = User::where('tgi',$request->tgi)->where('password',\DB::raw('password("$request->password")'))->exists();
if ($result) {
if($result->is_admin() == '1'){
// Authentication passed...
return redirect()->intended('dashboard');
}elseif($result->admin == '0'){
return redirect()->route('home');
}
elseif($result->admin == '3'){
return redirect()->route('manager');
}
return redirect()->back();
}
}
As SQL default password is hashed using SHA1 so we can compare user's password by using laravel raw query like this.
$result = User::where('tgi',$request->tgi)->where('password',\DB::raw('password("$request->password")'))->exists();
if($result){
your code....
}
It's redirecting to dashboard but getting 302 found.

Laravel not inserting into table

Basically I need to have a e-mail verification system. For clarity, I will post only needed chunks of code that have impact whatsoever. When user registers, a random 40 string token is generated and sent to them, that code is appended to the route like this:
Route::get('/user/verify/{token}', 'RegisterController#verifyUser');
So when user clicks on that link supposedly route should call this:
RegisterController:
public function verifyUser($token){
$verifyUser = new VerifyUser();
$verifyUser->token = $token;
$verifyUser->getByToken();
$user = new User();
$user->id = $verifyUser->user_id;
$user->get();
if(isset($verifyUser)){
if(!$user->verified){
$user->updateVerifiedStatus();
$status = "Uspešno ste verifikovali e-mail adresu. Sada se možete ulogovati";
} else{
$status = "Već ste se verifikovali.";
}
} else{
return redirect('/')->with('error', "Vaš e-mail ne postoji");
}
return redirect('/')->with('status', $status);
}
verify_user is table which has an id of the user, and the token field, and if user is not registered, there will be no instance of that user in the table, therefore -> if(isset($verifyUser)),
also, user table has an 'verified' field, which is a boolean and stores true and false values, therefore -> if(!$user->verified).
And here are models which are used in the above mentioned controller
VerifyUser:
class VerifyUser
{
public $user_id;
public $token;
public $created_at;
public $updated_at;
public function getByToken()
{
$result =
DB::table('verify_users')
->select('*')
->where('token', $this->token)
->first();
return $result;
}
public function create()
{
$result =
DB::table('verify_users')
->insert([
'user_id' => $this->user_id,
'token' => $this->token,
]);
return $result;
}
}
User
class User
{
public function get()
{
$result =
DB::table('users')
->select('*')
->where('id', $this->id)
->first();
return $result;
}
public function updateVerifiedStatus()
{
$data = [
'verified' => true,
];
$result =
DB::table('users')
->where('id', $this->id)
->update($data);
return $result;
}
}
So, when I click the link, everything passess, I get the success status, which tells me that $user->updateVerifiedStatus() funct is returned succesfully. But, when I check the table, the field is still false, and is not updated. Any ideas?

Symfony 4: Fetching user from DB ind custom user provider returns "Bad Credentials"

I am building an API based on Symfony 4.
In my custom user provider I dump the users email and the user data from database.
The email is shown but the second dump does not appear.
While fetching the user data it returns "Bad Credentials".
Here is my user provider:
<?php
// src/Security/User/WebserviceUserProvider.php
namespace App\Security\User;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
class WebserviceUserProvider implements UserProviderInterface
{
private $doctrine;
public function __construct (\Doctrine\Bundle\DoctrineBundle\Registry $doctrine)
{
$this->doctrine = $doctrine;
}
public function loadUserByUsername($email)
{
var_dump($email);
$userData = $this->doctrine->getManager()
->createQueryBuilder('SELECT u FROM users u WHERE u.email = :email')
->setParameter('email', $email)
->getQuery()
->getOneOrNullResult();
var_dump($userData);exit;
// pretend it returns an array on success, false if there is no user
if ($userData) {
$username = $userData['email'];
$password = $userData['password'];
$salt = $userData['salt'];
$roles = $userData['roles'];
// ...
return new WebserviceUser($username, $password, $salt, $roles);
}
throw new UsernameNotFoundException(
sprintf('Username "%s" does not exist.', $username)
);
}
public function refreshUser(UserInterface $user)
{
if (!$user instanceof WebserviceUser) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', get_class($user))
);
}
return $this->loadUserByUsername($user->getUsername());
}
public function supportsClass($class)
{
return WebserviceUser::class === $class;
}
}
If I send my json login data it returns the following:
string(13) "test#test.com" {"code":401,"message":"Bad credentials"}
Does anyone know this problem?

Where do i override authentication method in yii?

I need to override both authentication (for when user's trying to logging in) and also the function is being used to check if the user is logged in in the header of the application (the function that check the sessions and cookie to check if the user is logged in) but i don't know where are these methods? and also i don't know how to find where are these methods!
** The reason of ovveride is to also check a Flag, if the flag is FLASE don't authenticate the user, or even if the user is also authenticated on page change (header reload) log-out the user if the flag changed to FLASE**
It would be appreciated if you also helping me to find adequate references that can help me in similar situations beside yii/wiki and google i tried them :)
Regards,
For custom authentication extend CUserIdentity class:
app/components/UserIdentity.php
<?php
class UserIdentity extends CUserIdentity
{
const ERROR_USER_NOT_APPOVED=200;
private $_id;
/**
* Authenticates a user.
*
* #return boolean whether authentication succeeds.
*/
public function authenticate()
{
$criteria = new CDbCriteria;
$criteria->condition = 'LOWER(email.email)=LOWER(:email)';
$criteria->params = array(':email' => $this->username);
$member = Member::model()
->with('email')
->together()
->find($criteria);
if ($member === null) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
} elseif (!hash::check($this->password, $member->pass_hash)) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
} elseif (! $member->is_approved) {
$this->errorCode = self::ERROR_USER_NOT_APPOVED;
} else {
$this->_id = $member->id;
$this->username = $member->full_name;
$this->setState('email', $member->email->email);
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
/**
* #return integer the ID of the user record
*/
public function getId()
{
return $this->_id;
}
}
then create custom form (app/models/MainLoginForm.php):
<?php
/**
* MainLoginForm class.
* MainLoginForm is the data structure for keeping
* user login form data.
*/
class MainLoginForm extends CFormModel
{
public $email;
public $password;
public $rememberMe;
/**
* Declares the validation rules.
* The rules state that email and password are required,
* and password needs to be authenticated.
*/
public function rules()
{
return array(
array('email', 'filter', 'filter' => 'trim'),
array('email', 'required',
'message' => Yii::t('auth', 'Email address is required.')),
array('email', 'email',
'message' => Yii::t('auth', 'Enter a valid Email address.')),
array('password', 'required',
'message' => Yii::t('auth', 'Password is required.')),
// password needs to be authenticated
array('password', 'authenticate'),
array('rememberMe', 'safe'),
);
}
/**
* Declares attribute labels.
*/
public function attributeLabels()
{
return array(
'email' => Yii::t('auth', 'Email Address'),
'password' => Yii::t('auth', 'Password'),
'rememberMe' => Yii::t('auth', 'Remember me.'),
);
}
/**
* Authenticates the password.
* This is the 'authenticate' validator as declared in rules().
*/
public function authenticate($attribute, $params)
{
// we only want to authenticate when no input errors
if (! $this->hasErrors()) {
$identity = new UserIdentity($this->email, $this->password);
$identity->authenticate();
switch ($identity->errorCode) {
case UserIdentity::ERROR_NONE:
$duration = ($this->rememberMe)
? 3600*24*14 // 14 days
: 0; // login till the user closes the browser
Yii::app()->user->login($identity, $duration);
break;
default:
// UserIdentity::ERROR_USERNAME_INVALID
// UserIdentity::ERROR_PASSWORD_INVALID
// UserIdentity::ERROR_MEMBER_NOT_APPOVED
$this->addError('', Yii::t('auth',
'Incorrect username/password combination.'));
break;
}
}
}
}
and finally update your login method (actionLogin):
$form = new MainLoginForm;
if (isset($_POST['MainLoginForm'])) {
$form->attributes = $_POST['MainLoginForm'];
$valid = $form->validate();
if ($valid) {
// redirect
}
}
For auto logout you can extend CController:
app/components/MainBaseController.php
<?php
class MainBaseController extends CController
{
public $settings = array();
public function init()
{
parent::init();
// set global settings
// $this->settings = ...
if (YOUR_FLAG_VALIDATION AND !Yii::app()->user->isGuest) {
Yii::app()->user->logout();
}
}
}
and then use custom base controll:
class YourController extends MainBaseController
{
....
}

How to set default action dynamically in Yii

i want to change default action of a controller depends on which user is logged in.
Ex. There are two users in my site : publisher and author and i want to set publisher action as default action when a publisher is logged in, and same for author.
what should i do? when can I check my roles and set their relevant actions?
Another way to do this would be setting the defaultAction property in your controller's init() method. Somewhat like this:
<?php
class MyAwesomeController extends Controller{ // or extends CController depending on your code
public function init(){
parent::init(); // no need for this call if you don't have anything in your parent init()
if(array_key_exists('RolePublisher', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='publisher'; // name of your action
else if (array_key_exists('RoleAuthor', Yii::app()->authManager->getRoles(Yii::app()->user->id)))
$this->defaultAction='author'; // name of your action
}
// ... rest of your code
}
?>
Check out CAuthManager's getRoles(), to see that the returned array will have format of 'role'=>CAuthItem object, which is why i'm checking with array_key_exists().
Incase you don't know, the action name will be only the name without the action part, for example if you have public function actionPublisher(){...} then action name should be: publisher.
Another, simpler, thing you can do is keep the default action the same, but that default action simply calls an additional action function depending on what kind of user is logged in. So for example you have the indexAction function conditionally calling this->userAction or this->publisherAction depending on the check for who is logged in.
I think you can save "first user page" in user table. And when a user is authenticated, you can load this page from database. Where you can do this? I think best place is UserIdentity class. After that, you could get this value in SiteController::actionLogin();
You can get or set "first page" value:
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
This is a complete class:
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = User::model()->findByAttributes(array('username' => $this->username));
if ($user === null) {
$this->errorCode = self::ERROR_USERNAME_INVALID;
} else if ($user->password !== $user->encrypt($this->password)) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
} else {
$this->_id = $user->id;
if (null === $user->first_page) {
$firstPage = 'site/index';
} else {
$firstPage = $user->first_page;
}
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId()
{
return $this->_id;
}
}
/**
* Displays the login page
*/
public function actionLogin()
{
$model = new LoginForm;
// if it is ajax validation request
if (isset($_POST['ajax']) && $_POST['ajax'] === 'login-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if (isset($_POST['LoginForm'])) {
$model->attributes = $_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if ($model->validate() && $model->login())
$this->redirect(Yii::app()->user->first_page);
}
// display the login form
$this->render('login', array('model' => $model));
}
Also, you can just write right code only in this file. In SiteController file.