Laravel Nova show Dashboard based on Role - laravel

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

Related

Laravel check if user belongs to certain company before login

I'm developing an application to help companies manage its products.
First, the company should register itself to the app with an active admin user. The new registered company is not active by default.
I want to check if the user company active before logging in.
For example:
I want to register Nike to the app . the registered user is admin#nike.com
if I want to login with "admin#nike.com", it should not be possible till Nike company become active.
Database structure is like this:
Company:
com_id
com_name
com_isActive
User:
user_id
user_name
email
password
user_isAdmin
user_com_id
Any suggestions how to fix it?
Probably you have relation in your User model. Something like
public function company()
{
return $this->belongsTo(Company::class);
}
In your LoginController (if you want it only there) or in some middleware you can check request()->user()->company()->is_active and do whatever you need. RedirectIfAuthenticated middleware is a variant if you don't want to make new middleware
1.First add column to the company table called isActive and adminEmail
2.Make a new Validation Rule called CheckCompanyStatus by this command
php artisan make:rule CheckCompanyStatus
3.Inside this rule put the following logic inside passes()
$data = \Company::where('adminEmail',$value)->first();
if($data->isActive == true) {
return true;
} else {
return false;
}
Go to LoginController and override the function validateLogin() and put this logic
protected function validateLogin(Request $request)
{
$this->validate(['email'=>new \CheckCompany, 'password'=>
'required]);
}
Make sure to add adminEmail and isActive in your company registration form as well
and use all the classes at the top
Let me know if u have any errors

php laravel preventing multiple logins of a user from different devices/browser tabs at a given time

Does laravel provide a way to prevent multiple logins of a user from different devices / browsers at a given time? If yes then how can i force a user to logged in from a single device at a single time. I am developing a online quiz app using laravel 5.6 where users can logged in from a single place and take test.
laravel provide this method to invalidating and "logging out" a user's sessions that are active on other devices logoutOtherDevices()
to work with this method you need also to make sure that the
Illuminate\Session\Middleware\AuthenticateSession
middleware is present and un-commented in your app/Http/Kernel.php class' web middleware group:
'web' => [
// ...
\Illuminate\Session\Middleware\AuthenticateSession::class,
// ...
],
then you can use it like this
use Illuminate\Support\Facades\Auth;
Auth::logoutOtherDevices($password);
Perhaps this should get you started:
Add a column in users_table.php
$table->boolean('is_logged_in')->default(false);
When a user logs in: LoginController.php
public function postLogin()
{
// your validation
// authentication check
// if authenticated, update the is_logged_in attribute to true in users table
auth()->user()->update(['is_logged_in' => true]);
// redirect...
}
Now, whenever a user tries to login from another browser or device, it should check if that user is already logged in. So, again in LoginController.php
public function index()
{
if (auth()->check() && auth()->user()->is_logged_in == true) {
// your error logic or redirect
}
return view('path.to.login');
}
When a user logs out: LogoutController.php
public function logout()
{
auth()->user()->update(['is_logged_in' => false]);
auth()->logout();
// redirect to login page...
}

Controller constructor to check Auth middleware for two different guards

I have a dashboard view that shows certain contain depending on which user is viewing, whether it be an admin or just a regular user.
I can get my admins onto that page, but regular users aren't able to currently because of my middleware guard.
class DashboardController extends Controller {
public function __construct()
{
$this->middleware('auth:admin');
}
public function index()
{
return view('dashboard.index');
}
}
The following code checks on each DashboardController call for auth:admins, but I want regular users to access this too, is there a way to check the auth middleware twice like so?
$this->middleware(['auth:admin','auth']);
So ideally it will check if you're an admin or just a regular auth user.
Also on my view page, when accessing properties of an admin I'm using:
{{ Auth::user()->admin_username }}
Is this normal? I have an admin Model but I'm still accessing it via Auth::user() which feels strange to me, shouldn't it be Auth::admin()->admin_username
Accessing a particular page for users with differing roles is more suited for laravels gates and policy authorization mechanisms.
https://laravel.com/docs/5.5/authorization#writing-gates
These allow you to write fine tuned rules for each use case you have. Simple gates can be defined as closures within your application AuthServiceProvider. For example:
public function boot()
{
$this->registerPolicies();
Gate::define('access-dashboard', function ($user, $post) {
return auth()->check() && (auth()->user()->hasRole('admin') || auth()->user()->hasRole('regular'));
});
}
Then you can use the gate facade wherever necessary, for instance a controller method or constructor.
if (Gate::allows('access-dashboard', $model)) {
// The current user can access dashboard, load their data
}
Alternatively use the can or cant helpers on the user model directly.
if (auth()->user()->can('access-dashboard')) {
//
}
Of course, you can achieve similar via middleware, the advantage of using the above is you can authorize actions at specific points in your code as well as reusability.
As for for last question, as you have it written is correct.
{{ Auth::user()->admin_username }}
Auth::user() or auth()->user() simply returns the currently authenticated user, regardless of their role.
Policies will never work without auth middleware

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!');

Workflow of role/permission based content filtering using Entrust 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 !!

Resources