diff --git a/com_oauthserver/site/src/Repository/ClientRepository.php b/com_oauthserver/site/src/Repository/ClientRepository.php index 74d4a0a..b453b6e 100644 --- a/com_oauthserver/site/src/Repository/ClientRepository.php +++ b/com_oauthserver/site/src/Repository/ClientRepository.php @@ -2,36 +2,85 @@ namespace Webmasterskaya\Component\OauthServer\Site\Repository; -use Joomla\CMS\MVC\Factory\MVCFactoryAwareTrait; -use Joomla\CMS\MVC\Factory\MVCFactoryInterface; +use Joomla\CMS\Object\CMSObject; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; +use Webmasterskaya\Component\OauthServer\Administrator\Model\ClientModel; +use Webmasterskaya\Component\OauthServer\Site\Entity\Client; class ClientRepository implements ClientRepositoryInterface { - use MVCFactoryAwareTrait; + private ClientModel $clientModel; - public function __construct(MVCFactoryInterface $MVCFactory) + public function __construct(ClientModel $clientModel) { - $this->setMVCFactory($MVCFactory); + $this->clientModel = $clientModel; } /** * @param $clientIdentifier - * @return \League\OAuth2\Server\Entities\ClientEntityInterface + * @return \League\OAuth2\Server\Entities\ClientEntityInterface|null * @throws \Exception * @since version */ - public function getClientEntity($clientIdentifier): ClientEntityInterface + public function getClientEntity($clientIdentifier): ?ClientEntityInterface { - /** @var \Webmasterskaya\Component\OauthServer\Administrator\Table\ClientTable $table */ - $table = $this->getMVCFactory()->createTable('Client', 'Administrator'); - $table->load(['identifier' => $clientIdentifier]); - return $table; + $item = $this->clientModel->getItemByIdentifier($clientIdentifier); + + if (empty($item->id)) { + return null; + } + + return $this->buildClientEntity($item); } - public function validateClient($clientIdentifier, $clientSecret, $grantType) + public function validateClient($clientIdentifier, $clientSecret, $grantType): bool { - // TODO: Implement validateClient() method. + $item = $this->clientModel->getItemByIdentifier($clientIdentifier); + + if (empty($item->id)) { + return false; + } + + if (!$item->active) { + return false; + } + + if (!$this->isGrantSupported($item, $grantType)) { + return false; + } + + if (!!$item->public || hash_equals((string)$item->secret, (string)$clientSecret)) { + return true; + } + + return false; + } + + private function buildClientEntity(\stdClass|CMSObject $client): Client + { + $clientEntity = new Client(); + $clientEntity->setName($client->name); + $clientEntity->setIdentifier($client->identifier); + $clientEntity->setRedirectUri(array_map('strval', (array)$client->redirect_uris)); + $clientEntity->setConfidential(!$client->public); + $clientEntity->setAllowPlainTextPkce((bool)$client->allow_plain_text_pkce); + + return $clientEntity; + } + + private function isGrantSupported(\stdClass|CMSObject $client, ?string $grant): bool + { + if (null === $grant) { + return true; + } + + $grants = array_map('strval', (array)$client->grants); + + if (empty($grants)) { + return true; + } + + return \in_array($grant, $grants); } } \ No newline at end of file