verona 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a4e61f2037f343a773bb7dc01c3ea24ac04ebb79
4
+ data.tar.gz: d7fdbae52c02fb72c9cd733308fbdcbbdaa273a9
5
+ SHA512:
6
+ metadata.gz: d8e2cda02adc454441cd4c4bbd08987040bd0f98b1ce2a2063ee6262d873b036c04e55ed21b373954c6462feb814ec3fcfbb765f2b82fd4d6e6968ea72c1e0ad
7
+ data.tar.gz: 25b256850eab9e4976c55765293433a1fb5bc365e1018ab1266f524727bed133e9c80b1a941cb5e94842f37e3ef253287903fc9ffbe52f121f44820082dfc5e0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,16 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ verona (0.0.1)
5
+ json
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ json (1.8.1)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ verona!
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,35 @@
1
+ Verona is a simple gem for verifying Google Play In-App Purchase tokens, and retrieving the information associated with the purchase.
2
+
3
+ There are two reasons why you should verify in-app purchase receipts on the server: First, it allows you to keep your own records of past purchases, which is useful for up-to-the-minute metrics and historical analysis. Second, server-side verification over SSL is the most reliable way to determine the authenticity of purchasing records.
4
+
5
+ Verona is based on @mattt's ![Venice](https://github.com/nomad/venice) gem for iOS In-App Purchase verification.
6
+
7
+ ## Installation
8
+
9
+ $ gem install verona
10
+
11
+ ## Usage
12
+
13
+ ```ruby
14
+ require 'verona'
15
+
16
+ if receipt = Verona::Receipt.verify({
17
+ :package_name => "com.mycompany.app",
18
+ :product_id => "com.mycompany.app.iap",
19
+ :token => "token"
20
+ })
21
+ p receipt.to_h
22
+ end
23
+ ```
24
+
25
+ ## Contact
26
+
27
+ Simon Maddox
28
+
29
+ - http://github.com/simonmaddox
30
+ - http://twitter.com/simonmaddox
31
+ simon@simonmaddox.com
32
+
33
+ ## License
34
+
35
+ Verona is available under the MIT license. See the LICENSE file for more info.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler/setup'
2
+
3
+ gemspec = eval(File.read("verona.gemspec"))
4
+
5
+ task :build => "#{gemspec.full_name}.gem"
6
+
7
+ file "#{gemspec.full_name}.gem" => gemspec.files + ["verona.gemspec"] do
8
+ system "gem build verona.gemspec"
9
+ end
data/lib/verona.rb ADDED
@@ -0,0 +1,3 @@
1
+ require_relative 'verona/client'
2
+ require_relative 'verona/receipt'
3
+ require_relative 'verona/version'
@@ -0,0 +1,35 @@
1
+ require 'json'
2
+ require 'net/https'
3
+ require 'uri'
4
+
5
+ module Verona
6
+ class Client
7
+ def verify!(attributes = {}, options)
8
+ json = json_response_from_verifying_token(attributes)
9
+ error = json['error'] if json['error']
10
+ if !error and json
11
+ Receipt.new(json.merge(attributes))
12
+ else
13
+ false
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def json_response_from_verifying_token(attributes = {})
20
+ uri = URI("https://www.googleapis.com/androidpublisher/v1.1/applications/#{attributes[:package_name]}/inapp/#{attributes[:product_id]}/purchases/#{attributes[:token]}")
21
+ http = Net::HTTP.new(uri.host, uri.port)
22
+ http.use_ssl = true
23
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
24
+
25
+ request = Net::HTTP::Get.new(uri.request_uri)
26
+ request['Accept'] = "application/json"
27
+ request['Content-Type'] = "application/json"
28
+ request['Authorization'] = "Bearer #{ENV['GOOGLE_PLAY_ACCESS_TOKEN']}"
29
+
30
+ response = http.request(request)
31
+
32
+ JSON.parse(response.body)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,65 @@
1
+ require 'time'
2
+
3
+ module Verona
4
+ class Receipt
5
+ # The package name for the application
6
+ attr_reader :package_name
7
+
8
+ # The product identifier of the item that was purchased.
9
+ attr_reader :product_id
10
+
11
+ # The receipt's token
12
+ attr_reader :token
13
+
14
+ # The date and time this transaction occurred.
15
+ attr_reader :purchase_date
16
+
17
+ # The state of the purchase
18
+ attr_reader :purchase_state
19
+
20
+ # The consumption state of the purchase
21
+ attr_reader :consumed
22
+
23
+ # Developer payload
24
+ attr_reader :developer_payload
25
+
26
+ def initialize(attributes = {})
27
+ @package_name = attributes[:package_name] if attributes[:package_name]
28
+ @product_id = attributes[:product_id] if attributes[:product_id]
29
+ @token = attributes[:token] if attributes[:token]
30
+ @purchase_date = Time.at(attributes['purchaseTime'].to_i / 1000) if attributes['purchaseTime']
31
+ @purchase_state = Integer(attributes['purchaseState']) if attributes['purchaseState']
32
+ @consumed = Integer(attributes['consumptionState']) if attributes['consumptionState']
33
+ @developer_payload = attributes['developerPayload'] if attributes['developerPayload']
34
+ end
35
+
36
+ def to_h
37
+ {
38
+ :package_name => @package_name,
39
+ :product_id => @product_id,
40
+ :purchase_date => @purchase_date.httpdate,
41
+ :purchase_state => @purchase_state,
42
+ :consumed => @consumed,
43
+ :developer_payload => (@developer_payload rescue nil)
44
+ }
45
+ end
46
+
47
+ def to_json
48
+ self.to_h.to_json
49
+ end
50
+
51
+ class << self
52
+ def verify(data, options = {})
53
+ return verify!(data, options) rescue false
54
+ end
55
+
56
+ def verify!(data, options = {})
57
+ client = Client.new
58
+ client.verify!(data, options) rescue false
59
+ end
60
+
61
+ alias :validate :verify
62
+ alias :validate! :verify!
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,3 @@
1
+ module Verona
2
+ VERSION = "0.0.1"
3
+ end
data/verona.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "verona/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "verona"
7
+ s.authors = ["Simon Maddox"]
8
+ s.email = "simon@simonmaddox.com"
9
+ s.license = "MIT"
10
+ s.homepage = "http://simonmaddox.com"
11
+ s.version = Verona::VERSION
12
+ s.platform = Gem::Platform::RUBY
13
+ s.summary = "Google Play In-App Purchase Token Verification"
14
+ s.description = ""
15
+
16
+ s.add_dependency "json"
17
+
18
+ s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: verona
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Simon Maddox
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: ''
28
+ email: simon@simonmaddox.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - ./Gemfile
34
+ - ./Gemfile.lock
35
+ - ./lib/verona/client.rb
36
+ - ./lib/verona/receipt.rb
37
+ - ./lib/verona/version.rb
38
+ - ./lib/verona.rb
39
+ - ./LICENSE
40
+ - ./Rakefile
41
+ - ./README.md
42
+ - ./verona.gemspec
43
+ homepage: http://simonmaddox.com
44
+ licenses:
45
+ - MIT
46
+ metadata: {}
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 2.1.9
64
+ signing_key:
65
+ specification_version: 4
66
+ summary: Google Play In-App Purchase Token Verification
67
+ test_files: []