Skip to content

Commit

Permalink
Minimum of expiration time and expires_in for presigned urls
Browse files Browse the repository at this point in the history
  • Loading branch information
mullermp committed Jun 22, 2023
1 parent 951257f commit 6c88ef0
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 17 deletions.
2 changes: 2 additions & 0 deletions gems/aws-sdk-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Feature - Add :expiration accessor to `CredentialProvider` and do not refresh credentials when checking expiration.

3.175.0 (2023-06-15)
------------------

Expand Down
3 changes: 3 additions & 0 deletions gems/aws-sdk-core/lib/aws-sdk-core/credential_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ module CredentialProvider
# @return [Credentials]
attr_reader :credentials

# @param [Time]
attr_reader :expiration

# @return [Boolean]
def set?
!!credentials && credentials.set?
Expand Down
6 changes: 0 additions & 6 deletions gems/aws-sdk-core/lib/aws-sdk-core/refreshing_credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ def credentials
@credentials
end

# @return [Time,nil]
def expiration
refresh_if_near_expiration!
@expiration
end

# Refresh credentials.
# @return [void]
def refresh!
Expand Down
2 changes: 2 additions & 0 deletions gems/aws-sdk-s3/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Feature - Select minimum expiration time for presigned urls between the expiration time option and the credential expiration time.

1.126.0 (2023-06-16)
------------------

Expand Down
6 changes: 4 additions & 2 deletions gems/aws-sdk-s3/lib/aws-sdk-s3/presigner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def initialize(options = {})
# before the presigned URL expires. Defaults to 15 minutes. As signature
# version 4 has a maximum expiry time of one week for presigned URLs,
# attempts to set this value to greater than one week (604800) will
# raise an exception.
# raise an exception. The min value of this option and the credentials
# expiration time is used in the presigned URL.
#
# @option params [Time] :time (Time.now) The starting time for when the
# presigned url becomes active.
Expand Down Expand Up @@ -96,7 +97,8 @@ def presigned_url(method, params = {})
# before the presigned URL expires. Defaults to 15 minutes. As signature
# version 4 has a maximum expiry time of one week for presigned URLs,
# attempts to set this value to greater than one week (604800) will
# raise an exception.
# raise an exception. The min value of this option and the credentials
# expiration time is used in the presigned URL.
#
# @option params [Time] :time (Time.now) The starting time for when the
# presigned url becomes active.
Expand Down
3 changes: 3 additions & 0 deletions gems/aws-sigv4/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
Unreleased Changes
------------------

* Feature - Select the minimum expiration time for presigned urls between
the expiration time option and the credential expiration time.

1.5.2 (2022-09-30)
------------------

Expand Down
25 changes: 16 additions & 9 deletions gems/aws-sigv4/lib/aws-sigv4/signer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ def presign_url(options)
params['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256'
params['X-Amz-Credential'] = credential(creds, date)
params['X-Amz-Date'] = datetime
params['X-Amz-Expires'] = extract_expires_in(options)
params['X-Amz-Expires'] = presigned_url_expiration(options, creds).to_s
params['X-Amz-Security-Token'] = creds.session_token if creds.session_token
params['X-Amz-SignedHeaders'] = signed_headers(headers)

Expand Down Expand Up @@ -526,7 +526,6 @@ def event_signature(secret_access_key, date, string_to_sign)
hmac(k_credentials, string_to_sign)
end


def path(url)
path = url.path
path = '/' if path == ''
Expand Down Expand Up @@ -682,8 +681,8 @@ def downcase_headers(headers)

def extract_expires_in(options)
case options[:expires_in]
when nil then 900.to_s
when Integer then options[:expires_in].to_s
when nil then 900
when Integer then options[:expires_in]
else
msg = "expected :expires_in to be a number of seconds"
raise ArgumentError, msg
Expand All @@ -698,7 +697,6 @@ def uri_escape_path(string)
self.class.uri_escape_path(string)
end


def fetch_credentials
credentials = @credentials_provider.credentials
if credentials_set?(credentials)
Expand All @@ -720,21 +718,30 @@ def credentials_set?(credentials)
!credentials.secret_access_key.empty?
end

def presigned_url_expiration(options, creds)
expires_in = extract_expires_in(options)
return expires_in unless creds.respond_to?(:expiration)

creds_expiration_seconds = (creds.expiration - Time.now).to_i
[expires_in, creds_expiration_seconds].min
end

### CRT Code

# the credentials used by CRT must be a
# CRT StaticCredentialsProvider object
def crt_fetch_credentials
creds = fetch_credentials
Aws::Crt::Auth::StaticCredentialsProvider.new(
crt_creds = Aws::Crt::Auth::StaticCredentialsProvider.new(
creds.access_key_id,
creds.secret_access_key,
creds.session_token
)
[crt_creds, creds]
end

def crt_sign_request(request)
creds = crt_fetch_credentials
creds, _ = crt_fetch_credentials
http_method = extract_http_method(request)
url = extract_url(request)
headers = downcase_headers(request[:headers])
Expand Down Expand Up @@ -793,7 +800,7 @@ def crt_sign_request(request)
end

def crt_presign_url(options)
creds = crt_fetch_credentials
creds, ruby_creds = crt_fetch_credentials

http_method = extract_http_method(options)
url = extract_url(options)
Expand Down Expand Up @@ -821,7 +828,7 @@ def crt_presign_url(options)
use_double_uri_encode: @uri_escape_path,
should_normalize_uri_path: @normalize_path,
omit_session_token: @omit_session_token,
expiration_in_seconds: options.fetch(:expires_in, 900)
expiration_in_seconds: presigned_url_expiration(options, ruby_creds)
)
http_request = Aws::Crt::Http::Message.new(
http_method, url.to_s, headers
Expand Down

0 comments on commit 6c88ef0

Please sign in to comment.