Laravel 5 Seeding - php

I'm following the docs to seed the users table, which shows User::create being used
class UserTableSeeder extends Seeder {
public function run()
{
DB::table('users')->delete();
User::create([
'username' => 'test',
'firstname' => 'Test',
'lastname' => 'Test',
'email' => 'test#domain.com',
'password' => Hash::make('test'),
'role' => 'user'
]);
}
}
But it keeps saying:
PHP Fatal error: Class 'User' not found in /home/vagrant/projects/roopla/database/seeds/UserTableSeeder.php on line 17
I thought maybe I need to make:model using artisan for User, but it already exists. Can anyone point me in the right direction I'm only just starting out with Laravel and piecing it together through Laracast and the docs, but there's no Laracast on seeding for 5.0. It doesn't seem like you can generate seeds now as artisan doesn't recognize generate:seed

That's because in Laravel 5 User model is in App namespace whereas your seeder is in global namespace.
You should use:
\App\User::create([
'username' => 'test',
'firstname' => 'Test',
'lastname' => 'Test',
'email' => 'test#domain.com',
'password' => Hash::make('test'),
'role' => 'user'
]);
or at the beginning of seeder file:
use App\User;
and now you can use the code you showed

You need to either import your user model at the top of the seeder with use App\User; or just reference it via \App\User::create.... You need to reference the User model through it's namespace.

Related

Laravel: 2 Registration Forms with Login

I'm working in Laravel 8 and like to know what's the best approach for logging in with the 2 registration forms I have already set up. The forms are set up with just validation, but trying to figure out how to have a login for these different sign-up roles, which will go to 2 different dashboards.
This is where I'm at with my code...
web.php
// Profile
Route::get('/register/profile', [RegisterProfileController::class, 'index'])->name('register_profile');
Route::post('/register/profile', [RegisterProfileController::class, 'store']);
// Business
Route::get('/register/business', [RegisterBusinessController::class, 'index'])->name('register_business');
Route::post('/register/business', [RegisterBusinessController::class, 'store']);
RegisterProfileController.php (with just validation)
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class RegisterIndividualController extends Controller
{
public function index()
{
return view('auth.register_profile');
}
public function store(Request $request)
{
$this->validate($request, [
'firstname' => 'required|max:255',
'lastname' => 'required|max:255',
'username' => 'required|min:8|max:60|alpha_num',
'email' => 'required|email|max:255',
'phone' => 'required|digits:10',
'city' => 'required|max:100',
'state' => 'required',
'zip' => 'required|digits:5',
'password' => 'required|confirmed'
]
}
}
RegisterBusinessController.php (with just validation)
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class RegisterBusinessController extends Controller
{
public function index()
{
return view('auth.register_business');
}
public function store(Request $request)
{
$this->validate($request, [
'businessname' => 'required|max:255',
'firstname' => 'required|max:255',
'lastname' => 'required|max:255',
'username' => 'required|min:8|max:60||alpha_num',
'businessemail' => 'required|email|max:255',
'phone' => 'required|digits:10',
'address' => 'required|max:255',
'city' => 'required|max:100',
'state' => 'required',
'zip' => 'required|digits:5',
'website' => 'required|url',
'industry' => 'required',
'password' => 'required|confirmed'
]
}
}
I created the migration schema for each:
2021_10_26_011205_create_individuals_table.php
2021_10_26_011224_create_businesses_table.php
If you want to use Laravel's built-in authentication system, then you can set up your own authentication guards, which would let you log in using your existing models (here's a Stack Overflow answer with an example of setting up authentication with multiple models). Once you have this set up, you could then use the relevant guard in your login controller:
// Get the business model
$business = Business::where('businessemail', $request->input('businessemail'))->firstOrFail();
// Verify the password
if (Hash::check($request->input('password'), $business->password)) {
// Log in
Auth::guard('business')->login($business);
} else {
// Incorrect password
}
Additionally, since it looks like you're still in the early stages of development, I would recommend reconsidering your authentication model. Instead of having two completely different tables, and needing to set up two different authentication guards, I would recommend using the User model for both individuals and businesses, and adding an account_type column. You could then create a business_profiles table, which links to the users table via a user_id column, which would hold the business-only information (businessname, industry, and website).

Tests in Laravel not picking up collection attributes

I have a test in Laravel 7 constructed as follows:
<?php
namespace Tests\Feature\Http\Controllers\Auth;
use App\User;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;
class LoginControllerTest extends TestCase
{
use DatabaseMigrations;
/**
* A basic feature test example.
*
* #return void
*/
public function testLoginPractitioner()
{
$user = factory(User::class, 1)->make();
dump($user);
$response = $this->post('/api/login', [
'phone_number' => $user->phone_number,
'password' => $user->password
], [
'Accept' => 'application/json',
'Content_Type' => 'application/json'
]);
$this->assertDatabaseHas('users', [
'phone_number' => $user->phone_number,
]);
}
}
With the user factory defined as this:
$factory->define(User::class, function (Faker $faker) {
return [
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'phone_number' => '12' . $faker->numerify('#########'),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
'remember_token' => Str::random(10),
'is_admin' => false
];
});
When I dump the user object created in the test, I can see that it has a phone_number attribute:
#attributes: array:6 [
"email" => "leonora.tromp#example.com"
"email_verified_at" => "2021-01-31 11:25:02"
"phone_number" => "12326385883"
"password" => "$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi"
"remember_token" => "Oy8DfAonMu"
"is_admin" => false
]
But my test keeps failing and I get this message, as if it has not phone_number attribute:
1) Tests\Feature\Http\Controllers\Auth\LoginControllerTest::testLoginPractitioner
Exception: Property [phone_number] does not exist on this collection instance.
Additionally, the assert fails even if I use a number that I am sure is in the database. Why is this happening?
Your problem is $user is a Collection, when you give a factory an amount of models to create, it will return a Collection instance contained the models created in your case 1. Secondly for the model to be saved to the db you should call create() and not make().
Changing the user creation code to the following should solve the problem.
$user = factory(User::class)->create();
If you at a time need to create multiple users, you need to get them out of the Collection. As you seem confused about Collections, probably reading up on Collections would be wise.

