how to restrict user from accessing another user's pages by inputing id in url laravel - laravel

I have a web app i'm working on.Users can create patients, which have a unique id. Problem I have is that when another user logs in, he can easily access patients not assigned to him by simply inputing their id in the url. Please how do i solve this? Heres a sample of my route for the
user to view his patient:
Route::get('patients/{patient}/view', 'Portal\PatientController#viewPatient');
and in the Patientcontroller:
public function viewPatient($patient){
$patient = Patient::where('id', $patient)->first();
return view ('portal.patient',compact('patient'));
}
Please what am I doing wrong?

You can use policies for that:
Policies are classes that organize authorization logic around a particular model or resource. For example, if your application is a blog, you may have a Post model and a corresponding PostPolicy to authorize user actions such as creating or updating posts.
Or gates:
Gates are Closures that determine if a user is authorized to perform a given action
I'd use policies, but you also can manually check if a user can view a page with something like:
if (auth()->id() !== $patient) {
return redirect('/')->with('message', 'You can not view this page');
}

You could also keep GET to access to this page without inputing the id. For example, if you want to obtain patients only from the current user logged in :
web.php :
Route::get('patients/view', 'Portal\PatientController#viewPatient');
Patientcontroller :
public function viewPatient(){
$id = auth()->id();
$patient = Patient::where('id', $id)->first();
return view ('portal.patient',compact('patient'));
}
Keep in mind that this will work only with an authenticated user.

If your database table structure is like this
Patients
--------
id //Unique ID of Patient
user_id //User that created
patient
Then you can do the check in controller like.
public function viewPatient($patient)
{
$patient_check = Patient::where('id', $patient)->where('user_id','=',Auth::user()->id)->first();
if($patient_check == null || count($patient_check) == 0)
{
return "You cannot view this patient";
}
else
{
return view ('portal.patient',compact('patient'));
}
}
This is simple and yet does the work.

Related

How to restrict users to use application

I am using laravel framework to develop api’s ,it’s an existing application .there is a requirement if more than 5users registered from 6th user onwards i have to restrict them to use application until they approved by manager or they paid for registration fee then only the user will allow to use the application.
Can anyone give me the idea how to acheive this scenario or suggest me any package in laravel
Solution:
You can add 'status' field in your table. Now when your api is registering a user, you can check the No. of users in the database. If more than or equals to 5, you can set the status to 0. Now show the manager list of user with status 0 and when the status changes you can use the application.
Make sure to add condition where status = 1 when user is getting logged in.
I hope it helps!
Well, you can just put a isApproved column to indicate if the user is already approved or just like the email_verified_at that accepts timestamp as a value then create a middleware where you can check if the user is approved or not. then add a method to the user model to check if the user is approve :
User model
class User extends Authenticatable
{
public function isApproved()
{
// check if the account_approved_at column is not null.
return ! is_null($this->account_approved_at);
}
}
Middleware
class EnsureUserIsApproved
{
public function handle(Request $request, Closure $next)
{
if(! $request->user()->isApproved()) {
// can also use abort(403) instead of redirect
return redirect('route-where-you-want-the-user-to-redirect')
}
return $next($request);
}
}
You can check this for more information about middleware

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

How can I add ask username and password feature to only one of my laravel routes?

I have created a few forms in laravel. I want to restrict access to one of them only to a specific user.
I want to create a user and password myself.
This is my routes excerpt. This is the route I want to protect from access
Route::get('/tabledata_id_title', 'KedivimController#appearanceiddata');
This is my controller excerpt:
public function appearanceiddata()
{
//$magic = DB::table('prog_title')->select('pr_id', 'pr_title')->get();
$magic = DB::table('prog_title')->select('pr_id', 'pr_title')-> where('pr_index', '=', 1)->get();
return view ('takealook', ['magical' => $magic]);
}
This is a short fix for your problem.
public function appearanceiddata()
{
if (!Auth::guard('web')->check()) //check if someone is logged in
{
//redirect to login page.
}
else {
/*Check if the logged in user is your desired user.
Maybe try matching the logged in id with your desired id.
If you find that a user is logged in but they are not your desired user
then you may redirect them in some other place or show them a message. */
}
//$magic = DB::table('prog_title')->select('pr_id', 'pr_title')->get();
$magic = DB::table('prog_title')->select('pr_id', 'pr_title')-> where('pr_index', '=', 1)->get();
return view ('takealook', ['magical' => $magic]);
}
However, this practice is ok if you have one or two restricted field. But if you have more than that then you should read about middleware.

