From 79b161b4d08f56105157c9c64b6eb5b4dfa5f7b1 Mon Sep 17 00:00:00 2001 From: David Coutadeur Date: Fri, 13 Sep 2024 14:54:32 +0200 Subject: [PATCH] create cache functions (#37) --- composer.json | 3 +- src/Ltb/Cache.php | 66 ++++++++++++++++++++ tests/Ltb/CacheTest.php | 133 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 src/Ltb/Cache.php create mode 100644 tests/Ltb/CacheTest.php diff --git a/composer.json b/composer.json index cd0ad8d..3021491 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ "require": { "php": ">=7.4", "ext-ldap": ">=7.4", - "phpmailer/phpmailer": "^6.5.0" + "phpmailer/phpmailer": "^6.5.0", + "symfony/cache": "v5.4.42" }, "require-dev": { "phpunit/phpunit": ">=8", diff --git a/src/Ltb/Cache.php b/src/Ltb/Cache.php new file mode 100644 index 0000000..91ff8da --- /dev/null +++ b/src/Ltb/Cache.php @@ -0,0 +1,66 @@ +sspCache = new FilesystemAdapter( + $namespace, + $defaultLifetime, + $directory + ); + + // Clean cache from expired entries + $this->sspCache->prune(); + + } + + # Generate a cache entry containing a token, + # expiring after $cache_form_expiration seconds + function generate_form_token($cache_form_expiration) + { + $formtoken = hash('sha256', bin2hex(random_bytes(16))); + $cachedToken = $this->sspCache->getItem($formtoken); + $cachedToken->set($formtoken); + $cachedToken->expiresAfter($cache_form_expiration); + $this->sspCache->save($cachedToken); + error_log("generated form token: " . + $formtoken . + " valid for $cache_form_expiration s"); + return $formtoken; + } + + # Verify that give token exist in cache + # and if it exists, remove it from cache + function verify_form_token($formtoken) + { + $result = ""; + $cachedToken = $this->sspCache->getItem($formtoken); + if( $cachedToken->isHit() && $cachedToken->get() == $formtoken ) + { + # Remove token from cache entry + $this->sspCache->deleteItem($formtoken); + } + else + { + error_log("Invalid form token: sent: $formtoken, stored: " . + $cachedToken->get()); + $result = "invalidformtoken"; + } + return $result; + } + + +} + +?> diff --git a/tests/Ltb/CacheTest.php b/tests/Ltb/CacheTest.php new file mode 100644 index 0000000..d6f1391 --- /dev/null +++ b/tests/Ltb/CacheTest.php @@ -0,0 +1,133 @@ +assertTrue($cacheInstance->sspCache instanceof Symfony\Component\Cache\Adapter\FilesystemAdapter, "Error while initializing sspCache object"); + } + + + public function test_generate_form_token(): void + { + + $cacheInstance = new \Ltb\Cache( + "testCache", + 0, + null + ); + + $generated_token = ""; + + $cacheInstance->sspCache = Mockery::mock('FilesystemAdapter'); + $cacheInstance->sspCache->shouldreceive('getItem') + ->andReturnUsing( + function($token) use (&$generated_token){ + $generated_token = $token; + + $cacheItem = Mockery::mock('CacheItem'); + + $cacheItem->shouldreceive('set') + ->andReturnUsing( + function($formtoken) use (&$token) { + $this->assertEquals($formtoken, + $token, + "Error: received token in set ($formtoken) is different from received token in getItem ($token)"); + } + ); + + $cacheItem->shouldreceive('expiresAfter') + ->with(120); + + return $cacheItem; + } + ); + + $cacheInstance->sspCache->shouldreceive('save'); + + $receivedToken = $cacheInstance->generate_form_token(120); + $this->assertEquals("$receivedToken", + $generated_token, + "Error: received token in generate_form_token ($receivedToken) is different from received token in getItem ($generated_token)"); + + } + + public function test_verify_form_token_ok(): void + { + + $generated_token = "e712b08e55f8977e2b9ecad35d5180ed24345e76607413411e90df66b9538fa1"; + + $cacheInstance = new \Ltb\Cache( + "testCache", + 0, + null + ); + + $cacheInstance->sspCache = Mockery::mock('FilesystemAdapter'); + $cacheInstance->sspCache->shouldreceive('getItem') + ->andReturnUsing( + function($token) use(&$generated_token) { + $cacheItem = Mockery::mock('CacheItem'); + + $cacheItem->shouldreceive('isHit') + ->andReturn(true); + + $cacheItem->shouldreceive('get') + ->andReturn($generated_token); + + return $cacheItem; + } + ); + + $cacheInstance->sspCache->shouldreceive('deleteItem') + ->with($generated_token); + + $result = $cacheInstance->verify_form_token($generated_token); + $this->assertEquals("", + $result, + "Error: invalid result: '$result' sent by verify_form_token"); + + } + + public function test_verify_form_token_ko(): void + { + + $generated_token = "e712b08e55f8977e2b9ecad35d5180ed24345e76607413411e90df66b9538fa1"; + + $cacheInstance = new \Ltb\Cache( + "testCache", + 0, + null + ); + + $cacheInstance->sspCache = Mockery::mock('FilesystemAdapter'); + $cacheInstance->sspCache->shouldreceive('getItem') + ->andReturnUsing( + function($token) use(&$generated_token) { + $cacheItem = Mockery::mock('CacheItem'); + + $cacheItem->shouldreceive('isHit') + ->andReturn(false); + + $cacheItem->shouldreceive('get') + ->andReturn(null); + + return $cacheItem; + } + ); + + $result = $cacheInstance->verify_form_token($generated_token); + $this->assertEquals("invalidformtoken", + $result, + "Error: expected 'invalidformtoken', but received result: '$result' in verify_form_token"); + + } +}