aws / aws-sdk-ruby

The official AWS SDK for Ruby.
https://aws.amazon.com/sdk-for-ruby/
Apache License 2.0
3.57k stars 1.22k forks source link

Checking if a bucket exists returns true when AWS creds aren't valid #205

Closed dandunckelman closed 11 years ago

dandunckelman commented 11 years ago

I have a little function that checks if a bucket exists:

# check if a bucket exists
#
# name => String => The bucket's name
#
# returns boolean
def bucketExists(name)
  s3 = AWS::S3.new
  s3.buckets[name].exists?
end

When I run my script with invalid AWS creds, it returns true even though the bucket I'm checking doesn't exist. I found this when my config.yml looked like this:

aws_access_key: "****"
aws_secret_key: "****"

So, I got curious and looked here: https://github.com/aws/aws-sdk-ruby/blob/master/lib/aws/s3/bucket.rb#L504, which has this:

# @note This method only indicates if there is a bucket in S3, not
#   if you have permissions to work with the bucket or not.
# @return [Boolean] Returns true if the bucket exists in S3.
def exists?
  begin
    versioned? # makes a get bucket request without listing contents
               # raises a client error if the bucket doesn't exist or
               # if you don't have permission to get the bucket
               # versioning status.
    true
  rescue Errors::NoSuchBucket => e
    false # bucket does not exist
  rescue Errors::ClientError => e
    true # bucket exists
  end
end

I dug around the code and didn't find anything in NoSuchBucket and ClientError that would catch bad creds. I might take a stab at a pull request for this, but for now, I'll modify my code to ensure creds are valid.

dandunckelman commented 11 years ago

This should probably raise this error: http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/Errors/MissingCredentialsError.html

trevorrowe commented 11 years ago

It looks like what is happening is the service is returning a InvalidAccessKeyId error which is being caught as a ClientError (all 400 level responses are client errors, 500 level responses are service errors). This could be fixed if we instead of rescuing Errors::ClientError, we should rescue Errors::AccessDenied.

This change would allow the InvalidAccessKeyId error to raise up and would prevent the incorrect true value from being returned.

dandunckelman commented 11 years ago

Nice!

Just for reference, I tested it and got the following:

/home/dldunckel/.rvm/gems/ruby-1.9.3-p194@sites/gems/aws-sdk-1.8.5/lib/aws/core/client.rb:339:in `return_or_raise': The AWS Access Key Id you provided does not exist in our records. (AWS::S3::Errors::InvalidAccessKeyId)
    from /home/dldunckel/.rvm/gems/ruby-1.9.3-p194@sites/gems/aws-sdk-1.8.5/lib/aws/core/client.rb:440:in `client_request'
    from (eval):3:in `get_bucket_versioning'
    from /home/dldunckel/.rvm/gems/ruby-1.9.3-p194@sites/gems/aws-sdk-1.8.5/lib/aws/s3/bucket.rb:455:in `versioning_state'
    from /home/dldunckel/.rvm/gems/ruby-1.9.3-p194@sites/gems/aws-sdk-1.8.5/lib/aws/s3/bucket.rb:443:in `versioning_enabled?'
    from /home/dldunckel/.rvm/gems/ruby-1.9.3-p194@sites/gems/aws-sdk-1.8.5/lib/aws/s3/bucket.rb:506:in `exists?'
    from create.rb:141:in `bucketExists'
    from create.rb:343:in `uploadSiteContent'
    from create.rb:276:in `uploadContent'
    from create.rb:35:in `initialize'
    from create.rb:391:in `new'
    from create.rb:391:in `<main>'

Thanks!