laravel dropdown value restriction based on roles - laravel

I have status select box with option New,Re-new,Delete . have roles admin,student,teacher. Now for admin all three select option can list where as for student and teacher I want to hide Delete option from dropdown.
How to do it in laravel ? Can it be a part of validation rule ? or I have to generate with if n else. For role and permission I am using entrust and confide.
{{Former::select('status'->options(Subject::getAllowedoption('status'))}}
in model class under $rule I have the option defined New|Re-new|Delete and I am trying to find a way to restrict option Delete for role teacher.

Related

Laravel scope query only for users - exclude result for admin

I am very new into programming and trying to make some work on Laravel / Voyager.
I have a Customers table and on this table there is also Customer_Representative field where I can select / assign customer representatives from dropdown list.
What I am trying to achieve is I want each users with their assigned roles (Customer Representative) to list customers only assigned for them.
I am using this below code, but I am not able to see list of customers that other users created. I can only see the customers I / Admin created but If I login with their details I can see their assigned customers.
So as an admin I want to be able to see all customers, so I can also edit them with my login credentials.
public function scopeCurrentUser($query)
{
return $query->where('Customer_Representative', Auth::user()->id);
}
I saw many suggested to use if but I couldn't figure out how to do it.
Appreciate your supports !
If I understand correctly, you want to display:
admin users - all users
non-admin users - only assigned users
You can either change the query in controller, but if you want to do it in scope I suggest something like this:
public function scopeCurrentUser($query)
{
return $query->when(auth()->user()->is_not_admin, function ($q) {
$q->where('Customer_Representative', auth()->user()->id)
});
}
You change the auth()->user()->is_not_admin to your condition for non-admin validation. The scope utilizes the ->when() function to append the condition to query only if the condition (in this case if authenticated user is not an admin) is true.
So if authenticated user is not an admin, his query will be filtered by Customer_Representative.

Idiomatic way in Laravel to manage permissions with field level specificity

I am new to Laravel and I want to make data in my database available via RESTFUL API. I need to control permissions of data objects with field level specificity. I was curious what is the idiomatic way to do this in Laravel?
For example, I will have a database table called PrintMachine that has the fields Id,MachineName,ActivityStatus,ManufacturingYear. I want to assign the following permissions:
Web Administrators get Read and Edit access to all records and all fields in PrintMachine
Factory Managers get Read and Edit access to the PrintMachine.MachineName and PrintMachine.ActivityStatus fields for all records and get no access to any other fields in PrintMachine.
Floor Operators get Read access to the PrintMachine.MachineName field for all records and get no access to any other fields in PrintMachine.
People told me to consider Spatie Module and also read Gates and Policies, but it's not clear how either achieves field level permissions on their own.
The other option I was considering was to custom create my own solution by:
for GET requests, create three ViewModels called PrintMachineAdmin,PrintMachineManager,PrintMachineOperator, each class with properties accessible to the corresponding roles.
for POST/PUT requests, I'll have to write my own conditional statements to validate data based on the users roles
Is there a more idiomatic way to develop the a feature for field level permissions for restful apis?
So many options. An implementation of role and permission structure can achieve this and you can most certainly do this via the Spatie Module.
Eg adapted from spatie documentation:
$role = Role::create(['name' => 'Manager']); //db has roles table
//or if already created
//$role = Role::where('name', 'Manager')->first();
$permission = Permission::create(['name' => 'edit PrintMachine.MachineName']); //db permissions table
$role->givePermissionTo($permission); //now manager role has been assigned permission to edit machine name.
//assigning role to user
$user = User::create(['name'=> 'Manager User']); //or get existing
$user->assigneRole($role); //now this user has edit access to machine name
//to see if user has access
if( $user->hasPermissionTo('edit PrintMachine.MachineName') )
//do efit
//OR if you want to check using role
if( $user->hasRole('Manager')
//do manager stuff
//and in view you can use #can blade directive
#can( 'edit PrintMachine.MachineName' )
//authenticated user can edit machine name //show edit button/form
#endcan
//similarly #role directive will do the check using role
For super admins in AuthServiceProvider's boot method.
Gate::before(function ($user, $ability) {
return $user->hasRole('Super Admin') ? true : null;
});
Gate's before method precedes all other gate operations so all other permissions can be overridden here.

How to add 'OR' condition to call middleware on Laravel Routes?

I want to add 'OR' condition with middleware on laravel routes for Role and Permission. Can anyone please help me here. Below is the code which I am trying currently through some internet research but it is not working.
Route::get('get-all-users', 'API\Admin\AdminController#get_all_users')->middleware(['role:admin' OR 'permission:view.all.users']);
In this scenario, you will need to change the DB structure a bit. Tables would look like:
Actions
Roles
Role_action_mapping => This will have foreign keys of both the above tables as a many to many relationship.
Now, every action should have a role assigned to it. So, the permission view.all.users will have an entry in the table with admin(or any desired role) assigned to it by it's side in Role_action_mapping.
So all you will have to do is have a single middleware say permission:view.all.users on the route and just check if the current role of the user has an entry with view.all.users in the Role_action_mapping table.

Laravel User will have difference Role base on Project Model

I have Model name Project and User by using laravel relationship.
- project and user using many to many relationship.
What i want is using laravel authentication giving roles to the user base on project.
Which mean :
user "Ali" have role "admin" in project "project a" ,
but in project "project b" the user "Ali" role is "member".
How can i implement it?
Problem fixed :
My solution is add additional data inside the project_users pivot table store as string role.
When create new project and add with additional data using :
$user->projects()->save($project, ['role' => 'Manager']);
When need to call it :
$user_role = $user->projects()->where('user_id', $user['id'])->first()->pivot->role;
It will return a string 'Manager'
and use it to assign the role.
$user->syncRoles($user_role);
Look at the following links which will help you to achieve it.
https://github.com/spatie/laravel-permission
https://www.itsolutionstuff.com/post/laravel-56-user-roles-and-permissions-acl-using-spatie-tutorialexample.html
You can add the Role data e.g. role_id with a separate Role table or just role in Project To User Pivot Table project_users and retrieve the role info from this relationship.
Check out this Saving Additional Data On A Pivot Table section at Update Many To Many Relationship Laravel Documentation.

Show particular data in dropdown

How to exclude database row from the select menu ? For example: The admin can create user and append roles to them. The available roles are dev, admin, normal user. But the admin user have to see only the admin and normal user roles. I know I can add them in the BREAD menu but I want to restrict the vision on dev role and when another roles are added to show them automaticaly and not to add them on by one in the BREAD menu.
The simplest solution is to filter the set of roles pulled from the database. Since I am not familiar with your database schema, here is a rough solution that you should be able to tweak to your needs
$rolesQuery = Role::newQuery();
if (Auth::user()->is_admin) {
$rolesQuery->where('role', '!=', 'dev');
}
$roles = $rolesQuery->get();
You can cache this result for admins for future use.

Resources