Laravel scope query only for users - exclude result for admin - laravel

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.

Related

How to update a user using the 'Ion Auth' authentication library in CodeIgniter 4 framework

Below is my code snippet. I want to reduce the balance of a user in the database using Codeigniter 4?
dd($this->ionAuth->update($this->ionAuth->users()->row()->id, ['balance' => 1000]));
*I'm using Ion Auth for updating.
It's just a big burden when updating the database using modelling data.
It looks like you intend to use $this->ion_auth->user() instead of $this->ion_auth->users().
Also keep in mind that executing a dump and die on $this->ion_auth->update(...) returns a boolean not the updated user data.
References:
users() gets all users.
users()
Get the users.
Parameters
'Group IDs, group names, or group IDs and names' - array OPTIONAL. If an array of group ids, of group names, or of group ids and names are passed (or a single group id or name) this will return the users in those groups.
Usage
$users = $this->ion_auth->users()->result(); // get all users
user() gets a single user.
user()
Get a user.
Parameters
'Id' - integer OPTIONAL. If a user id is not passed the id of the currently logged in user will be used.
Usage
$user = $this->ion_auth->user()->row();
echo $user->email;
look here authentcate library for ci4
https://github.com/lonnieezell/myth-auth
go there download it
ionAuth is not compablitablke with ci4

Laravel: Check if the field was filled in the route, using Trait and Scope

I have an api that I am implementing multi-tenant based on an additional column in the tables.
For this I created a trait that implements a
static::addGlobalScope() and static::creating().
I have a user_idXtenant_id table. In this table I store the accesses that the user has.
My Route looks like this:
Route::get('{tenant_id}/products', function ($tenant_id) {
return App\Products::where(['tenant_id' => $tenant_id])->get();
})->middleware('role_or_permission:admin|seller|get-products');
Route::get('products', function () {
return App\Products::get();
})->middleware('role_or_permission:admin|seller|get-products');
The idea is that in the first route it is verified if the user has access to tenant_id and if he has access, return only the products of that tenant_id (here Polices can be useful and solve the problem).
The second route, on the other hand, must return all products of all tenant_id that the user has access to. For this, I use static :: addGlobalScope() to set the tenants that the user has access to in this way:
$builder->whereIn('tenant_id', $tenants);
The question is how to check in GlobalScope if tenant_id was filled in the model. So, if it is present, I only check the permission and if it is not present I include the tenant_id that the user has access to.
I hope I have been able to adequately exemplify the problem.
Any help is most welcome.
Thank you!

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.

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.

Retrieve selected keys from database from relations

I am using laravel 4 and I have to retrieve registrations and all users associated with that registrations but user table has lot more keys but I only need 3 keys so how can I get selected keys. I know laravel provide select method but its not working on relations.
Registration::where('section_id', '=', $key->id)
->with('user')
->select('users.id', 'users.name')
->get();
I tried users and user but nothing works. Could someone please post correct way to load this query.
Edit:
- Registration has one user
- Registrations has one section
I have registration table that contains section id and user id. I want to get all users, signed up for particular section. So this is very simple query and its working fine only problem is retrieving selected keys from database.
In your Registration model change your relation to this
public function user()
{
return $this->hasOne('User')->select('id','name');
}
And in your controller write this
Registration::where('section_id', '=', $key->id)->with('user')->get();
Hope this work for you.

Resources