148 lines
4.6 KiB
PHP
148 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Belevo\EnelixEMS;
|
|
|
|
use DateTimeImmutable;
|
|
use InvalidArgumentException;
|
|
use Throwable;
|
|
|
|
final class Lizenzpruefung
|
|
{
|
|
public const MANAGER_STANDARD = 'manager_standard';
|
|
public const MANAGER_PEAK = 'manager_peak';
|
|
|
|
public static function normalisiereCode(string $code): string
|
|
{
|
|
return strtoupper((string) preg_replace('/[^A-Z0-9]/i', '', $code));
|
|
}
|
|
|
|
public static function istLizenzcodeGueltig(string $code): bool
|
|
{
|
|
return preg_match(
|
|
'/^ENX[A-HJ-NP-Z2-9]{16}$/',
|
|
self::normalisiereCode($code)
|
|
) === 1;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $lease
|
|
*/
|
|
public static function pruefeLease(
|
|
array $lease,
|
|
string $installationID,
|
|
int $lastspitzenmodus,
|
|
?int $zeitpunkt = null
|
|
): void {
|
|
if (($lease['status'] ?? null) !== 'active') {
|
|
throw new InvalidArgumentException('Die Lizenz ist nicht aktiv.');
|
|
}
|
|
if (($lease['installationId'] ?? null) !== $installationID) {
|
|
throw new InvalidArgumentException('Die Lizenz gehoert zu einer anderen Installation.');
|
|
}
|
|
if (isset($lease['development']) && !is_bool($lease['development'])) {
|
|
throw new InvalidArgumentException('Der Entwicklungsstatus der Lizenz ist ungueltig.');
|
|
}
|
|
|
|
$ausgestelltAm = self::zeitstempel($lease, 'issuedAt');
|
|
$erneuernAb = self::zeitstempel($lease, 'refreshAfter');
|
|
$offlineBis = self::zeitstempel($lease, 'offlineUntil');
|
|
if ($ausgestelltAm > $erneuernAb || $erneuernAb > $offlineBis) {
|
|
throw new InvalidArgumentException('Die Lizenzzeitpunkte sind widerspruechlich.');
|
|
}
|
|
if (($zeitpunkt ?? time()) >= $offlineBis) {
|
|
throw new InvalidArgumentException('Die Offline-Freigabe ist abgelaufen.');
|
|
}
|
|
|
|
$berechtigungen = $lease['entitlements'] ?? null;
|
|
if (!is_array($berechtigungen)) {
|
|
throw new InvalidArgumentException('Die Lizenz enthaelt keine Berechtigungen.');
|
|
}
|
|
$standard = false;
|
|
$peak = false;
|
|
foreach ($berechtigungen as $berechtigung) {
|
|
if (!is_array($berechtigung)
|
|
|| ($berechtigung['status'] ?? null) !== 'active'
|
|
|| !is_int($berechtigung['quantity'] ?? null)
|
|
|| $berechtigung['quantity'] < 1
|
|
) {
|
|
continue;
|
|
}
|
|
$kennung = $berechtigung['catalog_key'] ?? $berechtigung['sku'] ?? null;
|
|
$standard = $standard || $kennung === self::MANAGER_STANDARD;
|
|
$peak = $peak || $kennung === self::MANAGER_PEAK;
|
|
}
|
|
|
|
if (!$standard && !$peak) {
|
|
throw new InvalidArgumentException('Die Manager-Berechtigung fehlt.');
|
|
}
|
|
if ($lastspitzenmodus !== 0 && !$peak) {
|
|
throw new InvalidArgumentException('Peak Shaving ist nicht lizenziert.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $lease
|
|
*/
|
|
public static function istLeaseGueltig(
|
|
array $lease,
|
|
string $installationID,
|
|
int $lastspitzenmodus,
|
|
?int $zeitpunkt = null
|
|
): bool {
|
|
try {
|
|
self::pruefeLease($lease, $installationID, $lastspitzenmodus, $zeitpunkt);
|
|
|
|
return true;
|
|
} catch (Throwable $fehler) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $lease
|
|
*/
|
|
public static function erneuerungFaellig(array $lease, ?int $zeitpunkt = null): bool
|
|
{
|
|
try {
|
|
return ($zeitpunkt ?? time()) >= self::zeitstempel($lease, 'refreshAfter');
|
|
} catch (Throwable $fehler) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $lease
|
|
*/
|
|
public static function offlineBis(array $lease): int
|
|
{
|
|
return self::zeitstempel($lease, 'offlineUntil');
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $lease
|
|
*/
|
|
public static function erneuernAb(array $lease): int
|
|
{
|
|
return self::zeitstempel($lease, 'refreshAfter');
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $lease
|
|
*/
|
|
private static function zeitstempel(array $lease, string $feld): int
|
|
{
|
|
$wert = $lease[$feld] ?? null;
|
|
if (!is_string($wert) || trim($wert) === '') {
|
|
throw new InvalidArgumentException($feld . ' fehlt in der Lizenz.');
|
|
}
|
|
|
|
try {
|
|
return (new DateTimeImmutable($wert))->getTimestamp();
|
|
} catch (Throwable $fehler) {
|
|
throw new InvalidArgumentException($feld . ' ist kein gueltiger ISO-8601-Zeitpunkt.', 0, $fehler);
|
|
}
|
|
}
|
|
}
|