Workflow of role/permission based content filtering using Entrust Laravel - laravel

I am using laravel 5 and added Entrust for roles and permissions.
I don't know how to use the permissions. If I have a permission create-post means what will it do?
create option in the Post controller will be permit? Or we need to assign a permission name to the page?
Please suggest an example. Even I don't know where to check permissions...

The workflow of Entrust is as follows
Create roles
Role::create(['name' => $role]);
e.g admin, reader etc
Create permissions
Permission::create($permission);
e.g can_read_post, can_edit_post, can_delete_post
Assign permissions to roles
$role = Role::where('admin)->first();
$role->perms()->sync($ids); //here the ids are ids of permissons which you want to assign
e.g admin has permissions (can_read_post, ca_edit_post, can_delete_post) and reader has permissions (ca_read_post)
Assign roles to users
You can assign a role to many users.
$user->roles()->attach($roleId);
Filter content based on Role or Permission
The basic setup has been completed. Now you can filter the content of your website using different methods. Here I will discuss a few
Define a filter in filters.php and apply on route
filters.php
Route::filter('admin', function()
{
if(!Entrust::hasRole('Administrator'))
{
return Redirect::to('/');
}
});
routes.php
Route::group(['before' => ['admin']], function(){
//add some routes which will require admin role
//any user which has not admin role will be redirected to home page
}
In your views
#if(Entrust::can('can_edit_post'))
//add some html which will only be visible to users who has such a role which has this permission
#endif
In your controllers/models/repos
Similarly you can filter content in models/controllers/repos etc.
So I guess you have got the basic idea. Now you can use Entrust functions almost anywhere. Hope this helps.

Briefly what we need to done to implement Entrust Laravel Package for role based permission is as below.
Install the package as per per the instructions given in
https://github.com/Zizaco/entrust
After all, done with the above Package(GitHub) like database table creation, Middleware, Controllers and all.
When a user login in the system, then there is an array provided by Auth, that contains all the actions user can (actions ability logged in user can) take.
Let a suppose we have a Controller named as CategoryController as below.
class CategoryController extends Controller
{
public function __construct()
{
$this->middleware('permission:category_index', ['only' => ['index']]);
$this->middleware('permission:category_create', ['only' => ['create', 'store']]);
$this->middleware('permission:category_edit', ['only' => ['edit', 'update']]);
$this->middleware('permission:category_delete', ['only' => ['delete']]);
$this->middleware('permission:category_view', ['only' => ['show']]);
}
}
We generally have 5 actions in a Controller, If we have a single route (called as resource route) in our routers/web.php file for all CRUD actions of single controller.
In this example, suppose we have all these 5 methods. So we also have entry in permission for these in permission table.. like I have
Permission Table
id display_name name
5 Delete Category category_delete
4 Edit Category category_edit
3 Create Category category_create
2 List Category category_index
We just need to add these permission names in our controllers as I have done in the CategoryController, If you use hyphon in permission table's name filed, then use like
$this->middleware('permission:category-create', ['only' => ['create', 'store']]);
Write all permissions in the controller constructor.
that' it!!
It will automatically check the logged-in user ability and according to the database entry in permission_role (relation table of role and permission), It will either show the page or access denied for that user.
Hope this works !!

Related

Laravel Nova show Dashboard based on Role

Within my users Table I have different roles. I have two different Dashboards and want to show the Dashboard based on thier roles. But I dont understand how the canSeeWhen method from laravel works?
https://nova.laravel.com/docs/4.0/customization/dashboards.html#defining-dashboards
Lets say I have the roles Admin and editor and trader.
I have the Admin Dashboard, this should be available for the admins and editors and I have the trader dashboard, this should be available for the traders.
You have multiple options, you can use the canSee method and the canSeeWhen method.
The canSee method accepts a callback and based on the return true or false it will show the dashboard.
example:
public function dashboards()
{
return [
.....
ExampleDashboard::make()->canSee(function ($request) {
return $request->user()->role == 'admin'
}),
];
}
In the above example, when the user role property is equal to 'admin' they see the dashboard.
When using the canSeeWhen it actually uses the policy system from laravel, maybe you are making a dashboard based on all user data then you want to know that the user that is viewing the data is also authorized to viewany user.
Then you could do something like this:
public function dashboards()
{
return [
...
ExampleDashboard::make()->canSeeWhen('viewAny', \App\Models\User::class),
];
}
Read more about the policies

Laravel multiple authentication from two different route and view

I want to implement a system where 6 types of users exist. So one is 'customer' who will login by a route like /login and rest of 5 users are admins and only they will be login using another route /system/base-admin. However, 'customer' never login with the /system/base-admin route if anyhow can known this route. And both route have different login form and if they failed to login 'customer' will be redirected /login and admins /system/base-admin.
I know about $guard and middleware check.
Question: How can i implement above scenario and how react professionals with this scenario?
Route::get('/login','CustomerLoginController#processLogin')->name('customer.login');
Route::get('/system/base-admin', 'AdminLoginController#processAdminLogin')->name('system.admin')
My Controller Looks like
public function processLogin(){ return view('customer.login');}
public function processAdminLogin(){ return view('admin.login')}
Thank you in advance.
The only reason I see to have different endpoints for login is to have different views.
Copy your Auth\LoginController, change $redirectTo to redirect to your admin panel. Overwrite AuthenticatesUsers\showLoginForm to show your admin form and update middleware in __construct.
Protect all your admin routes with admin middleware.
Now. Your users CAN login to your panel. BUT nothing will happen since they don't have access.
If you want to show them some kind of message when they try you can overwrite AuthenticatesUsers\login method with something like this
...
if ($this->attemptLogin($request)) {
if(!auth()->user()->isAdmin()){
throw ValidationException::withMessages([
$this->username() => 'You don\'t have access to this page',
]);
}
return $this->sendLoginResponse($request);
}
...

Same route in multiple role and route group?

I have route which I want to authorize on more than 1 one role.I have created 2 route group one is admin and other one is employee and there is a route abc.com/abc which I want to accessible on both roles. Admin routes are:
Route::group(['middleware'=>['auth','role:admin|hr-manager|manager ']],function(){
Route::get('employee',['as'=>'employee','uses'=>'EmployeeController#employeeList']);
Route::get('leave-type',['as'=>'leave.type','uses'=>'LeaveController#getLeaveType']);
}
Employee routes are:
Route::group(['middleware' => ['auth','role:employee']], function(){
Route::get('leave-type',['as'=>'leave.type','uses'=>'LeaveController#getLeaveType']);
}
Now when i login with admin i can't access leave-type route because admin user doesn't have employee role but when i assign admin user to employee role it will be accessible, and admin user can not be an employee so how can i accessible this route on both role.
Using laravel 5.4 and zizaco/entrust for ACL system. so please let me how what type of problem is this and how can get the solution.
Thanks in advance.
If you need more routes that are available to a base group and then a specific subset for others I'd suggest to reorganize the routes file to something as follows:
Route::middleware(['auth'])->group(function () {
//Routes available to all users
Route::get('leave-type',['as'=>'leave.type', 'uses'=>'LeaveController#getLeaveType']);
//Routes available to employees
Route::middleware(['role:employee'])->group(function () {
});
//Routes available to Admin, HR Manager and Manager
Route::middleware(['role:admin|hr-manager|manager'])->group(function () {
Route::get('employee', ['as'=>'employee', 'uses'=>'EmployeeController#employeeList']);
});
});

two users auth in a single table in laravel 5.2

I'm trying to build an online shop website using laravel framework
I have a table with these column : id, username, password, division_id
where division_id refers to a table called division with: id, division_type
and I have two division type : Admin and Customers
I'm trying to divide permission to access a certain number of pages based on their division_id such as admin can access Admin panel but not Customer, and customer can access Customer panel such as product-order page but not admin.
Both types can do almost everything in their accessible pages, and my main pages will have an Admin Panel, a customer Panel, and main website.
How can I do that in my project using only a single table and middle-ware group?
P.S. I'm new to this forum
For this Middleware, you just need to check if the division required to view the site is the same as the division that the user belongs to. In the handle function, you can pass a 3rd argument that represents a division name, such as customer
When you add the Middleware to your routes, you can pass the name of the division as an argument to the handle function like so:
'middleware' => ['division:customer']
Implementing this in an Route Group may look something like this:
Route::group(['prefix' => 'customer', 'middleware' => ['division:customer']], funtion(){
//route definitions for all these routes will require a "division" type of "customer"
});
Or you could apply it to route resources for RESTful routing:
Route::resource('customer', 'CustomerController')->middleware(['divison:customer']);
Or you could just apply it to a specific route:
Route::get('customer/{id}', 'CustomerController#show')->middleware(['division:customer']);
In your handle function you can access that value as the 3rd argument:
public function handle($request, Closure $next, Division $division)
To make the process of automagically resolving a dependency by something other than the primary key easy, we'll go ahead and pop open our App\Providers\RouteServiceProvider and add some magic inside of the boot function.
public function boot(Router $router)
{
parent::boot($router);
$router->bind('division', function($value) {
return Division::where(function($query) use($value){
if (is_int($value)) {
return $query->where('id', $value)->first();
} else {
return $query->where('type', ucfirst($value))->first();
}
return null;
});
});
Now, back to the Middleware, we can easily make a comparison against the $division in our handle function, and our authorized user.
if(app()->user()->division->type == $division->type) {
return $next($request);
}
abort(403, 'You are not authorized to view this page!');

Laravel 4 - Reuse controllers and views using routes

I'm building a blog application with Laravel 4 which has two types of users, the administrator and the regular user.
When users create their accounts or when they log in all of their routes have the "user" prefix , like this:
GET user/posts = PostsController#index
For administrators all of their routes have the "admin" prefix , like so:
GET admin/users = UsersController#index
To view all the posts from a user as an administrator I do this:
GET admin/users/($id)/posts = PostsController#index
So if a regular user is logged then I get his ID from session, but if the user is an administrator then I get the regular user ID from the url.
I also have to update the links inside the views, like this:
As a regular user: link_to("user/posts/create", "Create Post")
As an administrator: link_to("admin/users/1/posts/create", "Create Post")
Is there a better approach this?
Yeah, all users are users.
Anything that requires you to be an administrator should have a filter for that on the route.
So for example, if an administrator was only allowed to go to user/posts/delete/{id}, that route would look something like...
Route::post('user/posts/delete/{id}', array('before' => 'adminFilter', 'uses' => 'PostController#deletePost');
I'm not sure how you figure out if a user is an admin or regular user, but your filter could look something like...
Route::filter('adminFilter', function()
{
if (!Auth::user()->isAdmin())
{
return Redirect::to('home')->with('message', 'You aren't an admin!');
}
});
And you would simply put an isAdmin() function in your User model which describes how to tell if a user is admin and returns true or false.

Resources