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

Decrypt and validate credentials in raw_connect #69

Merged
merged 1 commit into from
Jul 17, 2017
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
59 changes: 35 additions & 24 deletions app/models/manageiq/providers/vmware/manager_auth_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,18 @@ def verify_credentials(auth_type = nil, options = {})
raise MiqException::MiqHostError, "No credentials defined" if missing_credentials?(auth_type)

options[:auth_type] = auth_type
begin

self.class.connection_rescue_block do
case auth_type.to_s
when 'default' then
with_provider_connection(options) do |vcd|
vcd.organizations.all
self.class.validate_connection(vcd)
end
when 'amqp' then
verify_amqp_credentials(options)
else
raise "Invalid Vmware vCloud Authentication Type: #{auth_type.inspect}"
end
rescue => err
miq_exception = translate_exception(err)
_log.error("Error Class=#{err.class.name}, Message=#{err.message}")
raise miq_exception
end

true
Expand All @@ -39,26 +36,11 @@ def connect(options = {})
self.class.raw_connect(server, port, username, password)
end

def translate_exception(err)
case err
when Fog::Compute::VcloudDirector::Unauthorized
MiqException::MiqInvalidCredentialsError.new "Login failed due to a bad username or password."
when Excon::Errors::Timeout
MiqException::MiqUnreachableError.new "Login attempt timed out"
when Excon::Errors::SocketError
MiqException::MiqHostError.new "Socket error: #{err.message}"
when MiqException::MiqInvalidCredentialsError, MiqException::MiqHostError
err
else
MiqException::MiqHostError.new "Unexpected response returned from system: #{err.message}"
end
end

module ClassMethods
def raw_connect(server, port, username, password)
def raw_connect(server, port, username, password, validate = false)
params = {
:vcloud_director_username => username,
:vcloud_director_password => password,
:vcloud_director_password => MiqPassword.try_decrypt(password),
:vcloud_director_host => server,
:vcloud_director_show_progress => false,
:port => port,
Expand All @@ -67,7 +49,36 @@ def raw_connect(server, port, username, password)
}
}

Fog::Compute::VcloudDirector.new(params)
connect = Fog::Compute::VcloudDirector.new(params)
connection_rescue_block { validate_connection(connect) } if validate
connect
end

def validate_connection(connection)
connection.organizations.all
end

def connection_rescue_block
yield
rescue => err
miq_exception = translate_exception(err)
_log.error("Error Class=#{err.class.name}, Message=#{err.message}")
raise miq_exception
end

def translate_exception(err)
case err
when Fog::Compute::VcloudDirector::Unauthorized
MiqException::MiqInvalidCredentialsError.new "Login failed due to a bad username or password."
when Excon::Errors::Timeout
MiqException::MiqUnreachableError.new "Login attempt timed out"
when Excon::Errors::SocketError
MiqException::MiqHostError.new "Socket error: #{err.message}"
when MiqException::MiqInvalidCredentialsError, MiqException::MiqHostError
err
else
MiqException::MiqHostError.new "Unexpected response returned from system: #{err.message}"
end
end
end
end
42 changes: 42 additions & 0 deletions spec/models/manageiq/providers/vmware/cloud_manager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,48 @@
)
end

context ".raw_connect" do
let(:params) do
{
:vcloud_director_username => "username",
:vcloud_director_password => "encrypted",
:vcloud_director_host => "server",
:vcloud_director_show_progress => false,
:port => "port",
:connection_options => {
:ssl_verify_peer => false # for development
}
}
end

before do
require 'fog/vcloud_director'
end

it "decrypts the vcloud password" do
encrypted = MiqPassword.encrypt("encrypted")
expect(::Fog::Compute::VcloudDirector).to receive(:new).with(params)

described_class.raw_connect("server", "port", "username", encrypted)
end

it "validates the password if validate is true if specified" do
expect(described_class).to receive(:validate_connection).and_raise(Fog::Compute::VcloudDirector::Unauthorized)
expect(::Fog::Compute::VcloudDirector).to receive(:new).with(params)

expect do
described_class.raw_connect("server", "port", "username", "encrypted", true)
end.to raise_error(MiqException::MiqInvalidCredentialsError, "Login failed due to a bad username or password.")
end

it "does not validate the password unless specified" do
expect(described_class).to_not receive(:validate_connection)
expect(::Fog::Compute::VcloudDirector).to receive(:new).with(params)

described_class.raw_connect("server", "port", "username", "encrypted")
end
end

it ".ems_type" do
expect(described_class.ems_type).to eq('vmware_cloud')
end
Expand Down