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

Add an RBS signature for sigv4 #3152

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ jobs:
bundle config set --local with 'build rbs'
bundle install

- name: Install rbs collection
run: rbs collection install

- name: Build SDK
run: bundle exec rake build

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

/.byebug_history
/.bundle
/.gem_rbs_collection
/.yardoc
/api-docs
/Gemfile.lock
/coverage
/rbs_collection.lock.yaml
*.gem
benchmark_report.json

Expand Down
2 changes: 2 additions & 0 deletions gems/aws-sigv4/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Feature - Add RBS signature files to support static type checking

1.10.1 (2024-10-21)
------------------

Expand Down
6 changes: 3 additions & 3 deletions gems/aws-sigv4/lib/aws-sigv4/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module Sigv4
class Request

# @option options [required, String] :http_method
# @option options [required, HTTP::URI, HTTPS::URI, String] :endpoint
# @option options [required, String, URI::HTTP, URI::HTTPS] :endpoint
# @option options [Hash<String,String>] :headers ({})
# @option options [String, IO] :body ('')
def initialize(options = {})
Expand All @@ -30,12 +30,12 @@ def http_method
@http_method
end

# @param [String, HTTP::URI, HTTPS::URI] endpoint
# @param [String, URI::HTTP, URI::HTTPS] endpoint
def endpoint=(endpoint)
@endpoint = URI.parse(endpoint.to_s)
end

# @return [HTTP::URI, HTTPS::URI]
# @return [URI::HTTP, URI::HTTPS]
def endpoint
@endpoint
end
Expand Down
4 changes: 2 additions & 2 deletions gems/aws-sigv4/lib/aws-sigv4/signer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def initialize(options = {})
# @option request [required, String] :http_method One of
# 'GET', 'HEAD', 'PUT', 'POST', 'PATCH', or 'DELETE'
#
# @option request [required, String, URI::HTTPS, URI::HTTP] :url
# @option request [required, String, URI::HTTP, URI::HTTPS] :url
# The request URI. Must be a valid HTTP or HTTPS URI.
#
# @option request [optional, Hash] :headers ({}) A hash of headers
Expand Down Expand Up @@ -383,7 +383,7 @@ def sign_event(prior_signature, payload, encoder)
# @option options [required, String] :http_method The HTTP request method,
# e.g. 'GET', 'HEAD', 'PUT', 'POST', 'PATCH', or 'DELETE'.
#
# @option options [required, String, HTTPS::URI, HTTP::URI] :url
# @option options [required, String, URI::HTTP, URI::HTTPS] :url
# The URI to sign.
#
# @option options [Hash] :headers ({}) Headers that should
Expand Down
13 changes: 13 additions & 0 deletions gems/aws-sigv4/sig/errors.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Aws
module Sigv4
module Errors
class MissingCredentialsError < ArgumentError
def initialize: (?String msg) -> void
end

class MissingRegionError < ArgumentError
def initialize: (*untyped) -> void
end
end
end
end
15 changes: 15 additions & 0 deletions gems/aws-sigv4/sig/interfaces.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module Aws
module Sigv4
interface _Credentials
def access_key_id: () -> String
def secret_access_key: () -> String
def session_token: () -> String?
def set?: () -> bool
end

interface _CredentialsProvider
def credentials: () -> _Credentials
def set?: () -> bool
end
end
end
4 changes: 4 additions & 0 deletions gems/aws-sigv4/sig/manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dependencies:
- name: tempfile
- name: stringio
- name: uri
25 changes: 25 additions & 0 deletions gems/aws-sigv4/sig/request.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Aws
module Sigv4
class Request
def initialize: (
http_method: String,
alextwoods marked this conversation as resolved.
Show resolved Hide resolved
endpoint: String | URI::HTTP | URI::HTTPS,
?headers: Hash[String, String],
?body: String | IO
) -> void
| (?Hash[Symbol, untyped]) -> void

def http_method=: (String http_method) -> void
def http_method: () -> String

def endpoint: () -> (URI::HTTP | URI::HTTPS)
def endpoint=: (String | URI::HTTP | URI::HTTPS endpoint) -> void

def headers=: (Hash[String, String] headers) -> void
def headers: () -> Hash[String, String]

