Skip to content

Commit

Permalink
Add middleware, method UserResetPassword, UserDelete, LockInitialize;…
Browse files Browse the repository at this point in the history
… change transport & configuration
  • Loading branch information
sunnyphp committed Nov 24, 2023
1 parent 7bc1041 commit 36bbd8f
Show file tree
Hide file tree
Showing 23 changed files with 580 additions and 52 deletions.
49 changes: 41 additions & 8 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

namespace SunnyPHP\TTLock;

use SunnyPHP\TTLock\Contract\Request\RequiredConfiguration;
use Webmozart\Assert\Assert;

/**
Expand All @@ -12,20 +13,27 @@ final class Configuration
{
private const ENDPOINT = 'https://euapi.ttlock.com';
private string $clientId;
private string $clientSecret;
private ?string $clientSecret;
private ?string $accessToken;
private string $endpointHost;
private static array $toArrayFilter = [
'clientId' => RequiredConfiguration::CLIENT_ID,
'clientSecret' => RequiredConfiguration::CLIENT_SECRET,
'accessToken' => RequiredConfiguration::ACCESS_TOKEN,
];

public function __construct(
string $clientId,
string $clientSecret,
?string $clientSecret = null,
?string $accessToken = null,
string $endpointHost = self::ENDPOINT
) {
Assert::notEmpty($clientId, 'ClientId param should be filled');
Assert::notEmpty($clientSecret, 'ClientSecret param should be filled');
Assert::notEmpty($endpointHost, 'EndpointHost param should be filled, use default value: ' . self::ENDPOINT);

$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
$this->accessToken = $accessToken;
$this->endpointHost = $endpointHost;
}

Expand All @@ -34,28 +42,53 @@ public function getClientId(): string
return $this->clientId;
}

public function getClientSecret(): string
public function getClientSecret(): ?string
{
return $this->clientSecret;
}

public function getAccessToken(): ?string
{
return $this->accessToken;
}

public function getEndpointHost(): string
{
return $this->endpointHost;
}

public function withClientId(string $clientId): self
{
return new self($clientId, $this->getClientSecret(), $this->getEndpointHost());
return new self($clientId, $this->getClientSecret(), $this->getAccessToken(), $this->getEndpointHost());
}

public function withClientSecret(?string $clientSecret): self
{
return new self($this->getClientId(), $clientSecret, $this->getAccessToken(), $this->getEndpointHost());
}

public function withClientSecret(string $clientSecret): self
public function withAccessToken(?string $accessToken): self
{
return new self($this->getClientId(), $clientSecret, $this->getEndpointHost());
return new self($this->getClientId(), $this->getClientSecret(), $accessToken, $this->getEndpointHost());
}

public function withEndpointHost(string $endpointHost): self
{
return new self($this->getClientId(), $this->getClientSecret(), $endpointHost);
return new self($this->getClientId(), $this->getClientSecret(), $this->getAccessToken(), $endpointHost);
}

public function toArray(?int $bitmask = null): array
{
$params = [];

foreach (self::$toArrayFilter as $key => $filterBit) {
if ($bitmask === null || ($bitmask & $filterBit) === $filterBit) {
Assert::propertyExists($this, $key);

$params[$key] = $this->{$key};
}
}

return $params;
}
}
11 changes: 11 additions & 0 deletions src/Contract/Middleware/BeforeResponse/BeforeResponseInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);

namespace SunnyPHP\TTLock\Contract\Middleware\BeforeResponse;

use SunnyPHP\TTLock\Contract\Middleware\MiddlewareInterface;

interface BeforeResponseInterface extends MiddlewareInterface
{
public function handle(array $response, ?MiddlewareInterface $next = null): array;
}
12 changes: 12 additions & 0 deletions src/Contract/Middleware/MiddlewareInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);

namespace SunnyPHP\TTLock\Contract\Middleware;

interface MiddlewareInterface
{
/**
* @return class-string
*/
public function getType(): string;
}
20 changes: 20 additions & 0 deletions src/Contract/Request/Lock/InitializeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);

