. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License version 3. * * In accordance with Section 7(b) of the GNU Affero General Public License version 3, * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ namespace Espo\Tools\OAuthServer\Secret; use Espo\Core\Name\Field; use Espo\Core\Utils\DateTime; use Espo\Core\Utils\PasswordHash; use Espo\ORM\EntityManager; use Espo\ORM\Query\Part\Order; use Espo\Tools\OAuthServer\Entities\Client; use Espo\Tools\OAuthServer\Entities\ClientSecret; use SensitiveParameter; class SecretValidator { public function __construct( private EntityManager $entityManager, private DateTime $dateTime, private PasswordHash $passwordHash, ) {} public function validate(Client $client, #[SensitiveParameter] string $secret): bool { $secrets = $this->entityManager ->getRDBRepositoryByClass(ClientSecret::class) ->sth() ->where([ ClientSecret::ATTR_CLIENT_ID => $client->getId(), ClientSecret::FIELD_STATUS => ClientSecret::STATUS_ACTIVE, ]) ->order(Field::CREATED_AT, Order::DESC) ->find(); foreach ($secrets as $entry) { /** @noinspection PhpParamsInspection */ if ($this->match($entry, $secret)) { return true; } } return false; } private function match(ClientSecret $entry, #[SensitiveParameter] string $secret): bool { if ($entry->getExpirationDate()?->isLessThanOrEqualTo($this->dateTime->getToday())) { return false; } return $this->passwordHash->verify($secret, $entry->getHash()); } }