fog-brightbox 1.5.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb1f5fab98014e9dda7db0f12f010f30e35277e6516151f3ebe4f1821c662dc3
4
- data.tar.gz: e4bb7b22b9c9e398923ce253708acfb0dd4519b7511428973ced16e20ac77e69
3
+ metadata.gz: 4ed1e1f608af748e905cfeafeb9f1a72674074f11720c854988e324de9e1fa84
4
+ data.tar.gz: c078791baaf84d13fb09c1f0d8ff17b9c1116f247cfb8c73647b529b97ce3bea
5
5
  SHA512:
6
- metadata.gz: 38c16b6810afe2ebb15edeedfff0732f54e34ccc0e8bb56af85efcbcf2d43c1776957dff2b0ca44afc5a1cbc7d6b7a98c015cb5feb95aea36c820ab0eada57fd
7
- data.tar.gz: 86e0cd498b82639fd952f3a08c03c15d8e8f623391889c23f602e6a1d7177cbe714b5527d3940e404e902d8a2acbc3c2004de97113ff6823b8656d07a35736ee
6
+ metadata.gz: fbfd902483fc3bb101255c4915d8fec6e54c5edf2995f6aa1b0eebe510e210a0b6173b109aa19811fee8fabc1c5f05c294d36b49fbcc9b15056bedf22e1ebac2
7
+ data.tar.gz: e3b208fa57e74eca736fa8d53683cbfa78645a6aa75a15b680f59365bbd26538cbb373828f92ba4d6de7a79a867e2377500179c9ef18171c35748dd3fa759e17
data/CHANGELOG.md CHANGED
@@ -1,3 +1,25 @@
1
+ ### 1.6.0 / 2022-07-25
2
+
3
+ Changes:
4
+
5
+ * Added support to opt-in to support Brightbox 2FA within clients.
6
+
7
+ Two Factor Authentication (2FA) support:
8
+
9
+ Passing `brightbox_support_two_factor` into a configuration will raise a new
10
+ error when user authentication has failed BUT the presence of the
11
+ `X-Brightbox-OTP: required` HTTP header is found.
12
+
13
+ This new error `Fog::Brightbox::OAuth2::TwoFactorMissingError` can be handled
14
+ differently by the client and the second factor can be prompted for or
15
+ recovered from a secure keychain.
16
+
17
+ Without opting in, the previous error `Excon::Errors::Unauthorized` is raised.
18
+
19
+ To send the OTP, the `brightbox_one_time_password` can be passed into a
20
+ configuration object or one_time_password can be passed to a credentials
21
+ object.
22
+
1
23
  ### 1.5.0 / 2022-06-09
2
24
 
3
25
  Changes:
@@ -39,21 +39,15 @@ module Fog
39
39
  @persistent = @config.connection_persistent?
40
40
  @connection = Fog::Core::Connection.new(@api_url, @persistent, @connection_options)
41
41
 
42
- # Authentication options
43
- client_id = @config.client_id
44
- client_secret = @config.client_secret
45
-
46
- username = @config.username
47
- password = @config.password
48
42
  @configured_account = @config.account
49
43
  # Request account can be changed at anytime and changes behaviour of future requests
50
44
  @scoped_account = @configured_account
51
45
 
52
- credential_options = { :username => username, :password => password }
53
- @credentials = CredentialSet.new(client_id, client_secret, credential_options)
46
+ @two_factor = @config.two_factor?
47
+ @one_time_password = @config.one_time_password
54
48
 
55
49
  # If existing tokens have been cached, allow continued use of them in the service
56
- @credentials.update_tokens(@config.cached_access_token, @config.cached_refresh_token)
50
+ credentials.update_tokens(@config.cached_access_token, @config.cached_refresh_token)
57
51
 
58
52
  @token_management = @config.managed_tokens?
59
53
  end
@@ -73,6 +67,12 @@ module Fog
73
67
  @scoped_account = @configured_account
74
68
  end
75
69
 
70
+ def credentials
71
+ client_id = @config.client_id
72
+ client_secret = @config.client_secret
73
+ @credentials ||= CredentialSet.new(client_id, client_secret, credential_options)
74
+ end
75
+
76
76
  # Returns the scoped account being used for requests
77
77
  #
78
78
  # * For API clients this is the owning account
@@ -122,7 +122,7 @@ module Fog
122
122
  def get_access_token
