mirror of
https://github.com/fog/fog-aws.git
synced 2022-11-09 13:50:52 -05:00
Merge pull request #45 from ehowe/assumerole
get signin token for federation
This commit is contained in:
commit
a37bb7e439
18 changed files with 325 additions and 46 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -12,3 +12,4 @@
|
|||
*.o
|
||||
*.a
|
||||
mkmf.log
|
||||
tests/.fog
|
||||
|
|
|
@ -19,6 +19,7 @@ require 'fog/aws/dynamodb'
|
|||
require 'fog/aws/elasticache'
|
||||
require 'fog/aws/elb'
|
||||
require 'fog/aws/emr'
|
||||
require 'fog/aws/federation'
|
||||
require 'fog/aws/glacier'
|
||||
require 'fog/aws/iam'
|
||||
require 'fog/aws/rds'
|
||||
|
|
|
@ -21,6 +21,7 @@ module Fog
|
|||
service(:elasticache, 'Elasticache')
|
||||
service(:elb, 'ELB')
|
||||
service(:emr, 'EMR')
|
||||
service(:federation, 'Federation')
|
||||
service(:glacier, 'Glacier')
|
||||
service(:iam, 'IAM')
|
||||
service(:rds, 'RDS')
|
||||
|
|
58
lib/fog/aws/federation.rb
Normal file
58
lib/fog/aws/federation.rb
Normal file
|
@ -0,0 +1,58 @@
|
|||
require 'fog/aws/core'
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class Federation < Fog::Service
|
||||
extend Fog::AWS::CredentialFetcher::ServiceMethods
|
||||
|
||||
recognizes :instrumentor, :instrumentor_name
|
||||
|
||||
request_path 'fog/aws/requests/federation'
|
||||
|
||||
request 'get_signin_token'
|
||||
|
||||
class Mock
|
||||
def self.data
|
||||
@data ||= {}
|
||||
end
|
||||
|
||||
def self.reset
|
||||
@data = nil
|
||||
end
|
||||
|
||||
def initialize(options={})
|
||||
end
|
||||
|
||||
def data
|
||||
self.class.data
|
||||
end
|
||||
|
||||
def reset_data
|
||||
self.class.reset
|
||||
end
|
||||
end
|
||||
|
||||
class Real
|
||||
include Fog::AWS::CredentialFetcher::ConnectionMethods
|
||||
|
||||
def initialize(options={})
|
||||
@instrumentor = options[:instrumentor]
|
||||
@instrumentor_name = options[:instrumentor_name] || 'fog.aws.federation'
|
||||
@connection_options = options[:connection_options] || {}
|
||||
@host = 'signin.aws.amazon.com'
|
||||
@path = '/federation'
|
||||
@scheme = 'https'
|
||||
@connection = Excon.new("#{@scheme}://#{@host}#{@path}")
|
||||
end
|
||||
|
||||
def request(action, session)
|
||||
response = @connection.get(
|
||||
:query => "Action=#{action}&SessionType=json&Session=#{session}",
|
||||
:expects => 200
|
||||
).body
|
||||
Fog::JSON.decode(response)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -120,6 +120,27 @@ module Fog
|
|||
:created_at => Time.now,
|
||||
:policies => {}
|
||||
}
|
||||
end,
|
||||
:roles => Hash.new do |rhash, rkey|
|
||||
rhash[rkey] = {
|
||||
:role_id => Fog::AWS::Mock.key_id,
|
||||
:arn => "arn:aws:iam:#{Fog::AWS::Mock.owner_id}:role/#{rkey}",
|
||||
:create_date => Time.now,
|
||||
:assume_role_policy_document => {
|
||||
"Version" => "2012-10-17",
|
||||
"Statement" => [
|
||||
{
|
||||
"Effect" => "Allow",
|
||||
"Principal" => {
|
||||
"Service" => [
|
||||
"ec2.amazonaws.com"
|
||||
]
|
||||
},
|
||||
"Action" => ["sts:AssumeRole"]
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
|
20
lib/fog/aws/parsers/sts/assume_role_with_web_identity.rb
Normal file
20
lib/fog/aws/parsers/sts/assume_role_with_web_identity.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module Parsers
|
||||
module AWS
|
||||
module STS
|
||||
class AssumeRoleWithWithWebIdentity < Fog::Parsers::Base
|
||||
def reset
|
||||
@response = {}
|
||||
end
|
||||
|
||||
def end_element(name)
|
||||
case name
|
||||
when 'AssumedRoleUser', 'Audience', 'Credentials', 'PackedPolicySize', 'Provider', 'SubjectFromWebIdentityToken'
|
||||
@response[name] = @value.strip
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
20
lib/fog/aws/requests/federation/get_signin_token.rb
Normal file
20
lib/fog/aws/requests/federation/get_signin_token.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class Federation
|
||||
class Real
|
||||
def get_signin_token(session)
|
||||
|
||||
request('getSigninToken', CGI.escape(Fog::JSON.encode(session)))
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_signin_token(session)
|
||||
{
|
||||
'SigninToken' => Fog::Mock.random_base64(752)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -50,6 +50,30 @@ module Fog
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def create_role(role_name, assume_role_policy_document, path = '/')
|
||||
if data[:roles].key?(role_name)
|
||||
raise Fog::AWS::IAM::EntityAlreadyExists.new("Role with name #{role_name} already exists")
|
||||
else
|
||||
data[:roles][role_name][:path] = path
|
||||
Excon::Response.new.tap do |response|
|
||||
response.body = {
|
||||
'Role' => {
|
||||
'Arn' => data[:roles][role_name][:arn].strip,
|
||||
'AssumeRolePolicyDocument' => Fog::JSON.encode(data[:roles][role_name][:assume_role_policy_document]),
|
||||
'CreateDate' => data[:roles][role_name][:create_date],
|
||||
'Path' => path,
|
||||
'RoleId' => data[:roles][role_name][:role_id].strip,
|
||||
'RoleName' => role_name,
|
||||
},
|
||||
'RequestId' => Fog::AWS::Mock.request_id
|
||||
}
|
||||
response.status = 200
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,6 +25,22 @@ module Fog
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def delete_role(role_name)
|
||||
role = data[:roles][role_name]
|
||||
|
||||
if role
|
||||
data[:roles].delete(role_name)
|
||||
Excon::Response.new.tap do |response|
|
||||
response.status = 200
|
||||
response.body = { 'RequestId' => Fog::AWS::Mock.request_id }
|
||||
end
|
||||
else
|
||||
raise Fog::AWS::IAM::NotFound.new("The role with name #{role_name} cannot be found.")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,6 +31,29 @@ module Fog
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def get_role(role_name)
|
||||
role = self.data[:roles][role_name]
|
||||
|
||||
raise Fog::AWS::IAM::NotFound.new("The role with name #{role_name} cannot be found") unless role
|
||||
|
||||
Excon::Response.new.tap do |response|
|
||||
response.body = {
|
||||
'Role' => {
|
||||
'Arn' => role[:arn].strip,
|
||||
'AssumeRolePolicyDocument' => Fog::JSON.encode(role[:assume_role_policy_document]),
|
||||
'CreateDate' => role[:create_date],
|
||||
'Path' => role[:path],
|
||||
'RoleId' => role[:role_id].strip,
|
||||
'RoleName' => role_name,
|
||||
},
|
||||
'RequestId' => Fog::AWS::Mock.request_id
|
||||
}
|
||||
response.status = 200
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,6 +36,28 @@ module Fog
|
|||
}.merge!(options))
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def list_roles(options={})
|
||||
Excon::Response.new.tap do |response|
|
||||
response.body = {
|
||||
'Roles' => data[:roles].map do |role, data|
|
||||
{
|
||||
'Arn' => data[:arn].strip,
|
||||
'AssumeRolePolicyDocument' => Fog::JSON.encode(data[:assume_role_policy_document]),
|
||||
'RoleId' => data[:role_id],
|
||||
'Path' => data[:path],
|
||||
'RoleName' => role,
|
||||
'CreateDate' => data[:create_date],
|
||||
}
|
||||
end,
|
||||
'RequestId' => Fog::AWS::Mock.request_id,
|
||||
'IsTruncated' => false,
|
||||
}
|
||||
response.status = 200
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
45
lib/fog/aws/requests/sts/assume_role_with_web_identity.rb
Normal file
45
lib/fog/aws/requests/sts/assume_role_with_web_identity.rb
Normal file
|
@ -0,0 +1,45 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class STS
|
||||
class Real
|
||||
require 'fog/aws/parsers/sts/assume_role_with_web_identity'
|
||||
|
||||
def assume_role_with_web_identity(role_arn, web_identity_token, role_session_name, options={})
|
||||
request_unsigned(
|
||||
'Action' => 'AssumeRoleWithWebIdentity',
|
||||
'RoleArn' => role_arn,
|
||||
'RoleSessionName' => role_session_name,
|
||||
'DurationSeconds' => options[:duration] || 3600,
|
||||
:idempotent => true,
|
||||
:parser => Fog::Parsers::AWS::STS::AssumeRoleWithWebIdentity.new
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
class Mock
|
||||
def assume_role_with_web_identity(role_arn, web_identity_token, role_session_name, options={})
|
||||
role = options[:iam].data[:roles].values.detect { |r| r[:arn] == role_arn }
|
||||
|
||||
Excon::Response.new.tap do |response|
|
||||
response.body = {
|
||||
'AssumedRoleUser' => {
|
||||
'Arn' => role[:arn],
|
||||
'AssumedRoleId' => role[:role_id]
|
||||
},
|
||||
'Audience' => 'fog',
|
||||
'Credentials' => {
|
||||
'AccessKeyId' => Fog::AWS::Mock.key_id(20),
|
||||
'Expiration' => options[:expiration] || Time.now + 3600,
|
||||
'SecretAccessKey' => Fog::AWS::Mock.key_id(40),
|
||||
'SessionToken' => Fog::Mock.random_hex(8)
|
||||
},
|
||||
'Provider' => 'fog',
|
||||
'SubjectFromWebIdentityToken' => Fog::Mock.random_hex(8)
|
||||
}
|
||||
response.status = 200
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,6 +16,7 @@ module Fog
|
|||
request :get_session_token
|
||||
request :assume_role
|
||||
request :assume_role_with_saml
|
||||
request :assume_role_with_web_identity
|
||||
|
||||
class Mock
|
||||
def self.data
|
||||
|
|
11
tests/requests/federation/get_signin_token_tests.rb
Normal file
11
tests/requests/federation/get_signin_token_tests.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
Shindo.tests('AWS::Federation | signin tokens', ['aws']) do
|
||||
@signin_token_format = {
|
||||
'SigninToken' => String
|
||||
}
|
||||
|
||||
tests("#get_signin_token").formats(@signin_token_format) do
|
||||
pending unless Fog.mocking?
|
||||
|
||||
Fog::AWS[:federation].get_signin_token("test_policy")
|
||||
end
|
||||
end
|
|
@ -2,42 +2,32 @@ Shindo.tests('AWS::IAM | role requests', ['aws']) do
|
|||
tests('success') do
|
||||
|
||||
@role = {
|
||||
'Arn' => String,
|
||||
'Arn' => String,
|
||||
'AssumeRolePolicyDocument' => String,
|
||||
'CreateDate' => Time,
|
||||
'Path' => String,
|
||||
'RoleId' => String,
|
||||
'RoleName' => String
|
||||
'CreateDate' => Time,
|
||||
'Path' => String,
|
||||
'RoleId' => String,
|
||||
'RoleName' => String
|
||||
}
|
||||
@role_format = {
|
||||
'Role' => @role,
|
||||
'RequestId' => String
|
||||
}
|
||||
tests("#create_role('fogrole')").formats(@role_format) do
|
||||
pending if Fog.mocking?
|
||||
Fog::AWS[:iam].create_role('fogrole', Fog::AWS::IAM::EC2_ASSUME_ROLE_POLICY).body
|
||||
end
|
||||
|
||||
tests("#get_role('fogrole')").formats(@role_format) do
|
||||
pending if Fog.mocking?
|
||||
Fog::AWS[:iam].get_role('fogrole').body
|
||||
end
|
||||
|
||||
@list_roles_format = {
|
||||
'Roles' => [{
|
||||
'Arn' => String,
|
||||
'AssumeRolePolicyDocument' => String,
|
||||
'CreateDate' => Time,
|
||||
'Path' => String,
|
||||
'RoleId' => String,
|
||||
'RoleName' => String
|
||||
}],
|
||||
'RequestId' => String,
|
||||
'Roles' => [@role],
|
||||
'RequestId' => String,
|
||||
'IsTruncated' => Fog::Boolean,
|
||||
}
|
||||
|
||||
tests("#list_roles").formats(@list_roles_format) do
|
||||
pending if Fog.mocking?
|
||||
body = Fog::AWS[:iam].list_roles.body
|
||||
returns(true){!! body['Roles'].find {|role| role['RoleName'] == 'fogrole'}}
|
||||
body
|
||||
|
@ -159,7 +149,6 @@ Shindo.tests('AWS::IAM | role requests', ['aws']) do
|
|||
end
|
||||
|
||||
tests("#delete_role('fogrole'").formats(AWS::IAM::Formats::BASIC) do
|
||||
pending if Fog.mocking?
|
||||
Fog::AWS[:iam].delete_role('fogrole').body
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
Shindo.tests('AWS::STS | assume role', ['aws']) do
|
||||
|
||||
@policy = {"Statement" => [{"Effect" => "Allow", "Action" => "*", "Resource" => "*"}]}
|
||||
@policy = {"Statement" => [{"Effect" => "Allow", "Action" => "*", "Resource" => "*"}]}
|
||||
|
||||
@response_format = {
|
||||
'SessionToken' => String,
|
||||
'SecretAccessKey' => String,
|
||||
'Expiration' => String,
|
||||
'AccessKeyId' => String,
|
||||
'Arn' => String,
|
||||
'RequestId' => String
|
||||
}
|
||||
@response_format = {
|
||||
'SessionToken' => String,
|
||||
'SecretAccessKey' => String,
|
||||
'Expiration' => String,
|
||||
'AccessKeyId' => String,
|
||||
'Arn' => String,
|
||||
'RequestId' => String
|
||||
}
|
||||
|
||||
tests("#assume_role('rolename', 'assumed_role_session', 'external_id', #{@policy.inspect}, 900)").formats(@response_format) do
|
||||
pending if Fog.mocking?
|
||||
Fog::AWS[:sts].assume_role("rolename","assumed_role_session","external_id", @policy, 900).body
|
||||
end
|
||||
tests("#assume_role('rolename', 'assumed_role_session', 'external_id', #{@policy.inspect}, 900)").formats(@response_format) do
|
||||
pending if Fog.mocking?
|
||||
Fog::AWS[:sts].assume_role("rolename","assumed_role_session","external_id", @policy, 900).body
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
Shindo.tests('AWS::STS | assume role with SAML', ['aws']) do
|
||||
|
||||
@policy = {"Statement" => [{"Effect" => "Allow", "Action" => "*", "Resource" => "*"}]}
|
||||
@policy = {"Statement" => [{"Effect" => "Allow", "Action" => "*", "Resource" => "*"}]}
|
||||
|
||||
@response_format = {
|
||||
'SessionToken' => String,
|
||||
'SecretAccessKey' => String,
|
||||
'Expiration' => String,
|
||||
'AccessKeyId' => String,
|
||||
'Arn' => String,
|
||||
'RequestId' => String
|
||||
}
|
||||
@response_format = {
|
||||
'SessionToken' => String,
|
||||
'SecretAccessKey' => String,
|
||||
'Expiration' => String,
|
||||
'AccessKeyId' => String,
|
||||
'Arn' => String,
|
||||
'RequestId' => String
|
||||
}
|
||||
|
||||
tests("#assume_role_with_saml('role_arn', 'principal_arn', 'saml_assertion', #{@policy.inspect}, 900)").formats(@response_format) do
|
||||
pending if Fog.mocking?
|
||||
Fog::AWS[:sts].assume_role_with_saml("role_arn","principal_arn","saml_assertion", @policy, 900).body
|
||||
end
|
||||
tests("#assume_role_with_saml('role_arn', 'principal_arn', 'saml_assertion', #{@policy.inspect}, 900)").formats(@response_format) do
|
||||
pending if Fog.mocking?
|
||||
Fog::AWS[:sts].assume_role_with_saml("role_arn","principal_arn","saml_assertion", @policy, 900).body
|
||||
end
|
||||
end
|
||||
|
|
26
tests/requests/sts/assume_role_with_web_identity_tests.rb
Normal file
26
tests/requests/sts/assume_role_with_web_identity_tests.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
Shindo.tests('AWS::STS | assume role with web identity', ['aws']) do
|
||||
@sts = Fog::AWS[:sts]
|
||||
@iam = Fog::AWS[:iam]
|
||||
@role = @iam.create_role('sts', Fog::AWS::IAM::EC2_ASSUME_ROLE_POLICY).body['Role']
|
||||
@token = Fog::AWS::Mock.key_id
|
||||
|
||||
@response_format = {
|
||||
'AssumedRoleUser' => {
|
||||
'Arn' => String,
|
||||
'AssumedRoleId' => String,
|
||||
},
|
||||
'Audience' => String,
|
||||
'Credentials' => {
|
||||
'AccessKeyId' => String,
|
||||
'Expiration' => Time,
|
||||
'SecretAccessKey' => String,
|
||||
'SessionToken' => String,
|
||||
},
|
||||
'Provider' => String,
|
||||
'SubjectFromWebIdentityToken' => String,
|
||||
}
|
||||
|
||||
tests("#assume_role_with_web_identity('#{@role['Arn']}', '#{@token}', 'fog')").formats(@response_format) do
|
||||
@sts.assume_role_with_web_identity(@role['Arn'], @token, 'fog', :iam => @iam).body
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue