spaceship 0.20.0 → 0.21.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 13327e628a59af20edccc21b45b712a7369ba849
4
- data.tar.gz: 899347df5eed63a08ab77a14f5bce260857260df
3
+ metadata.gz: e6a3472e6fb40f5531aa8ae2c860f26fe8594c37
4
+ data.tar.gz: af5a9f4a0b7c9115123b32c07ef642d3ad80cfe6
5
5
  SHA512:
6
- metadata.gz: 66ca044745dff1f1e44d41e67fa149c407b95a1796391aa24bf07864d682815d35273813076d50895e196b5ac45ef7a3a624d02aea71e46fb3bf3bfcfa6f961b
7
- data.tar.gz: c463fc2b1d2a5bf1adb4079d36815ebdd31e476429ab00774ec86f96517e22c2dee498e5142528ed2bc91ff0a196ef6f14fbd9c8183d0a9a92da00cbf18e9532
6
+ metadata.gz: 4b221fef762f3099d9893703b3959ba5302c595b23110af77a392febe04ae894b01d51065a877ebd8e0441c9e1210b09514ec87c3f9fb22264ac56c7fda2e2c9
7
+ data.tar.gz: 91d022c2ebacf26a18bdb8d1667ae886d0a91d709d1bacf214d9ed96e65c36d43e05ef75a0240540b40d138d51707fd0d55167f28725ec62940ae36d7fb961fd
@@ -39,6 +39,9 @@ module Spaceship
39
39
  # Raised when 302 is received from portal request
40
40
  class AppleTimeoutError < StandardError; end
41
41
 
42
+ # Raised when 401 is received from portal request
43
+ class UnauthorizedAccessError < StandardError; end
44
+
42
45
  # Authenticates with Apple's web services. This method has to be called once
43
46
  # to generate a valid session. The session will automatically be used from then
44
47
  # on.
@@ -66,8 +69,14 @@ module Spaceship
66
69
  end
67
70
 
68
71
  def initialize
72
+ options = {
73
+ request: {
74
+ timeout: 300,
75
+ open_timeout: 300
76
+ }
77
+ }
69
78
  @cookie = HTTP::CookieJar.new
70
- @client = Faraday.new(self.class.hostname) do |c|
79
+ @client = Faraday.new(self.class.hostname, options) do |c|
71
80
  c.response :json, content_type: /\bjson$/
72
81
  c.response :xml, content_type: /\bxml$/
73
82
  c.response :plist, content_type: /\bplist$/
@@ -168,9 +177,9 @@ module Spaceship
168
177
  end
169
178
 
170
179
  self.user = user
171
-
180
+ @password = password
172
181
  begin
173
- send_login_request(user, password) # different in subclasses
182
+ do_login(user, password)
174
183
  rescue InvalidUserCredentialsError => ex
175
184
  raise ex unless keychain_entry
176
185
 
@@ -182,20 +191,36 @@ module Spaceship
182
191
  end
183
192
  end
184
193
 
185
- def with_retry(tries = 5, &block)
186
- return block.call
187
- rescue Faraday::Error::TimeoutError, AppleTimeoutError => ex # New Faraday version: Faraday::TimeoutError => ex
194
+ def with_retry(tries = 5, &_block)
195
+ return yield
196
+ rescue Faraday::Error::ConnectionFailed, Faraday::Error::TimeoutError, AppleTimeoutError => ex # New Faraday version: Faraday::TimeoutError => ex
188
197
  unless (tries -= 1).zero?
189
198
  logger.warn("Timeout received: '#{ex.message}'. Retrying after 3 seconds (remaining: #{tries})...")
190
- sleep 3
199
+ sleep 3 unless defined? SpecHelper
200
+ retry
201
+ end
202
+ raise ex # re-raise the exception
203
+ rescue UnauthorizedAccessError => ex
204
+ if @loggedin
205
+ msg = "Auth error received: '#{ex.message}'. Login in again then retrying after 3 seconds (remaining: #{tries})..."
206
+ puts msg if $verbose
207
+ logger.warn msg
208
+ do_login(self.user, @password)
209
+ sleep 3 unless defined? SpecHelper
191
210
  retry
192
211
  end
193
-
194
212
  raise ex # re-raise the exception
195
213
  end
196
214
 
197
215
  private
198
216
 
217
+ def do_login(user, password)
218
+ @loggedin = false
219
+ ret = send_login_request(user, password) # different in subclasses
220
+ @loggedin = true
221
+ ret
222
+ end
223
+
199
224
  # Is called from `parse_response` to store the latest csrf_token (if available)
200
225
  def store_csrf_tokens(response)
201
226
  if response and response.headers
@@ -238,11 +263,11 @@ module Spaceship
238
263
  params_to_log = params_to_log.collect do |key, value|
239
264
  "{#{key}: #{value}}"
240
265
  end
241
- logger.info("#{method.upcase}: #{url} #{params_to_log.join(', ')}")
266
+ logger.info(">> #{method.upcase}: #{url} #{params_to_log.join(', ')}")
242
267
  end
243
268
 
244
269
  def log_response(method, url, response)
245
- logger.debug("#{method.upcase}: #{url}: #{response.body}")
270
+ logger.debug("<< #{method.upcase}: #{url}: #{response.body}")
246
271
  end
247
272
 
248
273
  # Actually sends the request to the remote server
@@ -250,6 +275,13 @@ module Spaceship
250
275
  def send_request(method, url_or_path, params, headers, &block)
251
276
  with_retry do
252
277
  response = @client.send(method, url_or_path, params, headers, &block)