123
123
  begin
124
124
  get_access_token!
125
- rescue Excon::Errors::Unauthorized, Excon::Errors::BadRequest
125
+ rescue Fog::Brightbox::OAuth2::TwoFactorMissingError, Excon::Errors::Unauthorized, Excon::Errors::BadRequest
126
126
  @credentials.update_tokens(nil, nil)
127
127
  end
128
128
  @credentials.access_token
@@ -154,8 +154,24 @@ module Fog
154
154
  @default_image_id ||= (@config.default_image_id || select_default_image)
155
155
  end
156
156
 
157
+ def two_factor?
158
+ @two_factor || false
159
+ end
160
+
157
161
  private
158
162
 
163
+ # This returns a formatted set of options for the credentials for this service
164
+ #
165
+ # @return [Hash]
166
+ def credential_options
167
+ {
168
+ username: @config.username,
169
+ password: @config.password
170
+ }.tap do |opts|
171
+ opts[:one_time_password] = @one_time_password if two_factor?
172
+ end
173
+ end
174
+
159
175
  # This makes a request of the API based on the configured setting for
160
176
  # token management.
161
177
  #
@@ -21,6 +21,10 @@ module Fog
21
21
  # Automatic token management
22
22
  recognizes :brightbox_token_management
23
23
 
24
+ # Two Factor Authentication support (2FA)
25
+ recognizes :brightbox_support_two_factor
26
+ recognizes :brightbox_one_time_password
27
+
24
28
  # Excon connection settings
25
29
  recognizes :persistent
26
30
 
@@ -33,6 +33,10 @@ module Fog
33
33
  # Set to specify the client secret to use for requests.
34
34
  # @option options [String] :brightbox_token_management (true)
35
35
  # Set to specify if the service should handle expired tokens or raise an error instead.
36
+ # @option options [Boolean] :brightbox_support_two_factor
37
+ # Set to enable two factor authentication (2FA) for this configuration/user
38
+ # @option options [String] :brightbox_one_time_password
39
+ # Set to pass through the current one time password when using 2FA
36
40
  # @option options [String] :brightbox_username
37
41
  # Set to specify your user account. Either user identifier (+usr-12345+) or email address
38
42
  # may be used.
@@ -226,6 +230,14 @@ module Fog
226
230
  def storage_temp_key
227
231
  @options[:brightbox_temp_url_key]
228
232
  end
233
+
234
+ def two_factor?
235
+ @options[:brightbox_support_two_factor] || false
236
+ end
237
+
238
+ def one_time_password
239
+ @options[:brightbox_one_time_password]
240
+ end
229
241
  end
230
242
  end
231
243
  end
@@ -6,6 +6,10 @@ module Fog
6
6
  # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-10
7
7
  #
8
8
  module OAuth2
9
+ TWO_FACTOR_HEADER = "X-Brightbox-OTP".freeze
10
+
11
+ class TwoFactorMissingError < StandardError; end
12
+
9
13
  # This builds the simplest form of requesting an access token
10
14
  # based on the arguments passed in
11
15
  #
@@ -13,16 +17,38 @@ module Fog
13
17
  # @param [CredentialSet] credentials
14
18
  #
15
19
  # @return [Excon::Response]
20
+ # @raise [Excon::Errors::Unauthorized] if the credentials are rejected by the server
21
+ # @raise [Fog::Brightbox::OAuth2::TwoFactorMissingError] if opted in to 2FA and server reports header is required
16
22
  def request_access_token(connection, credentials)
17
23
  token_strategy = credentials.best_grant_strategy
18
24
 
19
- connection.request(
20
- :path => "/token",
21
- :expects => 200,
22
- :headers => token_strategy.headers,
23
- :method => "POST",
24
- :body => Fog::JSON.encode(token_strategy.authorization_body_data)
25
- )
25
+ if two_factor?
26
+ # When 2FA opt-in is set, we can expect 401 responses as well
27
+ response = connection.request(
28
+ :path => "/token",
29
+ :expects => [200, 401],
30
+ :headers => token_strategy.headers,
31
+ :method => "POST",
32
+ :body => Fog::JSON.encode(token_strategy.authorization_body_data)
33
+ )
34
+
35
+ if response.status == 401 && response.headers[Fog::Brightbox::OAuth2::TWO_FACTOR_HEADER] == "required"
36
+ raise TwoFactorMissingError
37
+ elsif response.status == 401
38
+ raise Excon::Errors.status_error({ expects: 200 }, status: 401)
39
+ else
40
+ response
41
+ end
42
+ else
43
+ # Use classic behaviour and return Excon::
44
+ connection.request(
45
+ :path => "/token",
46
+ :expects => 200,
47
+ :headers => token_strategy.headers,
48
+ :method => "POST",
49
+ :body => Fog::JSON.encode(token_strategy.authorization_body_data)
50
+ )
51
+ end
26
52
  end
