I am currently building a job portal application using laravel 10.x. There will be two types of user roles who will be using the application:
- Employer
- Candidate
For permissions, I am using [spatie's permission package][1].
As per the requirements of the project, Employers can create jobs. Candidates can see all jobs but the employer will only be able to see the job he has created.
I have two approaches to build the above restriction:
- Using [Spatie's wildcard permissions][1] to achieve this where I can add
jobs.*.{user_id}
so that the permission is added in the spatie module and I have all permission related logic at one place
when the job is created, I will write the code to give permission to the employer to the job by doing:
$employer->givePermissionTo('jobs.*.'.$job_id)
and then validate whether the employer has the permission to view the job by checking
$user->can('job.view');
OR
Have a middleware to check the user type is employer and the one who created this job matches the user_id of the currently logged in user?
if($user->type == 'employer' && $job->employer_user_id != Auth::user()->id || $user->can('job.view');) abort('You do not have access to this job');
Which approach is the ideal solution?
Yes wildcard permissions can work perfectly. I think the middleware route makes it easier because you just have to remember to add the middleware to the routes. You can combine it with what you wanted to do. But if you give permission to an employer, I am not sure if the employer model is the same as the user model because if you give permission to the employer with
$employer->givePermissionTo('jobs.*.'.$job_id)
, doing$user->can('job.view');
does not check that the employer can view the job, if the employer is the same as the user, then you can check the permission instead with$user->can('job.view.1')
, where "1" is the job id.As an alternative, you can also try this.
You can consider using model policies for this use case.
Say, you have a Job model policy,
JobPolicy
view any jobs
permission to both candidate and employer role. This will allow both employer and candidate to view any jobs which should be ok as they both need to be able to view all jobs**. For the employer, what you can do is say, in the index method or the method where you list all jobs for the employer, you can filter with something likeJob::where('user_id', auth()->id())
to make sure the employer only sees jobs they created.viewAny
in yourJobPolicy
, you can have a logic like:view
in yourJobPolicy
, you can then have a logic that only allows an employer to view a job if they own the job.