This removes api authentification with token in favor of signature method. Refactorize code and clean up. It add more unit test plus code coverage in test/converage. - Added config.api.timestampTimeout - Added Helper::signRequest This calculates the request signature - Added more unit tests and extend code coverage. - Added rate limiter for web routes - Added RemoveSpaces Sanitizer on api requests - Added stress test suite - Changed AuthServiceProvider api-token to api-hmac - Changed CustomerSeeder to have at least of customer activated (for unit tests) - Changed used transation for saveing multiple models - Changed, in ServiceController generateApiToken to generateServicePassword - Changed, timestamp has to be send in request with a DateTime format, it also has to a UTC value - Composer added brianium/paratest - Composer update - Fixed case where removing single optin could be the wrong one (not for the good service) - Fixed customer delete - Fixed customer would not be resolved by brand. - Fixed Really check that request is json checking body content, preventing sending malformed requests - Remove ApiError::needAuth - Removed api_token - Removed ApiController::authenticate - Removed config.api.tokenTimeout - Removed Header check or usage because of HAProxy doing weird stuff - Removed lock files from gitignore - Removed memcached dependency - Removed unused questions resources api routes - Removed workspace file Migrations - Added unique index on services.bearer_token - Changed customer_id on customer_answer is nullable - Changed services.bearer_pwd length to 312 (the size of the token) - Dropped services.api_token and service.api_token_date
244 lines
10 KiB
PHP
244 lines
10 KiB
PHP
<?php
|
|
|
|
namespace App\Lib;
|
|
|
|
use App\Exceptions\AbortRowImportException;
|
|
use App\Models\Brand;
|
|
use App\Models\Customer;
|
|
use App\Models\CustomerInfo;
|
|
use App\Models\CustomerLogin;
|
|
use App\Models\SingleOptin;
|
|
use Carbon\Exceptions\InvalidFormatException;
|
|
use Database\migrations\LeGaulois2016Migration;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\File;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Illuminate\Support\Str;
|
|
|
|
/**
|
|
* @codeCoverageIgnore
|
|
*/
|
|
class MigrateOldData extends LeGaulois2016Migration
|
|
{
|
|
/** @var Brand */
|
|
private $brand;
|
|
|
|
/**
|
|
* runMigration
|
|
*
|
|
* @param Brand $brand
|
|
* @param string $table
|
|
* @return void
|
|
*/
|
|
public function runMigration(Brand $brand, string $table)
|
|
{
|
|
$this->table = $table;
|
|
$this->brand = $brand;
|
|
$this->instruct();
|
|
$this->up();
|
|
}
|
|
|
|
/**
|
|
* instruct
|
|
*
|
|
* @return array
|
|
*/
|
|
// phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh, Squiz.Commenting.FunctionComment.Missing
|
|
public function instruct(): array
|
|
{
|
|
$this->initFile();
|
|
$cleanDegeu = function (string $str) {
|
|
return html_entity_decode(
|
|
trim(str_replace('\\', '', ucwords(stripcslashes(strtolower($str))))),
|
|
ENT_QUOTES | ENT_HTML5,
|
|
'UTF-8'
|
|
);
|
|
};
|
|
return [
|
|
'Users' => [
|
|
'table' => $this->table,
|
|
'model' => Customer::class,
|
|
'comment' => sprintf('Migrating %s customers', $this->brand->name),
|
|
'bind' => [
|
|
'email' => [
|
|
'apply' => function ($v, $model) use ($cleanDegeu) {
|
|
$v = \mb_convert_encoding($v, "UTF-8");
|
|
$v = explode('#|#', $v);
|
|
$oldId = $v[0];
|
|
$first_name = $cleanDegeu($v[1]);
|
|
$last_name = $cleanDegeu($v[2]);
|
|
$birth_date = $v[3];
|
|
$address = $cleanDegeu($v[4]);
|
|
$address2 = $cleanDegeu($v[5]);
|
|
$city = $cleanDegeu($v[6]);
|
|
$postcode = $v[7];
|
|
$user_inscritNewsletter = $v[8];
|
|
$email = strtolower($v[9]);
|
|
$pwd = $v[10];
|
|
$created_at = $v[11];
|
|
$updated_at = $v[12];
|
|
$last_cnx = $v[13];
|
|
|
|
// * Just save Single optin.
|
|
if (empty($first_name) && empty($last_name)) {
|
|
$sglOptin = SingleOptin::where('email', strtolower($email))
|
|
->where('brand_id', $this->brand->id)->firstOrNew();
|
|
$sglOptin->email = strtolower($email);
|
|
$sglOptin->brand_id = $this->brand->id;
|
|
$sglOptin->save();
|
|
} else {
|
|
// * Validate Data.
|
|
$d = [
|
|
'first_name' => $first_name,
|
|
'last_name' => $last_name,
|
|
'address' => $address,
|
|
'address2' => $address2,
|
|
'city' => $city,
|
|
'postcode' => $postcode,
|
|
];
|
|
|
|
$validator = Validator::make($d, [
|
|
'first_name' => 'min:2',
|
|
'last_name' => 'min:2'
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
throw new AbortRowImportException();
|
|
}
|
|
|
|
$rules = [
|
|
'address' => 'string|min:2',
|
|
'address2' => 'string|min:2',
|
|
'city' => 'string|min:2',
|
|
'postcode' => 'digits_between:4,5'
|
|
];
|
|
|
|
$validate = function (array $data, array $rule) {
|
|
return Validator::make($data, $rule)->fails();
|
|
};
|
|
|
|
foreach ($rules as $key => $rule) {
|
|
if ($validate([$key => $d[$key]], [$key => $rule])) {
|
|
${$key} = null;
|
|
}
|
|
}
|
|
|
|
$model = Customer::where('email', $email)->firstOrNew();
|
|
$model->email = $email;
|
|
$model->created_at = $created_at;
|
|
$model->updated_at = $updated_at;
|
|
$model->save();
|
|
|
|
// * Filtre birthdate puisque c'est du sale dans la vielle crm.
|
|
try {
|
|
$expl = explode('-', $birth_date);
|
|
$d = Carbon::parse($birth_date);
|
|
if (
|
|
$d->toDateString() === sprintf(
|
|
'%s-%s-%s',
|
|
$expl[2] ?? '',
|
|
$expl[1] ?? '',
|
|
$expl[0] ?? ''
|
|
)
|
|
) {
|
|
$birth_date = $d->toDateString();
|
|
}
|
|
} catch (InvalidFormatException $e) {
|
|
$birth_date = '';
|
|
}
|
|
|
|
|
|
if ($birth_date === '0000-00-00') {
|
|
$birth_date = '';
|
|
}
|
|
|
|
$city = !empty($city) ? $city : null;
|
|
$postcode = !empty($postcode) ? $postcode : null;
|
|
$address = !empty($address) ? $address : null;
|
|
$address2 = !empty($address2) ? $address2 : null;
|
|
|
|
$cInfo = new CustomerInfo();
|
|
$cInfo->hashcode = Str::uuid();
|
|
$cInfo->firstname = ucfirst(strtolower($first_name));
|
|
$cInfo->lastname = ucfirst(strtolower($last_name));
|
|
$cInfo->birth_date = !strlen($birth_date) ? null : $birth_date;
|
|
$cInfo->address = $address;
|
|
$cInfo->address2 = $address2;
|
|
$cInfo->city = $city;
|
|
$cInfo->postcode = $postcode;
|
|
$cInfo->opt_in = $user_inscritNewsletter ? true : false;
|
|
$cInfo->brand_id = $this->brand->id;
|
|
$cInfo->customer_id = $model->id;
|
|
$cInfo->created_at = $created_at;
|
|
$cInfo->updated_at = $updated_at;
|
|
$cInfo->save();
|
|
|
|
$cLogin = new CustomerLogin();
|
|
$cLogin->password = Hash::make(trim($pwd));
|
|
$cLogin->brand_id = $this->brand->id;
|
|
$cLogin->customer_id = $model->id;
|
|
$cLogin->status = true;
|
|
$cLogin->created_at = $created_at;
|
|
$cLogin->updated_at = $updated_at;
|
|
$cLogin->last_connection = $last_cnx;
|
|
$cLogin->save();
|
|
|
|
$this->write(
|
|
[
|
|
'new' => $model->id,
|
|
'old' => $oldId,
|
|
'hashcode' => $cInfo->hashcode,
|
|
'created_at' => $created_at,
|
|
'updated_at' => $updated_at
|
|
]
|
|
);
|
|
}//end if
|
|
throw new AbortRowImportException();
|
|
},
|
|
'name' => [
|
|
'user_id',
|
|
'firstname',
|
|
'lastname',
|
|
'birthdate',
|
|
'address',
|
|
'address2',
|
|
'city',
|
|
'postcode',
|
|
'optin',
|
|
'email',
|
|
'pwd',
|
|
'created_at',
|
|
'updated_at',
|
|
'last_cnx'
|
|
]
|
|
],
|
|
]
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Create the migration file
|
|
*
|
|
* @return void
|
|
*/
|
|
public function initFile()
|
|
{
|
|
File::put(storage_path('crm_migration.csv'), sprintf('new;old;hashcode;created_at;updated_at') . PHP_EOL);
|
|
}
|
|
|
|
/**
|
|
* Write date in the migration file
|
|
*
|
|
* @param array $data
|
|
* @return void
|
|
*/
|
|
public function write(array $data)
|
|
{
|
|
foreach ($data as &$d) {
|
|
$d = sprintf('"%s"', $d);
|
|
}
|
|
File::append(storage_path('crm_migration.csv'), implode(';', $data) . PHP_EOL);
|
|
}
|
|
}
|