Laravel 4 create an user programatically with Zizaco/confide - php

I'm trying to create a user with the Zizaco/confide library, the user data comes from Facebook and not from a form.
I try this :
$user_profile = Facebook::api('/me','GET');
$new_user = new User;
$new_user->username = $user_profile['name'];
$new_user->password = Hash::make('secret');
$new_user->email = $user_profile['email'];
$new_user->confirmation_code = '456456';
$new_user->confirmed = true;
$new_user->save();
but it doesn't save the user. Any help ?

I found the problem, the confide library sets some default rules to create the user, you need to pass this rules to save a user:
public static $rules = array(
'username' => 'required|alpha_dash|unique:users',
'email' => 'required|email|unique:users',
'password' => 'required|between:4,11|confirmed',
'password_confirmation' => 'between:4,11',
);
with this example it works:
$user = new User();
$user->username = 'asdasd';
$user->email = 'angorusadf#gmail.com';
$user->password = '12312312';
$user->password_confirmation = '12312312';
$user->save();
Mabe the method should give you some information when you don't pass the rules.

Maybe it's a pretty late answer, but I'm posting this for future reference because I was myself looking for an answer to the same question, How to create a user programatically in zizaco/confide? or more generally, how to bypass zizaco/confide's requirement for setting a password when saving a user for the first time?
well, the answer is pretty simple, thanks to the new architecture which Zizaco implemented in the 4.* branch, it's now possible to register a new user validator class see more at the package's readme in short all you need in this very case though, is just to extend the current User validator and override validatePassword() to make it accept empty passwords for new users.
Below is an example implementation:
In routes.php
// we need to register our validator so that it gets used instead of the default one
// Register custom Validator for ConfideUsers
App::bind('confide.user_validator', 'MyUserValidator');
In app/models/MyUserValidator.php (that's basically a copy of the function in the class, simply just added a check whether this is a old user or not (if the user has an ID then this is an update operation) if this is a new user, the method always returns true!
/**
* Class MyUserValidator
* Custom Validation for Confide User
*/
class MyUserValidator extends \Zizaco\Confide\UserValidator //implements \Zizaco\Confide\UserValidatorInterface
{
/**
* Validates the password and password_confirmation of the given
* user
* #param ConfideUserInterface $user
* #return boolean True if password is valid
*/
public function validatePassword(\Zizaco\Confide\ConfideUserInterface $user)
{
$hash = App::make('hash');
if($user->getOriginal('password') != $user->password && $user->getOriginal('id')) {
if ($user->password == $user->password_confirmation) {
// Hashes password and unset password_confirmation field
$user->password = $hash->make($user->password);
unset($user->password_confirmation);
return true;
} else {
$this->attachErrorMsg(
$user,
'validation.confirmed::confide.alerts.wrong_confirmation',
'password_confirmation'
);
return false;
}
}
unset($user->password_confirmation);
return true;
}
}

Related

how to create custom registration in Laravel with two tables?

My registration form additionally accepts the name of the user's company, which I want to insert in a separate table "Holdings". All data is successfully saved to the Holdings and Users table, but an error occurs at the last step when redirecting to the home page.
ResgisterController:
protected function create(array $data)
{
//Mail::to($data['email'])->send(new Welcome($data['name']));
$id = User::insertGetId([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'role' => 8
]);
$oHolding = new Holdings;
$oHolding->shortname = $data['orgname'];
$oHolding->creator = $id;
$oHolding->save();
DB::table('users')->where('id', $id)->update([
'holding_id' => $oHolding->id,
]);
$user = DB::table('users')->select('*')->where('id', $id)->get();
return $user;
}
Error Message:
Argument 1 passed to Illuminate\Auth\SessionGuard::login() must implement interface Illuminate\Contracts\Auth\Authenticatable, instance of Illuminate\Support\Collection given, called in /Users/admin/Sites/jetime/vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers.php on line 35
Login Function
public function login(AuthenticatableContract $user, $remember = false)
{
$this->updateSession($user->getAuthIdentifier());
// If the user should be permanently "remembered" by the application we will
// queue a permanent cookie that contains the encrypted copy of the user
// identifier. We will then decrypt this later to retrieve the users.
if ($remember) {
$this->ensureRememberTokenIsSet($user);
$this->queueRecallerCookie($user);
}
// If we have an event dispatcher instance set we will fire an event so that
// any listeners will hook into the authentication events and run actions
// based on the login and logout events fired from the guard instances.
$this->fireLoginEvent($user, $remember);
$this->setUser($user);
}
I will be glad of any help, how to fix the error?
You are returning a collection rather than an instance of a class that implements Authenticatable.
You can see this happening here:
$user = DB::table('users')->select('*')->where('id', $id)->get();
return $user;
If you have the User model that ships with Laravel, then you'll actually want to do:
$user = User::find($id);
return $user;
Although your whole create method could be cleaned up to streamline all of this, however that isn't the topic of your question.

Insert data and Login in laravel

I am working on an assignment in laravel where I've an Application form. I want to submit application form with email, mobileNo, customerId etc.
What I want is to insert form data into users table and then user will be logged in with auto generated password and redirect to Customer's dashboard. Where will be a modal will be open and ask for add password.
On the other hand there is also a login page from where user can login as usual. The login functionality is working properly.
Can someone help me to achieve the above functionality. Thanks in advance.
**Data is : **
email='user#gmail.com'
mobile='9875425698'
customerId='CI10001';
ApplicationForm Controller Where I am getting data successfully
class ApplicationForm extends Controller
{
public function saveApplicationForm(Request $request){
return $request;
}
}
Add user by submiting form
$password = bcrypt('secret'); //add here random password
$user = new User();
$user->email = 'xyz#gmail.com';
$user->mobileNo = '123456789';
$user->customerId = '1245';
$user->password = $password;
$user->save();
after you insert raw on user table login by user id without password
Auth::loginUsingId($user->id);
Auth::loginUsingId($user->id,true); // Login and "remember" the given user...
by otherwise login with email and password
Auth::attempt(['email' => $user->email, 'password' => $password], $remember);
all action do in one method(action)
Following my comment:
In the RegisterController (App\Http\Controllers\Auth)
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'institution' => $data['institution'],
'password' => 'NOT_SET',
]);
}
Then create a middleware (e.g. php artisan make:middleware Must_have_password)
namespace App\Http\Middleware;
use Closure;
use Auth;
class Must_have_password
{
/**
* Verify if password is set, otherwise redirect to password-set page.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = Auth::user();
if ($user && $user->password !== 'NOT_SET') {
return $next($request);
}
else return redirect('/set-password');
}
}
Of course, you then need to create a password setting view and hook that to the /set-password route. As I said in the comment, you want to make sure that /set-password route is well protected because you don't want people hijacking accounts that way. The good thing about this approach (using NOT_SET) is that people can always use the password_reset infrastructure to reset their password if they don't do it initially.
This is a bit hacky, but because Laravel always encrypts the passwords, there is no way the value can become NOT_SET in another way. Alternatively, you could add a boolean to your user-model (something like Must_Reset) that redirects to the password-reset page.
You can also hook in the password-reset functionality of Laravel, look for 'One Time Password Laravel' (e.g. here).

Laravel 5 and Entrust. How to save user and attach role at the same time

Has anyone tried Entrust for User Roles & Permissions in Laravel 5?
I want to add and save user and attach role into it at the same time. here's my code
$role = Role::where('name','=','admin')->first();
$user = new User();
$user->name = Input::get('name');
$user->email = Input::get('email');
$user->password = Hash::make(Input::get('password'));
if($user->save()){
$user->attachRole($role);
return redirect('dashboard/users')->with('success-message','New user has been added');
}
But $user->attachRole($role); won't work though it works on my databaseSeeder but not on my UserController.
I think you have this problem because you never save in the DB.
Try something like this.
$role = Role::where('name','=','admin')->first();
$user = new User();
$user->name = Input::get('name');
$user->email = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->save()
$user->attachRole($role);
return redirect('dashboard/users')->with('success-message','New user has been added');
Of course this method will work only if you auto-increment your model's id using laravel's auto-increment feature. If you are using something like uuids to uniquely identify your fields, you should also include public $incrementing = false; inside your Model.
Make sure you include the HasRole trait inside your model.
Also take a look at Akarun's answer as it will also work.The create method, create's a new instance and also save to db so you don't need to $user->save()
I also use "Entrust" for managing my user permissions, but I use create syntax to store my User. Then I use "roles()->attach", like this :
$user = User::create($this->userInputs($request));
$user->roles()->attach($request->input('role'));
I am using the provided Auth setup that ships with Laravel 5 with my own adjustments, so I just do the following in Registrar.php:
public function create( array $data )
{
// Create a new user, and assign it to 'new_user'
$new_user = User::create( [
'username' => $data['username'], //<< Specific to my own db setup
'email' => $data['email'],
'password' => bcrypt( $data['password'] ),
] );
// Initiate the 'member' Role
$member = Role::where( 'name', '=', 'member' )->first();
// Give each new user the role of 'member'
$new_user->attachRole( $member );
// Return the new user with member role attached
return $new_user; //<<Or whatever you do next with your new user
}
You just have to be sure to use App\Role at the top of the file. Works great for me.

Check if user credentials match, without authenticating

Using the FOSUserbundle, I want to achieve the following:
1) User submits a POST with "username" and "password" parameters. Password is in plaintext.
2) In a controller, I parse the parameters as usual:
/**
* #Route("/api/token",name="api_token")
*/
public function tokenAction(Request $request) {
$username = $request->get('username');
$password = $request->get('password');
// ...
}
3) Finally, if the credentials match, I return something.
Note that I want to do this WITHOUT modifying the session, i.e. without actually authenticating the user and setting a token. I only want to check if the credentials match.
UPDATE
The accepted answer works, but only under the assumption that you have an active session. If you want to solve the case where you simply expose a REST layer or the like (which was my usecase), you can do the following, assuming your usernames are unique:
/**
* #Route("/api/token",name="api_token", options={"expose"=true})
*/
public function getTokenAction(Request $request) {
$username = $request->get('username');
$password = $request->get('password');
$user = $this->getDoctrine()
->getRepository('YourUserClass')
->findOneBy(["username" => $username]);
$encoder = $this->get('security.encoder_factory')->getEncoder($user);
$isValidPassword = $encoder->isPasswordValid($user->getPassword(),
$password,
$user->getSalt());
if ($isValidPassword) {
// Handle success
} else {
// Handle error
}
}
You should use an authentication service to do this, writing all code in controller is not a best practice. Anyway, to your answer, you can use this:
/**
* #Route("/api/token",name="api_token")
*/
public function tokenAction(Request $request) {
$username = $request->get('username');
$password = $request->get('password');
// fetch your user using user name
$user = ...
//If your controller is extended from Symfony\Bundle\FrameworkBundle\Controller\Controller
$encoder = $this->get('security.encoder_factory')->getEncoder($user);
//If you are extending from other ContainerAware Controller you may have to do
//$this->container->get('security.encoder_factory')->getEncoder($user)
//Check your user
$isValidPassword = $encoder->isPasswordValid(
$user->getPassword(),
$password,
$user->getSalt()
);
if ($isValidPassword) {
//.... do your valid stuff
}else{
//... Do your in valid stuff
}
}

Symfony 2 Get original data of entity from entity manager

I am using Sonata admin bundle for my application all works well,In my application i have users and admin,admin can add/edit/delete the users when i am trying to update a user there is a problem the password data is overrided from user table. i have overrided the preUpdate method of admin controller ,I got $object which has an instance of user entity manager so if user leaves to update password and saves data the password is lost.
public function preUpdate($object)
{
$Password = $object->getUserPassword();
if (!empty($Password)) { /* i check here if user has enter password then update it goes well*/
$salt = md5(time());
$encoderservice = $this->getConfigurationPool()->getContainer()->get('security.encoder_factory');
$User = new User();
$encoder = $encoderservice->getEncoder($User);
$encoded_pass = $encoder->encodePassword($Password, $salt);
$object->setUserSalt($salt)->setUserPassword($encoded_pass);
} else { /* here i try to set the old password if user not enters the new password but fails */
$object->setUserPassword($object->getUserPassword());
}
}
When i try to set $object->setUserPassword($object->getUserPassword()); it gets null and updates the password as null its not getting the edit data i have tried to get the repository (below) again to get the password but no luck its getting the same
$DM = $this->getConfigurationPool()->getContainer()->get('Doctrine')->getManager()->getRepository("...")->find(id here);
Is there a way i can access the original data of current entity in entity manager
You can access the original data by getting doctrine's Unit of Work.As from docs
You can get direct access to the Unit of Work by calling
EntityManager#getUnitOfWork(). This will return the UnitOfWork
instance the EntityManager is currently using.An array containing the
original data of entity
Grab the password from Unit of Work and use in your setter method
public function preUpdate($object)
{
$DM = $this->getConfigurationPool()->getContainer()->get('Doctrine')->getManager();
$uow = $DM->getUnitOfWork();
$OriginalEntityData = $uow->getOriginalEntityData( $object );
$Password = $object->getUserPassword();
if (!empty($Password)) { /* i check here if user has enter password then update it goes well*/
$salt = md5(time());
$encoderservice = $this->getConfigurationPool()->getContainer()->get('security.encoder_factory');
$User = new User();
$encoder = $encoderservice->getEncoder($User);
$encoded_pass = $encoder->encodePassword($Password, $salt);
$object->setUserSalt($salt)->setUserPassword($encoded_pass);
} else { /* here i try to set the old password if user not enters the new password but fails */
$object->setUserPassword($OriginalEntityData['Password']);/* your property name for password field */
}
}
Hope it works fine
Direct access to a Unit of Work
Reset entity in entity manage, example for onFlush event
/**
* #param OnFlushEventArgs $args
*
* #throws \Doctrine\ORM\ORMException
* #throws \Doctrine\ORM\OptimisticLockException
*/
public function onFlush(OnFlushEventArgs $args)
{
$em = $args->getEntityManager();
$uow = $em->getUnitOfWork();
foreach ($uow->getScheduledEntityUpdates() as $keyEntity => $entity) {
if ($entity instanceof Bill) {
$em->refresh($entity);
$this->createPdfs($entity);
}
}
}
$this->getConfigurationPool()
->getContainer()
->get('Doctrine')
->getRepository("...")
->find(id here);
So leave out the getManager() part;

Categories