Codeigniter securing certain pages based on user account - codeigniter

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
}
}

Related

How to Send User back to intended page in Laravel

I am building a Laravel App where people can read Books.
I have middleware, that control access to the Book
public function handle($request, Closure $next)
{
if (!(auth()->user()->isBasic() || auth()->user()->isCouple() || auth()->user()->isFamily())) {
return redirect(route('subscription-plan'));
}
return $next($request);
}
Inweb.php
To see the book and the details of the book
Route::get('/books/{book}', [BooksController::class, 'show'])->name('book')->middleware('verified');;
To read the book
Route::middleware(['basic'])->group(function (){
Route::get('/read/{book_id}', [BooksController::class, 'read'])->name('read');
});
I have 3 roles
Basic
Couple
Family
Subscriber
If the logged-in user is a subscriber, it redirects to /subscription-plan when he tried to access Read.
After subscription, I want to be able to redirect after subscription to the book I was trying to read before I was redirected to /subscription-plan.
I was researching how to use intended
redirect($this->redirectPath());
redirect()->intended($this->redirectPath());
But none of them is working.
Here is my final code
public function handleGatewayCallback()
{
...
redirect()->intended();
}
Not sure what are you doing on the subscription page.
Just thinking that the user will leave the app complete the payment externally "paypal" and the payment processor will redirect the user back to your system on your fallback url , on success or not.
If this is your case I don't think intended will work for you..
My suggestion is to use session and store the URL where you want to return the user after he has completed the payment on the subscription page.
Exmaple:
Store session key:
$request->session()->put('url_on_success', '/url-on-success');
Get the stored session:
$url = $request->session()->get('url_on_success');
Check : https://laravel.com/docs/6.x/session for more how to use sessions on Laravel.

How do I allow a 3rd party (twilio) access to current user account in laravel

I am making an application using laravel and twilio that gets feedback about student performance. The logic as follows.
A user, in my case the Student(called resident) logs in and uses a
web page form to send an eval request to a teacher (called
attending). This step starts a session and saves teacher info and
student info.
A random question is picked from a database and saved to the session.
The phone number of the teacher is pulled from a database and the random question is pulled from session and sent to the teacher on SMS using twilio.
The teacher responds with yes, no, or DNS (did not see) via Twilio SMS.
The teacher's response along with the student name, the teacher name and the question asked are saved to a database.
My application works up until step 5. The problem is that a new session is being started when the teacher responds via SMS. So everything after the response is saved to a new session. I can't get access to the original session. I think I need a way to automatically grant the teacher access to the student(ie. user's account). This seems to be a problem with it being a 3rd party application. Can this be done or is there another way to accomplish this?
Below is the code I am using for the response. It is not able to access the session that contains the residentName, the firstQuestion, or the attending_name data. It puts null for those values and uploads null to the database. How do I get access to the initial session in this situation?
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Session;
use Twilio\Rest\Client;
use Twilio\Twiml;
use App\Question;
use App\Answer;
class AskFirstQuestionsController extends Controller
{
public function qOneResponse(Request $request) {
$responderNumber = $request->input('From');
session()->put('responderNumber', $responderNumber);
session()->save();
$responderAnswer = strtolower($request->input('Body'));
$residentName = session::get('residentName');
$firstQuestion = session::get('first_question');
$attending_name = session::get('attending_name');
if (strpos($responderAnswer, 'yes') !== false) {
$answer = new
Answer(['attending'=>$attending_name,'resident_name'=>$residentName,'question_body'
=>$firstQuestion, 'answer_yes'=>1]);
$answer->save();
$smsResponse = "Great! Please help us reinforce this action by providing specific feedback
to the resident about what they did. Thank You for teaching!";
} else if (strpos($responderAnswer, 'no') !== false) {
$answer = new
answer::create(['attending'=>$attending_name,'resident_name'=>$resident_name,'question_body'
=>$firstQuestion, 'answer_no'=>1]);
$answer->save();
$smsResponse = "Ugh, ok...we will work on this. If you feel comfortable, please help us by
providing specific feedback to the resident about what they need to work on. Thank You for
teaching!";
} else if (strpos($responderAnswer, 'dns') !== false) {
$answer = new
answer::create(['attending'=>$attending_name,'resident_name'=>$resident_name,'question_body'
=>$firstQuestion, 'answer_dns'=>1]);
$answer->save();
$smsResponse = "How about trying a different question?";
} else {
$smsResponse = 'Please answer yes, no or dns.';
}
return response($this->respond($smsResponse))->header('Content-Type', 'application/xml');
}
public function respond($smsResponse) {
//get responderNumber and use it below
$responderNumber = session::get('responderNumber');
$response = new Twiml();
$response->message($smsResponse, ['to' => $responderNumber]);
return $response;
}
Do I need to do some type of multiauth approach and somehow grant the teacher automatic access to the student's account (user account)? Or do I have to re-write the logic so that the response-request lifecycle closes and then try to write to the database (maybe it will then use the original session data?)? Or is there a simpler way? Please help. I have been stuck for more than a week.
Twilio developer evangelist here.
I'm not a Laravel developer, but session objects in web application frameworks like this are normally tied to a cookie that either stores the contents of the session or an ID for the session which points to the contents in a database in order to add state to a user's session within a browser.
When Twilio receives an incoming SMS message the webhook that is sent to your server is not connected to the browser session that the user is part of, so you cannot access the same data.
Instead of using the session, you should store this as part of your actual database so that you can look up the details from the database when you receive the SMS.

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.

difference between two magento login checking code

I have used two kind of code which check user is logged in (not guest, registered user) or not.
The following are the two source codes.
(1)
$customer = Mage::getSingleton('customer/session')->getCustomer();
$customerId = Mage::getModel('customer/session')->getCustomerId();
if( !$customer || !$customerId ) {
//user is logout
}
else{
//user is logged-in
}
(2)
if( !Mage::getSingleton('customer/session')->isLoggedIn() )
{
//user is logged-in
}
I want to know both source codes are doing same thing.
Are both codes certainly checking only registered customer is logged-in or not.
Because i want to reject unregistered(guest user) user from accessing next block.
This is the correct method to check whether customer logged-in or not.
if( !Mage::getSingleton('customer/session')->isLoggedIn() )
{
//user is logged-in
}
The above code is magento inbuilt function to check whether customer logged-in or not.
But the below code is used to get logged-in customer id.
$customerId = Mage::getModel('customer/session')->getCustomerId();
If the customer logged-in then it will return the customer id, otherwise return null. So don't use this for check customer logged-in.

how to restrict user from accessing another user's pages by inputing id in url 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.

Resources