diff --git a/backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3AssetStore.cs b/backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3AssetStore.cs index 52dfe7cb2..5ad4639c5 100644 --- a/backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3AssetStore.cs +++ b/backend/src/Squidex.Infrastructure.Amazon/Assets/AmazonS3AssetStore.cs @@ -19,6 +19,7 @@ namespace Squidex.Infrastructure.Assets public sealed class AmazonS3AssetStore : DisposableObjectBase, IAssetStore, IInitializable { private const int BufferSize = 81920; + private readonly string? serviceUrl; private readonly string accessKey; private readonly string secretKey; private readonly string bucketName; @@ -27,12 +28,13 @@ namespace Squidex.Infrastructure.Assets private TransferUtility transferUtility; private IAmazonS3 s3Client; - public AmazonS3AssetStore(string regionName, string bucketName, string? bucketFolder, string accessKey, string secretKey) + public AmazonS3AssetStore(string? serviceUrl, string? regionName, string bucketName, string? bucketFolder, string accessKey, string secretKey) { Guard.NotNullOrEmpty(bucketName); Guard.NotNullOrEmpty(accessKey); Guard.NotNullOrEmpty(secretKey); + this.serviceUrl = serviceUrl; this.bucketName = bucketName; this.bucketFolder = bucketFolder; this.accessKey = accessKey; @@ -55,10 +57,20 @@ namespace Squidex.Infrastructure.Assets { try { - s3Client = new AmazonS3Client( - accessKey, - secretKey, - bucketRegion); + if (!string.IsNullOrWhiteSpace(serviceUrl)) + { + s3Client = new AmazonS3Client( + accessKey, + secretKey, + new AmazonS3Config { ServiceURL = serviceUrl }); + } + else + { + s3Client = new AmazonS3Client( + accessKey, + secretKey, + bucketRegion); + } transferUtility = new TransferUtility(s3Client); diff --git a/backend/src/Squidex/Config/Domain/AssetServices.cs b/backend/src/Squidex/Config/Domain/AssetServices.cs index 5054c6103..90d52acdd 100644 --- a/backend/src/Squidex/Config/Domain/AssetServices.cs +++ b/backend/src/Squidex/Config/Domain/AssetServices.cs @@ -88,7 +88,8 @@ namespace Squidex.Config.Domain }, ["AmazonS3"] = () => { - var regionName = config.GetRequiredValue("assetStore:amazonS3:regionName"); + var serviceUrl = config.GetOptionalValue("assetStore:amazonS3:serviceUrl"); + var regionName = config.GetOptionalValue("assetStore:amazonS3:regionName"); var bucketName = config.GetRequiredValue("assetStore:amazonS3:bucket"); var bucketFolder = config.GetRequiredValue("assetStore:amazonS3:bucketFolder"); @@ -96,7 +97,7 @@ namespace Squidex.Config.Domain var accessKey = config.GetRequiredValue("assetStore:amazonS3:accessKey"); var secretKey = config.GetRequiredValue("assetStore:amazonS3:secretKey"); - services.AddSingletonAs(c => new AmazonS3AssetStore(regionName, bucketName, bucketFolder, accessKey, secretKey)) + services.AddSingletonAs(c => new AmazonS3AssetStore(serviceUrl, regionName, bucketName, bucketFolder, accessKey, secretKey)) .As(); }, ["MongoDb"] = () => diff --git a/backend/src/Squidex/appsettings.json b/backend/src/Squidex/appsettings.json index ae7b38868..e5e64e2a6 100644 --- a/backend/src/Squidex/appsettings.json +++ b/backend/src/Squidex/appsettings.json @@ -284,6 +284,12 @@ "connectionString": "UseDevelopmentStorage=true" }, "AmazonS3": { + + /* + * The url of the S3 API service. Leave it empty if using the one provided by Amazon + */ + "serviceUrl": "", + /* * The name of your bucket. */ diff --git a/backend/tests/Squidex.Infrastructure.Tests/Assets/AmazonS3AssetStoreFixture.cs b/backend/tests/Squidex.Infrastructure.Tests/Assets/AmazonS3AssetStoreFixture.cs index 3e3fcec04..22dc6233f 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/Assets/AmazonS3AssetStoreFixture.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/Assets/AmazonS3AssetStoreFixture.cs @@ -13,7 +13,7 @@ namespace Squidex.Infrastructure.Assets public AmazonS3AssetStoreFixture() { - AssetStore = new AmazonS3AssetStore("eu-central-1", "squidex-test", "squidex-assets", "secret", "secret"); + AssetStore = new AmazonS3AssetStore(null, "eu-central-1", "squidex-test", "squidex-assets", "secret", "secret"); AssetStore.InitializeAsync().Wait(); } } diff --git a/backend/tests/Squidex.Infrastructure.Tests/Assets/AmazonS3AssetStoreTests.cs b/backend/tests/Squidex.Infrastructure.Tests/Assets/AmazonS3AssetStoreTests.cs index 454f4d1e5..b1fde1d1a 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/Assets/AmazonS3AssetStoreTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/Assets/AmazonS3AssetStoreTests.cs @@ -28,7 +28,7 @@ namespace Squidex.Infrastructure.Assets [Fact] public async Task Should_throw_exception_for_invalid_config() { - var sut = new AmazonS3AssetStore("invalid", "invalid", null, "invalid", "invalid"); + var sut = new AmazonS3AssetStore(null, "invalid", "invalid", null, "invalid", "invalid"); await Assert.ThrowsAsync(() => sut.InitializeAsync()); }