Laravel Http Client 419 unknown status - laravel

For testing reasons, I want to make the following Post Request with the Laravel HTTP Client:
$test = Http::post(route('users.leads.store', ['user' => $user->id]), [
"company_name" => "TESTCOMPANY",
"zip" => "49685",
"city" => "BÜHREN",
"street" => "MÜHLENKAMP 3",
"contact_name" => "FABIANLUKASSEN",
"phone1" => "017691443785",
"email" => "FABIANLUKASSEN#TESTEN.DE",
"website" => "www.fabianlukassen.de",
"category" => "Hotel",
"closed_until" => now(),
"appointment_end" => now()->addDays(1),
"appointment_comment" => "HALLO ICH BIN FABIAN",
"additional_contacts" => "",
"phone2" => "",
"sub_category" => "",
"expert_status" => 0
]);
I know that the route is working just fine. However, with debugging in phpStorm, I can see that the $test variable contains a 419 error (unknown status). Does anyone know what's wrong?
(I'm using laravel 8)

I agree with #ElektaKode that the issue is likely due to lack of csrf token.
In order to disable CSRF middleware while testing,
switch off CSRF token for this route at /app/Http/Midddleware/VerifyCsrfToken.php, by updating:
protected $except = [ 'your-route-url' ];
Then you can use api authentication to follow it up.
The simplest way to use api authentication, follow this doc,
The other ways are either using Laravel passport or using jwt for api.(both will consume more time to set up, as you are using for testing using api authentication is your go to method.)

Usually in Laravel, 419 Page Expired error comes from CSRF middleware meaning there was a failure while validating CSRF token. Add your CSRF token to your test request or consider disabling CSRF middleware while testing.

Post Request with Laravels HTTP Client
$test = Http::post(route('users.leads.store', ['user' => $user->id]), [
"company_name" => "TESTCOMPANY",
"place_id" => null,
"street" => "MÜHLENKAMP 3",
"zip" => "49685",
"city" => "BÜHREN",
"title" => null,
"contact_name" => "FABIANLUKASSEN",
"additional_contacts" => null,
"phone1" => "+49 163 3006603",
"phone2" => null,
"email" => "FABIANLUKASSEN#TESTEN.DE",
"category" => "Hotel",
"sub_category" => null,
"website" => "www.fabianlukassen.de",
"status" => 1,
"expert_status" => 0,
"coordinates" => null,
"expert_id" => 1,
"agent_id" => null,
"blocked" => 0,
"important_note" => null,
]);
Route
Route::apiResource('users.leads', UserLeadController::class);
Store Method in the UserLeadController
public function store(User $user, CreateLeadRequest $request)
{
//TODO: Relocate validation to request class
if(!UserLeadController::isPhone("test", $request->phone1)) {
abort(400, "Keine gültige Telefonnummer!");
return;
}
if(!UserLeadController::isPhoneNumberUnique("test", $request->phone1)) {
abort(400, "Die Telefonnummer existiert bereits!");
return;
}
/**
* The logged in User
* #var User $agent
*/
$agent = Auth::user();
$phoneUtil = PhoneNumberUtil::getInstance();
$lead = new Lead();
$lead->fill($request->except(['appointment_end', 'appointment_comment']));
// Leads created by experts will be blocked
if ($user->id === $agent->id) {
$lead->blocked = true;
}
$numberProto = $phoneUtil->parse($lead->phone1, 'DE');
$lead->phone1 = $phoneUtil->format($numberProto, PhoneNumberFormat::INTERNATIONAL);
try {
$lead->save();
} catch (QueryException $e) {
//$message = 'Lead besteht bereits.';
//return Response::json(['errors' => $message], 422);
abort(422, "Lead besteht bereits!");
return;
}
if ($request->closed_until) {
$lead->closed_until = Carbon::create($request->closed_until);
$event_end = $request->appointment_end
? Carbon::parse($request->appointment_end)
: Carbon::parse($request->closed_until)->addMinutes(90);
$lead->calendarEvents()->save(new CalendarEvent([
'body' => $request->appointment_comment ?? "Wurde von {$this->roleDescriptor($agent->roles)}" . $agent->name . " angelegt.",
'type' => CalendarEventType::CALLCENTER_APPOINTMENT,
'event_begin' => $lead->closed_until,
'event_end' => $event_end,
]));
$lead->status = LeadState::APPOINTMENT;
$lead->expert_status = LeadExpertAcceptance::ACCEPTED;
} else {
$lead->status = LeadState::OPEN;
}
if (isset($request->agent)) {
$lead->agent_id = $request->agent;
}
try {
$user->leads()->save($lead);
$lead->comments()->save(new Comment([
'body' => "Wurde von {$this->roleDescriptor($agent->roles)}" . $agent->name . " angelegt.",
'user_id' => $agent->id,
'commentable_type' => 'lead',
'commentable_id' => $lead->id,
'reason' => 'CREATED',
'date' => now('Europe/Berlin'),
]));
if ($request->closed_until) {
$lead->comments()->save(new Comment([
'body' => "Termin wurde von {$this->roleDescriptor($agent->roles)}" . $agent->name . " vereinbart.",
'user_id' => $agent->id,
'commentable_type' => 'lead',
'commentable_id' => $lead->id,
'reason' => 'APPOINTMENT',
'date' => now('Europe/Berlin')->addMinute(),
]));
}
} catch (QueryException $e) {
//not sure if this works
$message = $e->getMessage();
abort(400, $message);
return;
}
if (empty($message)) {
return Response::json(['message' => 'Lead saved', 'lead' => new LeadSingleResource($lead)]);
} else {
return Response::json(compact('message'), 500);
}
}
//TODO: relocate function to rule object
protected static function isPhoneNumberUnique($attribute, $value) {
$withSpace = PhoneFormatter::formatInternational($value);
$withoutSpace = preg_replace('/ /', '', $withSpace);
$protos = [$withSpace, $withoutSpace]; // Necessary because legacy (25.06.2020).
$booleanTest = Company::query()->whereIn('phone', $protos)->doesntExist()
|| Lead::query()->whereIn('phone1', $protos)->orWhereIn('phone2', $protos)->doesntExist();
return $booleanTest;
}
//TODO: relocate function to rule object
protected static function isPhone($attribute, $value) {
if (!$value) {
return false;
}
$phoneUtil = \libphonenumber\PhoneNumberUtil::getInstance();
$test = $phoneUtil->isValidNumber($phoneUtil->parse($value, 'DE'));
return $test;
}
fillable variable in the Lead Model
protected $fillable = [
'company_name',
'place_id',
'street',
'zip',
'city',
'title',
'contact_name',
'additional_contacts',
'phone1',
'phone2',
'email',
'category',
'sub_category',
'website',
'status',
'expert_status',
'coordinates',
'expert_id',
'agent_id',
'blocked',
'important_note'
];
As mentioned before, I receive a 200 OK status. Also, in a Vue.js component, I have done the following axios post request, which also just works fine.
axios
.post(`/api/users/${this.user_id}/leads`, {
"company_name": this.companyName,
"zip": this.zipCode,
"city": this.city,
"street": this.streetAndHouseNumber,
"contact_name": this.contactPartner,
"phone1": this.contactPartnerPhoneNumber,
"email": this.contactPartnerEmail,
"website": this.website,
"category": this.category,
"closed_until": this.appointmentStart,
"appointment_end": this.appointmentEnd,
"appointment_comment": this.comment,
//not used but needed (don't know the purpose)
"additional_contacts": "",
"phone2": "",
"sub_category": "",
"expert_status":this.expert_status,
}).then(() => {
window.location.href = this.routeSuccess;
}).catch((error) => {
this.showErrorAlert = true;
this.errorAlertMessage = error.response.data.message;
});
}