27
53
 
28
54
  # Encapsulates credentials required to request access tokens from the
@@ -33,12 +59,14 @@ module Fog
33
59
  class CredentialSet
34
60
  attr_reader :client_id, :client_secret, :username, :password
35
61
  attr_reader :access_token, :refresh_token, :expires_in
62
+ attr_reader :one_time_password
36
63
  #
37
64
  # @param [String] client_id
38
65
  # @param [String] client_secret
39
66
  # @param [Hash] options
40
67
  # @option options [String] :username
41
68
  # @option options [String] :password
69
+ # @option options [String] :one_time_password One Time Password for Two Factor authentication
42
70
  #
43
71
  def initialize(client_id, client_secret, options = {})
44
72
  @client_id = client_id
@@ -48,6 +76,7 @@ module Fog
48
76
  @access_token = options[:access_token]
49
77
  @refresh_token = options[:refresh_token]
50
78
  @expires_in = options[:expires_in]
79
+ @one_time_password = options[:one_time_password]
51
80
  end
52
81
 
53
82
  # Returns true if user details are available
@@ -142,6 +171,17 @@ module Fog
142
171
  "password" => @credentials.password
143
172
  }
144
173
  end
174
+
175
+ def headers
176
+ {
177
+ "Authorization" => authorization_header,
178
+ "Content-Type" => "application/json"
179
+ }.tap do |headers|
180
+ if @credentials.one_time_password
181
+ headers[TWO_FACTOR_HEADER] = @credentials.one_time_password
182
+ end
183
+ end
184
+ end
145
185
  end
146
186
 
147
187
  # This strategy attempts to use a refresh_token gained during an earlier
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Brightbox
3
- VERSION = "1.5.0"
3
+ VERSION = "1.6.0"
4
4
  end
5
5
  end
