mirror of
https://github.com/fog/fog.git
synced 2022-11-09 13:51:43 -05:00
commit
bcbe4e6fbb
11 changed files with 260 additions and 3 deletions
|
@ -20,6 +20,7 @@ module Fog
|
|||
service(:simpledb, 'aws/simpledb', 'SimpleDB')
|
||||
service(:sns, 'aws/sns', 'SNS')
|
||||
service(:sqs, 'aws/sqs', 'SQS')
|
||||
service(:sts, 'aws/sts', 'STS')
|
||||
service(:storage, 'aws/storage', 'Storage')
|
||||
|
||||
def self.indexed_param(key, values)
|
||||
|
@ -85,6 +86,10 @@ module Fog
|
|||
'Version' => options[:version]
|
||||
})
|
||||
|
||||
params.merge!({
|
||||
'SecurityToken' => options[:aws_session_token]
|
||||
}) if options[:aws_session_token]
|
||||
|
||||
body = ''
|
||||
for key in params.keys.sort
|
||||
unless (value = params[key]).nil?
|
||||
|
|
|
@ -6,7 +6,7 @@ module Fog
|
|||
class AWS < Fog::Service
|
||||
|
||||
requires :aws_access_key_id, :aws_secret_access_key
|
||||
recognizes :endpoint, :region, :host, :path, :port, :scheme, :persistent
|
||||
recognizes :endpoint, :region, :host, :path, :port, :scheme, :persistent, :aws_session_token
|
||||
|
||||
model_path 'fog/aws/models/compute'
|
||||
model :address
|
||||
|
@ -249,6 +249,7 @@ module Fog
|
|||
# * options<~Hash> - config arguments for connection. Defaults to {}.
|
||||
# * region<~String> - optional region to use, in
|
||||
# ['eu-west-1', 'us-east-1', 'us-west-1', 'us-west-2', 'ap-northeast-1', 'ap-southeast-1']
|
||||
# * aws_session_token<~String> - when using Session Tokens or Federated Users, a session_token must be presented
|
||||
#
|
||||
# ==== Returns
|
||||
# * EC2 object with connection to aws.
|
||||
|
@ -257,6 +258,7 @@ module Fog
|
|||
|
||||
@aws_access_key_id = options[:aws_access_key_id]
|
||||
@aws_secret_access_key = options[:aws_secret_access_key]
|
||||
@aws_session_token = options[:aws_session_token]
|
||||
@connection_options = options[:connection_options] || {}
|
||||
@hmac = Fog::HMAC.new('sha256', @aws_secret_access_key)
|
||||
@region = options[:region] ||= 'us-east-1'
|
||||
|
@ -306,6 +308,7 @@ module Fog
|
|||
params,
|
||||
{
|
||||
:aws_access_key_id => @aws_access_key_id,
|
||||
:aws_session_token => @aws_session_token,
|
||||
:hmac => @hmac,
|
||||
:host => @host,
|
||||
:path => @path,
|
||||
|
|
31
lib/fog/aws/parsers/sts/get_session_token.rb
Normal file
31
lib/fog/aws/parsers/sts/get_session_token.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
module Fog
|
||||
module Parsers
|
||||
module AWS
|
||||
module STS
|
||||
|
||||
class GetSessionToken < Fog::Parsers::Base
|
||||
# http://docs.amazonwebservices.com/IAM/latest/UserGuide/index.html?CreatingFedTokens.html
|
||||
|
||||
def reset
|
||||
@response = {}
|
||||
end
|
||||
|
||||
def end_element(name)
|
||||
case name
|
||||
when 'SessionToken', 'SecretAccessKey', 'Expiration', 'AccessKeyId'
|
||||
@response[name] = @value.strip
|
||||
when 'Arn', 'FederatedUserId'
|
||||
@response[name] = @value
|
||||
when 'PackedPolicySize'
|
||||
@response[name] = @value
|
||||
when 'RequestId'
|
||||
@response[name] = @value
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
20
lib/fog/aws/requests/sts/get_federation_token.rb
Normal file
20
lib/fog/aws/requests/sts/get_federation_token.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class STS
|
||||
class Real
|
||||
|
||||
require 'fog/aws/parsers/sts/get_session_token'
|
||||
|
||||
def get_federation_token(name, policy, duration=43200)
|
||||
request({
|
||||
'Action' => 'GetFederationToken',
|
||||
'Name' => name,
|
||||
'Policy' => MultiJson.encode(policy),
|
||||
'DurationSeconds' => duration,
|
||||
:parser => Fog::Parsers::AWS::STS::GetSessionToken.new
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
18
lib/fog/aws/requests/sts/get_session_token.rb
Normal file
18
lib/fog/aws/requests/sts/get_session_token.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
module Fog
|
||||
module AWS
|
||||
class STS
|
||||
class Real
|
||||
|
||||
require 'fog/aws/parsers/sts/get_session_token'
|
||||
|
||||
def get_session_token(duration=43200)
|
||||
request({
|
||||
'Action' => 'GetSessionToken',
|
||||
'DurationSeconds' => duration,
|
||||
:parser => Fog::Parsers::AWS::STS::GetSessionToken.new
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,7 +5,7 @@ module Fog
|
|||
class SimpleDB < Fog::Service
|
||||
|
||||
requires :aws_access_key_id, :aws_secret_access_key
|
||||
recognizes :host, :nil_string, :path, :port, :scheme, :persistent, :region
|
||||
recognizes :host, :nil_string, :path, :port, :scheme, :persistent, :region, :aws_session_token
|
||||
|
||||
request_path 'fog/aws/requests/simpledb'
|
||||
request :batch_put_attributes
|
||||
|
@ -70,6 +70,7 @@ module Fog
|
|||
|
||||
@aws_access_key_id = options[:aws_access_key_id]
|
||||
@aws_secret_access_key = options[:aws_secret_access_key]
|
||||
@aws_session_token = options[:aws_session_token]
|
||||
@connection_options = options[:connection_options] || {}
|
||||
@hmac = Fog::HMAC.new('sha256', @aws_secret_access_key)
|
||||
@nil_string = options[:nil_string]|| 'nil'
|
||||
|
@ -165,6 +166,7 @@ module Fog
|
|||
params,
|
||||
{
|
||||
:aws_access_key_id => @aws_access_key_id,
|
||||
:aws_session_token => @aws_session_token,
|
||||
:hmac => @hmac,
|
||||
:host => @host,
|
||||
:path => @path,
|
||||
|
|
|
@ -5,7 +5,7 @@ module Fog
|
|||
class SQS < Fog::Service
|
||||
|
||||
requires :aws_access_key_id, :aws_secret_access_key
|
||||
recognizes :region, :host, :path, :port, :scheme, :persistent
|
||||
recognizes :region, :host, :path, :port, :scheme, :persistent, :aws_session_token
|
||||
|
||||
request_path 'fog/aws/requests/sqs'
|
||||
request :change_message_visibility
|
||||
|
@ -78,6 +78,7 @@ module Fog
|
|||
def initialize(options={})
|
||||
@aws_access_key_id = options[:aws_access_key_id]
|
||||
@aws_secret_access_key = options[:aws_secret_access_key]
|
||||
@aws_session_token = options[:aws_session_token]
|
||||
@connection_options = options[:connection_options] || {}
|
||||
@hmac = Fog::HMAC.new('sha256', @aws_secret_access_key)
|
||||
options[:region] ||= 'us-east-1'
|
||||
|
@ -121,6 +122,7 @@ module Fog
|
|||
params,
|
||||
{
|
||||
:aws_access_key_id => @aws_access_key_id,
|
||||
:aws_session_token => @aws_session_token,
|
||||
:hmac => @hmac,
|
||||
:host => @host,
|
||||
:path => path || @path,
|
||||
|
|
137
lib/fog/aws/sts.rb
Normal file
137
lib/fog/aws/sts.rb
Normal file
|
@ -0,0 +1,137 @@
|
|||
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'aws'))
|
||||
|
||||
module Fog
|
||||
module AWS
|
||||
class STS < Fog::Service
|
||||
|
||||
class EntityAlreadyExists < Fog::AWS::STS::Error; end
|
||||
class ValidationError < Fog::AWS::STS::Error; end
|
||||
|
||||
requires :aws_access_key_id, :aws_secret_access_key
|
||||
recognizes :host, :path, :port, :scheme, :persistent
|
||||
|
||||
request_path 'fog/aws/requests/sts'
|
||||
request :get_federation_token
|
||||
request :get_session_token
|
||||
|
||||
class Mock
|
||||
def self.data
|
||||
@data ||= Hash.new do |hash, key|
|
||||
hash[key] = {
|
||||
:owner_id => Fog::AWS::Mock.owner_id,
|
||||
:server_certificates => {}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def self.reset
|
||||
@data = nil
|
||||
end
|
||||
|
||||
def self.server_certificate_id
|
||||
Fog::Mock.random_hex(16)
|
||||
end
|
||||
|
||||
def initialize(options={})
|
||||
@aws_access_key_id = options[:aws_access_key_id]
|
||||
end
|
||||
|
||||
def data
|
||||
self.class.data[@aws_access_key_id]
|
||||
end
|
||||
|
||||
def reset_data
|
||||
self.class.data.delete(@aws_access_key_id)
|
||||
end
|
||||
end
|
||||
|
||||
class Real
|
||||
|
||||
# Initialize connection to STS
|
||||
#
|
||||
# ==== Notes
|
||||
# options parameter must include values for :aws_access_key_id and
|
||||
# :aws_secret_access_key in order to create a connection
|
||||
#
|
||||
# ==== Examples
|
||||
# iam = STS.new(
|
||||
# :aws_access_key_id => your_aws_access_key_id,
|
||||
# :aws_secret_access_key => your_aws_secret_access_key
|
||||
# )
|
||||
#
|
||||
# ==== Parameters
|
||||
# * options<~Hash> - config arguments for connection. Defaults to {}.
|
||||
#
|
||||
# ==== Returns
|
||||
# * STS object with connection to AWS.
|
||||
def initialize(options={})
|
||||
require 'fog/core/parser'
|
||||
require 'multi_json'
|
||||
|
||||
@aws_access_key_id = options[:aws_access_key_id]
|
||||
@aws_secret_access_key = options[:aws_secret_access_key]
|
||||
@connection_options = options[:connection_options] || {}
|
||||
@hmac = Fog::HMAC.new('sha256', @aws_secret_access_key)
|
||||
@host = options[:host] || 'sts.amazonaws.com'
|
||||
@path = options[:path] || '/'
|
||||
@persistent = options[:persistent] || false
|
||||
@port = options[:port] || 443
|
||||
@scheme = options[:scheme] || 'https'
|
||||
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}#{@path}", @persistent, @connection_options)
|
||||
end
|
||||
|
||||
def reload
|
||||
@connection.reset
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def request(params)
|
||||
idempotent = params.delete(:idempotent)
|
||||
parser = params.delete(:parser)
|
||||
|
||||
body = Fog::AWS.signed_params(
|
||||
params,
|
||||
{
|
||||
:aws_access_key_id => @aws_access_key_id,
|
||||
:hmac => @hmac,
|
||||
:host => @host,
|
||||
:path => @path,
|
||||
:port => @port,
|
||||
:version => '2011-06-15'
|
||||
}
|
||||
)
|
||||
|
||||
begin
|
||||
response = @connection.request({
|
||||
:body => body,
|
||||
:expects => 200,
|
||||
:idempotent => idempotent,
|
||||
:headers => { 'Content-Type' => 'application/x-www-form-urlencoded' },
|
||||
:host => @host,
|
||||
:method => 'POST',
|
||||
:parser => parser
|
||||
})
|
||||
|
||||
response
|
||||
rescue Excon::Errors::HTTPStatusError => error
|
||||
if match = error.message.match(/<Code>(.*)<\/Code>(?:.*<Message>(.*)<\/Message>)?/m)
|
||||
case match[1]
|
||||
when 'EntityAlreadyExists', 'KeyPairMismatch', 'LimitExceeded', 'MalformedCertificate', 'ValidationError'
|
||||
raise Fog::AWS::STS.const_get(match[1]).slurp(error, match[2])
|
||||
else
|
||||
raise Fog::AWS::STS::Error.slurp(error, "#{match[1]} => #{match[2]}") if match[1]
|
||||
raise
|
||||
end
|
||||
else
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -35,6 +35,8 @@ class AWS < Fog::Bin
|
|||
Fog::AWS::RDS
|
||||
when :sns
|
||||
Fog::AWS::SNS
|
||||
when :sts
|
||||
Fog::AWS::STS
|
||||
else
|
||||
# @todo Replace most instances of ArgumentError with NotImplementedError
|
||||
# @todo For a list of widely supported Exceptions, see:
|
||||
|
|
21
tests/aws/requests/sts/get_federation_token_tests.rb
Normal file
21
tests/aws/requests/sts/get_federation_token_tests.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
Shindo.tests('AWS::STS | session tokens', ['aws']) do
|
||||
|
||||
@policy = {"Statement" => [{"Effect" => "Allow", "Action" => "*", "Resource" => "*"}]}
|
||||
|
||||
@federation_format = {
|
||||
'SessionToken' => String,
|
||||
'SecretAccessKey' => String,
|
||||
'Expiration' => String,
|
||||
'AccessKeyId' => String,
|
||||
'Arn' => String,
|
||||
'FederatedUserId' => String,
|
||||
'PackedPolicySize' => String,
|
||||
'RequestId' => String
|
||||
}
|
||||
|
||||
tests("#get_federation_token('test@fog.io', #{@policy.inspect})").formats(@federation_format) do
|
||||
pending if Fog.mocking?
|
||||
Fog::AWS[:sts].get_federation_token("test@fog.io", @policy).body
|
||||
end
|
||||
|
||||
end
|
16
tests/aws/requests/sts/session_token_tests.rb
Normal file
16
tests/aws/requests/sts/session_token_tests.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
Shindo.tests('AWS::STS | session tokens', ['aws']) do
|
||||
|
||||
@session_format = {
|
||||
'SessionToken' => String,
|
||||
'SecretAccessKey' => String,
|
||||
'Expiration' => String,
|
||||
'AccessKeyId' => String,
|
||||
'RequestId' => String
|
||||
}
|
||||
|
||||
tests("#get_session_token").formats(@session_format) do
|
||||
pending if Fog.mocking?
|
||||
Fog::AWS[:sts].get_session_token.body
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue