oja 0.1.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.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2012
2
+ Manfred Stienstra, Fingertips <manfred@fngtps.com>
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ this software and associated documentation files (the "Software"), to deal in
6
+ the Software without restriction, including without limitation the rights to
7
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ the Software, and to permit persons to whom the Software is furnished to do so,
9
+ subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ # Oja
2
+
3
+ Oja is a Ruby client for verification of Apple Store Receipts.
4
+
5
+ iOS and Mac application receive Receipts when handling purchases from the App Store. Before authorizing access to in-app content, these applications need to verify the receipt with Apple. Oja helps you check the Receipt's status.
6
+
7
+ ## Install
8
+
9
+ $ gem install oja
10
+
11
+ ## Get started
12
+
13
+ response = Oja.verify(:data => data)
14
+ if response.active?
15
+ # Whatever you need to do
16
+ elsif response.inactive?
17
+ # The receipt probably expired
18
+ else
19
+ raise RuntimeError, response.humanized_status
20
+ end
@@ -0,0 +1,10 @@
1
+ require 'oja/receipt'
2
+ require 'oja/request'
3
+ require 'oja/response'
4
+
5
+ module Oja
6
+ def self.verify_filename(receipt_filename)
7
+ receipt = Oja::Receipt.new(:filename => receipt_filename)
8
+ receipt.verify
9
+ end
10
+ end
@@ -0,0 +1,46 @@
1
+ require 'oja/request'
2
+ require 'oja/response'
3
+
4
+ module Oja
5
+ class Mock
6
+ class Response
7
+ attr_reader :status_code, :payload
8
+
9
+ def initialize(status_code, payload)
10
+ @status_code = status_code
11
+ @payload = payload
12
+ end
13
+
14
+ def ok?
15
+ 200 == status_code.to_i
16
+ end
17
+
18
+ def body
19
+ JSON.dump(payload)
20
+ end
21
+ end
22
+
23
+ class << self
24
+ attr_accessor :responses
25
+ end
26
+ @responses = []
27
+
28
+ def self.next_response_arguments
29
+ if responses.empty?
30
+ [200, { status: 0, receipt: '' }]
31
+ else
32
+ responses.pop
33
+ end
34
+ end
35
+
36
+ def self.next_response
37
+ Oja::Mock::Response.new(*next_response_arguments)
38
+ end
39
+ end
40
+
41
+ class Request
42
+ def response
43
+ @response ||= Oja::Mock.next_response
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,55 @@
1
+ require 'base64'
2
+
3
+ module Oja
4
+ class Receipt
5
+ attr_accessor :data, :filename
6
+
7
+ def initialize(attributes)
8
+ attributes.each do |attribute, value|
9
+ send("#{attribute}=", value)
10
+ end
11
+ end
12
+
13
+ def request(environment=:production)
14
+ request = Request.new(
15
+ :receipt => self,
16
+ :environment => environment
17
+ )
18
+ request.run
19
+ end
20
+
21
+ def read
22
+ File.read(filename)
23
+ end
24
+
25
+ def json_data
26
+ data ? JSON.dump(data) : read
27
+ end
28
+
29
+ def receipt_data
30
+ Base64.encode64(json_data)
31
+ end
32
+
33
+ def to_json
34
+ JSON.dump(
35
+ 'receipt-data' => receipt_data
36
+ )
37
+ end
38
+
39
+ def verify
40
+ if response = request(:production)
41
+ if response.sandbox_receipt_in_production?
42
+ request(:sandbox)
43
+ else
44
+ response
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def data_or_read
52
+ data || File.read(filename)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,37 @@
1
+ require 'rest'
2
+ require 'json'
3
+
4
+ module Oja
5
+ class Request
6
+ ENDPOINT = {
7
+ :production => 'https://buy.itunes.apple.com/verifyReceipt',
8
+ :sandbox => 'https://sandbox.itunes.apple.com/verifyReceipt'
9
+ }
10
+
11
+ attr_accessor :environment, :receipt
12
+
13
+ def initialize(attributes)
14
+ attributes.each do |attribute, value|
15
+ send("#{attribute}=", value)
16
+ end
17
+ end
18
+
19
+ def endpoint
20
+ ENDPOINT[environment]
21
+ end
22
+
23
+ def response
24
+ @response ||= REST.post(endpoint, receipt.to_json)
25
+ end
26
+
27
+ def response_data
28
+ JSON.parse(response.body)
29
+ end
30
+
31
+ def run
32
+ if response.ok?
33
+ Oja::Response.new(response_data)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,59 @@
1
+ module Oja
2
+ class Response
3
+ STATUS = {
4
+ 0 => :active,
5
+ 21000 => :bad_json,
6
+ 21002 => :malformed,
7
+ 21003 => :authentication_error,
8
+ 21004 => :authentication_failed,
9
+ 21005 => :service_unavailable,
10
+ 21006 => :inactive,
11
+ 21007 => :sandbox_receipt_in_production,
12
+ 21008 => :production_receipt_in_sandbox
13
+ }
14
+
15
+ HUMANIZED_STATUS = {
16
+ 0 => 'Active',
17
+ 21000 => 'Bad JSON',
18
+ 21002 => 'Malformed',
19
+ 21003 => 'Authentication Error',
20
+ 21004 => 'Authentication Failed',
21
+ 21005 => 'Service Unavailable',
22
+ 21006 => 'Inactive',
23
+ 21007 => 'Sandbox Receipt in Production',
24
+ 21008 => 'Production Receipt in Sandbox'
25
+ }
26
+
27
+ attr_reader :status_code, :receipt_data
28
+
29
+ def initialize(data)
30
+ self.data = data
31
+ end
32
+
33
+ def data=(data)
34
+ @status_code = data['status'].to_i
35
+ @receipt_data = data['receipt']
36
+ end
37
+
38
+ def status
39
+ STATUS[status_code]
40
+ end
41
+
42
+ def humanized_status
43
+ HUMANIZED_STATUS[status_code]
44
+ end
45
+
46
+ STATUS.each do |code, method|
47
+ define_method("#{method}?") do
48
+ status_code == code
49
+ end
50
+ end
51
+
52
+ def self.status_code(needle)
53
+ needle = needle.to_sym
54
+ STATUS.each do |status_code, status|
55
+ return status_code if needle == status
56
+ end; nil
57
+ end
58
+ end
59
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oja
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Manfred Stienstra
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-08-28 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: " Oja is a Ruby client for verification of Apple Store Receipts.\n"
22
+ email: manfred@fngtps.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - LICENSE
29
+ files:
30
+ - lib/oja/mock.rb
31
+ - lib/oja/receipt.rb
32
+ - lib/oja/request.rb
33
+ - lib/oja/response.rb
34
+ - lib/oja.rb
35
+ - LICENSE
36
+ - README.md
37
+ homepage:
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options:
42
+ - --charset=utf-8
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ hash: 3
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.8.24
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: iOS and Mac application receive Receipts when handling purchases from the App Store. Before authorizing access to in-app content, these applications need to verify the receipt with Apple. Oja helps you check the Receipt's status.
70
+ test_files: []
71
+