diff --git a/composer.json b/composer.json index 2211780..7056788 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ ], "require" : { "php" : ">=7.2", - "league/flysystem-aws-s3-v3": "1.0.25", + "league/flysystem-aws-s3-v3": "^3.0.0", "aws/aws-sdk-php": "^3.0.0" }, "suggest": { diff --git a/src/AwsFlyWrapper.php b/src/AwsFlyWrapper.php index a597a2d..0b0c72e 100644 --- a/src/AwsFlyWrapper.php +++ b/src/AwsFlyWrapper.php @@ -19,18 +19,18 @@ namespace oat\awsTools; +use League\Flysystem\AwsS3V3\AwsS3V3Adapter; +use League\Flysystem\FilesystemAdapter; +use League\Flysystem\Local\LocalFilesystemAdapter; use oat\oatbox\service\ConfigurableService; -use League\Flysystem\AdapterInterface; use oat\oatbox\filesystem\utils\FlyWrapperTrait; -use League\Flysystem\AwsS3v3\AwsS3Adapter; use oat\flysystem\Adapter\LocalCacheAdapter; -use League\Flysystem\Adapter\Local; use oat\oatbox\log\LoggerAwareTrait; /** * * @author Joel Bout */ -class AwsFlyWrapper extends ConfigurableService implements AdapterInterface +class AwsFlyWrapper extends ConfigurableService implements FilesystemAdapter { use FlyWrapperTrait; use LoggerAwareTrait; @@ -62,10 +62,18 @@ public function getClient() public function getAdapter() { if (is_null($this->adapter)) { - $adapter = new AwsS3Adapter($this->getClient(),$this->getOption(self::OPTION_BUCKET),$this->getOption(self::OPTION_PREFIX)); + $adapter = new AwsS3V3Adapter( + $this->getClient(), + $this->getOption(self::OPTION_BUCKET), + $this->getOption(self::OPTION_PREFIX), + new BucketOwnerVisibilityConverter(), + null, + [], + false // keeps the streams seekable + ); if ($this->hasOption(self::OPTION_CACHE)) { if (class_exists(LocalCacheAdapter::class)) { - $cached = new Local($this->getOption(self::OPTION_CACHE)); + $cached = new LocalFilesystemAdapter($this->getOption(self::OPTION_CACHE)); $adapter = new LocalCacheAdapter($adapter, $cached, true); // FlySystem::listContents caching. diff --git a/src/BucketOwnerVisibilityConverter.php b/src/BucketOwnerVisibilityConverter.php new file mode 100644 index 0000000..4a61a9f --- /dev/null +++ b/src/BucketOwnerVisibilityConverter.php @@ -0,0 +1,41 @@ +defaultForDirectories; + } +} \ No newline at end of file diff --git a/src/QtiItems/QtiItemAssetCloudFrontReplacer.php b/src/QtiItems/QtiItemAssetCloudFrontReplacer.php index 1c47fe9..a7bb0da 100644 --- a/src/QtiItems/QtiItemAssetCloudFrontReplacer.php +++ b/src/QtiItems/QtiItemAssetCloudFrontReplacer.php @@ -24,10 +24,11 @@ namespace oat\awsTools\QtiItems; use Aws\S3\S3Client; -use League\Flysystem\AwsS3v3\AwsS3Adapter; +use League\Flysystem\AwsS3V3\AwsS3V3Adapter; use League\Flysystem\Config; use oat\awsTools\AwsClient; use oat\awsTools\items\ItemCloudFrontReplacement; +use oat\awsTools\BucketOwnerVisibilityConverter; use oat\oatbox\service\ConfigurableService; use oat\taoItems\model\render\ItemAssetsReplacement; use oat\taoQtiItem\model\compile\QtiAssetReplacer\QtiItemAssetReplacer; @@ -153,12 +154,13 @@ private function getItemAssetsReplacement(): ItemAssetsReplacement return $this->getServiceLocator()->get(ItemAssetsReplacement::SERVICE_ID); } - protected function getAwsS3Adapter(S3Client $s3Client, string $bucket, string $prefix): AwsS3Adapter + protected function getAwsS3Adapter(S3Client $s3Client, string $bucket, string $prefix): AwsS3V3Adapter { - return new AwsS3Adapter( + return new AwsS3V3Adapter( $s3Client, $bucket, - $prefix + $prefix, + new BucketOwnerVisibilityConverter() ); } } diff --git a/src/items/ItemCloudFrontReplacement.php b/src/items/ItemCloudFrontReplacement.php index bcbd32d..8ea2e35 100644 --- a/src/items/ItemCloudFrontReplacement.php +++ b/src/items/ItemCloudFrontReplacement.php @@ -21,7 +21,8 @@ namespace oat\awsTools\items; -use League\Flysystem\AwsS3v3\AwsS3Adapter; +use League\Flysystem\AwsS3V3\AwsS3V3Adapter; +use League\Flysystem\FilesystemException; use oat\awsTools\AwsClient; use oat\oatbox\service\ConfigurableService; use oat\taoItems\model\render\ItemAssetsReplacement; @@ -142,14 +143,10 @@ protected function retrieveKeyFile() if (!file_exists($this->getOption(self::OPTION_LOCAL_KEYFILE))) { if ($this->hasOption(self::OPTION_S3_KEYFILE) && $this->hasOption(self::OPTION_S3_BUCKET) && $this->hasOption(self::OPTION_S3_PREFIX)) { $s3Client = $this->getClient()->getS3Client(); - $s3Adapter = new AwsS3Adapter($s3Client, $this->getOption(self::OPTION_S3_BUCKET), $this->getOption(self::OPTION_S3_PREFIX)); - $response = $s3Adapter->read($this->getOption(self::OPTION_S3_KEYFILE)); - if ($response !== false) { - file_put_contents($this->getOption(self::OPTION_LOCAL_KEYFILE), $response['contents']); - chmod($this->getOption(self::OPTION_LOCAL_KEYFILE), 0600); - } else { - throw new \common_Exception('Unable to retrieve key file from s3 : ' . $this->getOption(self::OPTION_LOCAL_KEYFILE)); - } + $s3Adapter = new AwsS3V3Adapter($s3Client, $this->getOption(self::OPTION_S3_BUCKET), $this->getOption(self::OPTION_S3_PREFIX)); + $key = $this->readKeyFile($s3Adapter); + file_put_contents($this->getOption(self::OPTION_LOCAL_KEYFILE), $key); + chmod($this->getOption(self::OPTION_LOCAL_KEYFILE), 0600); } else { throw new \common_Exception('Unable to retrieve key file from s3. You should have a configuration for : ' . self::OPTION_S3_KEYFILE . ',' . self::OPTION_S3_BUCKET . 'and' . self::OPTION_S3_PREFIX); } @@ -173,4 +170,21 @@ protected function getClient() } return $this->getServiceLocator()->get($serviceId); } + + private function readKeyFile(AwsS3V3Adapter $s3Adapter): string + { + try { + $response = $s3Adapter->read($this->getOption(self::OPTION_S3_KEYFILE)); + } catch (FilesystemException $e) { + } finally { + if (empty($response)) { + throw new \common_Exception(sprintf( + 'Unable to retrieve key file from s3 : %s', + $this->getOption(self::OPTION_LOCAL_KEYFILE) + )); + } + } + + return $response; + } } diff --git a/test/unit/QtiItemAssetCloudFrontReplacerTest.php b/test/unit/QtiItemAssetCloudFrontReplacerTest.php index 6831eaa..d1a56de 100644 --- a/test/unit/QtiItemAssetCloudFrontReplacerTest.php +++ b/test/unit/QtiItemAssetCloudFrontReplacerTest.php @@ -25,7 +25,7 @@ use Aws\S3\S3Client; use GuzzleHttp\Psr7\Stream; -use League\Flysystem\AwsS3v3\AwsS3Adapter; +use League\Flysystem\AwsS3V3\AwsS3V3Adapter; use oat\awsTools\AwsClient; use oat\awsTools\items\ItemCloudFrontReplacement; use oat\awsTools\QtiItems\QtiItemAssetCloudFrontReplacer; @@ -76,7 +76,7 @@ class QtiItemAssetCloudFrontReplacerTest extends TestCase private $itemAssetsReplacement; /** - * @var AwsS3Adapter + * @var AwsS3V3Adapter */ private $awsS3Adapter; @@ -89,8 +89,8 @@ public function setUp(): void $this->itemAssetsReplacement = $this->createMock(ItemCloudFrontReplacement::class); $this->itemAssetsReplacement->method('getOption')->willReturn('bucket_test'); - $this->awsS3Adapter = $this->createMock(AwsS3Adapter::class); - $this->awsS3Adapter->method('writeStream')->willReturn(true); + $this->awsS3Adapter = $this->createMock(AwsS3V3Adapter::class); + $this->awsS3Adapter->method('writeStream'); $replacer = new TestQtiItemAssetCloudFrontReplacer([ QtiItemAssetCloudFrontReplacer::OPTION_PREFIX => 'prefix', @@ -195,7 +195,7 @@ public function setAwsS3Adapter($mock) $this->awsS3Adapter = $mock; } - protected function getAwsS3Adapter(S3Client $s3Client, string $bucket, string $prefix): AwsS3Adapter + protected function getAwsS3Adapter(S3Client $s3Client, string $bucket, string $prefix): AwsS3V3Adapter { return $this->awsS3Adapter; }