namespace SunnyPHP\TTLock\Contract\Request\Lock;

use DateTimeImmutable;
use SunnyPHP\TTLock\Contract\Request\RequestInterface;

interface InitializeInterface extends RequestInterface
{
public function getLockData(): string;

public function getLockAlias(): ?string;

public function getGroupId(): ?int;

public function getNbInitSuccess(): ?bool;

public function getCurrentTime(): DateTimeImmutable;
}
6 changes: 3 additions & 3 deletions src/Contract/Request/RequestInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
interface RequestInterface
{
/**
* Returns True if client credentials required (clientId, clientSecret)
* @return bool
* Returns required configuration bitmask
* @return int
*/
public function isClientCredentialsRequired(): bool;
public function getRequiredConfiguration(): int;

/**
* Endpoint request URL part
Expand Down
11 changes: 11 additions & 0 deletions src/Contract/Request/RequiredConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);

namespace SunnyPHP\TTLock\Contract\Request;

final class RequiredConfiguration
{
public const CLIENT_ID = 1 << 0;
public const CLIENT_SECRET = 1 << 1;
public const ACCESS_TOKEN = 1 << 2;
}
22 changes: 22 additions & 0 deletions src/Contract/Request/User/DeleteInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);

namespace SunnyPHP\TTLock\Contract\Request\User;

use DateTimeImmutable;
use SunnyPHP\TTLock\Contract\Request\RequestInterface;

interface DeleteInterface extends RequestInterface
{
/**
* Username for delete (only numbers and english letters)
* @return string
*/
public function getUsername(): string;

/**
* Current time
* @return DateTimeImmutable
*/
public function getCurrentTime(): DateTimeImmutable;
}
28 changes: 28 additions & 0 deletions src/Contract/Request/User/ResetPasswordInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);

namespace SunnyPHP\TTLock\Contract\Request\User;

use DateTimeImmutable;
use SunnyPHP\TTLock\Contract\Request\RequestInterface;

interface ResetPasswordInterface extends RequestInterface
{
/**
* Username (only numbers and english letters)
* @return string
*/
public function getUsername(): string;

/**
* New password (32 chars, low case, md5 encrypted)
* @return string
*/
public function getPassword(): string;

/**
* Current time
* @return DateTimeImmutable
*/
public function getCurrentTime(): DateTimeImmutable;
}
14 changes: 14 additions & 0 deletions src/Contract/Response/Common/SuccessResponseInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);

namespace SunnyPHP\TTLock\Contract\Response\Common;

use SunnyPHP\TTLock\Contract\Response\ResponseInterface;

/**
* No data, no error, just success execution
*/
interface SuccessResponseInterface extends ResponseInterface
{

}
13 changes: 13 additions & 0 deletions src/Contract/Response/Lock/InitializeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);

namespace SunnyPHP\TTLock\Contract\Response\Lock;

use SunnyPHP\TTLock\Contract\Response\ResponseInterface;

interface InitializeInterface extends ResponseInterface
{
public function getLockId(): int;

public function getKeyId(): int;
}
53 changes: 41 additions & 12 deletions src/Entrypoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

namespace SunnyPHP\TTLock;

