itunes_receipt_decoder 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de043b4c77b3fbaac346b799f365f057b321c3fb
4
- data.tar.gz: 1d15e3c79f6d797db3ff2fdf3b1c95d1599b5e67
3
+ metadata.gz: 15142fd0c14f72948823cfb09e134b9e85bc835a
4
+ data.tar.gz: 9cf2d1412ca0c789d8fe7193aacee887c2cb0272
5
5
  SHA512:
6
- metadata.gz: 5acfe178ab3c36e0697ed3cf466551c94eb726413ccc2806cd7b40ec3177a9b394895eb0f4850051f3735c7a419d83338a082f16f3ca4aaeedc778f10bb87456
7
- data.tar.gz: 8a534a10ce32f203b7c450b02c7d60747880632abebc2765d064bc0fe85014c1a243dde361b9e74c497fc4aff2ec3718e472286050895c35798b54fcef668eca
6
+ metadata.gz: a25dadcf77df2605adf9c2c403df7a214c425ad2f4623fc7aeef96bb11689fb542e40d96c30b82a73c47cd1bc0afd4b236d680f1316971f5d9e1aef3703b78cb
7
+ data.tar.gz: f63a1df3a9733142c4caf9eec3685b7b5ee479f4414f66af3b152c53d9638368c57ae76679ace8873c87ca828286a2f4fc3a6b4bad5b25d18cfb7285f65a6d60
@@ -9,7 +9,7 @@ module ItunesReceiptDecoder
9
9
  class Base
10
10
  ##
11
11
  # The raw receipt, i.e. not base64 encoded
12
- attr_reader :raw_receipt, :options
12
+ attr_reader :raw_receipt, :receipt, :options, :style, :environment
13
13
 
14
14
  ##
15
15
  # Initializes with a raw (base64 decoded receipt)
@@ -20,12 +20,7 @@ module ItunesReceiptDecoder
20
20
  def initialize(raw_receipt, options = {})
21
21
  @raw_receipt = raw_receipt
22
22
  @options = options
23
- end
24
-
25
- ##
26
- # Returns the receipt receipt properties
27
- def receipt
28
- decode && @receipt
23
+ decode
29
24
  end
30
25
 
31
26
  ##
@@ -7,35 +7,37 @@ module ItunesReceiptDecoder
7
7
  ##
8
8
  # ItunesReceiptDecoder::Decode::TransactionReceipt
9
9
  class TransactionReceipt < Base
10
- ##
11
- # Decodes the receipt
12
- def decode
13
- @receipt ||= purchase_info
14
- self
10
+ def initialize(raw_receipt, options = {})
11
+ @style = :transaction
12
+ super
15
13
  end
16
14
 
17
- ##
18
- # Just returns :transaction
19
- def style
20
- :transaction
21
- end
15
+ private
22
16
 
23
- ##
24
- # Gets the environment from the payload
25
- def environment
26
- payload['environment']
17
+ def decode
18
+ @receipt = parse_purchase_info
19
+ @environment = payload.fetch('environment')
20
+ rescue KeyError => e
21
+ raise DecodingError, e.message
27
22
  end
28
23
 
29
- private
30
-
31
- def purchase_info
32
- contents = Base64.strict_decode64(payload['purchase-info'])
33
- result = parse_plist(contents)
34
- result.keys.each do |key|
24
+ def parse_purchase_info
25
+ purchase_info.keys.each do |key|
35
26
  new_key = key.tr('-', '_').to_sym
36
- result[new_key] = result.delete(key)
27
+ purchase_info[new_key] = purchase_info.delete(key)
37
28
  end
38
- result
29
+ purchase_info
30
+ end
31
+
32
+ def purchase_info
33
+ return @purchase_info if @purchase_info
34
+ contents = Base64.strict_decode64 payload.fetch('purchase-info')
35
+ rescue KeyError => e
36
+ raise DecodingError, e.message
37
+ rescue ArgumentError => e
38
+ raise DecodingError, e.message
39
+ else
40
+ @purchase_info = parse_plist(contents)
39
41
  end
40
42
 
41
43
  def payload
@@ -44,7 +46,9 @@ module ItunesReceiptDecoder
44
46
 
45
47
  def parse_plist(contents)
46
48
  plist = CFPropertyList::List.new(data: contents)
47
- CFPropertyList.native_types(plist.value)
49
+ hash = CFPropertyList.native_types(plist.value)
50
+ fail DecodingError, 'hash not found in plist' unless hash.is_a?(Hash)
51
+ hash
48
52
  end
49
53
  end
50
54
  end
@@ -34,27 +34,18 @@ module ItunesReceiptDecoder
34
34
  original_purchase_date expires_date
35
35
  cancellation_date)
36
36
 
37
- ##
38
- # Decodes the receipt
39
- def decode
40
- @receipt ||= parse_app_receipt_fields(payload.value)
41
- self
37
+ def initialize(raw_receipt, options = {})
38
+ @style = :unified
39
+ super
42
40
  end
43
41
 
44
- ##
45
- # Just returns :unified
46
- def style
47
- :unified
48
- end
42
+ private
49
43
 
50
- ##
51
- # Gets the environment from the receipt
52
- def environment
53
- decode.receipt[:environment]
44
+ def decode
45
+ @receipt = parse_app_receipt_fields(payload.value)
46
+ @environment = @receipt.fetch(:environment, nil)
54
47
  end
55
48
 
56
- private
57
-
58
49
  def parse_app_receipt_fields(fields)
59
50
  result = {}
60
51
  fields.each do |seq|
@@ -93,14 +84,18 @@ module ItunesReceiptDecoder
93
84
 
94
85
  def payload
95
86
  verify && OpenSSL::ASN1.decode(pkcs7.data)
87
+ rescue OpenSSL::ASN1::ASN1Error => e
88
+ raise DecodingError, e.message
96
89
  end
97
90
 
98
91
  def verify
99
- pkcs7.verify(nil, Config.certificate_store, nil, nil)
92
+ pkcs7.verify [], OpenSSL::X509::Store.new, nil, OpenSSL::PKCS7::NOVERIFY
100
93
  end
101
94
 
102
95
  def pkcs7
103
96
  @pkcs7 ||= OpenSSL::PKCS7.new(raw_receipt)
97
+ rescue ArgumentError => e
98
+ raise DecodingError, e.message
104
99
  end
105
100
  end
106
101
  end
@@ -3,5 +3,5 @@
3
3
  module ItunesReceiptDecoder
4
4
  ##
5
5
  # Gem version
6
- VERSION = '0.1.1'
6
+ VERSION = '0.2.0'
7
7
  end
@@ -3,7 +3,6 @@ require 'base64'
3
3
  require 'openssl'
4
4
  require 'cfpropertylist'
5
5
  require 'itunes_receipt_decoder/version'
6
- require 'itunes_receipt_decoder/config'
7
6
  require 'itunes_receipt_decoder/decode/base'
8
7
  require 'itunes_receipt_decoder/decode/transaction_receipt'
9
8
  require 'itunes_receipt_decoder/decode/unified_receipt'
@@ -11,6 +10,8 @@ require 'itunes_receipt_decoder/decode/unified_receipt'
11
10
  ##
12
11
  # ItunesReceiptDecoder
13
12
  module ItunesReceiptDecoder
13
+ class DecodingError < StandardError; end
14
+
14
15
  ##
15
16
  # Initializes either ItunesReceiptDecoder::Decode::Transaction or
16
17
  # ItunesReceiptDecoder::Decode::Unified with the base64 encoded receipt
@@ -20,6 +21,9 @@ module ItunesReceiptDecoder
20
21
  # * +options+ - optional arguments
21
22
  def self.new(receipt_data, options = {})
22
23
  raw_receipt = Base64.strict_decode64(receipt_data)
24
+ rescue ArgumentError => e
25
+ raise DecodingError, e.message
26
+ else
23
27
  if /^\{*+\}$/ =~ raw_receipt
24
28
  Decode::TransactionReceipt.new(raw_receipt, options)
25
29
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itunes_receipt_decoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mbaasy.com
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-27 00:00:00.000000000 Z
11
+ date: 2015-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: CFPropertyList
@@ -67,47 +67,47 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0.2'
69
69
  - !ruby/object:Gem::Dependency
70
- name: codeclimate-test-reporter
70
+ name: simplecov
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0.4'
75
+ version: '0.10'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0.4'
82
+ version: '0.10'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rubocop
84
+ name: codeclimate-test-reporter
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.33'
89
+ version: '0.4'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0.33'
96
+ version: '0.4'
97
97
  - !ruby/object:Gem::Dependency
98
- name: awesome_print
98
+ name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '1.6'
103
+ version: '0.33'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '1.6'
110
+ version: '0.33'
111
111
  description: |2
112
112
  Decode iTunes OS X and iOS receipts without remote server-side validation
113
113
  by using the Apple Inc Root Certificate.
@@ -117,7 +117,6 @@ extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
119
  - lib/itunes_receipt_decoder.rb
120
- - lib/itunes_receipt_decoder/config.rb
121
120
  - lib/itunes_receipt_decoder/decode/base.rb
122
121
  - lib/itunes_receipt_decoder/decode/transaction_receipt.rb
123
122
  - lib/itunes_receipt_decoder/decode/unified_receipt.rb
@@ -1,29 +0,0 @@
1
- ##
2
- # ItunesReceiptDecoder
3
- module ItunesReceiptDecoder
4
- ##
5
- # ItunesReceiptDecoder::Config
6
- class Config
7
- class << self
8
- ##
9
- # Set this to the path of the AppleIncRootCertificate.cer file
10
- attr_accessor :certificate_path
11
- end
12
-
13
- ##
14
- # Returns the OpenSSL X509 Store for the certificate
15
- def self.certificate_store
16
- return @certificate_store if @certificate_store
17
- @certificate_store = OpenSSL::X509::Store.new
18
- @certificate_store.add_cert(certificate)
19
- end
20
-
21
- ##
22
- # returns the OpenSSL X509 Certificate
23
- def self.certificate
24
- @certificate ||= OpenSSL::X509::Certificate.new(
25
- File.read(certificate_path)
26
- )
27
- end
28
- end
29
- end