From f7f4b65c925b899512fa334eea2c5e89710fe647 Mon Sep 17 00:00:00 2001 From: regdos Date: Fri, 24 Apr 2026 12:29:49 +0200 Subject: [PATCH] Fix #135 - remove suppress the errors by @ --- lib/OpenPayU/Oauth/Cache/OauthCacheFile.php | 45 +++-- .../Oauth/Cache/OauthCacheInterface.php | 23 +-- .../Oauth/Cache/OauthCacheMemcached.php | 25 ++- lib/OpenPayU/Oauth/Oauth.php | 2 +- .../Oauth/Cache/OauthCacheFileTest.php | 191 ++++++++++++++++++ 5 files changed, 240 insertions(+), 46 deletions(-) create mode 100644 tests/unit/OpenPayU/Oauth/Cache/OauthCacheFileTest.php diff --git a/lib/OpenPayU/Oauth/Cache/OauthCacheFile.php b/lib/OpenPayU/Oauth/Cache/OauthCacheFile.php index 8294d41..3e556f9 100644 --- a/lib/OpenPayU/Oauth/Cache/OauthCacheFile.php +++ b/lib/OpenPayU/Oauth/Cache/OauthCacheFile.php @@ -2,39 +2,54 @@ class OauthCacheFile implements OauthCacheInterface { - private $directory; + private ?string $directory; /** - * @param string $directory * @throws OpenPayU_Exception_Configuration */ - public function __construct($directory = null) + public function __construct(string $directory = null) { if ($directory === null) { - $directory = dirname(__FILE__).'/../../../Cache'; + $directory = __DIR__ . '/../../../Cache'; } - if (!is_dir($directory) || !is_writable($directory)) { - throw new OpenPayU_Exception_Configuration('Cache directory [' . $directory . '] not exist or not writable.'); + if ( ! is_dir($directory) || ! is_writable($directory)) { + throw new OpenPayU_Exception_Configuration( + 'Cache directory [' . $directory . '] not exist or not writable.' + ); } - $this->directory = $directory . (substr($directory, -1) != '/' ? '/' : ''); + $this->directory = $directory . (substr($directory, -1) !== '/' ? '/' : ''); } - public function get($key) + public function get(string $key): ?OauthResultClientCredentials { - $cache = @file_get_contents($this->directory . md5($key)); - return $cache === false ? null : unserialize($cache); + $cacheFile = $this->getFilePath($key); + + try { + return file_exists($cacheFile) ? unserialize( + file_get_contents($cacheFile), + ['allowed_classes' => [OauthResultClientCredentials::class]] + ) : null; + } catch (\Throwable $e) { + return null; + } } - public function set($key, $value) + public function set(string $key, OauthResultClientCredentials $value): bool { - return @file_put_contents($this->directory . md5($key), serialize($value)); + return file_put_contents($this->directory . md5($key), serialize($value)) !== false; } - public function invalidate($key) + public function invalidate(string $key): bool { - return @unlink($this->directory . md5($key)); + $cacheFile = $this->getFilePath($key); + + return !file_exists($cacheFile) || unlink($cacheFile); } -} \ No newline at end of file + private function getFilePath(string $key): string + { + return $this->directory . md5($key); + } +} diff --git a/lib/OpenPayU/Oauth/Cache/OauthCacheInterface.php b/lib/OpenPayU/Oauth/Cache/OauthCacheInterface.php index a7d7363..d377a7e 100644 --- a/lib/OpenPayU/Oauth/Cache/OauthCacheInterface.php +++ b/lib/OpenPayU/Oauth/Cache/OauthCacheInterface.php @@ -1,26 +1,11 @@ memcached = new Memcached(); $this->memcached->addServer($host, $port, $weight); $stats = $this->memcached->getStats(); - if ($stats[$host . ':' . $port]['pid'] == -1) { + if ($stats[$host . ':' . $port]['pid'] === -1) { throw new OpenPayU_Exception_Configuration('Problem with connection to memcached server [host=' . $host . '] [port=' . $port . '] [weight=' . $weight . ']'); } } - public function get($key) + public function get(string $key): ?OauthResultClientCredentials { $cache = $this->memcached->get($key); - return $cache === false ? null : unserialize($cache); + try { + return $cache === false ? null : unserialize( + $cache, + ['allowed_classes' => [OauthResultClientCredentials::class]] + ); + } catch (\Error $e) { + return null; + } } - public function set($key, $value) + public function set(string $key, OauthResultClientCredentials $value): bool { return $this->memcached->set($key, serialize($value)); } - public function invalidate($key) + public function invalidate(string $key): bool { return $this->memcached->delete($key); } - } diff --git a/lib/OpenPayU/Oauth/Oauth.php b/lib/OpenPayU/Oauth/Oauth.php index d7bdb76..9bf200f 100644 --- a/lib/OpenPayU/Oauth/Oauth.php +++ b/lib/OpenPayU/Oauth/Oauth.php @@ -27,7 +27,7 @@ public static function getAccessToken($clientId = null, $clientSecret = null) $tokenCache = self::$oauthTokenCache->get($cacheKey); - if ($tokenCache instanceof OauthResultClientCredentials && !$tokenCache->hasExpire()) { + if (isset($tokenCache) && !$tokenCache->hasExpire()) { return $tokenCache; } diff --git a/tests/unit/OpenPayU/Oauth/Cache/OauthCacheFileTest.php b/tests/unit/OpenPayU/Oauth/Cache/OauthCacheFileTest.php new file mode 100644 index 0000000..60387b6 --- /dev/null +++ b/tests/unit/OpenPayU/Oauth/Cache/OauthCacheFileTest.php @@ -0,0 +1,191 @@ +tempDir = sys_get_temp_dir() . '/oauthcache_test_' . uniqid('', true); + mkdir($this->tempDir, 0777, true); + } + + protected function tearDown(): void + { + foreach (glob($this->tempDir . '/*') as $file) { + unlink($file); + } + rmdir($this->tempDir); + } + + private function buildCredentials(string $token = 'test-token', int $expiresIn = 3600): OauthResultClientCredentials + { + $creds = new OauthResultClientCredentials(); + $creds->setAccessToken($token); + $creds->setTokenType('bearer'); + $creds->setExpiresIn($expiresIn); + $creds->setGrantType('client_credentials'); + $creds->calculateExpireDate(new DateTime()); + return $creds; + } + + /** @test */ + public function shouldThrowExceptionWhenDirectoryDoesNotExist(): void + { + $this->expectException(OpenPayU_Exception_Configuration::class); + $this->expectExceptionMessageMatches('/not exist or not writable/'); + + new OauthCacheFile('/nonexistent/path/that/does/not/exist'); + } + + /** @test */ + public function shouldThrowExceptionWhenDirectoryIsNotWritable(): void + { + $readonlyDir = $this->tempDir . '/readonly'; + mkdir($readonlyDir, 0444); + + try { + $this->expectException(OpenPayU_Exception_Configuration::class); + $this->expectExceptionMessageMatches('/not exist or not writable/'); + + new OauthCacheFile($readonlyDir); + } finally { + chmod($readonlyDir, 0777); + rmdir($readonlyDir); + } + } + + /** @test */ + public function shouldInstantiateWithValidDirectory(): void + { + $cache = new OauthCacheFile($this->tempDir); + $this->assertInstanceOf(OauthCacheFile::class, $cache); + } + + /** @test */ + public function shouldInstantiateWithDefaultDirectory(): void + { + $cache = new OauthCacheFile(); + $this->assertInstanceOf(OauthCacheFile::class, $cache); + } + + /** @test */ + public function shouldReturnNullWhenKeyNotFound(): void + { + $cache = new OauthCacheFile($this->tempDir); + + $result = $cache->get('nonexistent-key'); + + $this->assertNull($result); + } + + /** @test */ + public function shouldStoreAndRetrieveCredentials(): void + { + $cache = new OauthCacheFile($this->tempDir); + $creds = $this->buildCredentials('my-access-token'); + + $cache->set('my-key', $creds); + $result = $cache->get('my-key'); + + $this->assertInstanceOf(OauthResultClientCredentials::class, $result); + $this->assertSame('my-access-token', $result->getAccessToken()); + $this->assertSame('bearer', $result->getTokenType()); + $this->assertSame('client_credentials', $result->getGrantType()); + } + + /** @test */ + public function shouldReturnTrueOnSuccessfulSet(): void + { + $cache = new OauthCacheFile($this->tempDir); + $creds = $this->buildCredentials(); + + $result = $cache->set('some-key', $creds); + + $this->assertTrue($result); + } + + /** @test */ + public function shouldIsolateDifferentKeys(): void + { + $cache = new OauthCacheFile($this->tempDir); + $cache->set('key-a', $this->buildCredentials('token-a')); + $cache->set('key-b', $this->buildCredentials('token-b')); + + $this->assertSame('token-a', $cache->get('key-a')->getAccessToken()); + $this->assertSame('token-b', $cache->get('key-b')->getAccessToken()); + } + + /** @test */ + public function shouldOverwriteExistingCacheEntry(): void + { + $cache = new OauthCacheFile($this->tempDir); + $cache->set('key', $this->buildCredentials('old-token')); + $cache->set('key', $this->buildCredentials('new-token')); + + $result = $cache->get('key'); + $this->assertSame('new-token', $result->getAccessToken()); + } + + /** @test */ + public function shouldReturnNullForCorruptedCacheFile(): void + { + $cache = new OauthCacheFile($this->tempDir); + $corruptedFile = $this->tempDir . '/' . md5('corrupted-key'); + file_put_contents($corruptedFile, 'this is not valid serialized data }{{{'); + + $result = $cache->get('corrupted-key'); + + $this->assertNull($result); + } + + /** @test */ + public function shouldReturnNullForNonOauthResultClientCredentialsInCacheFile(): void + { + $cache = new OauthCacheFile($this->tempDir); + $nonOauthResultClientCredentialsFile = $this->tempDir . '/' . md5('non-oauth-client-credentials'); + file_put_contents($nonOauthResultClientCredentialsFile, serialize(new stdClass())); + + $result = $cache->get('non-oauth-client-credentials'); + + $this->assertNull($result); + } + + /** @test */ + public function shouldInvalidateExistingCacheEntry(): void + { + $cache = new OauthCacheFile($this->tempDir); + $cache->set('key', $this->buildCredentials()); + + $result = $cache->invalidate('key'); + + $this->assertTrue($result); + $this->assertNull($cache->get('key')); + } + + /** @test */ + public function shouldReturnTrueWhenInvalidatingNonExistentKey(): void + { + $cache = new OauthCacheFile($this->tempDir); + + $result = $cache->invalidate('does-not-exist'); + + $this->assertTrue($result); + } + + /** @test */ + public function shouldRemoveCacheFileOnInvalidate(): void + { + $cache = new OauthCacheFile($this->tempDir); + $key = 'key-to-remove'; + $cache->set($key, $this->buildCredentials()); + + $cache->invalidate($key); + + $this->assertFileDoesNotExist($this->tempDir . '/' . md5($key)); + } +}