use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use ReflectionClass;
use stdClass;
use SunnyPHP\TTLock\Contract\Middleware\BeforeResponse\BeforeResponseInterface;
use SunnyPHP\TTLock\Contract\Middleware\MiddlewareInterface;
use SunnyPHP\TTLock\Contract\Request;
use SunnyPHP\TTLock\Contract\Response;
use SunnyPHP\TTLock\Response as R;
Expand All @@ -19,32 +19,57 @@
* @method Response\OAuth2\RefreshAccessTokenInterface getOAuth2RefreshAccessToken(Request\OAuth2\RefreshAccessTokenInterface $request)
* @method Response\User\GetListInterface getUserList(Request\User\GetListInterface $request)
* @method Response\User\RegisterInterface getUserRegister(Request\User\RegisterInterface $request)
* @method Response\Common\SuccessResponseInterface getUserResetPassword(Request\User\ResetPasswordInterface $request)
* @method Response\Common\SuccessResponseInterface getUserDelete(Request\User\DeleteInterface $request)
* @method Response\Lock\InitializeInterface getLockInitialize(Request\Lock\InitializeInterface $request)
*/
final class Entrypoint
{
private Configuration $configuration;
private Transport $transport;
private Middleware $middleware;
private array $responseClass = [
Request\OAuth2\AccessTokenInterface::class => R\OAuth2\AccessToken::class,
Request\OAuth2\RefreshAccessTokenInterface::class => R\OAuth2\RefreshAccessToken::class,
Request\User\GetListInterface::class => R\User\GetList::class,
Request\User\RegisterInterface::class => R\User\Register::class,
Request\User\ResetPasswordInterface::class => R\Common\SuccessResponse::class,
Request\User\DeleteInterface::class => R\Common\SuccessResponse::class,
Request\Lock\InitializeInterface::class => R\Lock\Initialize::class,
];

public function __construct(
Configuration $configuration,
?ClientInterface $httpClient = null,
?RequestFactoryInterface $requestFactory = null,
?Transport $transport = null,
array $middlewares = [],
array $responseClasses = []
) {
$this->configuration = $configuration;
$this->transport = new Transport($configuration->getEndpointHost(), $httpClient, $requestFactory);
$this->transport = $transport ?: new Transport();
$this->middleware = new Middleware($middlewares);

if ($responseClasses !== []) {
$this->setResponseClasses($responseClasses);
}
}

public function withConfiguration(Configuration $configuration): self
{
return new self($configuration, $this->transport, $this->responseClass);
}

public function withConfigurationAccessToken(string $accessToken): self
{
return $this->withConfiguration($this->configuration->withAccessToken($accessToken));
}

public function addMiddleware(MiddlewareInterface $middleware): self
{
$this->middleware->add($middleware);

return $this;
}

public function setResponseClasses(array $responseClasses): self
{
foreach ($responseClasses as $requestInterface => $responseClass) {
Expand All @@ -66,24 +91,28 @@ public function setResponseClass(string $requestInterface, string $responseClass

public function getResponse(Request\RequestInterface $request, string $responseClass): Response\ResponseInterface
{
$url = $this->configuration->getEndpointHost() . $request->getEndpointUrl();

$params = $request->toArray();
if ($request->isClientCredentialsRequired()) {
$params = array_replace($params, [
'clientId' => $this->configuration->getClientId(),
'clientSecret' => $this->configuration->getClientSecret(),
]);
if ($bitmask = $request->getRequiredConfiguration()) {
$params = array_replace($params, $this->configuration->toArray($bitmask));
}

if ($request->getEndpointMethod() === Request\Method::POST) {
$requestObject = $this->transport->createPostRequest($request->getEndpointUrl(), [
$requestObject = $this->transport->createPostRequest($url, [
'Content-Type' => 'application/x-www-form-urlencoded',
], http_build_query($params));
} else {
$requestObject = $this->transport->createGetRequest($request->getEndpointUrl(), $params);
$requestObject = $this->transport->createGetRequest($url, $params);
}

$responseArray = $this->transport->getEndpointResponse($requestObject);

foreach ($this->middleware->getAll(BeforeResponseInterface::class) as $middleware) {
/** @var BeforeResponseInterface $middleware */
$responseArray = $middleware->handle($responseArray);
}

return new $responseClass($responseArray);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Exception/ApiException.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function getResponse(): ?ResponseInterface

public static function supports($content): bool
{
return is_array($content) && isset($content['errmsg']);
return is_array($content) && isset($content['errcode']) && $content['errcode'] != 0;
}

public static function createFromArray(array $content, ?ResponseInterface $response = null): self
Expand Down
Loading

0 comments on commit 36bbd8f

Please sign in to comment.