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 +4 -4
- data/lib/spaceship/client.rb +42 -10
- data/lib/spaceship/tunes/tunes_client.rb +49 -16
- data/lib/spaceship/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6a3472e6fb40f5531aa8ae2c860f26fe8594c37
|
4
|
+
data.tar.gz: af5a9f4a0b7c9115123b32c07ef642d3ad80cfe6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b221fef762f3099d9893703b3959ba5302c595b23110af77a392febe04ae894b01d51065a877ebd8e0441c9e1210b09514ec87c3f9fb22264ac56c7fda2e2c9
|
7
|
+
data.tar.gz: 91d022c2ebacf26a18bdb8d1667ae886d0a91d709d1bacf214d9ed96e65c36d43e05ef75a0240540b40d138d51707fd0d55167f28725ec62940ae36d7fb961fd
|
data/lib/spaceship/client.rb
CHANGED
@@ -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
|
-
|
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, &
|
186
|
-
return
|
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
|
-
|
130
|
-
req
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
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
|
-
|
342
|
-
req
|
343
|
-
|
344
|
-
|
345
|
-
|
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
|
-
|
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)
|
data/lib/spaceship/version.rb
CHANGED
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.
|
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-
|
12
|
+
date: 2016-02-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: credentials_manager
|