nucleus 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +9 -0
- data/README.md +43 -72
- data/lib/nucleus/adapter_resolver.rb +3 -3
- data/lib/nucleus/adapters/base_adapter.rb +109 -109
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/application.rb +111 -111
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/cloud_foundry_v2.rb +141 -141
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/data.rb +97 -97
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/domains.rb +5 -5
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/lifecycle.rb +41 -41
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/logs.rb +6 -6
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/regions.rb +33 -33
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/services.rb +6 -6
- data/lib/nucleus/adapters/v1/cloud_foundry_v2/vars.rb +80 -80
- data/lib/nucleus/adapters/v1/heroku/app_states.rb +57 -57
- data/lib/nucleus/adapters/v1/heroku/data.rb +78 -78
- data/lib/nucleus/adapters/v1/heroku/heroku.rb +146 -146
- data/lib/nucleus/adapters/v1/heroku/lifecycle.rb +51 -51
- data/lib/nucleus/adapters/v1/heroku/logs.rb +2 -2
- data/lib/nucleus/adapters/v1/heroku/regions.rb +42 -42
- data/lib/nucleus/adapters/v1/heroku/services.rb +168 -168
- data/lib/nucleus/adapters/v1/heroku/vars.rb +65 -65
- data/lib/nucleus/adapters/v1/openshift_v2/app_states.rb +68 -68
- data/lib/nucleus/adapters/v1/openshift_v2/application.rb +1 -1
- data/lib/nucleus/adapters/v1/openshift_v2/data.rb +96 -96
- data/lib/nucleus/adapters/v1/openshift_v2/lifecycle.rb +60 -60
- data/lib/nucleus/adapters/v1/openshift_v2/logs.rb +106 -106
- data/lib/nucleus/adapters/v1/openshift_v2/openshift_v2.rb +125 -125
- data/lib/nucleus/adapters/v1/openshift_v2/regions.rb +58 -58
- data/lib/nucleus/adapters/v1/openshift_v2/services.rb +173 -173
- data/lib/nucleus/adapters/v1/openshift_v2/vars.rb +49 -49
- data/lib/nucleus/adapters/v1/stub_adapter.rb +464 -464
- data/lib/nucleus/core/adapter_extensions/auth/auth_client.rb +44 -44
- data/lib/nucleus/core/adapter_extensions/auth/expiring_token_auth_client.rb +53 -53
- data/lib/nucleus/core/adapter_extensions/auth/http_basic_auth_client.rb +3 -3
- data/lib/nucleus/core/adapter_extensions/auth/o_auth2_auth_client.rb +95 -95
- data/lib/nucleus/core/adapter_extensions/auth/token_auth_client.rb +36 -36
- data/lib/nucleus/core/adapter_extensions/http_client.rb +5 -5
- data/lib/nucleus/core/common/files/archive_extractor.rb +1 -1
- data/lib/nucleus/core/common/files/archiver.rb +2 -2
- data/lib/nucleus/core/file_handling/file_manager.rb +64 -64
- data/lib/nucleus/core/file_handling/git_deployer.rb +133 -133
- data/lib/nucleus/core/import/adapter_configuration.rb +53 -53
- data/lib/nucleus/scripts/initialize_config_defaults.rb +26 -26
- data/lib/nucleus/version.rb +1 -1
- data/nucleus.gemspec +2 -2
- data/spec/integration/api/auth_spec.rb +3 -3
- data/spec/spec_helper.rb +98 -98
- data/spec/test_suites.rake +1 -1
- data/spec/unit/adapters/git_deployer_spec.rb +262 -262
- data/spec/unit/common/helpers/auth_helper_spec.rb +1 -1
- data/tasks/evaluation.rake +1 -1
- data/wiki/adapter_tests.md +0 -7
- data/wiki/implement_new_adapter.md +1 -1
- metadata +4 -20
- data/config/adapters/cloud_control.yml +0 -32
- data/lib/nucleus/adapters/v1/cloud_control/application.rb +0 -108
- data/lib/nucleus/adapters/v1/cloud_control/authentication.rb +0 -27
- data/lib/nucleus/adapters/v1/cloud_control/buildpacks.rb +0 -23
- data/lib/nucleus/adapters/v1/cloud_control/cloud_control.rb +0 -153
- data/lib/nucleus/adapters/v1/cloud_control/data.rb +0 -76
- data/lib/nucleus/adapters/v1/cloud_control/domains.rb +0 -68
- data/lib/nucleus/adapters/v1/cloud_control/lifecycle.rb +0 -27
- data/lib/nucleus/adapters/v1/cloud_control/log_poller.rb +0 -71
- data/lib/nucleus/adapters/v1/cloud_control/logs.rb +0 -103
- data/lib/nucleus/adapters/v1/cloud_control/regions.rb +0 -32
- data/lib/nucleus/adapters/v1/cloud_control/scaling.rb +0 -17
- data/lib/nucleus/adapters/v1/cloud_control/semantic_errors.rb +0 -31
- data/lib/nucleus/adapters/v1/cloud_control/services.rb +0 -162
- data/lib/nucleus/adapters/v1/cloud_control/token.rb +0 -17
- data/lib/nucleus/adapters/v1/cloud_control/vars.rb +0 -88
@@ -1,44 +1,44 @@
|
|
1
|
-
module Nucleus
|
2
|
-
module Adapters
|
3
|
-
class AuthClient
|
4
|
-
attr_reader :verify_ssl
|
5
|
-
|
6
|
-
# Create a new instance of an {AuthClient}.
|
7
|
-
# @param [Boolean] check_certificates true if SSL certificates are to be validated,
|
8
|
-
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
9
|
-
def initialize(check_certificates = true)
|
10
|
-
@verify_ssl = check_certificates
|
11
|
-
end
|
12
|
-
|
13
|
-
# Perform authentication with the given username and password at the desired endpoint.
|
14
|
-
# @param[String] username username to use for authentication
|
15
|
-
# @param[String] password password to the username, which is to be used for authentication
|
16
|
-
# @raise[Nucleus::Errors::EndpointAuthenticationError] if authentication failed
|
17
|
-
# @raise[Nucleus::Errors::UnknownAdapterCallError] if the generic AuthClient did expect the endpoint
|
18
|
-
# to behave differently, usually indicates implementation issues
|
19
|
-
# @return[Nucleus::Adapters::AuthClient] current AuthClient instance
|
20
|
-
def authenticate(username, password)
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
# Get the authentication header for the current AuthClient instance that must be used to execute requests
|
25
|
-
# against the endpoint.<br>
|
26
|
-
# If the authentication is known to be expired, a refresh will be made first.
|
27
|
-
# @raise[Nucleus::Errors::EndpointAuthenticationError] if the refresh failed
|
28
|
-
# @return[Hash<String, String>] authentication header that enables requests against the endpoint
|
29
|
-
def auth_header
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
# Refresh a rejected authentication and generate a new authentication header.<br>
|
35
|
-
# Should be called if the authentication is known to be expired, or when a request is rejected with an
|
36
|
-
# authentication header that used to be accepted.
|
37
|
-
# @raise [Nucleus::Errors::EndpointAuthenticationError] if token refresh failed or authentication never succeeded
|
38
|
-
# @return [Nucleus::Adapters::AuthClient] current AuthClient instance
|
39
|
-
def refresh
|
40
|
-
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
1
|
+
module Nucleus
|
2
|
+
module Adapters
|
3
|
+
class AuthClient
|
4
|
+
attr_reader :verify_ssl
|
5
|
+
|
6
|
+
# Create a new instance of an {AuthClient}.
|
7
|
+
# @param [Boolean] check_certificates true if SSL certificates are to be validated,
|
8
|
+
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
9
|
+
def initialize(check_certificates = true)
|
10
|
+
@verify_ssl = check_certificates
|
11
|
+
end
|
12
|
+
|
13
|
+
# Perform authentication with the given username and password at the desired endpoint.
|
14
|
+
# @param[String] username username to use for authentication
|
15
|
+
# @param[String] password password to the username, which is to be used for authentication
|
16
|
+
# @raise[Nucleus::Errors::EndpointAuthenticationError] if authentication failed
|
17
|
+
# @raise[Nucleus::Errors::UnknownAdapterCallError] if the generic AuthClient did expect the endpoint
|
18
|
+
# to behave differently, usually indicates implementation issues
|
19
|
+
# @return[Nucleus::Adapters::AuthClient] current AuthClient instance
|
20
|
+
def authenticate(username, password)
|
21
|
+
raise Errors::EndpointAuthenticationError, 'Authentication client does not support authentication'
|
22
|
+
end
|
23
|
+
|
24
|
+
# Get the authentication header for the current AuthClient instance that must be used to execute requests
|
25
|
+
# against the endpoint.<br>
|
26
|
+
# If the authentication is known to be expired, a refresh will be made first.
|
27
|
+
# @raise[Nucleus::Errors::EndpointAuthenticationError] if the refresh failed
|
28
|
+
# @return[Hash<String, String>] authentication header that enables requests against the endpoint
|
29
|
+
def auth_header
|
30
|
+
raise Errors::EndpointAuthenticationError,
|
31
|
+
'Authentication client does not support to create the authentication header'
|
32
|
+
end
|
33
|
+
|
34
|
+
# Refresh a rejected authentication and generate a new authentication header.<br>
|
35
|
+
# Should be called if the authentication is known to be expired, or when a request is rejected with an
|
36
|
+
# authentication header that used to be accepted.
|
37
|
+
# @raise [Nucleus::Errors::EndpointAuthenticationError] if token refresh failed or authentication never succeeded
|
38
|
+
# @return [Nucleus::Adapters::AuthClient] current AuthClient instance
|
39
|
+
def refresh
|
40
|
+
raise Errors::EndpointAuthenticationError, 'Authentication client does not support refresh'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,53 +1,53 @@
|
|
1
|
-
module Nucleus
|
2
|
-
module Adapters
|
3
|
-
class ExpiringTokenAuthClient < TokenAuthClient
|
4
|
-
# Create a new instance of an {ExpiringTokenAuthClient}. An expiring token knows when it starts to be invalid,
|
5
|
-
# saving requests to the endpoint that would fail anyways.
|
6
|
-
# @param [Boolean] check_certificates true if SSL certificates are to be validated,
|
7
|
-
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
8
|
-
# @yield [verify_ssl, username, password] Auth credentials token parser block,
|
9
|
-
# must provide the API token and its expiration date, usually retrieved from an HTTP call to the endpoint.
|
10
|
-
# @yieldparam [Boolean] verify_ssl true if SSL certificates are to be validated,
|
11
|
-
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
12
|
-
# @yieldparam [String] username username to be used to retrieve the API token
|
13
|
-
# @yieldparam [String] password password to be used to retrieve the API token
|
14
|
-
# @yieldreturn [Array<String>] Array with 2 contents:
|
15
|
-
# [0] = API token to be used for authenticated API requests,
|
16
|
-
# nil if authentication failed, e.g. due to bad credentials
|
17
|
-
# [1] = Expiration time until the token is valid
|
18
|
-
def initialize(check_certificates = true, &token_expiration_parser)
|
19
|
-
@token_expiration_parser = token_expiration_parser
|
20
|
-
super(check_certificates)
|
21
|
-
end
|
22
|
-
|
23
|
-
# @see AuthClient#authenticate
|
24
|
-
def authenticate(username, password)
|
25
|
-
token, expiration_time = @token_expiration_parser.call(verify_ssl, username, password)
|
26
|
-
|
27
|
-
# verification passed, credentials are valid
|
28
|
-
@api_token = token
|
29
|
-
@expires = expiration_time
|
30
|
-
self
|
31
|
-
end
|
32
|
-
|
33
|
-
# @see AuthClient#auth_header
|
34
|
-
def auth_header
|
35
|
-
|
36
|
-
|
37
|
-
{ 'Authorization' => "Bearer #{api_token}" }
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
# Checks if the token is expired.
|
43
|
-
# @return [true, false] true if the token is expired, false if it is still valid
|
44
|
-
def expired?
|
45
|
-
@expires >= Time.now
|
46
|
-
end
|
47
|
-
|
48
|
-
def to_s
|
49
|
-
api_token
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
1
|
+
module Nucleus
|
2
|
+
module Adapters
|
3
|
+
class ExpiringTokenAuthClient < TokenAuthClient
|
4
|
+
# Create a new instance of an {ExpiringTokenAuthClient}. An expiring token knows when it starts to be invalid,
|
5
|
+
# saving requests to the endpoint that would fail anyways.
|
6
|
+
# @param [Boolean] check_certificates true if SSL certificates are to be validated,
|
7
|
+
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
8
|
+
# @yield [verify_ssl, username, password] Auth credentials token parser block,
|
9
|
+
# must provide the API token and its expiration date, usually retrieved from an HTTP call to the endpoint.
|
10
|
+
# @yieldparam [Boolean] verify_ssl true if SSL certificates are to be validated,
|
11
|
+
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
12
|
+
# @yieldparam [String] username username to be used to retrieve the API token
|
13
|
+
# @yieldparam [String] password password to be used to retrieve the API token
|
14
|
+
# @yieldreturn [Array<String>] Array with 2 contents:
|
15
|
+
# [0] = API token to be used for authenticated API requests,
|
16
|
+
# nil if authentication failed, e.g. due to bad credentials
|
17
|
+
# [1] = Expiration time until the token is valid
|
18
|
+
def initialize(check_certificates = true, &token_expiration_parser)
|
19
|
+
@token_expiration_parser = token_expiration_parser
|
20
|
+
super(check_certificates)
|
21
|
+
end
|
22
|
+
|
23
|
+
# @see AuthClient#authenticate
|
24
|
+
def authenticate(username, password)
|
25
|
+
token, expiration_time = @token_expiration_parser.call(verify_ssl, username, password)
|
26
|
+
raise Errors::EndpointAuthenticationError, 'Authentication failed, credentials seem to be invalid' unless token
|
27
|
+
# verification passed, credentials are valid
|
28
|
+
@api_token = token
|
29
|
+
@expires = expiration_time
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
# @see AuthClient#auth_header
|
34
|
+
def auth_header
|
35
|
+
raise Errors::EndpointAuthenticationError, 'Authentication client was not authenticated yet' unless @api_token
|
36
|
+
raise Errors::EndpointAuthenticationError, 'Cached authentication token expired' if expired?
|
37
|
+
{ 'Authorization' => "Bearer #{api_token}" }
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Checks if the token is expired.
|
43
|
+
# @return [true, false] true if the token is expired, false if it is still valid
|
44
|
+
def expired?
|
45
|
+
@expires >= Time.now
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
api_token
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -20,7 +20,7 @@ module Nucleus
|
|
20
20
|
def authenticate(username, password)
|
21
21
|
packed_credentials = ["#{username}:#{password}"].pack('m*').delete("\n")
|
22
22
|
valid = @verification.call(verify_ssl, 'Authorization' => "Basic #{packed_credentials}")
|
23
|
-
|
23
|
+
raise Errors::EndpointAuthenticationError, 'Authentication failed, credentials seem to be invalid' unless valid
|
24
24
|
# verification passed, credentials are valid
|
25
25
|
@packed_credentials = packed_credentials
|
26
26
|
self
|
@@ -28,8 +28,8 @@ module Nucleus
|
|
28
28
|
|
29
29
|
# @see AuthClient#auth_header
|
30
30
|
def auth_header
|
31
|
-
|
32
|
-
|
31
|
+
raise Errors::EndpointAuthenticationError,
|
32
|
+
'Authentication client was not authenticated yet' unless @packed_credentials
|
33
33
|
{ 'Authorization' => "Basic #{@packed_credentials}" }
|
34
34
|
end
|
35
35
|
end
|
@@ -1,95 +1,95 @@
|
|
1
|
-
module Nucleus
|
2
|
-
module Adapters
|
3
|
-
class OAuth2AuthClient < AuthClient
|
4
|
-
include Nucleus::Logging
|
5
|
-
|
6
|
-
# Create a new instance of an {OAuth2AuthClient}, which uses the standardized OAuth2 authentication method.
|
7
|
-
# @param [Boolean] check_certificates true if SSL certificates are to be validated,
|
8
|
-
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
9
|
-
# @param [String] auth_url URL to the OAuth2 endpoint
|
10
|
-
def initialize(auth_url, check_certificates = true)
|
11
|
-
@auth_url = auth_url
|
12
|
-
super(check_certificates)
|
13
|
-
end
|
14
|
-
|
15
|
-
def authenticate(username, password)
|
16
|
-
return self if @access_token
|
17
|
-
response = post(query: { grant_type: 'password', username: username, password: password })
|
18
|
-
body = body(response)
|
19
|
-
extract(body)
|
20
|
-
# refresh token is not included in later updates
|
21
|
-
@refresh_token = body[:refresh_token]
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
|
-
def auth_header
|
26
|
-
|
27
|
-
if expired?
|
28
|
-
log.debug('OAuth2 access_token is expired, trigger refresh before returning auth_header')
|
29
|
-
# token is expired, renew first
|
30
|
-
refresh
|
31
|
-
end
|
32
|
-
# then return the authorization header
|
33
|
-
header
|
34
|
-
end
|
35
|
-
|
36
|
-
def refresh
|
37
|
-
if @refresh_token.nil?
|
38
|
-
|
39
|
-
end
|
40
|
-
log.debug("Attempt to refresh the access_token with our refresh_token: '#{@refresh_token}'")
|
41
|
-
response = post(query: { grant_type: 'refresh_token', refresh_token: @refresh_token })
|
42
|
-
extract(body(response))
|
43
|
-
self
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def post(params)
|
49
|
-
middleware = Excon.defaults[:middlewares].dup
|
50
|
-
middleware << Excon::Middleware::Decompress
|
51
|
-
middleware << Excon::Middleware::RedirectFollower
|
52
|
-
# explicitly allow redirects, otherwise they would cause an error
|
53
|
-
# TODO: Basic Y2Y6 could be cloud-foundry specific
|
54
|
-
request_params = { expects: [200, 301, 302, 303, 307, 308], middlewares: middleware.uniq,
|
55
|
-
headers: { 'Authorization' => 'Basic Y2Y6',
|
56
|
-
'Content-Type' => 'application/x-www-form-urlencoded',
|
57
|
-
'Accept' => 'application/json' } }.merge(params)
|
58
|
-
# execute the post request and return the response
|
59
|
-
Excon.new(@auth_url, ssl_verify_peer: verify_ssl).post(request_params)
|
60
|
-
rescue Excon::Errors::HTTPStatusError => e
|
61
|
-
log.debug "OAuth2 authentication failed: #{e}"
|
62
|
-
case e.response.status
|
63
|
-
when 403
|
64
|
-
log.error("OAuth2 for '#{@auth_url}' failed with status 403 (access denied), indicating an adapter issue")
|
65
|
-
raise Errors::UnknownAdapterCallError, 'Access to resource denied, probably the adapter must be updated'
|
66
|
-
when 400, 401
|
67
|
-
raise Errors::EndpointAuthenticationError, body(e.response)[:error_description]
|
68
|
-
end
|
69
|
-
# re-raise all unhandled exception, indicating adapter issues
|
70
|
-
raise Errors::UnknownAdapterCallError, 'OAuth2 call failed unexpectedly, probably the adapter must be updated'
|
71
|
-
end
|
72
|
-
|
73
|
-
def header
|
74
|
-
{ 'Authorization' => "#{@token_type} #{@access_token}" }
|
75
|
-
end
|
76
|
-
|
77
|
-
def expired?
|
78
|
-
return true if @expiration.nil?
|
79
|
-
Time.now >= @expiration
|
80
|
-
end
|
81
|
-
|
82
|
-
def body(response)
|
83
|
-
Oj.load(response.body, symbol_keys: true)
|
84
|
-
end
|
85
|
-
|
86
|
-
def extract(body)
|
87
|
-
@access_token = body[:access_token]
|
88
|
-
# number of seconds until expiration, deduct processing buffer
|
89
|
-
seconds_left = body[:expires_in] - 30
|
90
|
-
@expiration = Time.now + seconds_left
|
91
|
-
@token_type = body[:token_type]
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
1
|
+
module Nucleus
|
2
|
+
module Adapters
|
3
|
+
class OAuth2AuthClient < AuthClient
|
4
|
+
include Nucleus::Logging
|
5
|
+
|
6
|
+
# Create a new instance of an {OAuth2AuthClient}, which uses the standardized OAuth2 authentication method.
|
7
|
+
# @param [Boolean] check_certificates true if SSL certificates are to be validated,
|
8
|
+
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
9
|
+
# @param [String] auth_url URL to the OAuth2 endpoint
|
10
|
+
def initialize(auth_url, check_certificates = true)
|
11
|
+
@auth_url = auth_url
|
12
|
+
super(check_certificates)
|
13
|
+
end
|
14
|
+
|
15
|
+
def authenticate(username, password)
|
16
|
+
return self if @access_token
|
17
|
+
response = post(query: { grant_type: 'password', username: username, password: password })
|
18
|
+
body = body(response)
|
19
|
+
extract(body)
|
20
|
+
# refresh token is not included in later updates
|
21
|
+
@refresh_token = body[:refresh_token]
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def auth_header
|
26
|
+
raise Errors::EndpointAuthenticationError, 'Authentication client was not authenticated yet' unless @access_token
|
27
|
+
if expired?
|
28
|
+
log.debug('OAuth2 access_token is expired, trigger refresh before returning auth_header')
|
29
|
+
# token is expired, renew first
|
30
|
+
refresh
|
31
|
+
end
|
32
|
+
# then return the authorization header
|
33
|
+
header
|
34
|
+
end
|
35
|
+
|
36
|
+
def refresh
|
37
|
+
if @refresh_token.nil?
|
38
|
+
raise Errors::EndpointAuthenticationError, "Can't refresh token before initial authentication"
|
39
|
+
end
|
40
|
+
log.debug("Attempt to refresh the access_token with our refresh_token: '#{@refresh_token}'")
|
41
|
+
response = post(query: { grant_type: 'refresh_token', refresh_token: @refresh_token })
|
42
|
+
extract(body(response))
|
43
|
+
self
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def post(params)
|
49
|
+
middleware = Excon.defaults[:middlewares].dup
|
50
|
+
middleware << Excon::Middleware::Decompress
|
51
|
+
middleware << Excon::Middleware::RedirectFollower
|
52
|
+
# explicitly allow redirects, otherwise they would cause an error
|
53
|
+
# TODO: Basic Y2Y6 could be cloud-foundry specific
|
54
|
+
request_params = { expects: [200, 301, 302, 303, 307, 308], middlewares: middleware.uniq,
|
55
|
+
headers: { 'Authorization' => 'Basic Y2Y6',
|
56
|
+
'Content-Type' => 'application/x-www-form-urlencoded',
|
57
|
+
'Accept' => 'application/json' } }.merge(params)
|
58
|
+
# execute the post request and return the response
|
59
|
+
Excon.new(@auth_url, ssl_verify_peer: verify_ssl).post(request_params)
|
60
|
+
rescue Excon::Errors::HTTPStatusError => e
|
61
|
+
log.debug "OAuth2 authentication failed: #{e}"
|
62
|
+
case e.response.status
|
63
|
+
when 403
|
64
|
+
log.error("OAuth2 for '#{@auth_url}' failed with status 403 (access denied), indicating an adapter issue")
|
65
|
+
raise Errors::UnknownAdapterCallError, 'Access to resource denied, probably the adapter must be updated'
|
66
|
+
when 400, 401
|
67
|
+
raise Errors::EndpointAuthenticationError, body(e.response)[:error_description]
|
68
|
+
end
|
69
|
+
# re-raise all unhandled exception, indicating adapter issues
|
70
|
+
raise Errors::UnknownAdapterCallError, 'OAuth2 call failed unexpectedly, probably the adapter must be updated'
|
71
|
+
end
|
72
|
+
|
73
|
+
def header
|
74
|
+
{ 'Authorization' => "#{@token_type} #{@access_token}" }
|
75
|
+
end
|
76
|
+
|
77
|
+
def expired?
|
78
|
+
return true if @expiration.nil?
|
79
|
+
Time.now >= @expiration
|
80
|
+
end
|
81
|
+
|
82
|
+
def body(response)
|
83
|
+
Oj.load(response.body, symbol_keys: true)
|
84
|
+
end
|
85
|
+
|
86
|
+
def extract(body)
|
87
|
+
@access_token = body[:access_token]
|
88
|
+
# number of seconds until expiration, deduct processing buffer
|
89
|
+
seconds_left = body[:expires_in] - 30
|
90
|
+
@expiration = Time.now + seconds_left
|
91
|
+
@token_type = body[:token_type]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -1,36 +1,36 @@
|
|
1
|
-
module Nucleus
|
2
|
-
module Adapters
|
3
|
-
class TokenAuthClient < AuthClient
|
4
|
-
attr_reader :api_token
|
5
|
-
|
6
|
-
# Create a new instance of an {TokenAuthClient}.
|
7
|
-
# @param [Boolean] check_certificates true if SSL certificates are to be validated,
|
8
|
-
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
9
|
-
# @yield [verify_ssl, username, password] Auth credentials token parser block,
|
10
|
-
# must provide the API token, usually retrieved from an HTTP call to the endpoint.
|
11
|
-
# @yieldparam [Boolean] verify_ssl true if SSL certificates are to be validated,
|
12
|
-
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
13
|
-
# @yieldparam [String] username username to be used to retrieve the API token
|
14
|
-
# @yieldparam [String] password password to be used to retrieve the API token
|
15
|
-
# @yieldreturn [String] API token to be used for authenticated API requests,
|
16
|
-
# nil if authentication failed, e.g. due to bad credentials
|
17
|
-
def initialize(check_certificates = true, &token_parser)
|
18
|
-
@token_parser = token_parser
|
19
|
-
super(check_certificates)
|
20
|
-
end
|
21
|
-
|
22
|
-
def authenticate(username, password)
|
23
|
-
token = @token_parser.call(verify_ssl, username, password)
|
24
|
-
|
25
|
-
# verification passed, credentials are valid
|
26
|
-
@api_token = token
|
27
|
-
self
|
28
|
-
end
|
29
|
-
|
30
|
-
def auth_header
|
31
|
-
|
32
|
-
{ 'Authorization' => "Bearer #{api_token}" }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
1
|
+
module Nucleus
|
2
|
+
module Adapters
|
3
|
+
class TokenAuthClient < AuthClient
|
4
|
+
attr_reader :api_token
|
5
|
+
|
6
|
+
# Create a new instance of an {TokenAuthClient}.
|
7
|
+
# @param [Boolean] check_certificates true if SSL certificates are to be validated,
|
8
|
+
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
9
|
+
# @yield [verify_ssl, username, password] Auth credentials token parser block,
|
10
|
+
# must provide the API token, usually retrieved from an HTTP call to the endpoint.
|
11
|
+
# @yieldparam [Boolean] verify_ssl true if SSL certificates are to be validated,
|
12
|
+
# false if they are to be ignored (e.g. when using self-signed certificates in development environments)
|
13
|
+
# @yieldparam [String] username username to be used to retrieve the API token
|
14
|
+
# @yieldparam [String] password password to be used to retrieve the API token
|
15
|
+
# @yieldreturn [String] API token to be used for authenticated API requests,
|
16
|
+
# nil if authentication failed, e.g. due to bad credentials
|
17
|
+
def initialize(check_certificates = true, &token_parser)
|
18
|
+
@token_parser = token_parser
|
19
|
+
super(check_certificates)
|
20
|
+
end
|
21
|
+
|
22
|
+
def authenticate(username, password)
|
23
|
+
token = @token_parser.call(verify_ssl, username, password)
|
24
|
+
raise Errors::EndpointAuthenticationError, 'Authentication failed, credentials seem to be invalid' unless token
|
25
|
+
# verification passed, credentials are valid
|
26
|
+
@api_token = token
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def auth_header
|
31
|
+
raise Errors::EndpointAuthenticationError, 'Authentication client was not authenticated yet' unless @api_token
|
32
|
+
{ 'Authorization' => "Bearer #{api_token}" }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|