How to give access to views to specific user in laravel?

I have a Category Controller which checks if user is logged in
class CategoryController extends Controller
{
public function __construct() {
$this->middleware('auth');
}
...
My category routes are :
//Category Controller
Route::get('admin/category/{category}/edit', ['uses'=>'categoryController#edit','as'=>'admin.category.edit']);
Route::put('admin/category/{category}', ['uses'=>'categoryController#update','as'=>'admin.category.update']);
Route::get('admin/category/{category}', ['uses'=>'categoryController#show','as'=>'admin.category.show']);
Route::delete('admin/category/{category}', ['uses'=>'categoryController#destroy','as'=>'admin.category.destroy']);
Route::get('admin/category/create', ['uses'=>'categoryController#create','as'=>'admin.category.create']);
Route::get('admin/category', ['uses'=>'categoryController#index','as'=>'admin.category.index']);
Route::post('admin/category', ['uses'=>'categoryController#store','as'=>'admin.category.store']);
Is there a way to give access to these views to only specific user?
For example if user email is admin123#gmail.com then he is allowed to go to those view.
I know I can check like this
if(Auth::user()->email == 'admin123#gmail.com')
{
dd('admin Logged in');
}
But this is possible if i go to individual view and put all my content in the if statement.
Is there way to handle this in controller.
Thanks.
You can use the middlewares for these kinds of work.
From the docs
Middleware provide a convenient mechanism for filtering HTTP requests entering your application. For example, Laravel includes a middleware that verifies the user of your application is authenticated. If the user is not authenticated, the middleware will redirect the user to the login screen. However, if the user is authenticated, the middleware will allow the request to proceed further into the application.
You should restrict users by route groups. Use middleware for that.
However, if you have complicated logic, sometimes you may want to check if user is admin in controller, model and other classes. In this case you can create global helper isAdmin() and use it for simple checks. Examples:
if (isAdmin()) {
// Do something
}
{{ isAdmin() ? 'active' : '' }}
A better way to define user role is like 0 for admin, 1 for user, 2 for member.
Then you can check the user role like:
if(Auth::check())
{
if(Auth::User()->user_type == 0)
{
return view('admin_dashboard');
}
else if(Auth::User()->user_type == 1)
{
return view('user_dashboard');
}
else if(Auth::User()->user_type == 2)
{
return view('member_dashboard');
}
}

Codeigniter securing certain pages based on user account

I am developing a system whereby a user is a member of a Client account. There are 5 or 6 clients, and each client has a number of users. When a user logs in, the site is styled to the client they are a member of.
I have a function "view_campaign":
function view_campaign($campaignID = FALSE){
$this->load->model('client_model');
$this->load->model('campaign_model');
$data['main_content'] = 'campaign_overview';
$this->load->view('includes/template', $data);
}
So in the URL for example we have .../campaign/view_campaign/21 (for example). This will mean that the user gets to their campaign which has an ID of 21.
But how can I make it so it's secure i.e. users that are members of another client cant view the campaign? They could just change the URL and view campaigns related to other clients...
Thanks
Quite a broad question, I'm not sure what your database structure is but you want to do something like...
When the user first logs in you want to save their user ID and their client ID in a session. Then you want to have a function in your campaign model that gets the client ID a campaign belongs to.
Your view_campaign function would look something like
function view_campaign($campaignID = FALSE) {
$this->load->model('client_model');
$this->load->model('campaign_model');
//Get the user ID and client ID from a session or something
$userId = $this->session->userdata('userId');
$clientId = $this->session->userdata('clientId');
//Call a function in your model to see if the user belongs to the client
$campaignClientId = $this->campaign_model->getClient($campaignID )
//If the client ID the campaign belongs to matches the client ID the user
//belongs to then they can view it
if($campaignClientId === $clientId ) {
$data['main_content'] = 'campaign_overview';
$this->load->view('includes/template', $data);
} else {
//Redirect to another page
}
}

Resources