@@ -0,0 +1,41 @@
1
+ require "spec_helper"
2
+
3
+ describe Fog::Brightbox::Compute, "#credentials" do
4
+ describe "when 2FA support is disabled" do
5
+ before do
6
+ @options = {
7
+ brightbox_client_id: "app-12345",
8
+ brightbox_secret: "1234567890",
9
+ brightbox_username: "jason.null@brightbox.com",
10
+ brightbox_password: "HR4life",
11
+ brightbox_one_time_password: "123456"
12
+ }
13
+ @service = Fog::Brightbox::Compute.new(@options)
14
+ end
15
+
16
+ it "does not add passed OTP to credentials" do
17
+ assert_kind_of Fog::Brightbox::OAuth2::CredentialSet, @service.credentials
18
+ assert_nil @service.credentials.one_time_password
19
+ end
20
+ end
21
+
22
+ describe "with 2FA support is enabled" do
23
+ before do
24
+ @expected_otp = "123456"
25
+ @options = {
26
+ brightbox_client_id: "app-12345",
27
+ brightbox_secret: "1234567890",
28
+ brightbox_username: "jason.null@brightbox.com",
29
+ brightbox_password: "HR4life",
30
+ brightbox_support_two_factor: true,
31
+ brightbox_one_time_password: @expected_otp
32
+ }
33
+ @service = Fog::Brightbox::Compute.new(@options)
34
+ end
35
+
36
+ it "adds passed OTP to credentials" do
37
+ assert_kind_of Fog::Brightbox::OAuth2::CredentialSet, @service.credentials
38
+ assert @expected_otp, @service.credentials.one_time_password
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,305 @@
1
+ require "spec_helper"
2
+
3
+ describe Fog::Brightbox::Compute, "#get_access_token" do
4
+ before do
5
+ @new_access_token = "0987654321"
6
+ @new_refresh_token = "5432167890"
7
+
8
+ @options = {
9
+ brightbox_client_id: "app-12345",
10
+ brightbox_secret: "1234567890",
11
+ brightbox_username: "jason.null@brightbox.com",
12
+ brightbox_password: "HR4life",
13
+ brightbox_support_two_factor: true,
14
+ brightbox_one_time_password: "123456"
15
+ }
16
+ @service = Fog::Brightbox::Compute.new(@options)
17
+ end
18
+
19
+ describe "when user does not have 2FA enabled" do
20
+ describe "and authenticates correctly" do
21
+ before do
22
+ stub_authentication_request(auth_correct: true)
23
+
24
+ assert @service.two_factor?
25
+ end
26
+
27
+ describe "without !" do
28
+ it "updates credentials" do
29
+ token = @service.get_access_token
30
+ assert_equal "0987654321", token
31
+
32
+ assert_equal token, @service.access_token
33
+ end
34
+ end
35
+
36
+ describe "with !" do
37
+ it "updates credentials" do
38
+ token = @service.get_access_token!
39
+ assert_equal "0987654321", token
40
+
41
+ assert_equal token, @service.access_token
42
+ end
43
+ end
44
+ end
45
+
46
+ describe "and authenticates incorrectly" do
47
+ before do
48
+ stub_authentication_request(auth_correct: false)
49
+
50
+ assert @service.two_factor?
51
+ end
52
+
53
+ describe "without !" do
54
+ it "returns nil" do
55
+ assert_nil @service.get_access_token
56
+
57
+ assert_nil @service.access_token
58
+ assert_nil @service.refresh_token
59
+ end
60
+ end
61
+
62
+ describe "with !" do
63
+ it "raises an error" do
64
+ begin
65
+ @service.get_access_token!
66
+ rescue Excon::Error::Unauthorized
67
+ assert_nil @service.access_token
68
+ assert_nil @service.refresh_token
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "when user does have 2FA enabled" do
76
+ describe "and authenticates correctly" do
77
+ describe "without OTP" do
78
+ before do
79
+ stub_authentication_request(auth_correct: true,
80
+ two_factor_user: true)
81
+
82
+ assert @service.two_factor?
83
+ end
84
+
85
+ describe "without !" do
86
+ it "returns nil" do
87
+ assert_nil @service.get_access_token
88
+
89
+ assert_nil @service.access_token
90
+ assert_nil @service.refresh_token
91
+ end
92
+ end
93
+
94
+ describe "with !" do
95
+ it "raises an error" do
96
+ begin
97
+ @service.get_access_token!
98
+ rescue Fog::Brightbox::OAuth2::TwoFactorMissingError
99
+ assert_nil @service.access_token
100
+ assert_nil @service.refresh_token
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "with OTP" do
107
+ before do
108
+ stub_authentication_request(auth_correct: true,
109
+ two_factor_user: true,
110
+ otp_sent: true)
111
+
112
+ assert @service.two_factor?
113
+ end
114
+
115
+ describe "without !" do
116
+ it "updates credentials" do
117
+ token = @service.get_access_token
118
+ assert_equal "0987654321", token
119
+
120
+ assert_equal token, @service.access_token
121
+ end
122
+ end
123
+
124
+ describe "with !" do
125
+ it "updates credentials" do
126
+ token = @service.get_access_token!
127
+ assert_equal "0987654321", token
128
+
129
+ assert_equal token, @service.access_token
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ describe "and authenticates incorrectly" do
136
+ before do
137
+ stub_authentication_request(auth_correct: false,
138
+ two_factor_user: true)
139
+
140
+ assert @service.two_factor?
141
+ end
142
+
143
+ describe "without !" do
144
+ it "returns nil" do
145
+ assert_nil @service.get_access_token
146
+
147
+ assert_nil @service.access_token
148
+ assert_nil @service.refresh_token
149
+ end
150
+ end
151
+
152
+ describe "with !" do
153
+ it "raises an error" do
154
+ begin
155
+ @service.get_access_token!
156
+ rescue Fog::Brightbox::OAuth2::TwoFactorMissingError
157
+ assert_nil @service.access_token
158
+ assert_nil @service.refresh_token
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ describe "without 2FA support enabled" do
165
+ before do
166
+ @options = {
167
+ brightbox_client_id: "app-12345",
168
+ brightbox_secret: "1234567890",
169
+ brightbox_username: "jason.null@brightbox.com",
170
+ brightbox_password: "HR4life",
171
+ brightbox_support_two_factor: false,
172
+ brightbox_one_time_password: "123456"
173
+ }
174
+ @service = Fog::Brightbox::Compute.new(@options)
175
+
176
+ refute @service.two_factor?
177
+ end
178
+
179
+ describe "without !" do
180
+ it "returns nil" do
181
+ stub_authentication_request(auth_correct: false,
182
+ two_factor_user: true)
183
+
184
+ assert_nil @service.get_access_token
185
+
186
+ assert_nil @service.access_token
187
+ assert_nil @service.refresh_token
188
+ end
189
+ end
190
+
191
+ describe "with !" do
192
+ describe "when authentication incorrect" do
193
+ it "raises an error" do
194
+ stub_authentication_request(auth_correct: false,
195
+ two_factor_user: true,
196
+ otp_sent: true)
197
+
198
+ begin
199
+ @service.get_access_token!
200
+ rescue Excon::Error::Unauthorized
201
+ assert_nil @service.access_token
202
+ assert_nil @service.refresh_token
203
+ end
204
+ end
205
+ end
206
+
207
+ describe "with missing OTP" do
208
+ before do
209
+ @options = {
210
+ brightbox_client_id: "app-12345",
211
+ brightbox_secret: "1234567890",
212
+ brightbox_username: "jason.null@brightbox.com",
213
+ brightbox_password: "HR4life",
214
+ brightbox_support_two_factor: false
215
+ }
216
+ @service = Fog::Brightbox::Compute.new(@options)
217
+
218
+ refute @service.two_factor?
219
+ end
220
+
221
+ it "raises an error" do
222
+ stub_authentication_request(auth_correct: true,
223
+ two_factor_user: true,
224
+ otp_sent: false)
225
+
226
+ begin
227
+ @service.get_access_token!
228
+ rescue Excon::Error::Unauthorized
229
+ assert_nil @service.access_token
230
+ assert_nil @service.refresh_token
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
236
+ end
237
+
238
+ # @param auth_correct [Boolean] Treat username/password as correct
239
+ # @param two_factor_user [Boolean] Is user protected by 2FA on server
240
+ # @param otp_sent [Boolean] Is an OTP sent in the request?
241
+ def stub_authentication_request(auth_correct:,
242
+ two_factor_user: false,
243
+ otp_sent: nil)
244
+
245
+ two_factor_supported = @service.two_factor?
246
+
247
+ request = {
248
+ headers: {
249
+ "Authorization" => "Basic YXBwLTEyMzQ1OjEyMzQ1Njc4OTA=",
250
+ "Content-Type" => "application/json",
251
+ },
252
+ body: {
253
+ grant_type: "password",
254
+ username: "jason.null@brightbox.com",
255
+ password: "HR4life"
256
+ }.to_json
257
+ }.tap do |req|
258
+ # Only expect the header if the service should send it
259
+ # Without this, we stub a request that demands an OTP but it is not sent
260
+ if two_factor_supported && otp_sent
261
+ req[:headers]["X-Brightbox-OTP"] = "123456"
262
+ end
263
+ end
264
+
265
+ # The cases we are testing are:
266
+ #
267
+ # * User does not use 2FA and authenticate
268
+ # * User does not use 2FA and FAILS to authenticate
269
+ # * User does use 2FA and authenticate
270
+ # * User does use 2FA and FAILS to authenticate
271
+ # * User does use 2FA and FAILS to send OTP
272
+ #
273
+ response = if two_factor_user && !otp_sent
274
+ # OTP required header
275
+ {
276
+ status: 401,
277
+ headers: {
278
+ "X-Brightbox-OTP" => "required"
279
+ },
280
+ body: { error: "invalid_client" }.to_json
281
+ }
282
+ elsif !auth_correct
283
+ # No OTP header
284
+ {
285
+ status: 401,
286
+ headers: {},
287
+ body: { error: "invalid_client" }.to_json
288
+ }
289
+ else
290
+ {
291
+ status: 200,
292
+ headers: {},
293
+ body: {
294
+ access_token: @new_access_token,
295
+ refresh_token: @new_refresh_token,
296
+ expires_in: 7200
297
+ }.to_json
298
+ }
299
+ end
300
+
301
+ stub_request(:post, "https://api.gb1.brightbox.com/token")
302
+ .with(request)
303
+ .to_return(response)
304
+ end
305
+ end
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+
3
+ describe Fog::Brightbox::Compute, "#two_factor?" do
4
+ describe "when omitted" do
5
+ before do
6
+ @options = {
7
+ brightbox_client_id: "app-12345",
8
+ brightbox_secret: "1234567890",
9
+ brightbox_username: "jason.null@brightbox.com",
10
+ brightbox_password: "HR4life"
11
+ }
12
+ @service = Fog::Brightbox::Compute.new(@options)
13
+ end
14
+
15
+ it do
16
+ refute @service.two_factor?
17
+ end
18
+ end
19
+
20
+ describe "when disabled" do
21
+ before do
22
+ @options = {
23
+ brightbox_client_id: "app-12345",
24
+ brightbox_secret: "1234567890",
25
+ brightbox_username: "jason.null@brightbox.com",
26
+ brightbox_password: "HR4life",
27
+ brightbox_support_two_factor: false
28
+ }
29
+ @service = Fog::Brightbox::Compute.new(@options)
30
+ end
31
+
32
+ it do
33
+ refute @service.two_factor?
34
+ end
35
+ end
36
+
37
+ describe "when enabled" do
38
+ before do
39
+ @options = {
40
+ brightbox_client_id: "app-12345",
41
+ brightbox_secret: "1234567890",
42
+ brightbox_username: "jason.null@brightbox.com",
43
+ brightbox_password: "HR4life",
44
+ brightbox_support_two_factor: true
45
+ }
46
+ @service = Fog::Brightbox::Compute.new(@options)
47
+ end
48
+
49
+ it do
50
+ assert @service.two_factor?
51
+ end
52
+ end
53
+ end
@@ -37,4 +37,24 @@ describe Fog::Brightbox::OAuth2::UserCredentialsStrategy do
37
37
  assert_equal "Basic YXBwLTEyMzQ1Ol9fbWFzaGVkX2tleXNfMTIzX18=", headers["Authorization"]
