Mark van Holsteijn пре 5 година
родитељ
комит
1232717334
2 измењених фајлова са 42 додато и 17 уклоњено
  1. 26 11
      lib/Data/GoogleCloudStorage.php
  2. 16 6
      tst/Data/GoogleCloudStorageTest.php

+ 26 - 11
lib/Data/GoogleCloudStorage.php

@@ -2,6 +2,7 @@
 
 namespace PrivateBin\Data;
 
+use DateTime;
 use Exception;
 use Google\Cloud\Core\Exception\NotFoundException;
 use Google\Cloud\Storage\StorageClient;
@@ -9,6 +10,8 @@ use PrivateBin\Json;
 
 class GoogleCloudStorage extends AbstractData
 {
+    const DATETIME_FORMAT = 'Y-m-d\TH:i:s.u\Z';
+
     /**
      * returns a Google Cloud Storage data backend.
      *
@@ -218,20 +221,32 @@ class GoogleCloudStorage extends AbstractData
     }
 
     /**
-     * Purge outdated entries.
-     *
-     * @access public
-     * @param  string $namespace
-     * @param  int $time
-     * @return void
+     * @inheritDoc
      */
     public function purgeValues($namespace, $time)
     {
-        if ($namespace === 'traffic_limiter') {
-            // TODO implement purging of keys in namespace that are <= $time
-            // if GCS has no easy way to iterate all keys, consider using the
-            // self::$_traffic_limiter_cache in a similar way as the other
-            // implementations.
+        $prefix = 'config/' . $namespace . '/';
+        try {
+            foreach ($this->_bucket->objects(array('prefix' => $prefix)) as $object) {
+                $info        = $object->info();
+                $timeCreated = false;
+                if (key_exists('timeCreated', $info)) {
+                    $timeCreated = DateTime::createFromFormat(GoogleCloudStorage::DATETIME_FORMAT, $info['timeCreated']);
+                }
+                if ($timeCreated && ($timeCreated->getTimestamp() < $time)) {
+                    try {
+                        $object->delete();
+                    } catch (NotFoundException $e) {
+                        // deleted by another instance.
+                    }
+                } else {
+                    if (!$timeCreated) {
+                        error_log('failed to parse create timestamp ' . $info['timeCreated'] . ' of object ' . $object->name());
+                    }
+                }
+            }
+        } catch (NotFoundException $e) {
+            // no objects in the bucket yet
         }
     }
 

+ 16 - 6
tst/Data/GoogleCloudStorageTest.php

@@ -43,7 +43,6 @@ class GoogleCloudStorageTest extends PHPUnit_Framework_TestCase
         foreach (self::$_bucket->objects() as $object) {
             $object->delete();
         }
-        error_reporting(E_ALL);
     }
 
     public static function tearDownAfterClass()
@@ -145,17 +144,26 @@ class GoogleCloudStorageTest extends PHPUnit_Framework_TestCase
         $this->_model->setValue($salt, 'salt', 'master');
         $storedSalt = $this->_model->getValue('salt', 'master');
         $this->assertEquals($salt, $storedSalt);
+        $this->_model->purgeValues('salt', time() + 60);
+        $this->assertFalse($this->_model->getValue('salt', 'master'));
 
         $client = hash_hmac('sha512', '127.0.0.1', $salt);
         $expire = time();
         $this->_model->setValue($expire, 'traffic_limiter', $client);
         $storedExpired = $this->_model->getValue('traffic_limiter', $client);
         $this->assertEquals($expire, $storedExpired);
+        $this->assertEquals($expire, $storedExpired);
+        $this->_model->purgeValues('traffic_limiter', time() - 60);
+        $this->assertEquals($storedExpired, $this->_model->getValue('traffic_limiter', $client));
+        $this->_model->purgeValues('traffic_limiter', time() + 60);
+        $this->assertFalse($this->_model->getValue('traffic_limiter', $client));
 
         $purgeAt = $expire + (15 * 60);
         $this->_model->setValue($purgeAt, 'purge_limiter', 'at');
         $storedPurgedAt = $this->_model->getValue('purge_limiter', 'at');
         $this->assertEquals($purgeAt, $storedPurgedAt);
+        $this->_model->purgeValues('purge_limiter', time() + 60);
+        $this->assertFalse($this->_model->getValue('purge_limiter', 'at'));
     }
 }
 
@@ -431,11 +439,13 @@ class StorageObjectStub extends StorageObject
 
     public function __construct(ConnectionInterface $connection, $name, $bucket, $generation = null, array $info = array(), $encryptionKey = null, $encryptionKeySHA256 = null)
     {
-        $this->_name       = $name;
-        $this->_bucket     = $bucket;
-        $this->_generation = $generation;
-        $this->_info       = $info;
-        $this->_connection = $connection;
+        $this->_name                            = $name;
+        $this->_bucket                          = $bucket;
+        $this->_generation                      = $generation;
+        $this->_info                            = $info;
+        $this->_connection                      = $connection;
+        $timeCreated                            = new Datetime();
+        $this->_info['metadata']['timeCreated'] = $timeCreated->format(GoogleCloudStorage::DATETIME_FORMAT);
     }
 
     public function acl()