imobile 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v0.0.6. New push certificates read method for Ruby 1.8.6 on Heroku.
2
+
1
3
  v0.0.5. Renamed device_token to push_token throughout the API.
2
4
 
3
5
  v0.0.4. Updated CryptoSupport with the push token device attribute.
data/imobile.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{imobile}
5
- s.version = "0.0.5"
5
+ s.version = "0.0.6"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Victor Costan"]
@@ -96,21 +96,73 @@ module PushNotifications
96
96
  end
97
97
 
98
98
  # Decodes an APNs certificate.
99
- def self.decode_push_certificate(certificate_blob)
99
+ def self.decode_push_certificate(certificate_blob)
100
+ if use_new_certificate_decoder?
101
+ # Ruby 1.8.7 and above.
102
+ data = decode_push_certificate_new certificate_blob
103
+ else
104
+ # Ruby 1.8.6.
105
+ data = decode_push_certificate_heroku certificate_blob
106
+ end
107
+ data[:server_type] = server_type data[:certificate]
108
+ data
109
+ end
110
+
111
+ # Checks whether the new certificate decoding code is supported.
112
+ def self.use_new_certificate_decoder?
113
+ OpenSSL::PKCS12.respond_to? :new
114
+ end
115
+
116
+ # Decodes an APNs certificate, using the new (1.8.7+) OpenSSL methods.
117
+ def self.decode_push_certificate_new(certificate_blob)
100
118
  pkcs12 = OpenSSL::PKCS12.new certificate_blob
101
119
 
102
120
  certificate = pkcs12.certificate
103
121
  key = pkcs12.key
122
+
123
+ { :certificate => certificate, :key => key }
124
+ end
125
+
126
+ # Decodes an APNs certificate, using the openssl command-line tool.
127
+ #
128
+ # This works on Heroku, which uses Ruby 1.8.6.
129
+ def self.decode_push_certificate_heroku(certificate_blob)
130
+ # Most of the filesystem on Heroku is read-only. On the other hand, not
131
+ # everyone runs on Heroku. Find a reasonable temporary dir.
132
+ if defined? RAILS_ROOT
133
+ temp_dir = File.join RAILS_ROOT, 'tmp'
134
+ elsif File.exists? '/tmp'
135
+ temp_dir = '/tmp'
136
+ else
137
+ temp_dir = '.'
138
+ end
139
+
140
+ pkcs12_file_name = File.join temp_dir, "apns_#{Process.pid}.p12"
141
+ pem_file_name = File.join temp_dir, "apns_#{Process.pid}.pem"
142
+ out_file_name = File.join temp_dir, "apns_#{Process.pid}.err"
143
+
144
+ # Use the command-line openssl tool to break up the pkcs12 file.
145
+ File.open(pkcs12_file_name, 'wb') { |f| f.write certificate_blob }
146
+ Kernel.system "openssl pkcs12 -in #{pkcs12_file_name} -clcerts -nodes " +
147
+ "-out #{pem_file_name} -password pass: 2> #{out_file_name}"
148
+ pem_blob = File.read pem_file_name
149
+ [pkcs12_file_name, pem_file_name, out_file_name].each { |f| File.delete f }
150
+
151
+ certificate = OpenSSL::X509::Certificate.new pem_blob
152
+ key = OpenSSL::PKey::RSA.new pem_blob
153
+ { :certificate => certificate, :key => key }
154
+ end
155
+
156
+ # The Apple Push Notification server type that a certificate works with.
157
+ def self.server_type(certificate)
104
158
  case certificate.subject.to_s
105
159
  when /Apple Development Push/
106
- server_type = :sandbox
160
+ return :sandbox
107
161
  when /Apple Production Push/
108
- server_type = :production
162
+ return :production
109
163
  else
110
164
  raise "Invalid push certificate - #{certificate.inspect}"
111
- end
112
-
113
- { :certificate => certificate, :key => key, :server_type => server_type }
165
+ end
114
166
  end
115
167
 
116
168
  # Encodes a push notification in a binary string for APNs consumption.
@@ -13,6 +13,8 @@ require 'flexmock/test_unit'
13
13
 
14
14
  class CryptoAppFprintTest < Test::Unit::TestCase
15
15
  def setup
16
+ super
17
+
16
18
  testdata_path = File.join(File.dirname(__FILE__), '..', 'testdata')
17
19
  @device_attrs = File.open(File.join(testdata_path,
18
20
  'device_attributes.yml')) do |f|
@@ -13,6 +13,8 @@ require 'flexmock/test_unit'
13
13
 
14
14
  class PushNotificationTest < Test::Unit::TestCase
15
15
  def setup
16
+ super
17
+
16
18
  testdata_path = File.join(File.dirname(__FILE__), '..', 'testdata')
17
19
  @dev_cert_path = File.join(testdata_path, 'apns_developer.p12')
18
20
  @prod_cert_path = File.join(testdata_path, 'apns_production.p12')
@@ -46,6 +48,13 @@ class PushNotificationTest < Test::Unit::TestCase
46
48
  "Wrong data in prod certificate #{cert_data[:certificate].inspect}")
47
49
  end
48
50
 
51
+ def test_read_push_certificate_on_heroku
52
+ flexmock(Imobile::PushNotifications).
53
+ should_receive(:use_new_certificate_decoder?).and_return(false)
54
+
55
+ test_read_push_certificate
56
+ end
57
+
49
58
  def test_pack_push_token
50
59
  assert_equal @dev_token, Imobile.pack_hex_push_token(@hex_dev_token)
51
60
  end
@@ -10,6 +10,8 @@ require 'test/unit'
10
10
 
11
11
  class ValidateReceiptTest < Test::Unit::TestCase
12
12
  def setup
13
+ super
14
+
13
15
  testdata_path = File.join(File.dirname(__FILE__), '..', 'testdata')
14
16
  @forged_sandbox_blob = File.read File.join(testdata_path,
15
17
  'forged_sandbox_receipt')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: imobile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Costan