38
38
  assert_equal "application/json", headers["Content-Type"]
39
39
  end
40
+
41
+ describe "when 2FA OTP is included" do
42
+ before do
43
+ options = {
44
+ username: @username,
45
+ password: @password,
46
+ one_time_password: "123456"
47
+ }
48
+
49
+ @credentials = Fog::Brightbox::OAuth2::CredentialSet.new(@client_id, @client_secret, options)
50
+ @strategy = Fog::Brightbox::OAuth2::UserCredentialsStrategy.new(@credentials)
51
+ end
52
+
53
+ it "tests #headers" do
54
+ headers = @strategy.headers
55
+ assert_equal "Basic YXBwLTEyMzQ1Ol9fbWFzaGVkX2tleXNfMTIzX18=", headers["Authorization"]
56
+ assert_equal "application/json", headers["Content-Type"]
57
+ assert_equal "123456", headers["X-Brightbox-OTP"]
58
+ end
59
+ end
40
60
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fog-brightbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Thornthwaite
@@ -381,6 +381,9 @@ files:
381
381
  - lib/fog/brightbox/storage/not_found.rb
382
382
  - lib/fog/brightbox/version.rb
383
383
  - spec/fog/brightbox/compute/config_spec.rb
384
+ - spec/fog/brightbox/compute/credentials_spec.rb
385
+ - spec/fog/brightbox/compute/get_access_token_spec.rb
386
+ - spec/fog/brightbox/compute/two_factor_spec.rb
384
387
  - spec/fog/brightbox/compute/wrapped_request_spec.rb
385
388
  - spec/fog/brightbox/config_spec.rb
386
389
  - spec/fog/brightbox/link_helper_spec.rb
@@ -488,6 +491,9 @@ summary: This library can be used as a module for `fog` or as standalone provide
488
491
  to use the Brightbox Cloud in applications
489
492
  test_files:
490
493
  - spec/fog/brightbox/compute/config_spec.rb
494
+ - spec/fog/brightbox/compute/credentials_spec.rb
495
+ - spec/fog/brightbox/compute/get_access_token_spec.rb
496
+ - spec/fog/brightbox/compute/two_factor_spec.rb
491
497
  - spec/fog/brightbox/compute/wrapped_request_spec.rb
492
498
  - spec/fog/brightbox/config_spec.rb
493
499
  - spec/fog/brightbox/link_helper_spec.rb