Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimum of expiration time and expires_in for presigned urls #2872

Merged
merged 3 commits into from
Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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!
alextwoods marked this conversation as resolved.
Show resolved Hide resolved
@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