Related

Failed asserting that a row in the table student.sections matches the attributes

Hello im new to PHPUnit with minimum knowledge in laravel.
Im trying to test this method that mass create student section
public function setStudentsSection(Request $request)
{
$enrollments = Enrollment::whereIn('student_id', $request->students)->where('session_id', $request->session_id)->get();
$program_section = ProgramSection::withCount('students')->find($request->program_section_id);
if(($program_section->students_count + count($enrollments)) <= $program_section->max_students) {
foreach($enrollments as $enrollment) {
$response = StudentSection::create([
'student_id' => $enrollment->student_id,
'enrollment_id' => $enrollment->id,
'section_id' => $request->program_section_id,
'created_at' => Carbon::now()
]);
return $response;
}
}
return response()->json(['errors' => ['message' => 'Selected Section is full.']], 405);
}
UPDATE
Here's the test case. Im trying to match the method that i've modified with my test, but im failing to do so.
public function testCanMassAssignSection()
{
$sectioning_data = $this->setMassSectioning(10);
$this->json('POST', 'api/enrollments/set-students-section', $sectioning_data['data'])
->assertStatus(201);
$student_section_data = ['student_id' => $sectioning_data['student_ids'], 'section_id' => $sectioning_data['program_section']->id];
$this->assertDatabaseHas('student.sections', $student_section_data);
}
private function setMassSectioning($max_students)
{
$session = Session::factory()->create();
$program_section = ProgramSection::factory()->create(['session_id' => $session->id, 'max_students' => $max_students]);
$enrollments = Enrollment::factory(['session_id' => $session->id])->count(3)->create();
$student_ids = array();
foreach($enrollments as $enrollment) {
array_push($student_ids, $enrollment->student_id);
}
return [
'data' => ['program_section_id' => $program_section->id, 'session_id' => $session->id, 'students' => $student_ids],
'student_ids' => $enrollment->student_id,
'program_section' => $program_section
];
}
UPDATE
Here's the error the i get.
1) Test\Feature\EnrollmentTest::testCanMassAssignSection
Failed asserting that a row in the table [student.sections] matches the attributes {
"student_id": 2765,
"section_id": 1649
}.
Found: [
{
"id": 262,
"student_id": 2763,
"section_id": 1649,
"created_at": "2022-08-24 09:32:05",
"updated_at": "2022-08-24 09:32:05",
"enrollment_id": 1740
}
].
Still can't make it to match. I do not know what im doing wrong.
Solve! I just create $student data and added to $enrollments now assert in database match. Although don't know what exactly is happening on the background.
I think when i added to enrollments variable the 'student_id' => $student->id it creates those 3 records.
private function setMassSectioning($max_students)
{
$session = Session::factory()->create();
$student = Student::factory()->create();
$program_section = ProgramSection::factory()->create(['session_id' => $session->id, 'max_students' => $max_students]);
$enrollments = Enrollment::factory(['session_id' => $session->id, 'student_id' => $student->id])->count(3)->create();
$student_ids = array();
foreach($enrollments as $enrollment) {
array_push($student_ids, $enrollment->student_id);
}
return [
'data' => ['program_section_id' => $program_section->id, 'session_id' => $session->id, 'students' => $student_ids],
'student_ids' => $enrollment->student_id,
'program_section' => $program_section
];
}

Lumen unusual return value only when tried in Android (Kotlin)

I have a problem about unusual return in my lumen app version 7.
My teammate who is using kotlin in his android try to execute my api with case task_id and id is correctly inputed, he always got
["success" => false, "message" => "File Bukan Milik Task", "status" => 400]
If he got that response, It shouldn't execute the code below, but the targeted file was deleted and file in my digital ocean space was also deleted so the code below the return was executed. And also, with case task_id and id correctly inputed, the above return was not supposed to be hit. But it was been hit and the below code also hit. In the mean time, every time i tried this api in postman, It worked normally. with output :
return ["success" => true, "message" => "Berhasil Menghapus File", "status" => 200];
This is my deleteFileTask function api code
public function deleteFileTask(Request $request)
{
try{
$task_id = $request->get('task_id', null);
$id = $request->get('id', null);
$task = Task::with('attachments')->find($task_id);
if($task === null) return ["success" => false, "message" => "Id Task Tidak Ditemukan", "status" => 400];
$search = $task->attachments->search(function ($item) use ($id) {
return $item->id == $id;
});
if($search === false) return ["success" => false, "message" => "File Bukan Milik Task", "status" => 400];
$fileService = new FileService;
$delete_file_response = $fileService->deleteFile($id);
if($delete_file_response['success']) return ["success" => true, "message" => "Berhasil Menghapus File", "status" => 200];
else return ["success" => false, "message" => $delete_file_response['message'], "status" => 400];
} catch(Exception $err){
return ["success" => false, "message" => $err, "status" => 400];
}
}
This is my deleteFile function in FileService class
public function deleteFile($id)
{
$file = File::find($id);
if($file === null) return ["success" => false, "message" => "File Tidak Ditemukan"];
$set_private = Storage::disk('do')->setVisibility($file->link, 'private');
if(!$set_private) return ["success" => false, "message" => "File Gagal Didelete dari Space"];
$file->delete();
$purge_response = $this->purgeLink($file->link);
if(!$purge_response) return ["success" => false, "message" => "Gagal Purge Data"];
return ["success" => true];
}
Anyone know what the cause is?

Payfort Return Signature Mismatch For Apple Pay on Web

I'm integrating Apple Pay on our website using payfort.
Payfort ask to calculate signature which work fine if input values are string. But the problem is what if value is array.
As shown in following image from there documentation. They require apple_header and apple_paymentMethod field to be List data type. Now how should i calculate the signature in this case since it takes key and value as string. but in our case value is array. (i.e. apple_paymentMethod AND apple_paymentMethod)
I tried these 2 fields using json_encode function.
If i send these 2 fields as string then payfort api return invalid format for field: apple_header.
If i send these 2 fields as array then payfort api return Signature Mismatch.
I don't have any idea what am i missing.
Here is my code:
Controller Code:
$parameters = [
'digital_wallet' => 'APPLE_PAY',
'command' => 'PURCHASE',
'access_code' => config('payfort.APPLE_ACCESS_CODE'),
'merchant_identifier' => config('payfort.APPLE_MERCHANT_IDENTIFIER'),
'merchant_reference' => date( 'Y' ).str_pad($request->iOrderId, 6, 0, STR_PAD_LEFT) . '_' . time(),
'amount' => 7000,
'currency' => 'SAR',
'language' => 'en',
'customer_email' => 'test#gmail.com',
'apple_data' => $request->token['paymentData']['data'],
'apple_signature' => $request->token['paymentData']['signature'],
'apple_header' => json_encode([
'apple_transactionId'=> $request->token['paymentData']['header']['transactionId'],
'apple_ephemeralPublicKey'=> $request->token['paymentData']['header']['ephemeralPublicKey'],
'apple_publicKeyHash'=> $request->token['paymentData']['header']['publicKeyHash']
]),
'apple_paymentMethod' => json_encode([
'apple_displayName'=> $request->token['paymentMethod']['displayName'],
'apple_network'=> $request->token['paymentMethod']['network'],
'apple_type'=> $request->token['paymentMethod']['type']
]),
'customer_ip' => $request->ip(),
'customer_name' => 'ABC',
'merchant_extra' => $request->iOrderId,
'merchant_extra1' => $request->order_number,
'merchant_extra2' => $request->locale_info,
];
// canculate signature
$parameters['signature'] = $this->payfortCoreHelpers->calculateSignature($parameters, 'request', true);
// Add Array or List fields in back to parameters before send
$parameters['apple_header'] = [
'apple_transactionId'=> $request->token['paymentData']['header']['transactionId'],
'apple_ephemeralPublicKey'=> $request->token['paymentData']['header']['ephemeralPublicKey'],
'apple_publicKeyHash'=> $request->token['paymentData']['header']['publicKeyHash']
];
$parameters['apple_paymentMethod'] = [
'apple_displayName'=> $request->token['paymentMethod']['displayName'],
'apple_network'=> $request->token['paymentMethod']['network'],
'apple_type'=> $request->token['paymentMethod']['type']
];
calculateSignature function
public function calculateSignature($arrData, $signType = 'request', $isAppleRequest = false)
{
$shaString = '';
ksort($arrData);
foreach ($arrData as $k => $v) {
$shaString .= "$k=$v";
}
$shaString = config('payfort.SHA_REQUEST_PHRASE') . $shaString . config('payfort.SHA_REQUEST_PHRASE');
$signature = hash(config('payfort.SHA_TYPE'), $shaString);
return $signature;
}
Payfort Response
{
"amount": "7000",
"response_code": "00008",
"digital_wallet": "APPLE_PAY",
"signature": "****",
"merchant_identifier": "****",
"access_code": "****",
"customer_ip": "::1",
"language": "en",
"command": "PURCHASE",
"merchant_extra": "****",
"response_message": "Signature mismatch",
"merchant_reference": "20201599817035025",
"customer_email": "test#gmail.com",
"merchant_extra1": "1599817035025",
"merchant_extra2": "SAR",
"currency": "SAR",
"customer_name": "ABC",
"status": "00"
}
You might find this link helpful: https://github.com/devinweb/payment/blob/fa595fe60df4dff3c4f2189e37fd64fffdc8421b/src/Traits/Payfort/ApplePay.php#L51
This shows calculateSignature method that generates the signature for your request.
Particularly, line 67 shows that you need to have a comma followed by space between the items in the nested array.
ksort($arrData);
foreach ($arrData as $key => $value) {
if(is_array($value)){
$shaSubString = '{';
foreach ($value as $k => $v) {
$shaSubString .= "$k=$v, ";
}
$shaSubString = substr($shaSubString, 0, -2).'}';
$shaString .= "$key=$shaSubString";
}else{
$shaString .= "$key=$value";
}
}

