Method roles not found in laravel Auth - laravel-5

I keep getting the method not found error when I'm trying to assign a role to the user in the user registration section.
The following is the code that I am using in the AuthController
namespace App\Http\Controllers\Auth;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\User;
class AuthController extends Controller
{
protected function create(array $data)
{
$user = User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'email' => $data['email'],
])->get();
$user->roles()->sync([2]);
return $user;
}
}
following is my User model
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Zizaco\Entrust\HasRole;
use App\Role;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $table = 'users';
protected $fillable = [
'first_name','last_name', 'email', 'password'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
I'm not sure why this is happening. I think maybe it's not importing the User model properly, or I'm missing something. I'm new to laravel, so any help will be welcome.

To create a model simply use the following:
$user = User::create($attributes)
Notice that I did not call get() afterwords. get() will perform a query returning a Collection. I'm not sure what your Role model looks like, but it should work properly now.

Related

can't use assign role to User where i give factory

I want to create users with factories and directly assign roles to them. However, I encountered an error while seeding.
My Error was like there :
Method Illuminate\Database\Eloquent\Collection::assignRole does not exist.
Here is the code from my databaseSeeder.php :
$user = User::factory(10)->create()->assignRole('Admin');
That is my UserFactory code. This is default, I dont change anithing:
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* #extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserFactory extends Factory
{
/**
* Define the model's default state.
*
* #return array<string, mixed>
*/
public function definition()
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*
* #return static
*/
public function unverified()
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}
This is my user model:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
use PHPOpenSourceSaver\JWTAuth\Contracts\JWTSubject;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class User extends Authenticatable implements JWTSubject, HasMedia
{
use HasApiTokens, HasFactory, Notifiable, HasRoles, InteractsWithMedia;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'e-mail',
'passwords',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Please help me, Thanks!
Try assigning the role in your User factory callback like so:
class UserFactory extends Factory
{
...
public function configure()
{
return $this->afterCreating(function (User $user) {
$user->assignRole('Administrator');
});
}
...
This method will be automatically run when you run the factory. After each create it will run assignRole on the created User model.
Use the factory like so:
User::factory()->count(10)->create();
https://laravel.com/docs/8.x/database-testing#factory-callbacks

Laravel Spatie/Laravel-Permission Failed to fetch role data

what im trying to do is fetcing role data from single actions controller and got error messege when i test it out from postman. "message": "Call to undefined method App\Models\User::auth()", for anyone can give me hint or solution to fix this problems will highly appriciate. for further information im using jwt for auth, api as the guard.
so let me show you my code.
Controller:
<?php
namespace App\Http\Controllers\Api\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
class RoleController extends Controller
{
public function __invoke()
{
return User::auth()->user()->getRoleNames();
}
}
Model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable implements JWTSubject
{
use HasFactory, Notifiable, HasRoles;
protected $guard_name = "api";
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function getJWTIdentifier(){
return $this->getKey();
}
public function getJWTCustomClaims(){
return [];
}
}
routes:
//group route with prefix "admin"
Route::prefix('admin')->group(function () {
//route login
Route::post('/login', [App\Http\Controllers\Api\Admin\LoginController::class, 'index']);
//group route with middleware "auth"
Route::group(['middleware' => 'auth:api'], function() {
//data user
Route::get('/user', [App\Http\Controllers\Api\Admin\LoginController::class, 'getUser']);
//refresh token JWT
Route::get('/refresh', [App\Http\Controllers\Api\Admin\LoginController::class, 'refreshToken']);
//logout
Route::post('/logout', [App\Http\Controllers\Api\Admin\LoginController::class, 'logout']);
Route::prefix('authorization')->group(function () {
Route::get('/roles', RoleController::class);// not working
});
});
});
There are few ways you can try for getting those roles:
shows all the role names
Auth::user()->roles
$roles = $user->getRoleNames(); // Returns a collection
check user has specific role
Auth::user()->hasRole('admin')
check user has any roles
Auth::user()->hasAnyRole(['super_admin', 'vendor'])
For other usage take a look at the site:
Spatie roles and permission info

How to include a JSON column property in Laravel API Resource

I have a model which is illustrated below which I am struggling to access a very trivial property.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class Vendor extends Authenticatable
{
use Notifiable, HasApiTokens, SoftDeletes;
protected $guard = 'vendor';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'slug','images'
];
//images is a json column
protected $casts = [
'images' => 'array'
];
}
Within my model I now have a property which is
public function coverImage()
{
return \Storage::disk('s3')->url( $this->images['cover']);
}
I am basically trying to retrieve a property within my JSON column but whenever I try to access it in my API resource, it throws the error:
ErrorException: Trying to access array offset on value of type null in file C:\...\Models\Vendor.php on line 63
Is there something that I am missing?
I had a lightbulb moment, all I needed to do was to expose it in my VendorResource as thus
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class VendorResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request): array
{
return [
'id' => $this->id,
'email' => $this->email,
'coverImage'=> \Storage::disk('s3')->url( $this->images['cover'])
];
}
}

403 user does not have any necessary access rights in laravel usercontroller laratrust

I am trying to get all user in my table but I get an error 403 user does not have the necessary rights. I am using laratrust and vuejs. I have already logged in as a superadministrator. This is my controller class
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\user;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
public function __construct()
{
$this->middleware('role:user|superadministrator');
}
public function index()
{
return view('user.index');
}
public function getusers(){
$theUser = Auth::user();
if ($theUser->hasRole('superadministrator')) {
return $users;
}
}
}
My api route
Route::get('/allusers','UserController#getusers');
I have tried to go through the documentation but no success.Kindly help me solve this issue
User Model
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laratrust\Traits\LaratrustUserTrait;
class User extends Authenticatable
{
use LaratrustUserTrait;
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
What about if you try this:
public function getusers(Request $request){
$theUser = $request->user('api');
if ($theUser->hasRole('superadministrator')) {
return $users;
}
}

How to add a custom attribute to Auth::user() when one logs in

So, first I hope my title is not misleading. Please let me know if my title fits the question.
QUESTION.
I'm using Laravel 5.3 and I'm trying to find a way to add an attribute "role" to Auth::user() so that I can access it like
Auth::user()->role.
Role is not a field in the user table used for authentication but it's a value I calculate to get. The reason I ask is I don't want to calculate role every single time I need the value, instead I want to set it when authentication succeeds then reuse it.
Any idea how I can do this?
Or is there any way I can persist a value through out the time a user is logged in so that I can calculate it once and reuse it?
The best way you can achieve this is in your User.php model:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token','is_admin',
];
protected function getRole(){
if(\Session::has("role")){
return Session::get("role");
}else{
//calculate and save role in session
}
}//end get Role
}//end class
so you will check it like this
Auth::user()->getRole();
Make sure you save the role in session after login , the getRole will get it and attach to the user() object , This doesnt need middleware too
Hope it helps
Just add the method of the keyword you want to use at the bottom of the model and use belongsTo() to link it up to a corresponding model. Then we just do Auth::user()->role() to use it. This is assuming you have a model called Role with a table and roles defined. (laravel 5.2+)
public function role() {
return $this->belongsTo( Role::class );
}
The entire model is here:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $guarded = ['id', 'remember_token'];
protected $hidden = [ 'password', 'remember_token' ];
public static $rules = array(
'email' => 'required|email|unique:users,email',
'first_name' => 'required|min:2',
'last_name' => 'required|min:2'
);
public static $rules_password = array(
'password' => 'required|min:6|confirmed'
);
public function role() {
return $this->belongsTo( Role::class );
}
}

Resources