1
+ /*
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License").
5
+ * You may not use this file except in compliance with the License.
6
+ * A copy of the License is located at
7
+ *
8
+ * http://aws.amazon.com/apache2.0
9
+ *
10
+ * or in the "license" file accompanying this file. This file is distributed
11
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12
+ * express or implied. See the License for the specific language governing
13
+ * permissions and limitations under the License.
14
+ */
15
+
16
+ package software .amazon .awssdk .services .axdbfrontend .internal ;
17
+
18
+ import java .time .Clock ;
19
+ import java .time .Instant ;
20
+ import software .amazon .awssdk .annotations .Immutable ;
21
+ import software .amazon .awssdk .annotations .SdkInternalApi ;
22
+ import software .amazon .awssdk .auth .credentials .AwsCredentials ;
23
+ import software .amazon .awssdk .auth .credentials .CredentialUtils ;
24
+ import software .amazon .awssdk .auth .signer .Aws4Signer ;
25
+ import software .amazon .awssdk .auth .signer .params .Aws4PresignerParams ;
26
+ import software .amazon .awssdk .awscore .client .config .AwsClientOption ;
27
+ import software .amazon .awssdk .core .client .config .SdkClientConfiguration ;
28
+ import software .amazon .awssdk .http .SdkHttpFullRequest ;
29
+ import software .amazon .awssdk .http .SdkHttpMethod ;
30
+ import software .amazon .awssdk .identity .spi .AwsCredentialsIdentity ;
31
+ import software .amazon .awssdk .identity .spi .IdentityProvider ;
32
+ import software .amazon .awssdk .regions .Region ;
33
+ import software .amazon .awssdk .services .axdbfrontend .AxdbFrontendUtilities ;
34
+ import software .amazon .awssdk .services .axdbfrontend .model .GenerateAuthenticationTokenRequest ;
35
+ import software .amazon .awssdk .utils .CompletableFutureUtils ;
36
+ import software .amazon .awssdk .utils .Logger ;
37
+ import software .amazon .awssdk .utils .StringUtils ;
38
+
39
+ @ Immutable
40
+ @ SdkInternalApi
41
+ public final class DefaultAxdbFrontendUtilities implements AxdbFrontendUtilities {
42
+ private static final Logger log = Logger .loggerFor (AxdbFrontendUtilities .class );
43
+ private final Aws4Signer signer = Aws4Signer .create ();
44
+ private final Region region ;
45
+ private final IdentityProvider <? extends AwsCredentialsIdentity > credentialsProvider ;
46
+ private final Clock clock ;
47
+
48
+ public DefaultAxdbFrontendUtilities (DefaultBuilder builder ) {
49
+ this (builder , Clock .systemUTC ());
50
+ }
51
+
52
+ /**
53
+ * For testing purposes only
54
+ */
55
+ public DefaultAxdbFrontendUtilities (DefaultBuilder builder , Clock clock ) {
56
+ this .credentialsProvider = builder .credentialsProvider ;
57
+ this .region = builder .region ;
58
+ this .clock = clock ;
59
+ }
60
+
61
+ /**
62
+ * Used by AxdbFrontend low-level client's utilities() method
63
+ */
64
+ @ SdkInternalApi
65
+ static AxdbFrontendUtilities create (SdkClientConfiguration clientConfiguration ) {
66
+ return new DefaultBuilder ().clientConfiguration (clientConfiguration ).build ();
67
+ }
68
+
69
+ @ Override
70
+ public String generateAuthenticationToken (GenerateAuthenticationTokenRequest request ) {
71
+ SdkHttpFullRequest httpRequest = SdkHttpFullRequest .builder ()
72
+ .method (SdkHttpMethod .GET )
73
+ .protocol ("https" )
74
+ .host (request .hostname ())
75
+ .encodedPath ("/" )
76
+ .putRawQueryParameter ("Action" , request .action ().getAction ())
77
+ .build ();
78
+
79
+ Instant expirationTime = Instant .now (clock ).plus (request .expiresIn ());
80
+
81
+ Aws4PresignerParams presignRequest = Aws4PresignerParams .builder ()
82
+ .signingClockOverride (clock )
83
+ .expirationTime (expirationTime )
84
+ .awsCredentials (resolveCredentials (request ))
85
+ .signingName ("xanadu" )
86
+ .signingRegion (resolveRegion (request ))
87
+ .build ();
88
+
89
+ SdkHttpFullRequest fullRequest = signer .presign (httpRequest , presignRequest );
90
+ String signedUrl = fullRequest .getUri ().toString ();
91
+
92
+ String result = StringUtils .replacePrefixIgnoreCase (signedUrl , "https://" , "" );
93
+ return result ;
94
+ }
95
+
96
+ private Region resolveRegion (GenerateAuthenticationTokenRequest request ) {
97
+ if (request .region () != null ) {
98
+ return request .region ();
99
+ }
100
+
101
+ if (this .region != null ) {
102
+ return this .region ;
103
+ }
104
+
105
+ throw new IllegalArgumentException ("Region should be provided either in GenerateAuthenticationTokenRequest object " +
106
+ "or AxdbFrontendUtilities object" );
107
+ }
108
+
109
+ // TODO: update this to use AwsCredentialsIdentity when we migrate Signers to accept the new type.
110
+ private AwsCredentials resolveCredentials (GenerateAuthenticationTokenRequest request ) {
111
+ if (request .credentialsIdentityProvider () != null ) {
112
+ return CredentialUtils .toCredentials (
113
+ CompletableFutureUtils .joinLikeSync (request .credentialsIdentityProvider ().resolveIdentity ()));
114
+ }
115
+
116
+ if (this .credentialsProvider != null ) {
117
+ return CredentialUtils .toCredentials (CompletableFutureUtils .joinLikeSync (this .credentialsProvider .resolveIdentity ()));
118
+ }
119
+
120
+ throw new IllegalArgumentException ("CredentialProvider should be provided either in GenerateAuthenticationTokenRequest " +
121
+ "object or AxdbFrontendUtilities object" );
122
+ }
123
+
124
+ @ SdkInternalApi
125
+ public static final class DefaultBuilder implements Builder {
126
+ private Region region ;
127
+ private IdentityProvider <? extends AwsCredentialsIdentity > credentialsProvider ;
128
+
129
+ public DefaultBuilder () {
130
+ }
131
+
132
+ Builder clientConfiguration (SdkClientConfiguration clientConfiguration ) {
133
+ this .credentialsProvider = clientConfiguration .option (AwsClientOption .CREDENTIALS_IDENTITY_PROVIDER );
134
+ this .region = clientConfiguration .option (AwsClientOption .AWS_REGION );
135
+
136
+ return this ;
137
+ }
138
+
139
+ @ Override
140
+ public Builder region (Region region ) {
141
+ this .region = region ;
142
+ return this ;
143
+ }
144
+
145
+ @ Override
146
+ public Builder credentialsProvider (IdentityProvider <? extends AwsCredentialsIdentity > credentialsProvider ) {
147
+ this .credentialsProvider = credentialsProvider ;
148
+ return this ;
149
+ }
150
+
151
+ /**
152
+ * Construct a {@link AxdbFrontendUtilities} object.
153
+ */
154
+ @ Override
155
+ public AxdbFrontendUtilities build () {
156
+ return new DefaultAxdbFrontendUtilities (this );
157
+ }
158
+ }
159
+ }
0 commit comments