I am using laravel passport in py project and I want to create a token in every request for making it secure, but it not work now and I really became confused that what is the problem with my code, please help me.
here is my Model
use App\Models\Post;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\MediaLibrary\HasMedia\HasMedia;
use Spatie\MediaLibrary\HasMedia\HasMediaTrait;
use Spatie\MediaLibrary\Models\Media;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable implements HasMedia
{
use HasApiTokens, Notifiable;
use HasMediaTrait;
public function registerMediaConversions(Media $media = null)
{
$this->addMediaConversion('thumb')
->crop('crop-center', 50, 50);
$this->addMediaConversion('list')
->fit('crop', 312, 312);
$this->addMediaConversion('big')
->fit('fill', 1248, 1248);
}
protected $fillable = [
'name', 'email', 'password', "role"
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
public function posts()
{
return $this->hasMany(Post::class, 'post_author');
}
}
here is my controller
{
$data = \App\User::all();
$accessToken = $data->createToken('Token')->accessToken;
return response(['usersData' => $data]);
}
I solved my problem with bellow code:)
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')-> accessToken;
return response()->json(['success' => $success], $this-> successStatus);
Related
My app has 2 main modules which are Foo and Bar. It also has 3 types of role: admin, manager & staff.
Each user is assigned to a supervisor, so that every supervisor will have some subordinates assigned to him/her.
For example, staff1 is supervised by manager1 whom is also supervised by admin1.
The current practice for this relationship is implemented in both modules. Therefore each supervisor is in charge for the subordinates in the matter of their Foo and Bar.
User.php
<?php
namespace App;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Support\Str;
class User {
protected $fillable = ['name','email','password','supervisor_id'];
protected $appends = ['role'];
public function getRoleAttribute(){
return $this->roles[0];
}
public function getNameAttribute($value){
return Str::title($value);
}
public function parent(){
return $this->hasOne('App\UserStructure', 'user_id');
}
public function scopeSupervisor($query){
return $query->where('id', $this->supervisor_id)->first();
}
public function foo(){
return $this->hasMany(Foo::class, 'user_id', 'id');
}
public function bar(){
return $this->hasMany(Bar::class, 'user_id', 'id');
}
}
UserStructure.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserStructure extends Model{
protected $fillable = ['user_id', 'parent_id'];
public function user(){
return $this->belongsTo('App\User', 'user_id');
}
}
Role.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model{
protected $fillable = ['name'];
public function roles(){
return $this->belongsTo('App\User', 'role');
}
}
RoleAndPermission.php
<?php
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class RolesAndPermissionsSeeder extends Seeder{
public function run(){
$roles = ['admin','manager','staff'];
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
foreach ($roles as $role) {
Role::updateOrCreate(['name' => $role]);
}
}
}
UserSeeder.php
<?php
use Illuminate\Database\Seeder;
use App\User;
use App\UserStructure;
class UserSeeder extends Seeder{
public function run(){
$items = [
['role'=> 'admin',
'name'=> 'admin',
'email'=> 'admin#myapp.com',
'password'=> 'password',
'supervisor_id'=> 1],
['role'=> 'manager',
'name'=> 'manager',
'email'=> 'manager#myapp.com',
'password'=> 'password',
'supervisor_id'=> 1],
['role'=> 'staff',
'name'=> 'staff',
'email'=> 'staff#myapp.com',
'password'=> 'password',
'supervisor_id'=> 2],
];
foreach($items as $data) {
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'supervisor_id' => $data['supervisor_id'],
]);
$user->assignRole($data['role']);
}
$userStructure = [
['parent_id'=> 0, 'user_id'=> 1],
['parent_id'=> 1, 'user_id'=> 2],
['parent_id'=> 2, 'user_id'=> 3]
];
UserStructure::insert($userStructure);
}
}
My question is, how do I modify this relationship accordingly so that any supervisor [admin/ manager] will be assigned to the subordinate [manager/ staff] of one module only?
(E.g:
In Foo module, staff1 is supervised by manager1.
While in Bar module, he will be supervised by manager2.)
As i understand, you can add one column to the Role model (like type), and then assign roles to users with a condition
I have a project in which I want a Specific page to be viewed by a specific user which have a role of viewing for example I have User 1 that has an Admin Role and the Admin Role has the Ability to View this page in my design I made 3 models Users, Roles, and Abilities
User Model:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password','district','area','committee','position',
];
/**
* 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 answer()
{
return $this->hasMany('App\Answer');
}
public function roles()
{
return $this->belongsToMany('App\Role');
}
public function hasRole($role)
{
if ($this->roles()->where('name', $role)->first()) {
return true;
}
return false;
}
public function assignRole($role)
{
$this->roles()->save($role);
}
}
Role Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
protected $fillable = ['name'];
public function abilities()
{
return $this->belongsToMany('App\Ability');
}
public function hasAbility($ability)
{
if ($this->abilities()->where('name', $ability)->first()) {
return true;
}
return false;
}
public function assignAbility($ability)
{
$this->abilities()->save($ability);
}
public function users()
{
return $this->belongsToMany('App\User');
}
}
Ability Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Ability extends Model
{
protected $fillable = ['name'];
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
This is my UserPolicy:
<?php
namespace App\Policies;
use App\User;
use App\Role;
use Illuminate\Auth\Access\HandlesAuthorization;
class UserPolicy
{
use HandlesAuthorization;
public function view (Role $role)
{
return $role->hasAbility('view');
}
public function manage (User $user)
{
return true;
}
public function edit (User $user)
{
return true;
}
public function update (User $user)
{
return true;
}
public function add (User $user)
{
return true;
}
}
And the Controller of The Policy
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\User;
use App\Role;
class MemberController extends Controller
{
public function index(Role $role)
{
$this->authorize('view', $role);
return view ('members.create')->with('users', User::all());
}
public function manage(User $user)
{
$this->authorize('manage', $user);
return view ('members.manage')->with('users', User::all());
}
public function edit(User $user)
{
$this->authorize('edit', $user);
return view ('members.edit')->with('user', User::all())->with('roles', Role::all());
}
public function update(Request $request, User $user)
{
$this->authorize('update', $user);
$user->roles()->sync($request->roles);
return redirect('/members/edit');
}
public function store(User $user)
{
$this->authorize('add', $user);
$this->validate(request(), [
'name' => ['required', 'string', 'max:255'],
'district' => ['required', 'string', 'max:255'],
'area' => ['required', 'string', 'max:255'],
'committee' => ['required', 'string', 'max:255'],
'position' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
$data = request()->all();
$member = new User();
$member->name = $data['name'];
$member->district = $data['district'];
$member->area = $data['area'];
$member->committee = $data['committee'];
$member->position = $data['position'];
$member->email = $data['email'];
$member->password = Hash::make($data['password']);
$member->save();
return redirect('/members/create');
}
}
The index function should be the one related to the function view in the UserPolicy
and this is the can located in my blade.php file
#can('view', \App\Role::class)
<li class="">
<a class="" href="/members/create">
<span><i class="fa fa-user-plus" aria-hidden="true"></i></span>
<span>Add Member</span>
</a>
</li>
#endcan
in the policy when I link it to the name of the role of the logged in user everything works just fine but if I want to link it to an ability of the role it doesn't work so any idea on how the View Function in the UserPolicy should be implemented ?
The first parameter that is passed to the policy is the authenticated User, not its Role. I don't think it works. Maybe if you reimplement using an EXISTS query.
public function view (User $user)
{
return $user->roles()->whereHas('abilities', function ($ability) {
$ability->where('name', 'view');
})
->exists();
}
->exists() turns the query into an EXISTS query, which will return a boolean value if the query finds anything without having to return any rows.
https://laravel.com/docs/7.x/queries#aggregates
You could put that logic into an User method.
# User model
public function hasAbility($ability): bool
{
return $this->roles()->whereHas('abilities', function ($ability) {
$ability->where('name', 'view');
})
->exists();
}
public function view (User $user)
{
return $user->hasAbility('view');
}
I'm trying to make a simple login just for the moment and when I try to login I get this error
Cannot declare class App\Models\User, because the name is already in use
In my User Model, this is the model
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'username', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
The error says on this line
class User extends Authenticatable
This is my submit method on my Login.vue
submit() {
this.$refs.form.validate((valid) => {
if (valid) {
this.loading = true;
this.$inertia.post('/login', {
username: this.form.username,
password: this.form.password,
}).then(() => this.loading = false)
} else {
return false;
}
});
},
What am I doing wrong?
I would like to display privileges('name') instead of idPrivilege in the user collection. I have tried to add a relationship and use it in an Eloquent call but I'm getting an error.
User model
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $table = 'users';
protected $primaryKey = 'idUser';
protected $fillable = [
'name', 'email',
];
protected $hidden = [
'password', 'updated_at',
];
public function privilege()
{
return $this->hasOne(Privilege::class, 'idPrivilege', 'idPrivilege');
}
}
Privilege model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Privilege extends Model
{
protected $table = 'privileges';
protected $primaryKey = 'idPrivilege';
protected $fillable = [
'name',
];
protected $hidden = [
'updated_at',
];
public function user()
{
return $this->belongsTo(User::class, 'idPrivilege', 'idPrivilege');
}
}
UserController
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class UserController extends Controller
{
public function relationTest()
{
return User::where('idUser', 1)->privilege()->get();
}
}
I'm getting the below error when I use with('privilege') to my User collection is added privilege collection.
Call to undefined method Illuminate\Database\Eloquent\Builder::privilege().
where returns a Builder instance on which a privilege method does not exist, so you can simply use it as such:
return User::find(1)->privilege()->get();;
-- EDIT
User::find(1)->with(['privilege' => function($query) {
$query->select('name');
}])->get();
I can achieve it by using resource:
$user = User::where('idUser', 1)->with('privilege')->first();
return UserResource::make($user);
Inside UserResource:
public function toArray($request)
{
return [
'idUser' => $this->idUser,
'name' => $this->name,
'email' => $this->email,
'privilege' => $this->privilege['name'],
'createdAt' => $this->created_at,
];
}
but was hoping there is simplier method of getting that.
output:
{
"data": {
"idUser": 1,
"name": "Martin",
"email": "martin#martin.martin",
"privilege": "user",
"createdAt": "2019-05-05T01:11:43.000000Z"
}
}
I have facebook login which uses socialite library. The error in the question occurs when the callback occurs.
Here is my "USER" model
<?php
namespace App;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
class User extends Model implements Authenticatable
{
//use Illuminate\Contracts\Auth\Authenticatable;
/**
* 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',
];
use \Illuminate\Auth\Authenticatable;
public function posts()
{
return $this->hasMany('App\Post');
}
public function likes()
{
return $this->hasMany('App\Like');
}
}
The Socialite logins are handled by SocialAuthController and what i understood from the error is , auth()->login($user); , null is passed to the login("NULL"). Here is the code of SocialAuthController. What's the mistake i have made here and how to fix this. thanks in advance
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Socialite;
use App\SocialAccountService;
class SocialAuthController extends Controller
{
public function redirect($provider)
{
return Socialite::driver($provider)->redirect();
}
use \Illuminate\Auth\Authenticatable;
public function callback(SocialAccountService $service , $provider)
{
$user = $service->createOrGetUser(Socialite::driver($provider));
auth()->login($user);
return redirect()->to('/home');
}
}
The below is the handling service that will try to register user or log in if account already exists.
Here is the code of SocialAccountService.php
<?php
namespace App;
use Laravel\Socialite\Contracts\Provider;
class SocialAccountService
{
public function createOrGetUser(Provider $provider)
{
$providerUser = $provider->user();
$providerName = class_basename($provider);
$account = SocialAccount::whereProvider($providerName)
->whereProviderUserId($providerUser->getId())
->first();
if ($account) {
return $account->user;
} else {
$account = new SocialAccount([
'provider_user_id' => $providerUser->getId(),
'provider' => $providerName
]);
$user = User::whereEmail($providerUser->getEmail())->first();
if (!$user) {
$user = User::create([
'email' => $providerUser->getEmail(),
'name' => $providerUser->getName(),
]);
}
$account->user()->associate($user);
$account->save();
return $user;
}
}
}
This will try to find provider's account in the system and if it is not present it will create new user. This method will also try to associate social account with the email address in case that user already has an account.
My wild guess is that createOrGetUser() returns NULL because the SocialAccount does not have a user. So what could do is change the if condition in that method to check if the $account has a user:
public function createOrGetUser(Provider $provider)
{
...
if ( $account && property_exists($account, 'user') && $account->user ) {
return $account->user;
} else {
...