278
+ resp_hash = response.to_hash
279
+ if resp_hash[:status] == 401
280
+ msg = "Auth lost"
281
+ logger.warn msg
282
+ raise UnauthorizedAccessError.new, "Unauthorized Access"
283
+ end
284
+
253
285
  if response.body.to_s.include?("<title>302 Found</title>")
254
286
  raise AppleTimeoutError.new, "Apple 302 detected"
255
287
  end
@@ -5,6 +5,10 @@ module Spaceship
5
5
  class ITunesConnectError < StandardError
6
6
  end
7
7
 
8
+ # raised if the server failed to save temporarily
9
+ class ITunesConnectTemporaryError < ITunesConnectError
10
+ end
11
+
8
12
  attr_reader :du_client
9
13
 
10
14
  def initialize
@@ -120,18 +124,24 @@ module Spaceship
120
124
  end
121
125
 
122
126
  def send_login_request(user, password)
127
+ clear_user_cached_data
128
+
123
129
  data = {
124
130
  accountName: user,
125
131
  password: password,
126
132
  rememberMe: true
127
133
  }
128
134
 
129
- response = request(:post) do |req|
130
- req.url "https://idmsa.apple.com/appleauth/auth/signin?widgetKey=#{service_key}"
131
- req.body = data.to_json
132
- req.headers['Content-Type'] = 'application/json'
133
- req.headers['X-Requested-With'] = 'XMLHttpRequest'
134
- req.headers['Accept'] = 'application/json, text/javascript'
135
+ begin
136
+ response = request(:post) do |req|
137
+ req.url "https://idmsa.apple.com/appleauth/auth/signin?widgetKey=#{service_key}"
138
+ req.body = data.to_json
139
+ req.headers['Content-Type'] = 'application/json'
140
+ req.headers['X-Requested-With'] = 'XMLHttpRequest'
141
+ req.headers['Accept'] = 'application/json, text/javascript'
142
+ end
143
+ rescue UnauthorizedAccessError
144
+ raise InvalidUserCredentialsError.new, "Invalid username and password combination. Used '#{user}' as the username."
135
145
  end
136
146
 
137
147
  # get woinst, wois, and itctx cookie values
@@ -139,7 +149,7 @@ module Spaceship
139
149
  request(:get, "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa")
140
150
 
141
151
  case response.status
142
- when 403, 401
152
+ when 403
143
153
  raise InvalidUserCredentialsError.new, "Invalid username and password combination. Used '#{user}' as the username."
144
154
  when 200
145
155
  return response
@@ -203,6 +213,8 @@ module Spaceship
203
213
  if errors.count > 0 # they are separated by `.` by default
204
214
  if errors.count == 1 and errors.first == "You haven't made any changes."
205
215
  # This is a special error which we really don't care about
216
+ elsif errors.count == 1 and errors.first.include?("try again later")
217
+ raise ITunesConnectTemporaryError.new, errors.first
206
218
  else
207
219
  raise ITunesConnectError.new, errors.join(' ')
208
220
  end
@@ -338,13 +350,15 @@ module Spaceship
338
350
  raise "app_id is required" unless app_id
339
351
  raise "version_id is required" unless version_id.to_i > 0
340
352
 
341
- r = request(:post) do |req|
342
- req.url "ra/apps/#{app_id}/platforms/ios/versions/#{version_id}"
343
- req.body = data.to_json
344
- req.headers['Content-Type'] = 'application/json'
345
- end
353
+ with_tunes_retry do
354
+ r = request(:post) do |req|
355
+ req.url "ra/apps/#{app_id}/platforms/ios/versions/#{version_id}"
356
+ req.body = data.to_json
357
+ req.headers['Content-Type'] = 'application/json'
358
+ end
346
359
 
347
- handle_itc_response(r.body)
360
+ handle_itc_response(r.body)
361
+ end
348
362
  end
349
363
 
350
364
  #####################################################
@@ -780,19 +794,38 @@ module Spaceship
780
794
 
781
795
  private
782
796
 
797
+ def with_tunes_retry(tries = 5, &_block)
798
+ return yield
799
+ rescue Spaceship::TunesClient::ITunesConnectTemporaryError => ex
800
+ unless (tries -= 1).zero?
801
+ msg = "ITC temporary save error received: '#{ex.message}'. Retrying after 60 seconds (remaining: #{tries})..."
802
+ puts msg
803
+ logger.warn msg
804
+ sleep 60 unless defined? SpecHelper # unless FastlaneCore::Helper.is_test?
805
+ retry
806
+ end
807
+ raise ex # re-raise the exception
808
+ end
809
+
810
+ def clear_user_cached_data
811
+ @content_provider_id = nil
812
+ @sso_token_for_image = nil
813
+ @sso_token_for_video = nil
814
+ end
815
+
783
816
  # the contentProviderIr found in the UserDetail instance
784
817
  def content_provider_id
785
- user_detail_data.content_provider_id
818
+ @content_provider_id ||= user_detail_data.content_provider_id
786
819
  end
787
820
 
788
821
  # the ssoTokenForImage found in the AppVersionRef instance
789
822
  def sso_token_for_image
790
- ref_data.sso_token_for_image
823
+ @sso_token_for_image ||= ref_data.sso_token_for_image
791
824
  end
792
825
 
793
826
  # the ssoTokenForVideo found in the AppVersionRef instance
794
827
  def sso_token_for_video
795
- ref_data.sso_token_for_video
828
+ @sso_token_for_video ||= ref_data.sso_token_for_video
796
829
  end
797
830
 
798
831
  def update_tester_from_app!(tester, app_id, testing)
@@ -1,3 +1,3 @@
1
1
  module Spaceship
2
- VERSION = "0.20.0"
2
+ VERSION = "0.21.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spaceship
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-02-18 00:00:00.000000000 Z
12
+ date: 2016-02-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: credentials_manager