Well, thats a trouble. The code is simple:
public function action_index()
{
$post = $this->request->post();
if ($post) {
// if I type it like this, manually - it will work
$success = Auth::instance()->login('admin','password');
}
if (isset($success) and $success) { echo "Пользователь залогинен"; }
}
Unfortunately it log in only a first record in the database, which is admin as by default config was in the table, If I create a new user. Like this:
$auth = Auth::instance();
$user = new Model_User();
$user->username = "Victor";
$user->$auth->hash_password('psw123');
$user->email = "me#email.com";
$user->save();
And than use it like I said, only with a real data as
$post["email"] or $post["username"] with $post["password"]
code:
if ($post) {
// the values from posts: 'Victor' or 'me#email.com` & 'psw123'
$success = Auth::instance()->login('me#email.com','psw123');
}
it will not log in me.
upd I can't login as admin, but all working perfectly if I'll change the role to login (it's 1 in the database). But if the role will be set to 2 (it's an admin role) it will not accept me, even do not make an instance of Auth.
$post = $this->request->post();
$success = Auth::instance()->login($post['email'], $post['pass']);
if ($success)
{
echo "SUCCESS!";
}
Once again, if the role will be 2 (it means admin) this is not will Success me instead of login role.
What can be a reason of this trouble?
I'm assuming you're using a default ORM auth driver. You don't need to hash your password when saving a new user - it is done automatically by a filter in the model. So saving a new user should look something like that:
$user = ORM::factory("user");
$user->username = "Victor";
$user->password = "psw123";
$user->email = "me#email.com";
$user->save();
Related
I do import of users from a csv file to the database. In csv file I have some kinda username and password string. So how do I create a new user manually?
As I understand I need to getPasswordHash and generateAuthKey (last one generates random string). But probably I loose something important since when I try to log in I get an error that Username or Password is incorrect. Did anyone ever experienced such situation? Thanks in advance.
This should be the minimum required in your case. $username and $password are raw values taken from the CSV. Remember that there will be validation applied.
$user = new User();
$user->username = $username;
$user->setPassword($password);
$user->generateAuthKey();
return $user->save();
I think you forgot to set an active status of new User. You should check it in Login method of User model in your app, or in actionLogin of SiteController. For example, in my app the login method is:
public function login()
{
if ($this->validate() and $this->getUser()->status !== User::INACTIVE_STATUS) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
}
return false;
}
If you show your code we can help you faster)
So if you are importing a list of users from a csv file, you will probably process this in a loop, try:
foreach ($csv_data as $user_data) {
$user = new User();
$user->setPassword($password);
$user->username = $user_data->username // or anything else, depending on your code
$user->status = 1 // or = User::STATUS_ACTIVE, depending on your code
$user->save();
}
I am trying to log a user in using CakePHP 3 right after registration, but I have not been successful. This is what I am doing:
function register(){
// ....
if($result = $this->Users->save($user)){
// Retrieves corresponding user that was just saved
$authUser = $this->Users->get($result->id);
// Log user in using Auth
$this->Auth->setUser($authUser);
// Redirect user
$this->redirect('/users/account');
}
}
I guess posting this question opened my eyes to a fix. This is what I did to get it to work... if there is better way, I would be glad to change it...
function register(){
// .... Default CakePHP generated code
if($result = $this->Users->save($user)){
// Retrieve user from DB
$authUser = $this->Users->get($result->id)->toArray();
// Log user in using Auth
$this->Auth->setUser($authUser);
// Redirect user
$this->redirect(['action' => 'account']);
}
}
CakePHP 3.8 × cakephp/authentication update.
Any place you were calling AuthComponent::setUser(), you should now use setIdentity():
// Assume you need to read a user by access token
$user = $this->Users->find('byToken', ['token' => $token])->first();
// Persist the user into configured authenticators.
$this->Authentication->setIdentity($user);
Source: /authentication/1/en/migration-from-the-authcomponent.html#checking-identities
I am trying to insert records in the database using Eloquent. I have the following code wherein I am creating a new user and then inserting a new row in the profile table so that the user update his/her profile as and when he/she logs in.
$user = new User();
$user->fill(Input::all());
$user->save();
$profile = new Profile();
$user->profile()->save($profile);
return Response::json(array('message' => 'Your account has been created.'));
The biggest disadvantage of my code here is - it leaves my tables in a half fried state. For example if the user's record were created but for some reason , there was an issue while creating the profile record, a user can exist where a profile has not been created for him/her.
Is there a way this can be circumvented ? I know I can check for the existence of the profile when I am about to access the user's profile (and create it if it has not been created - with the default values) but I would like to know if there are any other methods apart from this.
I believe using transaction is the way forward, if yes - can you please provide me an example ?
thanks
You can use transaction here:
$user = new User();
$user->fill(Input::all());
try {
DB::beginTransaction();
$user->save();
$profile = new Profile();
$user->profile()->save($profile);
DB::commit();
return Response::json(array('message' => 'Your account has been created.'));
}
catch (QueryException $e) {
DB::rollBack();
return Redirect::to('url')->withInput()
->with('error', 'Error occurred. Try again or contact administrator');
}
You can use this
$user = new User();
$user->fill(Input::all());
$profile = new Profile();
return DB::transaction(function() use ($user, $profile) {
$user->save();
$user->profile()->save($profile);
return Response::json(array('message' => 'Your account has been created.'));
});
I would like to test a login function that one of the developers produced. What I would like to do is have test-users be created in my setUp and then I would like to use these users to test the login function. I would like to see that it returns the correct boolean when username and password are equal to the ones stored in our database. My problem is that when I am inserting my users at the moment I am giving the passwords in plain-text hence they are being stored in the database in plain-text, however there is an issue here. The login function hashes the password as you are trying to log in as the passwords in the database are hashed when registration is done. So basically the plain-text password I just inserted will never be matched since the login function hashes the password in an attempt to find a match. So what I would need to do is hash the test-user's password as I insert it. How would I go about doing this? This is what my code looks like at the moment:
<?php
include 'functions.php';
class Test extends PHPUnit_Framework_TestCase {
protected function setUp(){
global $mysqli;
$mysqli = new mysqli('localhost', 'xxx', 'xxxxx', 'xxxxx');
$mysqli->query("INSERT INTO members (id, username, pnumber, password) VALUES ('200', 'testbrute', '920314', 'xxxxx')");
}
public function testLogin(){
global $mysqli;
$correctPass = Login('920314','xxxxxx', $mysqli);
$this->assertTrue($correctPass);
$wrongPass = Login('920314','xxxxxxxxx', $mysqli);
$this->assertFalse($wrongPass);
$NoUserExists = Login("980611-5298","--..--..--", $mysqli);
$this->assertFalse($NoUserExists);
}
protected function tearDown(){
$mysqli = new mysqli('localhost', 'xxx', 'xxxxx', 'xxxxx');
$mysqli->query("DELETE FROM members WHERE id IN (200)");
}
}
?>
This is what the login function looks like:
function login($pnumber, $password, $mysqli) {
// Using prepared Statements means that SQL injection is not possible.
if ($stmt = $mysqli->prepare("SELECT id, username, password, salt FROM members WHERE pnumber = ? LIMIT 1")) {
$stmt->bind_param('s', $pnumber); // Bind "$pnumber" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
$stmt->bind_result($user_id, $username, $db_password, $salt); // get variables from result.
$stmt->fetch();
$password = hash('sha512', $password.$salt); // hash the password with the unique salt.
if($stmt->num_rows == 1) { // If the user exists
// We check if the account is locked from too many login attempts
if(checkbrute($user_id, $mysqli) == true) {
// Account is locked
// Send an email to user saying their account is locked
return "account locked";
} else {
if($db_password == $password) { // Check if the password in the database matches the password the user submitted.
// Password is correct!
$ip_address = $_SERVER['REMOTE_ADDR']; // Get the IP address of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT']; // Get the user-agent string of the user.
$user_id = preg_replace("/[^0-9]+/", "", $user_id); // XSS protection as we might print this value
$_SESSION['user_id'] = $user_id;
$username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username); // XSS protection as we might print this value
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512', $password.$ip_address.$user_browser);
// Login successful.
return "login successful";
} else {
// Password is not correct
// We record this attempt in the database
$now = time();
$mysqli->query("INSERT INTO login_attempts (user_id, time) VALUES ('$user_id', '$now')");
return 'pass incorrect';
}
}
} else {
// No user exists.
return 'no exist';
}
}
}
I am new to phpunit and testing in general so please be overly-descriptive.
Forget trying to test against the actual database. As a general rule, you don't want to have your tests dependent on external services if you can help it.
You can inject a mock mysqli object and specify it's behavior. Then you don't have to worry about any values being added to the database or are dependent on having the database even exist.
So in your test rather than declaring a global $mysqli do:
$mockMysqli = $this->getMockBuilder('mysqli')
->disableOriginalConstructor()
->setMethods(array('prepare'))
->getMock();
$mockMysqli->expects($this->once())
->method('prepare')
->will($this->returnValue($mockStmt) //Have to also create a mock mysqli_stmt object
Based on how your function is, you will end up with a few mock objects returning other mock objects which is a code smell that you function is doing too much. Because of this, you would be better off breaking it up into smaller pieces that can then be mocked and tested separately. I find that generally speaking if the function is hard to test, that it is not a good design and should be refactored. Most good designs end up being easy to test with one or two mock objects.
everybody! I'm doing an application with several databases where each one belongs to one specific department.
So, I have on my Bootstrap.php the method _initDoctrine() that initialize the connection with DB (meanwhile, i have only one).
public function _initDoctrine() {
$this->getApplication()->getAutoloader()
->pushAutoloader(array('Doctrine', 'autoload'));
spl_autoload_register(array('Doctrine', 'modelsAutoload'));
$manager = Doctrine_Manager::getInstance();
$manager->setAttribute(Doctrine::ATTR_AUTO_ACCESSOR_OVERRIDE, true);
$manager->setAttribute(
Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE
);
$manager->setAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true);
$doctrineConfig = $this->getOption('doctrine');
Doctrine::loadModels($doctrineConfig['models_path']);
$conn = Doctrine_Manager::connection($doctrineConfig['dsn'], 'doctrine');
$conn->setAttribute(Doctrine::ATTR_USE_NATIVE_ENUM, true);
return $conn;
}
In my login page, there's 3 options (databases) which the user will choose to connect.
So, there's anyway to init doctrine config after login??
PS: sorry my english