Skip to content

Commit

Permalink
Add support for using application credentials for authentication (#533)
Browse files Browse the repository at this point in the history
* Add initial support for using application credentials for auth

* Add spec test for using application credentials

* Add application credentials options to identity

* Return nil from scope if application credential is used
  • Loading branch information
scornelissen85 authored Mar 20, 2024
1 parent 9d9029a commit be1d005
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 16 deletions.
11 changes: 11 additions & 0 deletions lib/fog/openstack/auth/token/v3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ def credentials
'methods' => ['token'],
'token' => {'id' => @token}
}
elsif @application_credential
{
'methods' => ['application_credential'],
'application_credential' => @application_credential
}
else
{
'methods' => ['password'],
Expand Down Expand Up @@ -50,6 +55,7 @@ def path
end

def scope
return nil if @application_credential
return @project.identity if @project
return @domain.identity if @domain
end
Expand Down Expand Up @@ -96,6 +102,11 @@ def build_credentials(auth)

if auth[:openstack_auth_token]
@token = auth[:openstack_auth_token]
elsif auth[:openstack_application_credential_id] and auth[:openstack_application_credential_secret]
@application_credential = {
:id => auth[:openstack_application_credential_id],
:secret => auth[:openstack_application_credential_secret],
}
else
@user = Fog::OpenStack::Auth::User.new(auth[:openstack_userid], auth[:openstack_username])
@user.password = auth[:openstack_api_key]
Expand Down
3 changes: 2 additions & 1 deletion lib/fog/openstack/compute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ class Compute < Fog::Service
:openstack_project_name, :openstack_project_id,
:openstack_project_domain, :openstack_user_domain, :openstack_domain_name,
:openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id,
:openstack_identity_api_version
:openstack_identity_api_version, :openstack_application_credential_id,
:openstack_application_credential_secret

## MODELS
#
Expand Down
11 changes: 7 additions & 4 deletions lib/fog/openstack/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ module Core
attr_reader :openstack_project_id
attr_reader :openstack_project_domain_id
attr_reader :openstack_identity_api_version
attr_reader :openstack_application_credential_id
attr_reader :openstack_application_credential_secret

# fallback
def self.not_found_class
Expand Down Expand Up @@ -184,10 +186,11 @@ def setup(options)
@openstack_can_reauthenticate = false
else
missing_credentials = []

missing_credentials << :openstack_api_key unless @openstack_api_key
unless @openstack_username || @openstack_userid
missing_credentials << 'openstack_username or openstack_userid'
unless @openstack_application_credential_secret and @openstack_application_credential_id
missing_credentials << :openstack_api_key unless @openstack_api_key
unless @openstack_username || @openstack_userid
missing_credentials << 'openstack_username/openstack_userid or openstack_application_credential_secret and openstack_application_credential_id'
end
end
unless missing_credentials.empty?
raise ArgumentError, "Missing required arguments: #{missing_credentials.join(', ')}"
Expand Down
3 changes: 2 additions & 1 deletion lib/fog/openstack/identity/v3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class V3 < Fog::Service
:openstack_user_domain_id, :openstack_project_domain_id,
:openstack_api_key, :openstack_current_user_id, :openstack_userid, :openstack_username,
:current_user, :current_user_id, :current_tenant,
:provider, :openstack_identity_api_version, :openstack_cache_ttl
:provider, :openstack_identity_api_version, :openstack_cache_ttl, :openstack_application_credential_id,
:openstack_application_credential_secret

model_path 'fog/openstack/identity/v3/models'
model :domain
Expand Down
3 changes: 2 additions & 1 deletion lib/fog/openstack/network.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class Network < Fog::Service
:openstack_project_name, :openstack_project_id,
:openstack_project_domain, :openstack_user_domain, :openstack_domain_name,
:openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id,
:openstack_identity_api_version
:openstack_identity_api_version, :openstack_application_credential_id,
:openstack_application_credential_secret

## MODELS
#
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 21 additions & 8 deletions spec/identity_v3_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
end

it 'authenticates with password, userid and domain_id' do
VCR.use_cassette('authv3_a') do
Fog::OpenStack::Identity::V3.new(
:openstack_domain_id => @openstack_vcr.domain_id,
:openstack_api_key => @openstack_vcr.password,
:openstack_userid => @openstack_vcr.user_id,
:openstack_region => @openstack_vcr.region,
:openstack_auth_url => @os_auth_url
VCR.use_cassette('authv3_a') do
Fog::OpenStack::Identity::V3.new(
:openstack_domain_id => @openstack_vcr.domain_id,
:openstack_api_key => @openstack_vcr.password,
:openstack_userid => @openstack_vcr.user_id,
:openstack_region => @openstack_vcr.region,
:openstack_auth_url => @os_auth_url
)
end
end

it 'authenticates with password, username and domain_id' do
VCR.use_cassette('authv3_b') do
Fog::OpenStack::Identity::V3.new(
Expand All @@ -47,6 +47,19 @@
end
end

it 'authenticates with application credentials' do
VCR.use_cassette('authv3_application_credential') do
Fog::OpenStack::Identity::V3.new(
:openstack_domain_id => @openstack_vcr.domain_id,
:openstack_application_credential_id => @openstack_vcr.application_credential_id,
:openstack_application_credential_secret => @openstack_vcr.application_credential_secret,
:openstack_userid => @openstack_vcr.user_id,
:openstack_region => @openstack_vcr.region,
:openstack_auth_url => @os_auth_url
)
end
end

it 'authenticates in another region' do
VCR.use_cassette('idv3_endpoint') do
@endpoints_all = @service.endpoints.all
Expand Down
8 changes: 7 additions & 1 deletion spec/shared_context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ class OpenStackVCR
:domain_id,
:region,
:region_other,
:interface
:interface,
:application_credential_id,
:application_credential_secret

# This method should be called in a "before :all" call to set everything up.
# A properly configured instance of the service class (e.g.
Expand Down Expand Up @@ -109,6 +111,8 @@ def initialize(options)
@domain_id = 'default'
@domain_name = 'Default'
@project_name = 'admin'
@application_credential_id = '423f19a4ac1e4f48bbb4180756e6eb6c'
@application_credential_secret = 'rEaqvJka48mpv'

unless use_recorded
@region = ENV['OS_REGION_NAME'] || options[:region_name] || @region
Expand All @@ -121,6 +125,8 @@ def initialize(options)
@domain_name = ENV['OS_USER_DOMAIN_NAME'] || options[:domain_name] || @domain_name
@domain_id = ENV['OS_USER_DOMAIN_ID'] || options[:domain_id] || @domain_id
@project_name = ENV['OS_PROJECT_NAME'] || options[:project_name] || @project_name
@application_credential_id = ENV['OS_APPLICATION_CREDENTIAL_ID'] || options[:application_credential_id] || @application_credential_id
@application_credential_secret = ENV['OS_APPLICATION_CREDENTIAL_SECRET'] || options[:application_credential_secret] || @application_credential_secret
end

# TODO: remove
Expand Down

0 comments on commit be1d005

Please sign in to comment.