-
Notifications
You must be signed in to change notification settings - Fork 774
Expand file tree
/
Copy pathAwsApplicationExtensions.cs
More file actions
109 lines (91 loc) · 3.8 KB
/
Copy pathAwsApplicationExtensions.cs
File metadata and controls
109 lines (91 loc) · 3.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System;
using System.Threading.Tasks;
using Amazon;
using Amazon.Runtime;
using Amazon.S3;
using BaGet.Aws;
using BaGet.Core;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
namespace BaGet
{
public static class AwsApplicationExtensions
{
public static BaGetApplication AddAwsS3Storage(this BaGetApplication app)
{
app.Services.AddBaGetOptions<S3StorageOptions>(nameof(BaGetOptions.Storage));
app.Services.AddTransient<S3StorageService>();
app.Services.TryAddTransient<IStorageService>(provider => provider.GetRequiredService<S3StorageService>());
app.Services.AddProvider<IStorageService>((provider, config) =>
{
if (!config.HasStorageType("AwsS3")) return null;
return provider.GetRequiredService<S3StorageService>();
});
app.Services.AddSingleton(provider =>
{
var options = provider.GetRequiredService<IOptions<S3StorageOptions>>().Value;
if (options.ForcePathStyle)
{
// Required to support presigned urls generation for MiniO configured to us-east-1 region
AWSConfigsS3.UseSignatureVersion4 = true;
}
var config = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.GetBySystemName(options.Region),
ForcePathStyle = options.ForcePathStyle,
UseHttp = options.UseHttp
};
if (!string.IsNullOrWhiteSpace(options.ServiceUrl))
{
config.ServiceURL = options.ServiceUrl;
}
if (options.UseInstanceProfile)
{
var credentials = FallbackCredentialsFactory.GetCredentials();
return new AmazonS3Client(credentials, config);
}
if (!string.IsNullOrEmpty(options.AssumeRoleArn))
{
var credentials = FallbackCredentialsFactory.GetCredentials();
var assumedCredentials = AssumeRoleAsync(
credentials,
options.AssumeRoleArn,
$"BaGet-Session-{Guid.NewGuid()}")
.GetAwaiter()
.GetResult();
return new AmazonS3Client(assumedCredentials, config);
}
if (!string.IsNullOrEmpty(options.AccessKey))
{
return new AmazonS3Client(
new BasicAWSCredentials(
options.AccessKey,
options.SecretKey),
config);
}
return new AmazonS3Client(config);
});
return app;
}
public static BaGetApplication AddAwsS3Storage(this BaGetApplication app, Action<S3StorageOptions> configure)
{
app.AddAwsS3Storage();
app.Services.Configure(configure);
return app;
}
private static async Task<AWSCredentials> AssumeRoleAsync(
AWSCredentials credentials,
string roleArn,
string roleSessionName)
{
var assumedCredentials = new AssumeRoleAWSCredentials(credentials, roleArn, roleSessionName);
var immutableCredentials = await credentials.GetCredentialsAsync();
if (string.IsNullOrWhiteSpace(immutableCredentials.Token))
{
throw new InvalidOperationException($"Unable to assume role {roleArn}");
}
return assumedCredentials;
}
}
}