There is a project of Hotels, and for each hotel there is one admin.
What I have done:
In Usertype table different types of Users like chef,managers,hotel
If user type is hotel means it is the admin of that hotel.
Now for each and every CRUD and other functionalities I get hotel id like this
$hotel_id = \Auth::user()->hotel_id;
and checked this hotel_id in each query(like get user, save user, get invoice,set invoice,check food etc).
Is this the correct way?
Yes, it's a correct way to check if a user is hotel's admin. But it's better to use policies for that:
public function update(User $user, Hotel $hotel)
{
return $user->id === $hotel->user_id;
}
Policies are classes that organize authorization logic around a particular model or resource.
https://laravel.com/docs/5.5/authorization#generating-policies
Related
I have to create an application in which there are 5 types of accounts
Super admin
Inventory admin
Shop owner
Shop manager
User
So How can I create these multiple accounts with Laravel, should I use different middleware group for each. also, i have to create privileges with all.
Currently, I am using it with different middleware and session for each and separate tables in DB for each, but I don't think so that's a good way to do it.
What is the way to create these multiple accounts with Laravel.
#Thanks
In addition to providing authentication services, Laravel also provides a simple way to authorize user actions against a given resource. Laravel's approach to authorization is simple, and there are two primary ways of authorizing actions: gates and policies. Please refer the Laravel documentation for more details.
Authorization in Laravel 5.5
As #Fawzan has said, if you only working with Roles (or a Group) then just create a groups table and then link each user to the appropriate group. You then have a single user table with a groupID for each user.
Then you could create a blade directive to help you in your app to check if a user has a specific role. (Place this inside your AppServiceProvider)
Blade::directive('hasRole', function ($role) {
return auth()->user()->role->name = $role;
});
// Or a little more performant if you call the directive many times.
$roles = Role::all()->pluck('id', 'name')->toArray();
Blade::directive('hasRole', function ($role) use ($roles) {
return auth()->user()->roleID == $roles[$role];
});
You can add a column to users table called user_type and
insert the decimal value for each user for example
Super admin = 1;
Inventory admin = 2;
Shop owner = 3;
Shop manager = 4;
User = 5;
and based on the user_type you can do all your operation.
I am developing an application in which I have views for different roles.
For example, I have a form which has 5 fields. It may have 3 fields for role 1 and all fields for role 5 available when submitting.
Now, where I am showing the form data as graphically or using table, I have options to show 5 columns or fields for some role and less fields form for some other role.
Right now I am doing if else logic in each action of controller to determine the role then pass the appropriate data to the view, how do you manage this? I would like to know.
PLEASE READ FULL BEFORE SAYING 'SHOW ME SOME CODE :('
EDIT:
1 more question, suppose there is a users class and have a 1 to 1 relation with type class, in the views i can do:
{{ Auth::user()->type->key }}
Or some complex ones like
{{ Auth::user()->as_member->claims->sum('amount_claimed') }}
This is a complex relation, user as a member have many claims and I am summing it up here. Is it better to do this in controller then pass them as a value?
Generally speaking User and Role share Many-To-Many relation. A user can have many roles and a role can be shared by many users.
To implement it three database tables are required
1. users
2. roles
3. role_user (pivot table)
Then the relation could be defined in the models as
class User extends Model
{
public function roles()
{
return $this->belongsToMany('App\Roles');
}
//suppose you currently want to assign each user only one role
//however also want to provision multiple roles for user in future
//then you can define a virtual/calculated attribute to your model
//to simplify usage considering each user has only one role
public function getRoleAttribute()
{
return $this->roles[0]->name; //name is a field on the roles table
}
protected $appends = ['role']; //to ensure that the calculated attribute is available to ajax/json/api requests as well
}
class Role extends Model
{
public function users()
{
return $this->belongsToMany('App\User');
}
}
Say you have three users as sample data
User1 has role 'User'
User2 has role 'Manager'
User3 has role 'Admin'
Now you can test the functionality with a sample view like
<h4>Current user is {{auth()->user()->name}} having a role of {{auth()->user()->role}}</h4>
<div class="example-form">
<h4 class="all">Visible to all - User1, User2, User3</h4>
#if( (auth()->user()->role ==='Manager') || (auth()->user()->role ==='Admin'))
<h4>Visible to Manager and Admin only - User2 and User3</h4>
#endif
#if(auth()->user()->role === 'Admin')
<h4>Visible only to Administrator - User3</h4>
#endif
</div>
Hope this is what you are aiming for - is my understanding okay.
However since you have mentioned that you are using Laravel 5.2, better way of doing it would be to use out-of-box authorization provided by Laravel 5.2.
Refer Authorization documentation
I have 5 user profiles: SuperAdmin, FederationPresident, AssociationPresident, ClubPresident, simpleUser
I could grow with time.
So the relations are simple:
A simpleUser belongsTo a club
A club belongsTo an association
An association belongsTo a federation.
Right now, I just have a "type" field in my user table to diferenciate them.
Now, I'm building it, but I write all along my code:
if (Auth::user()->isSuperAdmin){
...
}elseif (Auth::user()->isPresidentFederation()){
...
}
And I want to refactor it, because it is an hugly way to code it.
Now, first, I managed Roles, and used #can('dothis') in my code, but it is kind of too much in my case and it doesn't fit so well to my use case, so I deleted it.
Everywhere, I have to test what kind of user is logged to know what he is able to perform.
I already use Middlewares to restrict access to unauthorized pages.
For a list of user, a SuperAdmin can see all users, a FederationPresident can see all user of his federation, an AssociationPresident can see all user of his association, etc.
So, I manage it like that:
$associations = Association::with('federation.country')
->whereHas('federation', function ($query) {
if (!Auth::user()->isSuperAdmin()) {
$query->where('president_id', Auth::user()->id);
}
})->get();
But in the case I would do it for a list of clubs, query would grow, because I would need to check what kind of user is logged.
All those "if" in my code are a bit annoying, as they will be everywhere...
Any help will be appreciated!
I am trying to create a laravel application with version 5.2. Where there will be 3 types of users
Administrator (website manager) - using default "users" table for
this.
Owners (Website listing creator from frontend) - using a
table "owners" for this.
Customer (Visitors or registered
visitors) - using a table "customers" for this.
Now my problem is:
i want to make sure login Owners will get proper authentication and redirect to their own (other then default Auth route) route.
And same with customer, and they will be mainly login through frontend of the website, so their route will be different from owners and Administrator. And these customer will also get authentication.
How can i manage that? I have worked around with single table, but being as a new person to Laravel i am not sure how i can achieve with multiple table.
I have checked laravel 5.2 started supporting multiple gaurds now, but not sure how can i do this.
There are certain packages for this, but i dont want to relay on package for this.
Thank you!
I would suggest you follow a Polymorphic approach for this.
Let's say there are three different tables - administrators, owners, customers
Now for all of them, there is a common table with the name users which will have the columns :- profile_id, profile_type.
Now profile_id will become the foreign key for tables administrators, owners and customers and profile_type will tell which Model the user belongs to.
Relation would be like,
class User {
public function profile() {
return $this->morphTo();
}
}
--
class Administrator {
public function user() {
return $this->morphOne('App\User', 'profile');
}
}
Here we are using morphOne instead of morphMany because the profile_id field in users table should have only one row for one admin.
Lastly, for the purpose of creation/storing. You'll have to :-
Create an admin like
$admin = Administrator::create($inputs);
Then do
$user = new User($inputs);
$admin->user()->save($user);
You're done!
You can learn more about it this approach from https://laravel.com/docs/5.1/eloquent-relationships#polymorphic-relations
Thanks,
I was working on making a group functionality for my website which uses a many to many relationship between groups and users.
My User model looks like this:
public function groups(){
return $this->belongsToMany('App\Group')->withPivot('role')->withTimestamps();
}
My Groups model looks like this:
public function users(){
return $this->belongsToMany('App\User')->withPivot('role')->withTimestamps();
}
So my third column has the name of role which is a string variable and is set to a default of "member" for members of my group and I set it to "admin" for the actual user who creates a new group. But I want the admin to have the option of making multiple members admins as well which would require me to check weather the current current user who sent the request is an admin or not. If he is, then I wanna be able to take his request of making a member an admin which would require me to update the role for that particular "member" to an "admin".
In the laravel documentation it only shows you how to attach and detach data in a pivot table and else where I have only seen methods of retrieving data from the first two columns but how can I do the same for additional columns and also be able to update it using the updateExistingPivot method?
You could access the column simply using pivot e.g :
$user->pivot->role
Take a look at Retrieving Intermediate Table Columns in documentation Eloquent Relationships.
Hope this helps.