spaceship 0.20.0 → 0.21.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
  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