candy_check 0.0.3 → 0.0.5
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 +1 -0
- data/.travis.yml +4 -3
- data/LICENSE.txt +2 -2
- data/README.md +1 -1
- data/candy_check.gemspec +5 -3
- data/lib/candy_check/app_store/client.rb +3 -2
- data/lib/candy_check/app_store/verification.rb +2 -1
- data/lib/candy_check/app_store/verification_failure.rb +15 -5
- data/lib/candy_check/app_store/verifier.rb +7 -4
- data/lib/candy_check/cli/app.rb +1 -1
- data/lib/candy_check/cli/commands/play_store.rb +3 -1
- data/lib/candy_check/play_store/client.rb +5 -5
- data/lib/candy_check/play_store/verification.rb +3 -1
- data/lib/candy_check/play_store/verifier.rb +1 -1
- data/lib/candy_check/utils/config.rb +2 -2
- data/lib/candy_check/version.rb +1 -1
- data/spec/app_store/client_spec.rb +16 -5
- data/spec/app_store/verification_spec.rb +4 -3
- data/spec/app_store/verifier_spec.rb +1 -1
- data/spec/cli/commands/app_store_spec.rb +1 -1
- data/spec/cli/commands/play_store_spec.rb +1 -1
- data/spec/play_store/client_spec.rb +1 -1
- data/spec/play_store/verification_spec.rb +4 -2
- data/spec/play_store/verifier_spec.rb +3 -3
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 414f845cc6a6fa6a27f814866675412925ed8a85
|
4
|
+
data.tar.gz: a2699ef81d97d170e964bf08bcbd5949284f00ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9449d7d55b94fa560d8be6bdc2f1d082287e78561f6c935d4a2ca3836759ddd0ac3d6385052624436257c21f889e4e5bd087d48b57fe4b6736fd580b554d496d
|
7
|
+
data.tar.gz: 15579d8441886b67bcb4d28a9c9404cc836e553821e4d9c46e8dfec8090fb929b5d6ac1baa7fc5c58c396869a79840143400b1bb632d32f4c016b4cd00b1dfcc
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
language: ruby
|
2
2
|
sudo: false
|
3
|
+
cache: bundler
|
3
4
|
rvm:
|
4
5
|
- '2.2'
|
5
6
|
- '2.1'
|
6
7
|
- '2.0'
|
7
|
-
- '1.9.3'
|
8
8
|
- ruby-head
|
9
9
|
- rbx-2
|
10
|
-
- jruby-
|
10
|
+
- jruby-20mode
|
11
|
+
- jruby-21mode
|
11
12
|
- jruby-head
|
12
13
|
matrix:
|
13
14
|
allow_failures:
|
14
15
|
- rvm: ruby-head
|
15
16
|
- rvm: jruby-head
|
16
|
-
fast_finish: true
|
17
|
+
fast_finish: true
|
data/LICENSE.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c)
|
1
|
+
Copyright (c) 2016 Jonas Thiel
|
2
2
|
|
3
3
|
MIT License
|
4
4
|
|
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
data/candy_check.gemspec
CHANGED
@@ -13,12 +13,14 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.license = 'MIT'
|
14
14
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
16
|
-
spec.executables = spec.files.grep(
|
17
|
-
spec.test_files = spec.files.grep(
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.0')
|
21
|
+
|
20
22
|
spec.add_dependency 'multi_json', '~> 1.10'
|
21
|
-
spec.add_dependency 'google-api-client', '~> 0.8'
|
23
|
+
spec.add_dependency 'google-api-client', '~> 0.8.6'
|
22
24
|
spec.add_dependency 'thor', '~> 0.19'
|
23
25
|
|
24
26
|
spec.add_development_dependency 'rubocop', '~> 0.28'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'multi_json'
|
2
|
+
require 'net/http'
|
2
3
|
|
3
4
|
module CandyCheck
|
4
5
|
module AppStore
|
@@ -6,7 +7,7 @@ module CandyCheck
|
|
6
7
|
# servers (either sandbox or production).
|
7
8
|
class Client
|
8
9
|
# Mimetype for JSON objects
|
9
|
-
JSON_MIME_TYPE = 'application/json'
|
10
|
+
JSON_MIME_TYPE = 'application/json'.freeze
|
10
11
|
|
11
12
|
# Initialize a new client bound to an endpoint
|
12
13
|
# @param endpoint_url [String]
|
@@ -32,7 +33,7 @@ module CandyCheck
|
|
32
33
|
|
33
34
|
def build_http_connector
|
34
35
|
Net::HTTP.new(@uri.host, @uri.port).tap do |net|
|
35
|
-
net.use_ssl
|
36
|
+
net.use_ssl = true
|
36
37
|
net.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
37
38
|
end
|
38
39
|
end
|
@@ -18,7 +18,8 @@ module CandyCheck
|
|
18
18
|
# @param receipt_data [String] the raw data to be verified
|
19
19
|
# @param secret [String] the optional shared secret
|
20
20
|
def initialize(endpoint_url, receipt_data, secret = nil)
|
21
|
-
@endpoint_url
|
21
|
+
@endpoint_url = endpoint_url
|
22
|
+
@receipt_data = receipt_data
|
22
23
|
@secret = secret
|
23
24
|
end
|
24
25
|
|
@@ -1,11 +1,21 @@
|
|
1
1
|
module CandyCheck
|
2
2
|
module AppStore
|
3
3
|
# Represents a failing call against the verification server
|
4
|
-
class VerificationFailure
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
#
|
4
|
+
class VerificationFailure
|
5
|
+
# @return [Fixnum] the code of the failure
|
6
|
+
attr_reader :code
|
7
|
+
|
8
|
+
# @return [String] the message of the failure
|
9
|
+
attr_reader :message
|
10
|
+
|
11
|
+
# Initializes a new instance which bases on a JSON result
|
12
|
+
# from Apple servers
|
13
|
+
# @param code [Fixnum]
|
14
|
+
# @param message [String]
|
15
|
+
def initialize(code, message)
|
16
|
+
@code = code
|
17
|
+
@message = message
|
18
|
+
end
|
9
19
|
|
10
20
|
class << self
|
11
21
|
# Gets a known failure or build an unknown failure
|
@@ -4,9 +4,9 @@ module CandyCheck
|
|
4
4
|
# The call return either an {Receipt} or a {VerificationFailure}
|
5
5
|
class Verifier
|
6
6
|
# HTTPS endpoint for production receipts
|
7
|
-
PRODUCTION_ENDPOINT = 'https://buy.itunes.apple.com/verifyReceipt'
|
7
|
+
PRODUCTION_ENDPOINT = 'https://buy.itunes.apple.com/verifyReceipt'.freeze
|
8
8
|
# HTTPS endpoint for sandbox receipts
|
9
|
-
SANDBOX_ENDPOINT = 'https://sandbox.itunes.apple.com/verifyReceipt'
|
9
|
+
SANDBOX_ENDPOINT = 'https://sandbox.itunes.apple.com/verifyReceipt'.freeze
|
10
10
|
# Status code from production endpoint when receiving a sandbox
|
11
11
|
# receipt which occurs during the app's review process
|
12
12
|
REDIRECT_TO_SANDBOX_CODE = 21_007
|
@@ -57,8 +57,11 @@ module CandyCheck
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def redirect_code
|
60
|
-
config.production?
|
61
|
-
|
60
|
+
if config.production?
|
61
|
+
REDIRECT_TO_SANDBOX_CODE
|
62
|
+
else
|
63
|
+
REDIRECT_TO_PRODUCTION_CODE
|
64
|
+
end
|
62
65
|
end
|
63
66
|
|
64
67
|
def redirect?(failure)
|
data/lib/candy_check/cli/app.rb
CHANGED
@@ -14,7 +14,9 @@ module CandyCheck
|
|
14
14
|
# @option options [String] :application_name for the API call
|
15
15
|
# @option options [String] :application_version for the API call
|
16
16
|
def initialize(package, product_id, token, options)
|
17
|
-
@package
|
17
|
+
@package = package
|
18
|
+
@product_id = product_id
|
19
|
+
@token = token
|
18
20
|
super(options)
|
19
21
|
end
|
20
22
|
|
@@ -15,13 +15,13 @@ module CandyCheck
|
|
15
15
|
class DiscoveryError < RuntimeError; end
|
16
16
|
|
17
17
|
# API endpoint
|
18
|
-
API_URL = 'https://accounts.google.com/o/oauth2/token'
|
18
|
+
API_URL = 'https://accounts.google.com/o/oauth2/token'.freeze
|
19
19
|
# API scope for Android services
|
20
|
-
API_SCOPE = 'https://www.googleapis.com/auth/androidpublisher'
|
20
|
+
API_SCOPE = 'https://www.googleapis.com/auth/androidpublisher'.freeze
|
21
21
|
# API discovery namespace
|
22
|
-
API_DISCOVER = 'androidpublisher'
|
22
|
+
API_DISCOVER = 'androidpublisher'.freeze
|
23
23
|
# API version
|
24
|
-
API_VERSION = 'v2'
|
24
|
+
API_VERSION = 'v2'.freeze
|
25
25
|
|
26
26
|
# Initializes a client using a configuration.
|
27
27
|
# @param config [ClientConfig]
|
@@ -85,7 +85,7 @@ module CandyCheck
|
|
85
85
|
|
86
86
|
def validate_rpc!
|
87
87
|
return if rpc.purchases.products.get
|
88
|
-
|
88
|
+
raise DiscoveryError, 'Unable to get the API discovery'
|
89
89
|
rescue NoMethodError
|
90
90
|
raise DiscoveryError, 'Unable to get the API discovery'
|
91
91
|
end
|
@@ -17,7 +17,9 @@ module CandyCheck
|
|
17
17
|
# @param token [String]
|
18
18
|
def initialize(client, package, product_id, token)
|
19
19
|
@client = client
|
20
|
-
@package
|
20
|
+
@package = package
|
21
|
+
@product_id = product_id
|
22
|
+
@token = token
|
21
23
|
end
|
22
24
|
|
23
25
|
# Performs the verification against the remote server
|
@@ -24,7 +24,7 @@ module CandyCheck
|
|
24
24
|
# @raise [ArgumentError] if attribute is missing
|
25
25
|
def validates_presence(name)
|
26
26
|
return if send(name)
|
27
|
-
|
27
|
+
raise ArgumentError, "Configuration field #{name} is missing"
|
28
28
|
end
|
29
29
|
|
30
30
|
# Checks for the inclusion of an attribute
|
@@ -32,7 +32,7 @@ module CandyCheck
|
|
32
32
|
# @param values [Array] of possible values
|
33
33
|
def validates_inclusion(name, *values)
|
34
34
|
return if values.include?(send(name))
|
35
|
-
|
35
|
+
raise ArgumentError, "Configuration field #{name} should be "\
|
36
36
|
"one of: #{values.join(', ')}"
|
37
37
|
end
|
38
38
|
end
|
data/lib/candy_check/version.rb
CHANGED
@@ -9,7 +9,20 @@ describe CandyCheck::AppStore::Client do
|
|
9
9
|
'some_secret_password'
|
10
10
|
end
|
11
11
|
let(:response) do
|
12
|
-
'{
|
12
|
+
'{
|
13
|
+
"receipt": {
|
14
|
+
"item_id": "521129812"
|
15
|
+
},
|
16
|
+
"status": 0
|
17
|
+
}'
|
18
|
+
end
|
19
|
+
let(:expected) do
|
20
|
+
{
|
21
|
+
'status' => 0,
|
22
|
+
'receipt' => {
|
23
|
+
'item_id' => '521129812'
|
24
|
+
}
|
25
|
+
}
|
13
26
|
end
|
14
27
|
|
15
28
|
subject { CandyCheck::AppStore::Client.new(endpoint_url) }
|
@@ -25,8 +38,7 @@ describe CandyCheck::AppStore::Client do
|
|
25
38
|
.to_return(
|
26
39
|
body: response
|
27
40
|
)
|
28
|
-
result
|
29
|
-
expected = { 'status' => 0 }
|
41
|
+
result = subject.verify(receipt_data)
|
30
42
|
result.must_equal expected
|
31
43
|
end
|
32
44
|
|
@@ -41,8 +53,7 @@ describe CandyCheck::AppStore::Client do
|
|
41
53
|
.to_return(
|
42
54
|
body: response
|
43
55
|
)
|
44
|
-
result
|
45
|
-
expected = { 'status' => 0 }
|
56
|
+
result = subject.verify(receipt_data, password)
|
46
57
|
result.must_equal expected
|
47
58
|
end
|
48
59
|
end
|
@@ -43,11 +43,12 @@ describe CandyCheck::AppStore::Verification do
|
|
43
43
|
|
44
44
|
private
|
45
45
|
|
46
|
-
|
46
|
+
DummyClient = Struct.new(:response) do
|
47
47
|
attr_reader :receipt_data, :secret
|
48
48
|
|
49
49
|
def verify(receipt_data, secret)
|
50
|
-
@receipt_data
|
50
|
+
@receipt_data = receipt_data
|
51
|
+
@secret = secret
|
51
52
|
response
|
52
53
|
end
|
53
54
|
end
|
@@ -56,7 +57,7 @@ describe CandyCheck::AppStore::Verification do
|
|
56
57
|
recorded = []
|
57
58
|
dummy = DummyClient.new(response)
|
58
59
|
stub = proc do |*args|
|
59
|
-
recorded <<
|
60
|
+
recorded << args
|
60
61
|
dummy
|
61
62
|
end
|
62
63
|
CandyCheck::AppStore::Client.stub :new, stub do
|
@@ -101,7 +101,7 @@ describe CandyCheck::AppStore::Verifier do
|
|
101
101
|
CandyCheck::AppStore::VerificationFailure.fetch(code)
|
102
102
|
end
|
103
103
|
|
104
|
-
|
104
|
+
DummyAppStoreVerification = Struct.new(:endpoint, :data, :secret) do
|
105
105
|
attr_accessor :results
|
106
106
|
def call!
|
107
107
|
results.shift
|
@@ -72,7 +72,7 @@ describe CandyCheck::PlayStore::Client do
|
|
72
72
|
result['purchaseState'].must_equal 0
|
73
73
|
result['consumptionState'].must_equal 0
|
74
74
|
result['developerPayload'].must_equal \
|
75
|
-
|
75
|
+
'payload that gets stored and returned'
|
76
76
|
result['purchaseTimeMillis'].must_equal '1421676237413'
|
77
77
|
result['kind'].must_equal 'androidpublisher#productPurchase'
|
78
78
|
end
|
@@ -66,14 +66,16 @@ describe CandyCheck::PlayStore::Verification do
|
|
66
66
|
|
67
67
|
private
|
68
68
|
|
69
|
-
|
69
|
+
DummyGoogleClient = Struct.new(:response) do
|
70
70
|
attr_reader :package, :product_id, :token
|
71
71
|
|
72
72
|
def boot!
|
73
73
|
end
|
74
74
|
|
75
75
|
def verify(package, product_id, token)
|
76
|
-
@package
|
76
|
+
@package = package
|
77
|
+
@product_id = product_id
|
78
|
+
@token = token
|
77
79
|
response
|
78
80
|
end
|
79
81
|
end
|
@@ -78,15 +78,15 @@ describe CandyCheck::PlayStore::Verifier do
|
|
78
78
|
@recorded.must_equal calls
|
79
79
|
end
|
80
80
|
|
81
|
-
|
82
|
-
|
81
|
+
DummyPlayStoreVerification = Struct.new(:client, :package,
|
82
|
+
:product_id, :token) do
|
83
83
|
attr_accessor :results
|
84
84
|
def call!
|
85
85
|
results.shift
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
|
89
|
+
DummyPlayStoreClient = Struct.new(:config) do
|
90
90
|
attr_reader :booted
|
91
91
|
def boot!
|
92
92
|
@booted = true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: candy_check
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Thiel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.8.6
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.8.6
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: thor
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -254,7 +254,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
254
254
|
requirements:
|
255
255
|
- - ">="
|
256
256
|
- !ruby/object:Gem::Version
|
257
|
-
version: '0'
|
257
|
+
version: '2.0'
|
258
258
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
259
259
|
requirements:
|
260
260
|
- - ">="
|
@@ -262,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
262
262
|
version: '0'
|
263
263
|
requirements: []
|
264
264
|
rubyforge_project:
|
265
|
-
rubygems_version: 2.4.
|
265
|
+
rubygems_version: 2.4.8
|
266
266
|
signing_key:
|
267
267
|
specification_version: 4
|
268
268
|
summary: Check and verify in-app receipts
|