venice 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ venice (0.0.1)
5
+ commander (~> 4.1.2)
6
+ excon (~> 0.17.0)
7
+ json (~> 1.7.3)
8
+ terminal-table (~> 1.4.5)
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ commander (4.1.3)
14
+ highline (~> 1.6.11)
15
+ diff-lcs (1.1.3)
16
+ excon (0.17.0)
17
+ highline (1.6.15)
18
+ json (1.7.7)
19
+ multi_json (1.6.1)
20
+ rake (10.0.3)
21
+ rspec (2.12.0)
22
+ rspec-core (~> 2.12.0)
23
+ rspec-expectations (~> 2.12.0)
24
+ rspec-mocks (~> 2.12.0)
25
+ rspec-core (2.12.2)
26
+ rspec-expectations (2.12.1)
27
+ diff-lcs (~> 1.1.3)
28
+ rspec-mocks (2.12.2)
29
+ simplecov (0.7.1)
30
+ multi_json (~> 1.0)
31
+ simplecov-html (~> 0.7.1)
32
+ simplecov-html (0.7.1)
33
+ terminal-table (1.4.5)
34
+
35
+ PLATFORMS
36
+ ruby
37
+
38
+ DEPENDENCIES
39
+ rake
40
+ rspec
41
+ simplecov
42
+ venice!
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013 Mattt Thompson (http://mattt.me/)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # Venice
2
+ **iTunes Receipt Verification**
3
+
4
+ Venice is a simple gem for verifying Apple In-App Purchase receipts, and retrieving the information associated with receipt data.
5
+
6
+ From Apple's [In-App Purchase Programming Guide](http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/VerifyingStoreReceipts/VerifyingStoreReceipts.html):
7
+
8
+ > Your application should perform the additional step of verifying that the receipt you received from Store Kit came from Apple. This is particularly important when your application relies on a separate server to provide subscriptions, services, or downloadable content. Verifying receipts on your server ensures that requests from your application are valid.
9
+
10
+ > - `quantity`: The number of items purchased. This value corresponds to the quantity property of the SKPayment object stored in the transaction’s payment property.
11
+ > - `product_id`: The product identifier of the item that was purchased. This value corresponds to the productIdentifier property of the SKPayment object stored in the transaction’s payment property.
12
+ > - `transaction_id`: The transaction identifier of the item that was purchased. This value corresponds to the transaction’s transactionIdentifier property.
13
+ > - `purchase_date`: The date and time this transaction occurred. This value corresponds to the transaction’s transactionDate property.
14
+ > - `original_transaction_id`: For a transaction that restores a previous transaction, this holds the original transaction identifier.
15
+ > - `original_purchase_date`: For a transaction that restores a previous transaction, this holds the original purchase date.
16
+ > - `app_item_id`: A string that the App Store uses to uniquely identify the application that created the payment transaction. If your server supports multiple applications, you can use this value to differentiate between them. Applications that are executing in the sandbox do not yet have an app-item-id assigned to them, so this key is missing from receipts created by the sandbox.
17
+ > - `version_external_identifier`: An arbitrary number that uniquely identifies a revision of your application. This key is missing in receipts created by the sandbox.
18
+ > - `bid`: The bundle identifier for the application.
19
+ > - `bvrs`: A version number for the application.
20
+
21
+ ## Installation
22
+
23
+ $ gem install venice
24
+
25
+ ## Usage
26
+
27
+ ```ruby
28
+ require 'venice'
29
+
30
+ data = "(Base64-Encoded Receipt Data)"
31
+ if receipt = Venice::Receipt.verify(data)
32
+ p receipt.to_h
33
+ end
34
+ ```
35
+
36
+ ## Comand Line Interface
37
+
38
+ Venice also comes with the `iap` binary, which provides a convenient way to verify receipts from the command line.
39
+
40
+
41
+ $ iap verify /path/to/receipt
42
+
43
+ +-----------------------------+-------------------------------+
44
+ | Receipt |
45
+ +-----------------------------+-------------------------------+
46
+ | app_item_id | |
47
+ | bid | com.mindmobapp.MindMob |
48
+ | bvrs | 20120427 |
49
+ | original_purchase_date | Mon, 30 Apr 2012 15:05:55 GMT |
50
+ | original_transaction_id | 1000000046178817 |
51
+ | product_id | com.mindmobapp.download |
52
+ | purchase_date | Mon, 30 Apr 2012 15:05:55 GMT |
53
+ | quantity | 1 |
54
+ | transaction_id | 1000000046178817 |
55
+ | version_external_identifier | |
56
+ +-----------------------------+-------------------------------+
57
+
58
+ ## Contact
59
+
60
+ Mattt Thompson
61
+
62
+ - http://github.com/mattt
63
+ - http://twitter.com/mattt
64
+ - m@mattt.me
65
+
66
+ ## License
67
+
68
+ Venice is available under the MIT license. See the LICENSE file for more info.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ gemspec = eval(File.read("venice.gemspec"))
5
+
6
+ task :build => "#{gemspec.full_name}.gem"
7
+
8
+ file "#{gemspec.full_name}.gem" => gemspec.files + ["venice.gemspec"] do
9
+ system "gem build venice.gemspec"
10
+ system "gem install venice-#{Venice::VERSION}.gem"
11
+ end
data/bin/iap ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'commander/import'
4
+ require 'terminal-table'
5
+
6
+ require 'venice'
7
+
8
+ HighLine.track_eof = false # Fix for built-in Ruby
9
+ Signal.trap("INT") {} # Suppress backtrace when exiting command
10
+
11
+ program :version, Venice::VERSION
12
+ program :description, 'A command-line interface for sending push notifications'
13
+
14
+ program :help, 'Author', 'Mattt Thompson <m@mattt.me>'
15
+ program :help, 'Website', 'https://github.com/mattt'
16
+ program :help_formatter, :compact
17
+
18
+ default_command :help
19
+
20
+ command :verify do |c|
21
+ c.syntax = 'iap verify RECEIPT'
22
+ c.summary = 'Verifies an In-App Purchase Receipt'
23
+ c.description = ''
24
+
25
+ c.example 'description', 'iap verify /path/to/receipt'
26
+
27
+ c.action do |args, options|
28
+ say_error "Missing receipt argument" and abort unless file = args.first
29
+ say_error "Receipt file does not exist" unless File.exist?(file)
30
+
31
+ begin
32
+ receipt = Venice::Receipt.verify!(File.read(file))
33
+
34
+ table = Terminal::Table.new :title => "Receipt" do |t|
35
+ hash = receipt.to_h
36
+ hash.keys.sort.each do |key|
37
+ t << [key, hash[key]]
38
+ end
39
+ end
40
+
41
+ puts table
42
+
43
+ rescue => e
44
+ say_error "Exception: #{e}" and abort
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,43 @@
1
+ require 'excon'
2
+ require 'json'
3
+
4
+ module Venice
5
+ ITUNES_PRODUCTION_RECEIPT_VERIFICATION_ENDPOINT = "https://buy.itunes.apple.com/verifyReceipt"
6
+ ITUNES_DEVELOPMENT_RECEIPT_VERIFICATION_ENDPOINT = "https://sandbox.itunes.apple.com/verifyReceipt"
7
+
8
+ class Client
9
+ attr_accessor :verification_url
10
+
11
+ def initialize
12
+ @verification_url = ENV['IAP_VERIFICATION_ENDPOINT']
13
+ end
14
+
15
+ def verify!(data)
16
+ response = Excon.post(@verification_url, :headers => headers, :body => {'receipt-data' => data}.to_json)
17
+ JSON.parse(response.body)
18
+ end
19
+
20
+ class << self
21
+ def development
22
+ client = self.new
23
+ client.verification_url = ITUNES_DEVELOPMENT_RECEIPT_VERIFICATION_ENDPOINT
24
+ client
25
+ end
26
+
27
+ def production
28
+ client = self.new
29
+ client.verification_url = ITUNES_PRODUCTION_RECEIPT_VERIFICATION_ENDPOINT
30
+ client
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def headers
37
+ {
38
+ 'Accept' => 'application/json',
39
+ 'Content-Type' => 'application/json'
40
+ }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,154 @@
1
+ require 'time'
2
+
3
+ module Venice
4
+ class ReceiptVerificationError < StandardError; end
5
+
6
+ # 21000: The App Store could not read the JSON object you provided.
7
+ class InvalidJSONObjectError < ReceiptVerificationError; end
8
+
9
+ # 21002: The data in the receipt-data property was malformed.
10
+ class MalformedReceiptDataError < ReceiptVerificationError; end
11
+
12
+ # 21003: The receipt could not be authenticated.
13
+ class ReceiptVerificationAuthenticationError < ReceiptVerificationError; end
14
+
15
+ # 21004: The shared secret you provided does not match the shared secret on file for your account.
16
+ class SharedSecretMismatchError < ReceiptVerificationError; end
17
+
18
+ # 21005: The receipt server is not currently available.
19
+ class ReceiptVerificationServerOfflineError < ReceiptVerificationError; end
20
+
21
+ # 21006: This receipt is valid but the subscription has expired. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response.
22
+ class ValidReceiptExpiredSubscriptionError < ReceiptVerificationError; end
23
+
24
+ # 21007: This receipt is a sandbox receipt, but it was sent to the production service for verification.
25
+ class SandboxReceiptSentToProductionError < ReceiptVerificationError; end
26
+
27
+ # 21008: This receipt is a production receipt, but it was sent to the sandbox service for verification.
28
+ class ProductionReceiptSentToSandboxError < ReceiptVerificationError; end
29
+
30
+ RECEIPT_VERIFICATION_ERRORS_BY_STATUS_CODE = {
31
+ 21000 => InvalidJSONObjectError,
32
+ 21002 => MalformedReceiptDataError,
33
+ 21003 => ReceiptVerificationAuthenticationError,
34
+ 21004 => SharedSecretMismatchError,
35
+ 21005 => ReceiptVerificationServerOfflineError,
36
+ 21006 => ValidReceiptExpiredSubscriptionError,
37
+ 21007 => SandboxReceiptSentToProductionError,
38
+ 21008 => ProductionReceiptSentToSandboxError
39
+ }
40
+
41
+ class Receipt
42
+ # The number of items purchased. This value corresponds to the quantity property of the SKPayment object stored in the transaction’s payment property.
43
+ attr_reader :quantity
44
+
45
+ # The product identifier of the item that was purchased. This value corresponds to the productIdentifier property of the SKPayment object stored in the transaction’s payment property.
46
+ attr_reader :product_id
47
+
48
+ # The transaction identifier of the item that was purchased. This value corresponds to the transaction’s transactionIdentifier property.
49
+ attr_reader :transaction_id
50
+
51
+ # The date and time this transaction occurred. This value corresponds to the transaction’s transactionDate property.
52
+ attr_reader :purchase_date
53
+
54
+ # A string that the App Store uses to uniquely identify the application that created the payment transaction. If your server supports multiple applications, you can use this value to differentiate between them. Applications that are executing in the sandbox do not yet have an app-item-id assigned to them, so this key is missing from receipts created by the sandbox.
55
+ attr_reader :app_item_id
56
+
57
+ # An arbitrary number that uniquely identifies a revision of your application. This key is missing in receipts created by the sandbox.
58
+ attr_reader :version_external_identifier
59
+
60
+ # The bundle identifier for the application.
61
+ attr_reader :bid
62
+
63
+ # A version number for the application.
64
+ attr_reader :bvrs
65
+
66
+ # For a transaction that restores a previous transaction, this is the original receipt
67
+ attr_accessor :original
68
+
69
+ # For an active subscription was renewed with transaction that took place after the receipt your server sent to the App Store, this is the latest receipt.
70
+ attr_accessor :latest
71
+
72
+ def initialize(attributes = {})
73
+ @quantity = Integer(attributes['quantity']) if attributes['quantity']
74
+ @product_id = attributes['product_id']
75
+ @transaction_id = attributes['transaction_id']
76
+ @purchase_date = DateTime.parse(attributes['purchase_date']) if attributes['purchase_date']
77
+ @app_item_id = attributes['app_item_id']
78
+ @version_external_identifier = attributes['version_external_identifier']
79
+ @bid = attributes['bid']
80
+ @bvrs = attributes['bvrs']
81
+
82
+ if attributes['original_transaction_id'] || attributes['original_purchase_date']
83
+ original_attributes = {
84
+ 'transaction_id' => attributes['original_transaction_id'],
85
+ 'purchase_date' => attributes['original_purchase_date']
86
+ }
87
+
88
+ self.original = Receipt.new(original_attributes)
89
+ end
90
+ end
91
+
92
+ def to_h
93
+ {
94
+ :quantity => @quantity,
95
+ :product_id => @product_id,
96
+ :transaction_id => @transaction_id,
97
+ :purchase_date => (@purchase_date.httpdate rescue nil),
98
+ :original_transaction_id => (@original.transaction_id rescue nil),
99
+ :original_purchase_date => (@original.purchase_date.httpdate rescue nil),
100
+ :app_item_id => @app_item_id,
101
+ :version_external_identifier => @version_external_identifier,
102
+ :bid => @bid,
103
+ :bvrs => @bvrs
104
+ }
105
+ end
106
+
107
+ def to_json
108
+ self.to_h.to_json
109
+ end
110
+
111
+ class << self
112
+ def verify(data, options = {})
113
+ verify!(data, options) rescue false
114
+ end
115
+
116
+ def verify!(data, options = {})
117
+ client = Client.production
118
+
119
+ begin
120
+ json = client.verify!(data)
121
+ status, receipt_attributes = json['status'].to_i, json['receipt']
122
+
123
+ case status
124
+ when 0, 21006
125
+ receipt = Receipt.new(receipt_attributes)
126
+
127
+ if latest_receipt_attributes = json['latest_receipt_info']
128
+ receipt.latest = Receipt.new(latest_receipt_attributes)
129
+ end
130
+
131
+ return receipt
132
+ else
133
+ raise RECEIPT_VERIFICATION_ERRORS_BY_STATUS_CODE[status] || ReceiptVerificationError
134
+ end
135
+
136
+ rescue => error
137
+ case error
138
+ when SandboxReceiptSentToProductionError
139
+ client = Client.development
140
+ retry
141
+ when ProductionReceiptSentToSandboxError
142
+ client = Client.production
143
+ retry
144
+ else
145
+ raise error
146
+ end
147
+ end
148
+ end
149
+
150
+ alias :validate :verify
151
+ alias :validate! :verify!
152
+ end
153
+ end
154
+ end
data/lib/venice.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Venice
2
+ VERSION = "0.0.1"
3
+ end
4
+
5
+ require 'venice/client'
6
+ require 'venice/receipt'
data/spec/receipt ADDED
@@ -0,0 +1 @@
1
+ ewoJInNpZ25hdHVyZSIgPSAiQXBNVUJDODZBbHpOaWtWNVl0clpBTWlKUWJLOEVkZVhrNjNrV0JBWHpsQzhkWEd1anE0N1puSVlLb0ZFMW9OL0ZTOGNYbEZmcDlZWHQ5aU1CZEwyNTBsUlJtaU5HYnloaXRyeVlWQVFvcmkzMlc5YVIwVDhML2FZVkJkZlcrT3kvUXlQWkVtb05LeGhudDJXTlNVRG9VaFo4Wis0cFA3MHBlNWtVUWxiZElWaEFBQURWekNDQTFNd2dnSTdvQU1DQVFJQ0NHVVVrVTNaV0FTMU1BMEdDU3FHU0liM0RRRUJCUVVBTUg4eEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUtEQXBCY0hCc1pTQkpibU11TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURXpNREVHQTFVRUF3d3FRWEJ3YkdVZ2FWUjFibVZ6SUZOMGIzSmxJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVEE1TURZeE5USXlNRFUxTmxvWERURTBNRFl4TkRJeU1EVTFObG93WkRFak1DRUdBMVVFQXd3YVVIVnlZMmhoYzJWU1pXTmxhWEIwUTJWeWRHbG1hV05oZEdVeEd6QVpCZ05WQkFzTUVrRndjR3hsSUdsVWRXNWxjeUJUZEc5eVpURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRGdZMEFNSUdKQW9HQkFNclJqRjJjdDRJclNkaVRDaGFJMGc4cHd2L2NtSHM4cC9Sd1YvcnQvOTFYS1ZoTmw0WElCaW1LalFRTmZnSHNEczZ5anUrK0RyS0pFN3VLc3BoTWRkS1lmRkU1ckdYc0FkQkVqQndSSXhleFRldngzSExFRkdBdDFtb0t4NTA5ZGh4dGlJZERnSnYyWWFWczQ5QjB1SnZOZHk2U01xTk5MSHNETHpEUzlvWkhBZ01CQUFHamNqQndNQXdHQTFVZEV3RUIvd1FDTUFBd0h3WURWUjBqQkJnd0ZvQVVOaDNvNHAyQzBnRVl0VEpyRHRkREM1RllRem93RGdZRFZSMFBBUUgvQkFRREFnZUFNQjBHQTFVZERnUVdCQlNwZzRQeUdVakZQaEpYQ0JUTXphTittVjhrOVRBUUJnb3Foa2lHOTJOa0JnVUJCQUlGQURBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQUVhU2JQanRtTjRDL0lCM1FFcEszMlJ4YWNDRFhkVlhBZVZSZVM1RmFaeGMrdDg4cFFQOTNCaUF4dmRXLzNlVFNNR1k1RmJlQVlMM2V0cVA1Z204d3JGb2pYMGlreVZSU3RRKy9BUTBLRWp0cUIwN2tMczlRVWU4Y3pSOFVHZmRNMUV1bVYvVWd2RGQ0TndOWXhMUU1nNFdUUWZna1FRVnk4R1had1ZIZ2JFL1VDNlk3MDUzcEdYQms1MU5QTTN3b3hoZDNnU1JMdlhqK2xvSHNTdGNURXFlOXBCRHBtRzUrc2s0dHcrR0szR01lRU41LytlMVFUOW5wL0tsMW5qK2FCdzdDMHhzeTBiRm5hQWQxY1NTNnhkb3J5L0NVdk02Z3RLc21uT09kcVRlc2JwMGJzOHNuNldxczBDOWRnY3hSSHVPTVoydG04bnBMVW03YXJnT1N6UT09IjsKCSJwdXJjaGFzZS1pbmZvIiA9ICJld29KSW05eWFXZHBibUZzTFhCMWNtTm9ZWE5sTFdSaGRHVXRjSE4wSWlBOUlDSXlNREV5TFRBMExUTXdJREE0T2pBMU9qVTFJRUZ0WlhKcFkyRXZURzl6WDBGdVoyVnNaWE1pT3dvSkltOXlhV2RwYm1Gc0xYUnlZVzV6WVdOMGFXOXVMV2xrSWlBOUlDSXhNREF3TURBd01EUTJNVGM0T0RFM0lqc0tDU0ppZG5KeklpQTlJQ0l5TURFeU1EUXlOeUk3Q2draWRISmhibk5oWTNScGIyNHRhV1FpSUQwZ0lqRXdNREF3TURBd05EWXhOemc0TVRjaU93b0pJbkYxWVc1MGFYUjVJaUE5SUNJeElqc0tDU0p2Y21sbmFXNWhiQzF3ZFhKamFHRnpaUzFrWVhSbExXMXpJaUE5SUNJeE16TTFOems0TXpVMU9EWTRJanNLQ1NKd2NtOWtkV04wTFdsa0lpQTlJQ0pqYjIwdWJXbHVaRzF2WW1Gd2NDNWtiM2R1Ykc5aFpDSTdDZ2tpYVhSbGJTMXBaQ0lnUFNBaU5USXhNVEk1T0RFeUlqc0tDU0ppYVdRaUlEMGdJbU52YlM1dGFXNWtiVzlpWVhCd0xrMXBibVJOYjJJaU93b0pJbkIxY21Ob1lYTmxMV1JoZEdVdGJYTWlJRDBnSWpFek16VTNPVGd6TlRVNE5qZ2lPd29KSW5CMWNtTm9ZWE5sTFdSaGRHVWlJRDBnSWpJd01USXRNRFF0TXpBZ01UVTZNRFU2TlRVZ1JYUmpMMGROVkNJN0Nna2ljSFZ5WTJoaGMyVXRaR0YwWlMxd2MzUWlJRDBnSWpJd01USXRNRFF0TXpBZ01EZzZNRFU2TlRVZ1FXMWxjbWxqWVM5TWIzTmZRVzVuWld4bGN5STdDZ2tpYjNKcFoybHVZV3d0Y0hWeVkyaGhjMlV0WkdGMFpTSWdQU0FpTWpBeE1pMHdOQzB6TUNBeE5Ub3dOVG8xTlNCRmRHTXZSMDFVSWpzS2ZRPT0iOwoJImVudmlyb25tZW50IiA9ICJTYW5kYm94IjsKCSJwb2QiID0gIjEwMCI7Cgkic2lnbmluZy1zdGF0dXMiID0gIjAiOwp9
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ RECEIPT_DATA = File.read(File.join(File.dirname(__FILE__), "receipt"))
4
+
5
+ describe 'Receipt Verification' do
6
+ describe 'production' do
7
+ it 'verifies a receipt' do
8
+
9
+ lambda {
10
+ receipt = Venice::Receipt.verify!(RECEIPT_DATA)
11
+
12
+ receipt.quantity.should == 1
13
+ receipt.product_id.should == "com.mindmobapp.download"
14
+ receipt.transaction_id.should == "1000000046178817"
15
+ receipt.original.should_not be nil
16
+ }.should_not raise_error
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ unless ENV['CI']
2
+ require 'simplecov'
3
+
4
+ SimpleCov.start do
5
+ add_filter 'spec'
6
+ add_filter '.bundle'
7
+ end
8
+ end
9
+
10
+ require 'venice'
11
+ require 'rspec'
data/venice.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "venice"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "venice"
7
+ s.authors = ["Mattt Thompson"]
8
+ s.email = "m@mattt.me"
9
+ s.homepage = "http://github.com/mattt/venice"
10
+ s.version = Venice::VERSION
11
+ s.platform = Gem::Platform::RUBY
12
+ s.summary = "iTunes In-App Purchase Receipt Verification"
13
+ s.description = ""
14
+
15
+ s.add_dependency "excon", "~> 0.17.0"
16
+ s.add_dependency "json", "~> 1.7.3"
17
+ s.add_dependency "commander", "~> 4.1.2"
18
+ s.add_dependency "terminal-table", "~> 1.4.5"
19
+
20
+ s.add_development_dependency "rspec"
21
+ s.add_development_dependency "rake"
22
+ s.add_development_dependency "simplecov"
23
+
24
+ s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
25
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
27
+ s.require_paths = ["lib"]
28
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: venice
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mattt Thompson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: excon
16
+ requirement: &70234168645000 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.17.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70234168645000
25
+ - !ruby/object:Gem::Dependency
26
+ name: json
27
+ requirement: &70234168644160 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 1.7.3
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70234168644160
36
+ - !ruby/object:Gem::Dependency
37
+ name: commander
38
+ requirement: &70234168643160 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 4.1.2
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70234168643160
47
+ - !ruby/object:Gem::Dependency
48
+ name: terminal-table
49
+ requirement: &70234168642500 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.4.5
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70234168642500
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70234168642100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70234168642100
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: &70234168649060 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70234168649060
80
+ - !ruby/object:Gem::Dependency
81
+ name: simplecov
82
+ requirement: &70234168648620 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70234168648620
91
+ description: ''
92
+ email: m@mattt.me
93
+ executables:
94
+ - iap
95
+ extensions: []
96
+ extra_rdoc_files: []
97
+ files:
98
+ - ./Gemfile
99
+ - ./Gemfile.lock
100
+ - ./lib/venice/client.rb
101
+ - ./lib/venice/receipt.rb
102
+ - ./lib/venice.rb
103
+ - ./LICENSE
104
+ - ./Rakefile
105
+ - ./README.md
106
+ - ./venice.gemspec
107
+ - spec/receipt
108
+ - spec/receipt_verification_spec.rb
109
+ - spec/spec_helper.rb
110
+ - bin/iap
111
+ homepage: http://github.com/mattt/venice
112
+ licenses: []
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ! '>='
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ segments:
124
+ - 0
125
+ hash: -3463739383832533267
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ segments:
133
+ - 0
134
+ hash: -3463739383832533267
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 1.8.15
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: iTunes In-App Purchase Receipt Verification
141
+ test_files:
142
+ - spec/receipt
143
+ - spec/receipt_verification_spec.rb
144
+ - spec/spec_helper.rb