Laravel : PushNotification for fcm not working on live

I am using PushNotification (by Edujogon) for push notification services.
So, for that I created a file in config/pushnotification and set my key and all for fcm and apn.
On this file I set
'fcm' => [
'priority' => 'normal',
'dry_run' => false,
'apiKey' => 'My-Api-key',
],
And sending on fcm key to sendFCM function
if(count($fcmDeviceIds) > 0) {
$this->sendFCM($fcmDeviceIds, $payload, $addedPost);
}
And my sendFCM function :
private function sendFCM($tokens, $payload, $addedPost) {
$poroductDetail = Product::find($addedPost->product_id)->first();
$productTitle = $poroductDetail->title;
$payloadData = ([$addedPost, 'notificationType' => 'postNotification']);
try {
$push = new PushNotification('fcm');
$feedback = $push->setMessage([
'fcm' => [
'alert' => [
'title' => isset($payload['title']) ? $payload['title'] : 'myTitle',
'body' => $payload['body']." for ".$productTitle
],
'sound' => isset($payload['sound']) ? $payload['sound'] : 'default'
],
'extraPayLoad' => $payloadData
])->setDevicesToken($tokens)->send()->getFeedback();
} catch (\Exception $ex) {
Log::error($ex->getTraceAsString());
}
}
So when I check in local I got all notifications but on live i did'nt gt any notification.What's the problem in my code ?

REST User registration and Login through Api Key

