Laravrl5- user permissions for whole module controllers - php

I created a simple system to set permissions for users in the admin panel using AdminMiddleware.
Every user has permissions like groups, posts, pages ....
Routes/web:
Route::group(['middleware' => 'admin'], function()
{
Route::get('/admin' , 'admin\AdminController#index')->name('admin');
//all admin panel routes
}
In the AdminMiddleware
public function handle($request, Closure $next)
{
if(Auth::check()){
if ($request->user()->user_type !== 'man')
{
return redirect('/');
}
$user_permissions = Auth::user()->permissions;
foreach($user_permissions as $value){
$controller = Controllers::get_controller($value->controller_id);
$permissions['name'] = $controller->controller_name;
$all_permissions[] = $permissions;
unset($permissions);
}
foreach ($all_permissions as $value){
$controllers[] = trim($value['name']);
}
$request->user()->controllers = $controllers;
return $next($request);
}
else{
return redirect('/login');
}
}
So I get a list of all user permissions which represent controllers names and in every controller (in this controller i check if the user has permission named 'users' to access the users controller to view their data)
protected $user;
public function __construct(){
$this->middleware(function ($request, $next) {
$this->user= Auth::user();
if(!in_array('users',$this->user->controllers)){
session()->flash('error' , 'No permission');
return redirect('/admin');
}
else{
return $next($request);
}
});
}
I use this for every controller and it works for a small project but when it comes to a large project with modules (nWidart/laravel-modules) it'll be hard. What I want is to check for the permission for the whole module not for every single controller in the module. So if I have a module named blog I want to check if the logged in user has permission to access any controller in that module how could this be done?

I created a middleware for every module and in the middleware i get user permissions and check if he the permission to access this group
public function handle($request, Closure $next)
{
if(Auth::check()){
if ($request->user()->user_type !== 'man')
{
return redirect('/');
}
$user_permissions = Auth::user()->permissions;
$user_group = Auth::user()->group_id;
if($user_group == 1){ //all permissions admin
return $next($request);
}
else{
//get user permissions as an array
if(in_array('groups',$user_permissions)){ //module name is groups
return $next($request);
}
else{
return redirect('/home');
}
}
}
else{
return redirect('/login');
}
}
Routes
Route::group(['middleware' => 'admin'], function()
{
Route::get('/admin' , 'admin\AdminController#index')->name('admin');
});
Route::group(['middleware' => 'users'], function()
{
Route::get('/adminUsers' , '\Modules\Users\Http\Controllers\UsersController#index');
});
Route::group(['middleware' => 'groups'], function()
{
Route::get('/groups' , '\Modules\Groups\Http\Controllers\GroupsController#index');
});

Related

How to add multiple roles to a route group laravel

I'm trying to add multiple roles to a route group in my web file in Laravel.
I would like protect certain routes based on the users Role like the admin section.
Some Routes need multiple roles for access.
Example Roles:
SuperAdmin
Admin
Moderator
etc..
This works and I can go to the admin panel if loged in and have One Role only in the route group.
Route::middleware(['auth','role:SuperAdmin'])->group(function () {
Secret routes..
});
This does not work if I try and add more roles to to the route group
like this: Route::middleware(['auth','role:SuperAdmin|Admin|Moderator'])->group(function () {
Note the 'role:SuperAdmin|Admin|Moderator'
This is the RoleMiddleware file:
public function handle($request, Closure $next, $role, $permission = null)
{
if (!$request->user()->hasRole($role)) {
abort(404);
}
if ($permission !== null && !$request->user()->can($permission)) {
abort(404);
}
return $next($request);
}
The User Class has a trait called use:HasPermissionTrait
class User extends Authenticatable
{
use Notifiable, HasPermissionsTrait, Billable;
In that HasPermissionsTrait I have the following:
I have permission setup fine, just focusing on the Roles in this file. I moved the Role logic to the top.
use App\{Role, Permission};
trait HasPermissionsTrait
{
public function hasRole(...$roles)
{
foreach ($roles as $role) {
if ($this->roles->contains('name', $role)) {
return true;
}
}
return false;
}
public function roles()
{
return $this->belongsToMany(Role::class, 'users_roles');
}
... // Permission logic start here...
}
Worth Mentioning:
The tables for roles are:
users
roles
users_roles (I know the correct naming convention should be roles_users, but not relevant here)
Just need to know how to get this working in the route group:
'role:SuperAdmin|Admin|Moderator'
Solution:
RoleMiddleware file:
public function handle($request, Closure $next, $role, $permission = null)
{
$role = strtolower( $request->user()->hasRole($role));
$allowed_roles = array_slice(func_get_args(), 2);
if (!$request->user()->hasRole(in_array($role, $allowed_roles))) {
abort(404);
}
if ($permission !== null && !$request->user()->can($permission)) {
abort(404);
}
return $next($request);
}
Can do route group like this.
Route::middleware(['auth','role:SuperAdmin|Admin'])->group(function () {
This is what I did in my CheckRole Middleware
public function handle($request, Closure $next) {
// I'm using the api guard
$role = strtolower( request()->user()->type );
$allowed_roles = array_slice(func_get_args(), 2);
if( in_array($role, $allowed_roles) ) {
return $next($request);
}
throw new AuthenticationException();
}
And in my router file
Route::group(["middleware" => "role:admin,worker"], function() {
});
This might not be the perfect solution, at least it works for me.
Route::middleware(['auth'])->group(function () {
//Routes available to super admin
Route::middleware(['role:SuperAdmin'])->group(function () {
//write route hear
});
//Routes available to SuperAdmin, Admin and Moderator
Route::middleware(['role:SuperAdmin|Admin|Moderator'])->group(function () {
//write route hear
})
});
try this way to define route group of routing. I already use this syntax and it's work.
define auth in parent middleware group and roles defined in the child middleware groupe.
explode the roles in your middleware and check against the available roles
public function handle($request, Closure $next, $role, $permission = null)
{
$roles = is_array($role)
? $role
: explode('|', $role);
if (!$request->user()->hasRole($roles)) {
abort(404);
}
if ($permission !== null && !$request->user()->can($permission)) {
abort(404);
}
return $next($request);
}

Laravel 6 Error: Page not redirecting to the defined route

I've been stuck here for a while. I hope I can clearly explain the issue. I'm trying to have separate pages for admin and user. For that, I have created an admin middleware. Now when I login, it redirects me to the same page either its admin or user. I want it to go to admin dashboard when admin logs in and to the user home when user logs in. I hope the issue is clear.
Here is the AdminMiddleware code:
public function handle($request, Closure $next)
{
if(Auth::user()->user_type == 'admin') //If usertype is admin
{
return $next($request);
}
else {
return redirect('home');
}
}
Here are the routes code:
Route::get('/','HomeController#index');
//For Admin
Route::group(['middleware' => ['auth','admin']], function() {
Route::get('/admin','HomeController#home_page');
Route::get('/users-list', 'UserController#users_list');
});
Here is the HomeController code:
public function index()
{
return view('home', compact('currantWorkspace'));
}
I've added the Middleware path to kernel.php file.
I'll be happy to provide any other details if needed. Any solutions/suggestions will be highly appreciated.
Edit
I've tried this, but still issue.
protected function redirectTo(){
if (Auth::user()->user_type != 'admin') {
return 'admin';
//return redirect('/admin');
}
else {
return 'home';
//return redirect('/');
}
}
I think the redirectTo function is not working, or not checking the if/else conditions
Why don't you create an 'if, else' statement in your login function like:
if(Auth::user()->user_type == "Admin"){
return Redirect::route('dashboard');
}else if(Auth::user()->user_type == "Standard User"){
return Redirect::route('home');
}
Change the route as follows.
Route::get('/','HomeController#index')->name('home');
Route::group(['middleware' => ['auth','admin']], function()
{
Route::get('/admin','HomeController#home_page')->name('admin.home');
Route::get('/users-list', 'UserController#users_list');
});
Change the redirect statement in middleware as
public function handle($request, Closure $next)
{
if(Auth::user()->user_type == 'admin') //If usertype is admin
{
return $next($request);
}
else
{
return redirect()->route('home');
OR
return redirect('/');
}
}
There are a few problems, currently, the key thing is that the middleware you defined is not being called when anyone tries to log in.
To make it work I think you just need to add this to your LoginController.php
protected function authenticated()
{
if (Auth::user()->user_type == 'admin') {
return redirect('dashboard');
}
return redirect('home');
}
This method basically tells laravel what you want to do after the user is logged in.

Restricting Access to Manager users - Laravel 5.5

I am a newbie with Laravel. I am doing a tutorial and i have issues on restricting access to manager users. I have been able to assign roles (manager and members) to my users at the moment. But my issue lies in the Manager Middleware.
If the user is a manager, it doesn't return the $next($request); but instead it routes to /home after authentication and if user isn't a manager, it routes to /home as well instead of /tickets.
There is a file called RedirectIfAuthenticated, i changed the route in there but the issue still remained the same.
So what am i missing to restrict access to my managers?
Manager middleware
public function handle($request, Closure $next)
{
if(!Auth::check())
{
return redirect('/login');
}
else{
$user = Auth::user();
if($user->hasRole('Manager'))
{
return $next($request);
}
else{
redirect('/tickets');
}
}
return $next($request);
}
Routes
Route::group(array('prefix' => 'admin', 'namespace' => 'Admin', 'middleware' =>'manager'), function () {
Route::get('users', 'UsersController#index');
Route::get('users/{id?}/edit', 'UsersController#edit');
Route::post('users/{id?}/edit','UsersController#update');
Route::get('roles', 'RolesController#index');
Route::get('roles/create', 'RolesController#create');
Route::post('roles/create', 'RolesController#store');
});
Just do the following:
in the else part: instead of redirect('/tickets'); use return redirect('/tickets');
i.e. it will become:
public function handle($request, Closure $next)
{
if(!Auth::check())
{
return redirect('/login');
}
else{
$user = Auth::user();
if($user->hasRole('Manager'))
{
return $next($request);
}
else{
return redirect('/tickets');
}
}
return $next($request);
}
That's it

Midedlware class is not working in Laravel 5.3

I have a laravel application in this application i have following function for login user
public function login() {
try {
$inputs = Input::except('_token');
$validator = Validator::make($inputs, User::$login);
if ($validator->fails()) {
return Redirect::to('/')->with('message', 'Please Enter Valid Credentials');
} else {
$respones = \UserHelper::processLogin($inputs);
if ($respones) {
return Redirect::to('/dashboard')->with('success_message', 'Welcome to Tressly Admin Dashboard');
} else {
return Redirect::to('/')->with('message', 'Please Enter Valid Information ');
}
}
} catch (Exception $ex) {
return CommonHelper::AdminExceptions($ex);
}
}
Now as user logout and presses the back button , browser show previous page as it is present in cache. Now on this page as user tries to access any protected route application It shows following error
I want to redirect it to '/'( home route)as logged out user tries to acess any protect routes following error comes
Class App\Illuminate\Auth\Middleware\AdminAuthenticate does not exist
I have made a custom Authentication Middle , handle function of the middleware is
public function handle($request, Closure $next, $guard = null) {
if (Auth::check()) {
return $next($request);
}
return redirect('/');
}
I have also registered it in kernal.php in $routeMiddleware like
'authAdmin' => \Illuminate\Auth\Middleware\AdminAuthenticate::class,
and protected my route like
Route::group(['middleware' => 'authAdmin'], function () {
///routes
});
Any ideas ?
use
'authAdmin' => \App\Http\Middleware\AdminAuthenticate::class,
Instead of
'authAdmin' =>\Illuminate\Auth\Middleware\AdminAuthenticate::class,
I hope it it will work
Is there a reason you made a custom middleware class that does exactly the same thing as the already present 'auth' middleware?
RedirectifAuthenticated.php does this;
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
https://laravel.com/docs/5.3/authentication#protecting-routes

Laravel 5.1 Middleware users types redirections

I am trying to make an app in Laravel 5.1.
In my users table I have 3 types of users, admin, agent and farmer. In the users table there is a column named user_type_id where admin is user_type_id=1, agent is user_type_id=2 and farmer is user_type_id=3.
Admin has permission to do everything where agent has few permission.
Problem is while using middleware, my Authenticate.php and AgentAuthenticate.php middleware files are acting as if they are the same, meaning agent is getting all the powers of admin. is there any logical error? here is the code.
agentAuthenticate.php (middleware)
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('auth/login');
}
}
if(! $this->auth->user()->user_type != 2) {
return redirect()->guest('auth/login');
}
return $next($request);
}
Authenticate.php
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('auth/login');
}
}
if(! $this->auth->user()->user_type != 1) {
return redirect()->guest('auth/login');
}
return $next($request);
}
routes.php
//guest routes
Route::resource('/farmerPoint','farmerPointController',['only' => ['index', 'show']]);
Route::resource('/crop','cropController',['only' => ['index', 'show']]);
//Admin routes
Route::group(['middleware' => 'auth'], function () {
Route::resource('agent','agentController');
Route::resource('farmer','farmerController');
Route::resource('farmer.crop','farmerCropController');
Route::resource('cropType','cropTypeController');
Route::resource('crop','cropController',['except' => ['index','show']]);
Route::resource('farmerPoint','farmerPointController',['except' => ['index','show']]);
Route::get('/AdminPanel',function(){
return view('frontend.AdminPanel');
});
});
//agent routes
Route::group(['middleware' => 'agent'], function () {
Route::resource('farmer','farmerController');
Route::resource('farmer.crop','farmerCropController');
Route::resource('agent','agentController',['only' => ['index','show']]);
Route::get('/AgentPanel',function(){
return view('frontend.AgentPanel');
});
});
In Authenticate.php it should be:
if($this->auth->user()->user_type != 1) {
return redirect()->guest('auth/login');
}
because you want to make redirection for all users with type different than admin
And in agentAuthenticate.php it should be:
if(!in_array($this->auth->user()->user_type, [1,2])) {
return redirect()->guest('auth/login');
}
because you want to make redirection for all users with type different than agent but if user is admin you don't want to make redirection too (you mentioned Admin has permission to do everything)

Categories