Using Auth to get the role of user in a pivot table - laravel

I have the following database structure a users & roles table joined using a pivot table:
The users table contains all the info such as email and password, while the roles table defines the different roles :
roles table
1 -> admin
2 -> encoder
3 -> salesman
4 -> tech
Now the roles are defined many-to-many because, there are some encoders that are assigned also as an admin. Others may have an salesman+admin role, or even encoder+salesman. Basically it multiple roles can be assigned to someone.
Table Structure
users
id
email
roles
id
role
role_user
id
role_id
user_id
I know that if I do
$user = User::find(1)->email;
return $user;
the result would display the email of the user with ID 1.
I was trying to do $user = Auth::user()->roles; so that it will get the role of the currently authenticated user.
But doing so returns a JSON which displays all the roles the user is assigned to.
I was hoping to use this in a filter, to do something like this
$user=Auth::user()->roles;
if($user == 'admin')
{
//do something
}
else
{
//you are not an admin
}
if($user == 'encoder')
{
//do something
}
else
{
//you are not an encoder
}

Just a small fix for the code at the bottom:
public function hasRole($role = null) {
$hasRole = false;
$hasRole = !$this->roles->filter(function($item) use ($role) {
return $item->name == $role;
})->isEmpty();
return $hasRole;
}
#lozadaOmr: You have to add "use"!

Since it is a many-to-many relationship so you are getting a collection in the $user when you use following code:
$user = Auth::user()->roles;
So, you need to loop all the Role models and have to check if($someUser->role == 'admin') within the loop and in this case you may do it like this:
$roles = Auth::user()->roles;
$isAdmin = false;
$isAdmin = !$roles->filter(function($role) {
return $role->role == 'admin';
})->isEmpty();
if($isAdmin) {
// admin...
}
Also you may add a method in your User model like this:
// User model
public function isAdmin()
{
$isAdmin = false;
$isAdmin = !$this->roles->filter(function($item) {
return $item->role == 'admin';
})->isEmpty();
return $isAdmin;
}
So you can use:
if(Auth::user()->isAdmin()) {
// admin...
}
Update: Check any role:
public function hasRole($role = null)
{
$hasRole = false;
$hasRole = !$this->roles->filter(function($item) {
return $item->role == $role;
})->isEmpty();
return $hasRole;
}
Now you can use:
if(Auth::user()->hasRole('encoder')) {
//...
}

Related

How can I search for a user who has 2 roles with Spatie Laravel-permission?

I'm working with Laravel, currently I'm only focused on permissions and I need to validate that if a user has the role of Seller and Administrator they will list all the sellers, in case they don't, just list a project.
I've tried to create my own functions but I always fall into True and only allow me to validate 1 role no more
public function isSeller(){
foreach (Auth::user()->getRoleNames() as $role) {
if ($role == 'vendedor') {
return true;
} else {
return false;
}
}
}
If in the previous query within if I put && $role == 'admin' it will always return true even if the user does not have the role.
You can directly check as given below, it will return true if user has role seller or admin
Auth::user()->hasRole('seller','admin')
If you want to check user has both roles then
Auth::user()->hasAllRoles('seller','admin')

Restrict some users to update or view other users data in Laravel

I have users with role manager, and I only want them to update or view other users(employee) data that belong in the same department as the manager user. If the manager user is not in the same department as the user he's trying to update it should redirect the back.
i.e., the manager might try to change the user id in the URL, and I want to deny access to if that user belongs in another department.
I have all my roles and permissions set up.
The Department field is in USER TABLE
public function show($id)
{
$team = User::where('id', $id)->with('roles')->first();
return view('backend.user.team.show', compact('team'));
}
public function edit($id)
{
$user_roles = Role::all();
$team = User::find($id);
$business = Business::all();
return view('backend.user.team.edit', compact('team', 'user_roles', 'business'))->with('user', auth()->user());
}
You should use policies and gates.
Take a look at the documentation:
Writing policies
Writing gates
Basically, you should do something like this:
Create a policy to handle your user permissions:
php artisan make:policy UsersPolicy
This command will create a UsersPolicy file within the App/policies/ directory.
Open the UsersPolicy file and create a checkUserDepartament within that file:
public function checkUserDepartament(User $user, User $userToBeManaged)
{
return $user->departament === $userToBeManaged->departament;
}
The function above return true if the current logged in user departament is the same of the user you want to edit. Otherwise, return false.
Within your AuthServiceProvide:
Gate::define('user-belongs-to-same-departament', 'App\Policies\UsersPolicy#checkUserDepartament');
To use the Gate, do something like this within your controller:
use Gate; //At the top of the controller.
// I assume that $id is the id of the user you want to edit.
public function edit($id)
{
if(Gate::allows('user-belongs-to-same-departament', User::find($id))){
$user_roles = Role::all();
$team = User::find($id);
$business = Business::all();
return view('backend.user.team.edit', compact('team', 'user_roles', 'business'))->with('user', auth()->user());
}else {
return response('Unauthorized', 401);
}
}
Hope it helps.

