costan-imobile 0.0.5 → 0.0.6
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/CHANGELOG +2 -0
- data/imobile.gemspec +1 -1
- data/lib/imobile/push_notification.rb +58 -6
- data/test/crypto_app_fprint_test.rb +2 -0
- data/test/push_notification_test.rb +9 -0
- data/test/validate_receipt_test.rb +2 -0
- metadata +1 -1
data/CHANGELOG
CHANGED
data/imobile.gemspec
CHANGED
@@ -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
|
-
|
160
|
+
return :sandbox
|
107
161
|
when /Apple Production Push/
|
108
|
-
|
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')
|