I am not new to codeignitor , but still i didn't used they feature called 'API keys' authentication.
What i want to do ?
Register a user in my_users table and there is apikey as column that should store and generate unique api while user registration.
Login User , user give username , password and it get response as logged in if correct information is given , with it's respective apikey in my_users table.
After login i want to use apikey for all other user related calls like bookATask with header as X-API-KEY , which will allow me to control user session at client side and secure login and sign system.
Problem in Setup:
I am being asked each time i make a request to pass X-API-KEY which is wrong because , maybe there is call register_post in User controller which register users and Api key cannot be passed in headers unless it is generated in this method right?
I am just getting status:FALSE and error:Invalid Api key on each call i make.
What am i doing?
(Only changed code)
application/config/rest.php
defined('BASEPATH') OR exit('No direct script access allowed');
$config['force_https'] = FALSE;
$config['rest_default_format'] = 'json';
$config['rest_supported_formats'] = [
'json',
'array',
'csv',
'html',
'jsonp',
'php',
'serialized',
'xml',
];
$config['rest_status_field_name'] = 'status';
$config['rest_message_field_name'] = 'error';
$config['enable_emulate_request'] = TRUE;
$config['rest_realm'] = 'REST API';
$config['rest_auth'] = 'basic';
$config['auth_source'] = '';
$config['allow_auth_and_keys'] = TRUE;
$config['auth_library_class'] = '';
$config['auth_library_function'] = '';
$config['auth_override_class_method_http']['user']['register']['post'] = 'none';
$config['auth_override_class_method_http']['user']['login']['post'] = 'none';
$config['rest_valid_logins'] = ['user1' => '12345'];
$config['rest_ip_whitelist_enabled'] = FALSE;
$config['rest_ip_whitelist'] = '';
$config['rest_ip_blacklist_enabled'] = FALSE;
$config['rest_ip_blacklist'] = '';
$config['rest_database_group'] = 'default';
$config['rest_keys_table'] = 'my_users';
$config['rest_enable_keys'] = TRUE;
$config['rest_key_column'] = 'apikey';
$config['rest_limits_method'] = 'ROUTED_URL';
$config['rest_key_length'] = 40;
$config['rest_key_name'] = 'X-API-KEY';
$config['rest_enable_logging'] = TRUE;
$config['rest_logs_table'] = 'app_logs';
$config['rest_enable_access'] = FALSE;
$config['rest_access_table'] = 'access';
$config['rest_logs_json_params'] = FALSE;
$config['rest_enable_limits'] = TRUE;
$config['rest_limits_table'] = 'app_limits';
$config['rest_ignore_http_accept'] = FALSE;
$config['rest_ajax_only'] = FALSE;
$config['rest_language'] = 'english';
$config['check_cors'] = FALSE;
$config['allowed_cors_headers'] = [
'Origin',
'X-Requested-With',
'Content-Type',
'Accept',
'Access-Control-Request-Method'
];
$config['allowed_cors_methods'] = [
'GET',
'POST',
'OPTIONS',
'PUT',
'PATCH',
'DELETE'
];
$config['allow_any_cors_domain'] = FALSE;
$config['allowed_cors_origins'] = [];
application/config/autoload.php
$autoload['libraries'] = array('database');
controllers/api/Key.php
defined('BASEPATH') OR exit('No direct script access allowed');
require APPPATH . '/libraries/REST_Controller.php';
class Key extends REST_Controller {
protected $methods = [
'index_put' => ['level' => 10, 'limit' => 10],
'index_delete' => ['level' => 10],
'level_post' => ['level' => 10],
'regenerate_post' => ['level' => 10],
];
public function index_put()
{
$key = $this->_generate_key();
$level = $this->put('level') ? $this->put('level') : 1;
$ignore_limits = ctype_digit($this->put('ignore_limits')) ? (int) $this->put('ignore_limits') : 1;
if ($this->_insert_key($key, ['level' => $level, 'ignore_limits' => $ignore_limits]))
{
$this->response([
'status' => TRUE,
'key' => $key
], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
}
else
{
$this->response([
'status' => FALSE,
'message' => 'Could not save the key'
], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
}
}
public function index_delete()
{
$key = $this->delete('key');
if (!$this->_key_exists($key))
{
$this->response([
'status' => FALSE,
'message' => 'Invalid API key'
], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
}
$this->_delete_key($key);
$this->response([
'status' => TRUE,
'message' => 'API key was deleted'
], REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code
}
public function level_post()
{
$key = $this->post('key');
$new_level = $this->post('level');
if (!$this->_key_exists($key))
{
$this->response([
'status' => FALSE,
'message' => 'Invalid API key'
], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
}
if ($this->_update_key($key, ['level' => $new_level]))
{
$this->response([
'status' => TRUE,
'message' => 'API key was updated'
], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
}
else
{
$this->response([
'status' => FALSE,
'message' => 'Could not update the key level'
], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
}
}
public function suspend_post()
{
$key = $this->post('key');
if (!$this->_key_exists($key))
{
$this->response([
'status' => FALSE,
'message' => 'Invalid API key'
], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
}
if ($this->_update_key($key, ['level' => 0]))
{
$this->response([
'status' => TRUE,
'message' => 'Key was suspended'
], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
}
else
{
$this->response([
'status' => FALSE,
'message' => 'Could not suspend the user'
], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
}
}
public function regenerate_post()
{
$old_key = $this->post('key');
$key_details = $this->_get_key($old_key);
if (!$key_details)
{
$this->response([
'status' => FALSE,
'message' => 'Invalid API key'
], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
}
$new_key = $this->_generate_key();
if ($this->_insert_key($new_key, ['level' => $key_details->level, 'ignore_limits' => $key_details->ignore_limits]))
{
$this->_update_key($old_key, ['level' => 0]);
$this->response([
'status' => TRUE,
'key' => $new_key
], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
}
else
{
$this->response([
'status' => FALSE,
'message' => 'Could not save the key'
], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
}
}
private function _generate_key()
{
do
{
$salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);
if ($salt === FALSE)
{
$salt = hash('sha256', time() . mt_rand());
}
$new_key = substr($salt, 0, config_item('rest_key_length'));
}
while ($this->_key_exists($new_key));
return $new_key;
}
private function _get_key($key)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->get(config_item('rest_keys_table'))
->row();
}
private function _key_exists($key)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->count_all_results(config_item('rest_keys_table')) > 0;
}
private function _insert_key($key, $data)
{
$data[config_item('rest_key_column')] = $key;
$data['date_created'] = function_exists('now') ? now() : time();
return $this->db
->set($data)
->insert(config_item('rest_keys_table'));
}
private function _update_key($key, $data)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->update(config_item('rest_keys_table'), $data);
}
private function _delete_key($key)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->delete(config_item('rest_keys_table'));
}
}
(Method used in controller to generate Api key)
private function _generate_key()
{
do
{
// Generate a random salt
$salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);
// If an error occurred, then fall back to the previous method
if ($salt === FALSE)
{
$salt = hash('sha256', time() . mt_rand());
}
$new_key = substr($salt, 0, config_item('rest_key_length'));
}
while ($this->_key_exists($new_key));
return $new_key;
}
private function _key_exists($key)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->count_all_results(config_item('rest_keys_table')) > 0;
}
On Database i have two extra tables app_limits , app_logs , and apikey column with varchar(40) in my_users table that's all , can anyone help me solving my issue , what am i doing wrong ?
I have found the answer myself , i just modifying these variables helped me :
$config['auth_override_class_method_http']['user']['customer_register']['post'] = 'none';
$config['auth_override_class_method_http']['user']['customer_login']['post'] = 'none';
these are basically exception methods for Api key which can be register and login , thanks myself

Resources