returning value from a function in middleware in laravel

i've a function in my admin model which has connected to role model by many to many relationship. i created a middleware to check the roles of admins and redirect them to their dashboard, but i'm not sure it is returning the correct value. here is the way i'm checking -> Auth::check() && Auth::user()->role(). i mean the role() method is returning the role_id but how to check it ? like Auth::check() && Auth::user()->role()->role_id == 1, though this is not a correct way
You can create a function in your User(or Admin whichever is authenticatable) Model :
<?php
public function hasRoles(array $roles)
{
return $this->roles()->whereIn('role_id', [$roles])->exists();
}
// Then you can check using ids
const ADMIN_ROLE = 1;
const OTHER_ROLE = 2;
if(Auth::user() && Auth::user()->hasRoles([self::ADMIN_ROLE, self::OTHER_ROLE])){
// Current user is either admin or other role
}
If you have name of a role then you can use that instead of ids as well.
Here is the better way.
In user model, write a function something like this .
public function hasRole( ... $roles ) {
foreach ($roles as $role) {
if ($this->roles->contains('column_name', $role)) {
return true;
}
}
return false;
}
in middleware, you'd write something like this
if(Auth::user() && Auth::user()->hasRole("admin", "moderator)){
return $next($request);
}
This way you'd not check for ids , because ids might change.

how to pass session variable into view using laravel4

I want to pass logged in id into my view page.i got the id in the function of user_login_submits.
Actually i want to get the id in one more function in the same controller.
how to get the session id in controller..
Normally session put its enough i did like that.
Here is my code anyone can check and tel me what need to change here
Controller
public function user_login_submits()
{
$inputs = Input::all();
$uname = Input::get('username');
$password = Input::get('password');
$logincheck=Userlogin::login_checks($uname,$password);
if($logincheck == 1)
{
$id=Session::get('customer_id');
return Redirect::to('businessprio/create_news?p=1');
}
else if($logincheck == 0)
{
//echo "fail";
return Redirect::to('businessprio/create');
}
}
Model
public static function login_checks($uname,$password)
{
$check = DB::table('customer_login')
->where('username','=',$uname)
->where('password','=',$password)->get();
if($check)
{
//Session::put(['customer_id'=>'value']);
Session::put('customer_id', $check[0]->customer_id);
Session::put('username', $check[0]->username);
return 1;
}
else
{
return 0;
}
}
I won't pass it to model, instead i would do it in controller itself,
public function user_login_submits()
{
$uname = Input::get('username');
$password = Input::get('password');
$check = DB::table('customer_login')
->where('username','=',$uname)
->where('password','=',$password)->count();
if($check==1)
{
$id=Session::get('customer_id');
return Redirect::to('businessprio/create_news?p=1');
}
else
{
return Redirect::to('businessprio/create');
}
}
Recommendation :
But i would strongly recommend you to do it by Auth::attempt i.e., to follow the clean one
public function user_login_submits()
{
if (Auth::attempt(['email' => $userEmail, 'password' => $userPassword])) {
return Redirect::to('businessprio/create_news?p=1');
}
else
{
return Redirect::to('businessprio/create');
}
}
If you do so, then you can access the Default checking for authenticated user
Auth::check()
Get the Logged in user details by
Auth::user()->id
Auth::user()->username
Note : To use default Auth::attempt you should use the User Model too.

Laravel 4 - Display a different view depending on a value in user database

I'm trying to display a profile View depending if a user has activated their account - i.e. active = 1 (or 0 for inactive)
If the user has activated their account show a View with users details of if they haven't display a different View saying they need to activate their account.
This is the code I am having trouble with:
public function user($username) {
// Get the /username from URL and check the database
$user = User::where('username', '=', $username);
// If /username does exist
if($user->count()->('active', '=', 1)) {
// Grab user info from database
$user = $user->first();
// return the active user view
return View::make('profile.active-user')->with('user', $user);
} else {
// Grab user info from database
$user = $user->first();
// return the inactive view
return View::make('profile.inactive-user')->with('user', $user);
}
return App::abort(404); // else throw a 404
}
Any help/logic would be really appreciated.
Thanks, Jack.
You can simplify it a bit by combining the eloquent query and 404. Also you already have your user object after the query so no need for extra eloquent stuff:
public function user($username) {
//get user from db, if no result throw not found (404)
$user = User::where('username', '=', $username)->firstOrFail();
if($user->active) {
// return the active user view
return View::make('profile.active-user')->with('user', $user);
} else {
// return the inactive view
return View::make('profile.inactive-user')->with('user', $user);
}
}

Resources