No hashing on Password field in Laravel seeder

I've recently inherited a project from a Laravel developer to look at. Unfortunately, when I migrate and seed the user table, the password ciphering is not working, as follows:
public function run()
{
DB::table('users')->insert([
'email' => 'admin#site.co.uk',
'first_name' => 'Site',
'last_name' => 'Admin',
'username' => 'admin',
'password' => 'localhostPassword'
]);
}
When I run php artisan migrate --seed the password field is the string literal as above, and when I try to sign in it tells me that my password credentials are incorrect.
As I'm not an Artisan Laravel developer I'm not sure where to start, but I'm expecting the password field to be hashed like this $2y$10$u/FcKFPKsgRs8whJZ6ODAO90qllmGjqROnkmuQnxcpynG6WaIbX8e, which is what is generated when I use the register form in the current code base.
You need to hash it before storing it:
use Illuminate\Support\Facades\Hash; // <-- import it at the top
//
public function run()
{
DB::table('users')->insert([
'email' => 'admin#site.co.uk',
'first_name' => 'Site',
'last_name' => 'Admin',
'username' => 'admin',
'password' => Hash::make('localhostPassword') // <---- check this
]);
}
Note: An alternative is to use the bcrypt() helper instead of the Hash::make() method.
Chech the documentation regarding this aspect:
Basic Usage
You may hash a password by calling the make method on the Hash
facade:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Http\Controllers\Controller;
class UpdatePasswordController extends Controller
{
/**
* Update the password for the user.
*
* #param Request $request
* #return Response
*/
public function update(Request $request)
{
// Validate the new password length...
$request->user()->fill([
'password' => Hash::make($request->newPassword)
])->save();
}
}
You have to manually bcrypt the password like below
public function run()
{
DB::table('users')->insert([
'email' => 'admin#site.co.uk',
'first_name' => 'Site',
'last_name' => 'Admin',
'username' => 'admin',
'password' => bcrypt('localhostPassword')
]);
}

