Module: AWSUDO
- Defined in:
- lib/awsudo.rb
Constant Summary collapse
- AWS_ROLES =
File.join(ENV['HOME'], '.aws-roles')
Class Attribute Summary collapse
-
.idp_login_url ⇒ Object
readonly
Returns the value of attribute idp_login_url.
-
.saml_provider_name ⇒ Object
readonly
Returns the value of attribute saml_provider_name.
Class Method Summary collapse
- .assume_role(role) ⇒ Object
- .assume_role_using_agent(role) ⇒ Object
- .assume_role_using_password(role) ⇒ Object
- .assume_role_with_saml(saml_assertion, role_arn) ⇒ Object
- .config(idp_login_url, saml_provider_name) ⇒ Object
- .get_federated_credentials ⇒ Object
- .get_saml_assertion(username, password) ⇒ Object
- .resolve_role(role, roles_filename = AWS_ROLES) ⇒ Object
Class Attribute Details
.idp_login_url ⇒ Object (readonly)
Returns the value of attribute idp_login_url.
16 17 18 |
# File 'lib/awsudo.rb', line 16 def idp_login_url @idp_login_url end |
.saml_provider_name ⇒ Object (readonly)
Returns the value of attribute saml_provider_name.
16 17 18 |
# File 'lib/awsudo.rb', line 16 def saml_provider_name @saml_provider_name end |
Class Method Details
.assume_role(role) ⇒ Object
55 56 57 |
# File 'lib/awsudo.rb', line 55 def self.assume_role(role) assume_role_using_agent(role) rescue assume_role_using_password(role) end |
.assume_role_using_agent(role) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/awsudo.rb', line 35 def self.assume_role_using_agent(role) socket_name = ENV['AWS_AUTH_SOCK'] credentials = UNIXSocket.open(socket_name) do |client| client.puts role response = client.gets raise "Connection closed by peer" if response.nil? JSON.parse(response.strip) end raise credentials['error'] if credentials['error'] credentials end |
.assume_role_using_password(role) ⇒ Object
48 49 50 51 52 53 |
# File 'lib/awsudo.rb', line 48 def self.assume_role_using_password(role) username, password = get_federated_credentials saml_assertion = get_saml_assertion(username, password) role_arn = resolve_role(role) assume_role_with_saml(saml_assertion, role_arn).to_h end |
.assume_role_with_saml(saml_assertion, role_arn) ⇒ Object
83 84 85 86 87 88 89 90 |
# File 'lib/awsudo.rb', line 83 def self.assume_role_with_saml(saml_assertion, role_arn) principal_arn = "#{role_arn[/^arn:aws:iam::\d+:/]}saml-provider/#{saml_provider_name}" sts = Aws::STS::Client.new(credentials: Aws::Credentials.new('a', 'b', 'c'), region: 'us-east-1') sts.assume_role_with_saml( role_arn: role_arn, principal_arn: principal_arn, saml_assertion: saml_assertion).credentials end |
.config(idp_login_url, saml_provider_name) ⇒ Object
19 20 21 22 |
# File 'lib/awsudo.rb', line 19 def self.config(idp_login_url, saml_provider_name) @idp_login_url = idp_login_url @saml_provider_name = saml_provider_name end |
.get_federated_credentials ⇒ Object
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/awsudo.rb', line 24 def self.get_federated_credentials fd = IO.sysopen("/dev/tty", "w") console = IO.new(fd,"w") console.print "Login: " username = STDIN.gets.chomp console.print "Password: " password = STDIN.noecho(&:gets).chomp console.print "\n" [username, password] end |
.get_saml_assertion(username, password) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/awsudo.rb', line 59 def self.get_saml_assertion(username, password) uri = URI.parse(idp_login_url) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_PEER req = Net::HTTP::Post.new(uri.request_uri) req.set_form_data({'username' => username, 'password' => password}) res = http.request(req) raise "Authentication failed" if res['Location'].nil? uri = URI.parse(res['Location']) req = Net::HTTP::Get.new(uri.request_uri) req['Cookie'] = res['Set-Cookie'] http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_PEER res = http.request(req) doc = REXML::Document.new(res.body) REXML::XPath.first(doc, '/html/body/form/input[@name = "SAMLResponse"]/@value').to_s end |
.resolve_role(role, roles_filename = AWS_ROLES) ⇒ Object
92 93 94 95 96 97 98 99 100 |
# File 'lib/awsudo.rb', line 92 def self.resolve_role(role, roles_filename = AWS_ROLES) return role if role =~ /^arn:aws:iam::\d+:role\/\S+$/ raise "`#{role}' is not a valid role" if role =~ /\s/ line = File.readlines(roles_filename).find {|line| line =~ /^#{role}\s+arn:aws:iam::\d+:role\/\S+\s*$/ } raise "`#{role}' is not a valid role" if line.nil? role_arn = line.split(/\s+/)[1] raise "`#{role}' is not a valid role" if role_arn.nil? role_arn end |