def body=: (String | IO body) -> void
def body: () -> (String | IO)
end
end
end
12 changes: 12 additions & 0 deletions gems/aws-sigv4/sig/signature.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Aws
module Sigv4
class Signature
attr_accessor headers: Hash[String, String]
attr_accessor canonical_request: String
attr_accessor string_to_sign: String
attr_accessor content_sha256: String
attr_accessor signature: String
attr_accessor extra: Hash[untyped, untyped]
end
end
end
51 changes: 51 additions & 0 deletions gems/aws-sigv4/sig/signer.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module Aws
module Sigv4
class Signer
def initialize: (
service: String,
region: String,
?access_key_id: String,
?secret_access_key: String,
?session_token: String,
?credentials: _Credentials,
?credentials_provider: _CredentialsProvider,
?unsigned_headers: Array[String],
?uri_escape_path: bool,
?apply_checksum_header: bool,
?signing_algorithm: :sigv4 | :sigv4a | :'sigv4-s3express',
?omit_session_token: bool,
?normalize_path: bool,
) -> void
jterapin marked this conversation as resolved.
Show resolved Hide resolved
| (?Hash[Symbol, untyped]) -> void

attr_reader service: String
attr_reader region: String
attr_reader credentials_provider: _CredentialsProvider
attr_reader unsigned_headers: Array[String]
attr_reader apply_checksum_header: bool

def sign_request: (
http_method: String,
url: String | URI::HTTPS | URI::HTTP,
?headers: Hash[String, String],
?body: String | IO | StringIO | Tempfile,
) -> Signature

def sign_event: (
String,
String,
untyped
) -> [Hash[String, untyped], String]

def presign_url: (
http_method: String,
url: String | URI::HTTP | URI::HTTPS,
?headers: Hash[String, String],
?expires_in: Integer,
?body: String | IO,
?body_digest: String,
?time: Time,
) -> (URI::HTTP | URI::HTTPS)
end
end
end
5 changes: 3 additions & 2 deletions gems/aws-sigv4/spec/signer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ module Sigv4
body: body
)
expect(signature.headers['x-amz-content-sha256']).to eq(Digest::SHA256.hexdigest('abc'))
body.unlink
end

it 'reads non-file IO objects into memory to compute checksusm' do
Expand All @@ -313,7 +314,7 @@ module Sigv4
end

it 'does not read the body if X-Amz-Content-Sha256 if already present' do
body = double('http-payload')
body = StringIO.new('body')
expect(body).to_not receive(:read)
expect(body).to_not receive(:rewind)
signature = Signer.new(options).sign_request(
Expand Down Expand Up @@ -348,7 +349,7 @@ module Sigv4
'Foo' => 'foo',
'Bar' => 'bar bar',
'Bar2' => '"bar bar"',
'Content-Length' => 9,
'Content-Length' => '9',
'X-Amz-Date' => '20120101T112233Z',
},
body: StringIO.new('http-body')
Expand Down
30 changes: 30 additions & 0 deletions rbs_collection.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
sources:
- type: git
name: ruby/gem_rbs_collection
remote: https://github.com/ruby/gem_rbs_collection.git
revision: main
repo_dir: gems

path: .gem_rbs_collection

gems:
- name: stringio
ignore: false
- name: tempfile
ignore: false
- name: uri
ignore: false
- name: addressable
jterapin marked this conversation as resolved.
Show resolved Hide resolved
ignore: true
- name: diff-lcs
ignore: true
- name: rake
ignore: true
- name: rbs
ignore: true
- name: rubocop
ignore: true
- name: webmock
ignore: true
- name: yard
ignore: true
11 changes: 5 additions & 6 deletions tasks/rbs.rake
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,17 @@ namespace :rbs do
task :spytest do
failures = []
# Just test s3 for most type coverage
%w[core s3].each do |identifier|
sdk_gem = "aws-sdk-#{identifier}"
puts "Run rspec with RBS::Test on `#{sdk_gem}`"
%w[aws-sigv4 aws-sdk-core aws-sdk-s3].each do |gem_name|
puts "Run rspec with RBS::Test on `#{gem_name}`"
env = {
'RUBYOPT' => '-r bundler/setup -r rbs/test/setup',
'RBS_TEST_RAISE' => 'true',
'RBS_TEST_LOGLEVEL' => 'error',
'RBS_TEST_OPT' => "-I gems/aws-sdk-core/sig -I gems/#{sdk_gem}/sig",
'RBS_TEST_OPT' => "-I gems/aws-sdk-core/sig -I gems/#{gem_name}/sig",
'RBS_TEST_TARGET' => "\"Aws,Aws::*,Seahorse,Seahorse::*\"",
}
sh(env, "bundle exec rspec gems/#{sdk_gem}/spec --tag '~rbs_test:skip'") do |ok, _|
failures << File.basename(File.dirname("gems/#{sdk_gem}/sig")) unless ok
sh(env, "bundle exec rspec gems/#{gem_name}/spec --tag '~rbs_test:skip'") do |ok, _|
failures << File.basename(File.dirname("gems/#{gem_name}/sig")) unless ok
end
end
abort('one or more rspec with RBS::Test failed: %s' % [failures.join(', ')]) unless failures.empty?
Expand Down
Loading