Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F120823847
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
30 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/app/Http/Controllers/Controller.php b/src/app/Http/Controllers/Controller.php
index a32410b..a83e696 100644
--- a/src/app/Http/Controllers/Controller.php
+++ b/src/app/Http/Controllers/Controller.php
@@ -1,265 +1,262 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function healthcheck()
{
try {
$this->generateCert("test", "test", Carbon::now()->addDays(2));
} catch (\Exception $e) {
\Log::warning("Caught an error: " . $e->getMessage());
return response()->json(["status" => 'FAILURE', "message" => "Certificate signing failed."], 500);
}
try {
DB::select("SELECT 1");
} catch (\Exception $e) {
\Log::warning("Connection to db failed: " . $e->getMessage());
\Log::info(\config('database.connections.mysql.host'));
\Log::info(\config('database.connections.mysql.port'));
\Log::info(\config('database.connections.mysql.database'));
\Log::info(\config('database.connections.mysql.username'));
return response()->json(["status" => 'FAILURE', "message" => "Connection to database failed."], 500);
}
return response()->json(["status" => 'OK']);
}
private function generateCert(string $comment, string $systemUuid, Carbon $expirationDate)
{
//Reset errors
while (openssl_error_string() != null);
// We use 2048 bits because the Plesk Key Administrator does not support license
// key bodies larger than 4000 bytes.
$dn = [
"countryName" => "CH",
"stateOrProvinceName" => "Zurich",
"organizationName" => "Apheleia IT AG",
"organizationalUnitName" => "Product Sales",
"commonName" => $systemUuid,
"emailAddress" => "contact@apheleia-it.ch",
];
//
$privkey = openssl_pkey_new([
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA
]);
$csr = openssl_csr_new($dn, $privkey, ['digest_alg' => 'sha256']);
$contents = file_get_contents('/etc/ssl/openssl.cnf');
$contents = $contents . "
[custom]
basicConstraints=CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
nsComment = \"$comment\"
";
$tmpFile = \tempnam("/tmp", "OPENSSLCNF");
file_put_contents($tmpFile, $contents);
$validForDays = Carbon::now()->diffInDays($expirationDate, false);
if ($validForDays <= 0) {
throw new \Exception("Expiration date is in the past. Valid for $validForDays days.");
}
$caCert = \config("app.ca_cert");
$caPrivateKey = \config("app.ca_private_key");
$x509 = openssl_csr_sign($csr, $caCert, $caPrivateKey, $validForDays, [
'digest_alg' => 'sha256',
'x509_extensions' => 'custom',
'config' => $tmpFile
]
);
if (!$x509) {
\Log::warning("Failed to sign\n");
throw new \Exception("Failed to sign");
}
// Save your private key, CSR and self-signed cert for later use
// openssl_csr_export($csr, $csrout) and var_dump($csrout);
if (!openssl_x509_export($x509, $certout)) {
throw new \Exception("Failed to export the certificate");
}
if (!openssl_pkey_export($privkey, $pkeyout)) {
throw new \Exception("Failed to export the key");
}
$errors = "";
while ($msg = openssl_error_string()) {
$errors .= $msg;
}
if (!empty($errors)) {
\Log::warning($errors);
throw new \Exception("Errors while signing: $errors");
}
return $certout . $pkeyout;
}
const PRODUCT_PREFIXES = ['PLESK', 'NFR', 'COLLABORA'];
private function validateProductId(string $productId)
{
foreach (self::PRODUCT_PREFIXES as $prefix) {
if ((bool)preg_match("/^$prefix-[0-9]*$/", $productId)) {
return true;
}
}
return false;
}
private function numUsersFromProduct(string $productId)
{
$numUsers = $productId;
foreach (self::PRODUCT_PREFIXES as $prefix) {
$numUsers = str_replace("$prefix-", '', $numUsers);
}
if (!is_numeric($numUsers)) {
throw new \Exception("Failed to extract number of users from product: $productId");
}
return intval($numUsers);
}
- private function updateLicense(\App\Models\License $license, $object, string $idempotencyKey)
+ private function updateLicense(\App\Models\License $license, $object, string $idempotencyKey, $testMode)
{
if (\App\Models\License::where('idempotency_key', $idempotencyKey)->exists()) {
throw new \Exception("Idempotency key already exists: $idempotencyKey");
}
$productId = $object['productId'];
if (empty($productId)) {
throw new \Exception("No product id.");
}
if (!$this->validateProductId($productId)) {
throw new \Exception("Invalid product id.");
}
$numUsers = $this->numUsersFromProduct($productId);
$comment = base64_encode(
json_encode(['users' => $numUsers, 'nfr' => $object['nfr']])
);
$license->key_id = $object['keyId'];
$license->num_licenses = $numUsers;
$license->product_id = $object['productId'];
$license->status = $object['status'];
$license->creation_date = Carbon::parse($object['creationDate']);
$license->expiration_date = Carbon::parse($object['expirationDate']);
$license->idempotency_key = $idempotencyKey;
$license->owner_id = $object['owner']['id'];
$license->nfr = $object['nfr'];
+ $license->test_license = $testMode;
$license->body = $this->generateCert($comment, 'PLESK' . $license->shortId(), $license->expiration_date);
}
public function createKey(Request $request)
{
$testMode = $request->testMode == 'true';
$idempotencyKey = $request->idempotencyKey;
$object = $request->except(['testMode', 'idempotencyKey']);
$license = new \App\Models\License();
- $this->updateLicense($license, $object, $idempotencyKey);
+ $this->updateLicense($license, $object, $idempotencyKey, $testMode);
- if (!$testMode) {
- $license->save();
- }
+ $license->save();
$object['body'] = $license->body;
return response()->json($object);
}
private function serializeLicense(\App\Models\License $license)
{
return [
"keyId" => $license->key_id,
"productId" => $license->product_id,
"status" => $license->status,
"body" => $license->body,
"creationDate" => $license->creation_date->format('Y-m-d\TH:i:s.vp'),
"operationDate" => Carbon::now()->format('Y-m-d\TH:i:s.vp'),
"expirationDate" => $license->expiration_date->format('Y-m-d\TH:i:s.vp'),
"owner" => [
"id" => $license->owner_id
],
"nfr" => (bool)$license->nfr
];
}
public function getKey(Request $request, string $keyId)
{
if (!is_numeric($keyId)) {
return abort(404);
}
$keyId = (int)$keyId;
- $license = \App\Models\License::where('key_id', $keyId)->first();
+ $license = \App\Models\License::withTestMode($request->testMode == 'true')->where('key_id', $keyId)->first();
if (!$license) {
return abort(404);
}
return response()->json($this->serializeLicense($license));
}
public function updateKey(Request $request, string $keyId)
{
if (!is_numeric($keyId)) {
return abort(404);
}
$keyId = (int)$keyId;
- $license = \App\Models\License::withTrashed()->where('key_id', $keyId)->first();
+ $testMode = $request->testMode == 'true';
+ $license = \App\Models\License::withTrashed()->withTestMode($testMode)->where('key_id', $keyId)->first();
if (!$license) {
return abort(404);
}
- $testMode = $request->testMode == 'true';
$idempotencyKey = $request->idempotencyKey;
$object = $request->except(['testMode', 'idempotencyKey']);
if ($license->trashed() && $object['status'] != \App\Models\License::STATUS_TERMINATED) {
$license->restore();
}
- $this->updateLicense($license, $object, $idempotencyKey);
+ $this->updateLicense($license, $object, $idempotencyKey, $testMode);
- if (!$testMode) {
- $license->save();
- }
+ $license->save();
$object['body'] = $license->body;
return response()->json($object);
}
public function deleteKey(Request $request, string $keyId)
{
if (!is_numeric($keyId)) {
return abort(404);
}
$keyId = (int)$keyId;
- $license = \App\Models\License::where('key_id', $keyId)->first();
+ $license = \App\Models\License::withTestMode($request->testMode == 'true')->where('key_id', $keyId)->first();
if (!$license) {
return abort(404);
}
$license->status = \App\Models\License::STATUS_TERMINATED;
$license->save();
$license->delete();
}
}
diff --git a/src/app/Models/License.php b/src/app/Models/License.php
index ac3f923..94bb66b 100644
--- a/src/app/Models/License.php
+++ b/src/app/Models/License.php
@@ -1,93 +1,94 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Carbon\Carbon;
class License extends Model
{
use SoftDeletes;
const STATUS_ACTIVE = "active";
const STATUS_TERMINATED = "terminated";
const STATUS_SUSPENDED = "suspended";
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'key_id',
'product_id',
'num_licenses',
'idempotency_key',
'creation_date',
'expiration_date',
'body',
'owner_id',
'nfr',
+ 'test_license',
'status'
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
// 'password',
// 'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'creation_date' => 'datetime',
'expiration_date' => 'datetime',
];
protected $dates = [
'created_at',
'updated_at',
'deleted_at',
'creation_date',
'expiration_date'
];
public function shortId()
{
return str_pad($this->key_id, 10, "0", STR_PAD_LEFT);
}
public static function commentFromBody($body) {
$body_parsed = openssl_x509_parse($body);
return json_decode(
base64_decode($body_parsed['extensions']['nsComment']),
true
);
}
public static function usersFromBody($body) {
return intval(self::commentFromBody($body)['users']);
}
public static function nfrFromBody($body) {
$comments = self::commentFromBody($body);
if (!array_key_exists('nfr', $comments)) {
return false;
}
return (bool)intval($comments['nfr']);
}
public static function expirationDateFromBody($body)
{
$body_parsed = openssl_x509_parse($body);
return new Carbon("@{$body_parsed['validTo_time_t']}");
}
}
diff --git a/src/app/Providers/AppServiceProvider.php b/src/app/Providers/AppServiceProvider.php
index ee8ca5b..470ef5f 100644
--- a/src/app/Providers/AppServiceProvider.php
+++ b/src/app/Providers/AppServiceProvider.php
@@ -1,28 +1,35 @@
<?php
namespace App\Providers;
+use Illuminate\Database\Query\Builder;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
- //
+ Builder::macro(
+ 'withTestMode',
+ function ($testMode) {
+ /** @var Builder $this */
+ return $this->where('test_license', $testMode);
+ }
+ );
}
}
diff --git a/src/database/migrations/2022_12_05_000001_create_license_table.php b/src/database/migrations/2022_12_05_000001_create_license_table.php
index bc8ba12..27b4237 100644
--- a/src/database/migrations/2022_12_05_000001_create_license_table.php
+++ b/src/database/migrations/2022_12_05_000001_create_license_table.php
@@ -1,43 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('licenses', function (Blueprint $table) {
$table->id();
$table->integer('key_id')->unique();
$table->integer('num_licenses');
$table->string('product_id');
$table->string('idempotency_key')->unique();
$table->string('body', 2000);
$table->string('status');
$table->integer('owner_id');
$table->boolean('nfr');
+ $table->boolean('test_license');
$table->timestamps();
$table->timestamp('creation_date')->nullable();
$table->timestamp('expiration_date')->nullable();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('licenses');
}
};
diff --git a/src/tests/Feature/ApiTest.php b/src/tests/Feature/ApiTest.php
index 030dee5..7de7775 100644
--- a/src/tests/Feature/ApiTest.php
+++ b/src/tests/Feature/ApiTest.php
@@ -1,352 +1,399 @@
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Carbon\Carbon;
class ApiTest extends TestCase
{
public function setUp(): void
{
parent::setUp();
Carbon::setTestNow(Carbon::createFromDate(2016, 8, 29));
\App\Models\License::truncate();
}
/**
* {@inheritDoc}
*/
public function tearDown(): void
{
\App\Models\License::truncate();
parent::tearDown();
}
public function testHealth()
{
$response = $this->get("api/v2/plesk/healthcheck");
$response->assertStatus(200);
$json = $response->json();
$this->assertSame($json['status'], 'OK');
\config([
'app.ca_cert' => "invalid",
'app.ca_private_key' => "invalid"
]);
$response = $this->get("api/v2/plesk/healthcheck");
$response->assertStatus(500);
$json = $response->json();
$this->assertSame($json['status'], 'FAILURE');
\config([
'app.ca_cert' => null,
'app.ca_private_key' => null
]);
}
public function testCreate()
{
$post = [
"keyId" => 123456789,
"productId" => "PLESK-10",
"items" => [
"item" => "cpu_cores",
"value" => '5'
],
"body" => null,
"status" => 'active',
"creationDate" => "2016-08-29T09:12:33.000Z",
"operationDate" => "2016-08-29T09:12:33.000Z",
"expirationDate" => "2016-09-29T09:12:33.000Z",
"owner" => [
"id" => 12345
],
"nfr" => false,
"activationData" => ""
];
$response = $this->postJson("api/v2/plesk/key?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174000", $post);
$response->assertStatus(200);
// Validate license
$license = \App\Models\License::where('key_id', $post['keyId'])->first();
$this->assertNotNull($license);
$this->assertSame(\App\Models\License::usersFromBody($license->body), 10);
$this->assertSame(\App\Models\License::nfrFromBody($license->body), false);
// We can't mock the "now" used by openssl, so we make sure the offset matches instead.
Carbon::setTestNow();
$this->assertSame((new Carbon($post['expirationDate']))->diffInDays(\App\Models\License::expirationDateFromBody($license->body), false), Carbon::now()->diffInDays(Carbon::createFromDate(2016, 8, 29)));
Carbon::setTestNow(Carbon::createFromDate(2016, 8, 29));
$this->assertSame($license->key_id, $post['keyId']);
$this->assertSame($license->product_id, $post['productId']);
$this->assertSame($license->num_licenses, 10);
$this->assertSame($license->idempotency_key, "123e4567-e89b-12d3-a456-426614174000");
$this->assertTrue($license->creation_date->eq(new Carbon($post['creationDate'])));
$this->assertTrue($license->expiration_date->eq(new Carbon($post['expirationDate'])));
$this->assertSame($license->owner_id, $post['owner']['id']);
+ $this->assertSame($license->test_license, 0);
// Validate returned json object
$json = $response->json();
$this->assertSame($json['keyId'], $post['keyId']);
$this->assertSame($json['productId'], $post['productId']);
// $this->assertSame($json['items'], $post['items']);
$this->assertSame($json['body'], $license->body);
$this->assertSame($json['status'], $post['status']);
$this->assertSame($json['creationDate'], $post['creationDate']);
$this->assertSame($json['operationDate'], $post['operationDate']);
$this->assertSame($json['expirationDate'], $post['expirationDate']);
$this->assertSame($json['owner']['id'], $post['owner']['id']);
$this->assertSame($json['nfr'], $post['nfr']);
$this->assertSame($json['activationData'], null);
// Test idempotency
$response = $this->postJson("api/v2/plesk/key?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174000", $post);
$response->assertStatus(500);
// Test recreate key
$response = $this->postJson("api/v2/plesk/key?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174123", $post);
$response->assertStatus(500);
}
public function testTestMode()
{
$post = [
"keyId" => 7,
"productId" => "PLESK-10",
"items" => [
"item" => "cpu_cores",
"value" => '5'
],
"body" => null,
"status" => 'active',
"creationDate" => "2016-08-29T09:12:33.000Z",
"operationDate" => "2016-08-29T09:12:33.000Z",
"expirationDate" => "2016-09-29T09:12:33.000Z",
"owner" => [
"id" => 12345
],
"nfr" => false,
"activationData" => ""
];
$response = $this->postJson("api/v2/plesk/key?testMode=true&idempotencyKey=123e4567-e89b-12d3-a456-426614174123", $post);
$response->assertStatus(200);
$json = $response->json();
$this->assertArrayHasKey('body', $json);
$this->assertSame(\App\Models\License::usersFromBody($json['body']), 10);
- $this->assertFalse(\App\Models\License::where('key_id', $post['keyId'])->exists());
+ $license = \App\Models\License::where('key_id', $post['keyId'])->first();
+ $this->assertNotNull($license);
+ $this->assertSame($license->test_license, 1);
+
+ $response = $this->get("api/v2/plesk/key/{$post['keyId']}?testMode=true");
+ $response->assertStatus(200);
+
+ $response = $this->get("api/v2/plesk/key/{$post['keyId']}?testMode=false");
+ $response->assertStatus(404);
}
public function testNFRLicense()
{
$post = [
"keyId" => 7,
"productId" => "PLESK-10",
"items" => [
"item" => "cpu_cores",
"value" => '5'
],
"body" => null,
"status" => 'active',
"creationDate" => "2016-08-29T09:12:33.000Z",
"operationDate" => "2016-08-29T09:12:33.000Z",
"expirationDate" => "2016-09-29T09:12:33.000Z",
"owner" => [
"id" => 12345
],
"nfr" => true,
"activationData" => ""
];
$response = $this->postJson("api/v2/plesk/key?testMode=true&idempotencyKey=123e4567-e89b-12d3-a456-426614174123", $post);
$response->assertStatus(200);
$json = $response->json();
$this->assertSame(\App\Models\License::nfrFromBody($json['body']), true);
$this->assertSame($json['nfr'], true);
}
public function testGet()
{
$post = [
"keyId" => 123456789,
"productId" => "PLESK-10",
"items" => [
"item" => "cpu_cores",
"value" => '5'
],
"body" => null,
"status" => 'active',
"creationDate" => "2016-08-29T09:12:33.000Z",
"operationDate" => "2016-08-29T09:12:33.000Z",
"expirationDate" => "2016-09-29T09:12:33.000Z",
"owner" => [
"id" => 12345
],
"nfr" => false,
"activationData" => ""
];
$response = $this->postJson("api/v2/plesk/key?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174000", $post);
$response->assertStatus(200);
$license = \App\Models\License::where('key_id', $post['keyId'])->first();
// Test get
$response = $this->get("api/v2/plesk/key/{$post['keyId']}");
$response->assertStatus(200);
// Validate returned json object
$json = $response->json();
$this->assertSame($json['keyId'], $post['keyId']);
$this->assertSame($json['productId'], $post['productId']);
$this->assertSame($json['body'], $license->body);
$this->assertSame($json['status'], $post['status']);
//TODO we're loosing subsecond accuracy because of the PDO interface (I think)
$this->assertSame($json['creationDate'], $post['creationDate']);
// $this->assertSame($json['operationDate'], $post['operationDate']);
$this->assertSame($json['expirationDate'], $post['expirationDate']);
$this->assertSame($json['owner']['id'], $post['owner']['id']);
$this->assertSame($json['nfr'], $post['nfr']);
// $this->assertSame($json['activationData'], null);
$response = $this->get("api/v2/plesk/key/invalid");
$response->assertStatus(404);
$response = $this->get("api/v2/plesk/key/77777");
$response->assertStatus(404);
}
public function testTerminate()
{
$post = [
"keyId" => 123456789,
"productId" => "PLESK-10",
"items" => [
"item" => "cpu_cores",
"value" => '5'
],
"body" => null,
"status" => 'active',
"creationDate" => "2016-08-29T09:12:33.000Z",
"operationDate" => "2016-08-29T09:12:33.000Z",
"expirationDate" => "2016-09-29T09:12:33.000Z",
"owner" => [
"id" => 12345
],
"nfr" => false,
"activationData" => ""
];
$response = $this->postJson("api/v2/plesk/key?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174000", $post);
$response->assertStatus(200);
$response = $this->delete("api/v2/plesk/key/{$post['keyId']}");
$response->assertStatus(200);
$license = \App\Models\License::withTrashed()->where('key_id', $post['keyId'])->first();
$this->assertSame($license->status, "terminated");
$this->assertTrue($license->trashed());
$response = $this->delete("api/v2/plesk/key/invalid");
$response->assertStatus(404);
$response = $this->delete("api/v2/plesk/key/77777");
$response->assertStatus(404);
}
+ public function testTerminateTestMode()
+ {
+ $post = [
+ "keyId" => 123456789,
+ "productId" => "PLESK-10",
+ "items" => [
+ "item" => "cpu_cores",
+ "value" => '5'
+ ],
+ "body" => null,
+ "status" => 'active',
+ "creationDate" => "2016-08-29T09:12:33.000Z",
+ "operationDate" => "2016-08-29T09:12:33.000Z",
+ "expirationDate" => "2016-09-29T09:12:33.000Z",
+ "owner" => [
+ "id" => 12345
+ ],
+ "nfr" => false,
+ "activationData" => ""
+ ];
+
+ $response = $this->postJson("api/v2/plesk/key?testMode=true&idempotencyKey=123e4567-e89b-12d3-a456-426614174000", $post);
+ $response->assertStatus(200);
+
+ $response = $this->delete("api/v2/plesk/key/{$post['keyId']}?testMode=true");
+ $response->assertStatus(200);
+
+ $license = \App\Models\License::withTrashed()->where('key_id', $post['keyId'])->first();
+ $this->assertSame($license->status, "terminated");
+ $this->assertTrue($license->trashed());
+
+ $response = $this->delete("api/v2/plesk/key/invalid?testMode=true");
+ $response->assertStatus(404);
+
+ $response = $this->delete("api/v2/plesk/key/77777?testMode=true");
+ $response->assertStatus(404);
+ }
+
public function testUpdate()
{
$post = [
"keyId" => 123456789,
"productId" => "PLESK-10",
"items" => [
"item" => "cpu_cores",
"value" => '5'
],
"body" => null,
"status" => 'active',
"creationDate" => "2016-08-29T09:12:33.000Z",
"operationDate" => "2016-08-29T09:12:33.000Z",
"expirationDate" => "2016-09-29T09:12:33.000Z",
"owner" => [
"id" => 12345
],
"nfr" => false,
"activationData" => ""
];
$response = $this->postJson("api/v2/plesk/key?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174000", $post);
$response->assertStatus(200);
// The upgrade
$post['productId'] = "PLESK-100";
$response = $this->putJson("api/v2/plesk/key/{$post['keyId']}?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174001", $post);
$response->assertStatus(200);
$json = $response->json();
$this->assertSame($json['productId'], $post['productId']);
$license = \App\Models\License::where('key_id', $post['keyId'])->first();
$this->assertSame($license->num_licenses, 100);
// Suspend
$post['status'] = "suspended";
$response = $this->putJson("api/v2/plesk/key/{$post['keyId']}?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174002", $post);
$response->assertStatus(200);
$json = $response->json();
$this->assertSame($json['status'], $post['status']);
$license = \App\Models\License::where('key_id', $post['keyId'])->first();
$this->assertSame($license->status, "suspended");
// Renew after delete
$response = $this->delete("api/v2/plesk/key/{$post['keyId']}");
$response->assertStatus(200);
$post['status'] = "active";
$response = $this->putJson("api/v2/plesk/key/{$post['keyId']}?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174003", $post);
$response->assertStatus(200);
$json = $response->json();
$this->assertSame($json['status'], $post['status']);
$license = \App\Models\License::where('key_id', $post['keyId'])->first();
$this->assertSame($license->status, "active");
}
public function testSignature() {
$post = [
"keyId" => 123456789,
"productId" => "PLESK-10",
"items" => [
"item" => "cpu_cores",
"value" => '5'
],
"body" => null,
"status" => 'active',
"creationDate" => "2016-08-29T09:12:33.000Z",
"operationDate" => "2016-08-29T09:12:33.000Z",
"expirationDate" => "2016-09-29T09:12:33.000Z",
"owner" => [
"id" => 12345
],
"nfr" => false,
"activationData" => ""
];
$response = $this->postJson("api/v2/plesk/key?testMode=false&idempotencyKey=123e4567-e89b-12d3-a456-426614174000", $post);
$response->assertStatus(200);
// Validate license
$license = \App\Models\License::where('key_id', $post['keyId'])->first();
$body = $license->body;
// $body_parsed = openssl_x509_parse($body);
// var_export($body_parsed);
$publicKey = openssl_get_publickey(\config("app.ca_cert"));
$ret = openssl_x509_verify($body, $publicKey);
$this->assertSame($ret, 1);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Apr 24, 10:12 AM (2 d, 4 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18862687
Default Alt Text
(30 KB)
Attached To
Mode
rPLESKISV plesk-isv-endpoint
Attached
Detach File
Event Timeline