Class: AwsMfaSecure::Base
- Inherits:
-
Object
- Object
- AwsMfaSecure::Base
show all
- Extended by:
- Memoist
- Defined in:
- lib/aws_mfa_secure/base.rb
Instance Method Summary
collapse
Instance Method Details
#aws_cli_installed? ⇒ Boolean
34
35
36
37
|
# File 'lib/aws_mfa_secure/base.rb', line 34
def aws_cli_installed?
return false unless File.exist?("#{ENV['HOME']}/.aws")
system("type aws > /dev/null 2>&1")
end
|
#aws_cli_setup? ⇒ Boolean
39
40
41
42
|
# File 'lib/aws_mfa_secure/base.rb', line 39
def aws_cli_setup?
File.exist?("#{ENV['HOME']}/.aws/config") &&
File.exist?("#{ENV['HOME']}/.aws/credentials")
end
|
#aws_config(prop) ⇒ Object
134
135
136
137
138
139
|
# File 'lib/aws_mfa_secure/base.rb', line 134
def aws_config(prop)
profile_data = AWSConfig[aws_profile]
return unless profile_data
v = profile_data[prop.to_s]
v unless v.blank?
end
|
#aws_mfa_env_set? ⇒ Boolean
28
29
30
31
32
|
# File 'lib/aws_mfa_secure/base.rb', line 28
def aws_mfa_env_set?
ENV['AWS_ACCESS_KEY_ID'] &&
ENV['AWS_SECRET_ACCESS_KEY'] &&
ENV['AWS_MFA_SERIAL']
end
|
#aws_profile ⇒ Object
142
143
144
|
# File 'lib/aws_mfa_secure/base.rb', line 142
def aws_profile
ENV['AWS_PROFILE'] || 'default'
end
|
#credentials ⇒ Object
55
56
57
|
# File 'lib/aws_mfa_secure/base.rb', line 55
def credentials
JSON.load(IO.read(session_creds_path))
end
|
#fetch_creds? ⇒ Boolean
44
45
46
|
# File 'lib/aws_mfa_secure/base.rb', line 44
def fetch_creds?
!good_session_creds?
end
|
#get_session_token(shell: false) ⇒ Object
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# File 'lib/aws_mfa_secure/base.rb', line 70
def get_session_token(shell: false)
retries = 0
begin
token_code = mfa_prompt
options = {
serial_number: mfa_serial,
token_code: token_code,
}
options[:duration_seconds] = ENV['AWS_MFA_TTL'] if ENV['AWS_MFA_TTL']
if shell
shell_get_session_token(options) else sts.get_session_token(options)
end
rescue Aws::STS::Errors::ValidationError, Aws::STS::Errors::AccessDenied, MfaError => e
$stderr.puts "#{e.class}: #{e.message}"
$stderr.puts "Incorrect MFA code. Please try again."
retries += 1
if retries >= 3
$stderr.puts "Giving up after #{retries} retries."
exit 1
end
retry
end
end
|
#good_session_creds? ⇒ Boolean
48
49
50
51
52
53
|
# File 'lib/aws_mfa_secure/base.rb', line 48
def good_session_creds?
return false unless File.exist?(session_creds_path)
expiration = Time.parse(credentials["expiration"])
Time.now.utc < expiration end
|
#iam_mfa? ⇒ Boolean
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# File 'lib/aws_mfa_secure/base.rb', line 13
def iam_mfa?
return true if aws_mfa_env_set?
return false unless aws_cli_installed? && aws_cli_setup?
return false unless mfa_serial
aws_access_key_id = aws_config(:aws_access_key_id)
aws_secret_access_key = aws_config(:aws_secret_access_key)
source_profile = aws_config(:source_profile)
aws_access_key_id && aws_secret_access_key && !source_profile
end
|
#mfa_prompt ⇒ Object
97
98
99
100
101
102
103
104
105
|
# File 'lib/aws_mfa_secure/base.rb', line 97
def mfa_prompt
if ENV['AWS_MFA_TOKEN']
token_code = ENV.delete('AWS_MFA_TOKEN') return token_code
end
$stderr.print "Please provide your MFA code: "
$stdin.gets.strip
end
|
#mfa_serial ⇒ Object
125
126
127
|
# File 'lib/aws_mfa_secure/base.rb', line 125
def mfa_serial
ENV['AWS_MFA_SERIAL'] || aws_config(:mfa_serial)
end
|
#save_creds(credentials) ⇒ Object
60
61
62
63
64
|
# File 'lib/aws_mfa_secure/base.rb', line 60
def save_creds(credentials)
FileUtils.mkdir_p(File.dirname(session_creds_path))
IO.write(session_creds_path, JSON.pretty_generate(credentials))
flush_cache end
|
#session_creds_path ⇒ Object
66
67
68
|
# File 'lib/aws_mfa_secure/base.rb', line 66
def session_creds_path
"#{SESSIONS_PATH}/#{@aws_profile}"
end
|
#shell_get_session_token(options) ⇒ Object
Credentials class uses this version of get-session-token to allow the AWS Ruby SDK itself to be patched.
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/aws_mfa_secure/base.rb', line 108
def shell_get_session_token(options)
args = options.map { |k,v| "--#{k.to_s.gsub('_','-')} #{v}" }.join(' ')
command = "aws sts get-session-token #{args} 2>&1"
out = `#{command}`
unless out.include?("Credentials")
raise(MfaError, out.strip) end
data = JSON.load(out)
resp = data.deep_transform_keys { |k| k.underscore }
credentials = Aws::STS::Types::Credentials.new(resp["credentials"])
Aws::STS::Types::GetSessionTokenResponse.new(credentials: credentials)
end
|
#sts ⇒ Object
129
130
131
|
# File 'lib/aws_mfa_secure/base.rb', line 129
def sts
Aws::STS::Client.new
end
|