Laravel Passport - Invalid credentials using grant_type is passowrd

I am having difficulty setting up Passport in Laravel 5.6. The first time when I followed this tutorial, I had implemented perfectly but now again when I am following than getting following error.
{
"error": "invalid_credentials",
"message": "The user credentials were incorrect."
}
I have tried out all possible solutions but none of them works. So thought to post it here.
Info:
I am using iMac - High Sierra. storage directory has 777
permission. I have set using sudo chmod -R 777 storage command.
However, when I checked the laravel.log file didn't have permission so
I have grant 777 to it as well. still getting the error.
Laravel error log - laravel.log
local.ERROR: The user credentials were incorrect. {"exception":"[object] (League\\OAuth2\\Server\\Exception\\OAuthServerException(code: 6): The user credentials were incorrect. at /Users/username/Sites/mysite/vendor/league/oauth2-server/src/Exception/OAuthServerException.php:160)
My Implementation Steps
I run composer require laravel/passport
Added passport service provider in app.php Laravel\Passport\PassportServiceProvider::class,
Migrated the database php artisan migrate
Added Passport::routes()
Added use HasApiTokens to User model
In auth.php set gourds api driver to password
Passport client credentials php artisan passport:client --passoword
Passport keys php artisan passport:keys
Added route and register controller as below
Route
Route::post( 'register', 'Api\Auth\RegisterController#register' );
RegisterController Class
namespace App\Http\Controllers\Api\Auth;
use App\User;
use function bcrypt;
use function dd;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Route;
use Laravel\Passport\Client;
use function response;
class RegisterController extends Controller
{
private $client;
public function __construct() {
$this->client = Client::findOrFail(1);
}
public function register( Request $request ) {
$this->validate( $request, [
'name' => 'required',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:6|confirmed',
] );
$user = User::create( [
'name' => request( 'name' ),
'email' => request( 'email' ),
'password' => bcrypt( 'password' )
] );
$params = [
'grant_type' => 'password',
'client_id' => $this->client->id,
'client_secret' => $this->client->secret,
'username' => request( 'email' ),
'password' => request( 'password' ),
'scope' => '*'
];
$request->request->add( $params );
$proxy = Request::create( 'oauth/token', 'POST' );
return Route::dispatch( $proxy );
}
}
You are hashing the word 'password' not the actual password coming from request.
You should use it like this:
bcrypt(request('password'))
try to use hash::make function instead of bcrypt for your password when creating user like below
$user = User::create([
'name' => request('name'),
'email' => request('email'),
'password' => Hash::make(request('password'))
]);

Simple Laravel 5 Seeding: Closure object cannot have properties

I am trying to seed some files, yet I get:
[Error Exception] Closure object cannot have properties
Not sure what is wrong, since I do very basic seeding.
Here are my files:
all.php in tests/factories/all.php
$factory('App\User', [
'name' => $faker->name,
'email' => $faker->email,
'password' => password_hash('000400', PASSWORD_DEFAULT)
]);
This is the command I am using:
php artisan db:seed --class="UserTableSeeder"
This is my UserTableSeeder:
public function run()
{
// User::create([
// 'name' => 'Rainbow Warrior',
// 'email' => 'email#exmaple.org',
// 'password' => password_hash('123456', PASSWORD_DEFAULT)
// ]);
TestDummy::times(20)->create('App\User');
}
I had a typo inside my all.php that looked like this:
$factory('App\Comment', [
'user_id' => 'factory:App\User',
'question' => $factory->sentence,
'answer' => $factory->text
]);
If you look closely, you will notice, that instead of $faker, I wrote $factory. Well... fair enough.

Categories