Added S3 support
continuous-integration/drone/pr Build is passing

This commit is contained in:
Khwezi Mngoma
2026-05-19 10:23:36 +02:00
parent da141311ff
commit f245bc94e1
4 changed files with 83 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
using Amazon.Runtime;
using LiteCharms.Features.S3;
using LiteCharms.Features.S3.Configuration;
namespace LiteCharms.Features.Extensions;
public static class S3
{
public static IServiceCollection AddGarageS3(this IServiceCollection services, IConfiguration configuration)
{
var optionsSection = configuration.GetSection(nameof(S3Settings));
services.Configure<S3Settings>(optionsSection);
var options = optionsSection.Get<S3Settings>()
?? throw new InvalidOperationException("S3 configuration section is missing.");
var credentials = new BasicAWSCredentials(options.AccessKey, options.SecretKey);
var s3Config = new AmazonS3Config
{
ServiceURL = options.ServiceUrl,
AuthenticationRegion = options.Region,
ForcePathStyle = true,
};
services.AddSingleton<IAmazonS3>(new AmazonS3Client(credentials, s3Config));
services.AddScoped<S3Service>();
return services;
}
}
@@ -128,6 +128,16 @@
<Using Include="FluentResults" />
<Using Include="Mediator" />
</ItemGroup>
<!-- Amazon S3 SDK -->
<ItemGroup>
<PackageReference Include="AWSSDK.Extensions.NetCore.Setup" Version="4.0.3.40" />
<PackageReference Include="AWSSDK.S3" Version="4.0.23.3" />
<!-- global Usings -->
<Using Include="Amazon.S3" />
<Using Include="Amazon.S3.Model" />
</ItemGroup>
<!-- Shared Usings -->
<ItemGroup>
@@ -0,0 +1,14 @@
namespace LiteCharms.Features.S3.Configuration;
public class S3Settings
{
public string? ServiceUrl { get; set; }
public string? AccessKey { get; set; }
public string? SecretKey { get; set; }
public string? BucketName { get; set; }
public string? Region { get; set; }
}
+28
View File
@@ -0,0 +1,28 @@
namespace LiteCharms.Features.S3;
public class S3Service(IAmazonS3 amazonS3)
{
public async Task<Result<string>> UploadFileAsync(string bucketName, string fileName, Stream fileStream, string contentType, string cdnBaseUrl, CancellationToken cancellationToken = default)
{
try
{
var putRequest = new PutObjectRequest
{
BucketName = bucketName,
Key = fileName,
InputStream = fileStream,
ContentType = contentType
};
var response = await amazonS3.PutObjectAsync(putRequest, cancellationToken);
return response.HttpStatusCode != System.Net.HttpStatusCode.OK
? Result.Fail<string>($"Failed to upload {fileName} to S3.")
: Result.Ok(string.Format(cdnBaseUrl, bucketName, fileName));
}
catch (Exception ex)
{
return Result.Fail<string>(new Error($"Error uploading {fileName} to S3: {ex.Message}").CausedBy(ex));
}
}
}