crusade-apns 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +9 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +29 -0
  7. data/Rakefile +8 -0
  8. data/crusade-apns.gemspec +28 -0
  9. data/lib/crusade/apns.rb +3 -0
  10. data/lib/crusade/apns/configuration.rb +52 -0
  11. data/lib/crusade/apns/crypto/user_token_generator.rb +23 -0
  12. data/lib/crusade/apns/push_package/directory_structure_generator.rb +38 -0
  13. data/lib/crusade/apns/push_package/manifest_generator.rb +42 -0
  14. data/lib/crusade/apns/push_package/signature_generator.rb +45 -0
  15. data/lib/crusade/apns/push_package/website_file_generator.rb +37 -0
  16. data/lib/crusade/apns/push_package/zip_file_generator.rb +31 -0
  17. data/lib/crusade/apns/push_package_generator.rb +50 -0
  18. data/lib/crusade/apns/version.rb +5 -0
  19. data/signature +0 -0
  20. data/test/fixtures/config.yml +23 -0
  21. data/test/fixtures/icons/icon_128x128.png +0 -0
  22. data/test/fixtures/icons/icon_128x128@2x.png +0 -0
  23. data/test/fixtures/icons/icon_16x16.png +0 -0
  24. data/test/fixtures/icons/icon_16x16@2x.png +0 -0
  25. data/test/fixtures/icons/icon_32x32.png +0 -0
  26. data/test/fixtures/icons/icon_32x32@2x.png +0 -0
  27. data/test/fixtures/ssl/ca.crt +33 -0
  28. data/test/fixtures/ssl/ca.key +51 -0
  29. data/test/fixtures/ssl/certificate.p12 +0 -0
  30. data/test/fixtures/ssl/hash +1 -0
  31. data/test/fixtures/ssl/ia.crt +29 -0
  32. data/test/fixtures/ssl/ia.csr +27 -0
  33. data/test/fixtures/ssl/ia.key +51 -0
  34. data/test/fixtures/ssl/manifest_example.json +4 -0
  35. data/test/fixtures/ssl/signature +0 -0
  36. data/test/fixtures/ssl/signature_example +0 -0
  37. data/test/integration/push_package_generator_test.rb +40 -0
  38. data/test/integration/user_token_generator_test.rb +19 -0
  39. data/test/support/fixtures.rb +18 -0
  40. data/test/support/ssl_support.rb +19 -0
  41. data/test/support/zip_support.rb +13 -0
  42. data/test/test_helper.rb +9 -0
  43. data/test/unit/configuration_test.rb +155 -0
  44. data/test/unit/push_package/directory_structure_generator_test.rb +39 -0
  45. data/test/unit/push_package/manifest_generator_test.rb +37 -0
  46. data/test/unit/push_package/signature_generator_test.rb +41 -0
  47. data/test/unit/push_package/website_file_generator_test.rb +41 -0
  48. data/test/unit/push_package/zip_file_generator_test.rb +51 -0
  49. data/test/unit/push_package_generator_test.rb +6 -0
  50. metadata +206 -0
@@ -0,0 +1,5 @@
1
+ module Crusade
2
+ module APNS
3
+ VERSION = "0.5.0"
4
+ end
5
+ end
data/signature ADDED
File without changes
@@ -0,0 +1,23 @@
1
+ default: &default
2
+ site_name: Apns config fixture
3
+ push_id: web.com.example.push.id
4
+ iconset_dir: lib/icon.iconset
5
+ certificate: config/certificate.p12
6
+ certificate_password: test
7
+
8
+ development:
9
+ <<: *default
10
+ url_format: http://www.example.com/push/%@
11
+ webservice_url: https://www.example.com/push
12
+ allowed_domains:
13
+ - http://www.example.com
14
+ - https://www.example.com
15
+
16
+ test:
17
+ <<: *default
18
+ url_format: http://localhost/push/%@
19
+ webservice_url: https://localhost/push
20
+ allowed_domains:
21
+ - http://localhost
22
+ - https://localhost
23
+ certificate_password:
Binary file
Binary file
@@ -0,0 +1,33 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ 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
33
+ -----END CERTIFICATE-----
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
Binary file
@@ -0,0 +1 @@
1
+ SHA256(manifest_example)= 52d019e5076f5104de79ab880bb0c82da5dea4f3822b16f6139950fa9613dd29
@@ -0,0 +1,29 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIFAjCCAuoCAQEwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVUsxEzARBgNV
3
+ BAgTClNvbWUtU3RhdGUxDzANBgNVBAcTBkxvbmRvbjEUMBIGA1UEChMLZHJvdWNo
4
+ eSBsdGQwHhcNMTMwOTEyMTcwMzQ4WhcNMTUwOTEyMTcwMzQ4WjBFMQswCQYDVQQG
5
+ EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk
6
+ Z2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA/a6Z
7
+ YxG6VqT5O91a6C48O1B2Hpqfu6u3EqFs6gLjqyNGw2StjidzskkQGXlGkyl8ugCm
8
+ 8u52IHpkHBrf/XoAiS7/LG3arIvHN1xlsSJ7Q8CgPU/H2OQdbLSqR19RGFzkzlzP
9
+ cPIGwCrYmtiYh8bJ5L929twL5y4hoBWhSRmnOBm9HWmjls+awMDDhQI0ska7YQFJ
10
+ 7/KAjfch36r8yUcULuoAcw6Oi4z/4tV0XZLqFE+kgKTXvI9/DBxCZO2/6ztX9A75
11
+ t9e78FpvYw7s6xTj1Z3pLJ5Tk2FcuDJuN4iGKS4y3b8oBHMOoT34f95FtFUp3rpt
12
+ wgQOzGQwY3jfYDkE16YJ5UDgqysgcbtLluPBjL1rX9+uNMB0Qd20n/FXDdoYTvat
13
+ TWHYY8CP8+09iaRpy6DzpmRTF3VtTAzL6QxqwQ4bQQsUbJHnfxu/faltSafCx/KP
14
+ 3WUCeHQASj39SckFse6PbS2ys6pdbjzD9zrIdw0G574jg1wJIjoWjMlaTseL43yg
15
+ odjlZZXIWruiviQ5RzGdhNndXwsun26Q5KL+j7DxJQ7vIy68XZU7UotjMX98nwLk
16
+ cgh/o9fIPM5rZ3wjfHQ0ftMNSC2Xn0+qq5y1LtcdYy+cam1uEw0sYdlK8M56DUGP
17
+ bC3ih21HEVHMXApfWGQRug9pRkOjleqk5tifpJECAwEAATANBgkqhkiG9w0BAQUF
18
+ AAOCAgEAeRl1frI7rmXOf2wxarRslLhsEjycLwUH4LBsdVSJ242S1ks3YecG9Fet
19
+ y1Ey+plfppUCI83s/qYQTMrGMQCiKkxdeZeyY7+ckt7eemJMOszj95HEIDDtG7LK
20
+ o9f6K7Fw+VOP5M4XQqE/g3mFKHpcw2InR6DBIpS4vWA8FLSPrn3w63bLbUebmXYf
21
+ 55jeDKJcQEh8QI7OEl0vJNWPXGOC8CDyg4J23KtHu6KahN/p/RkXcK8JLZoxuB0u
22
+ tbZCFXXfTUvusTylFX+MZfbhdoVgQNJldxWpK/Pjvd6hQntCWlC0diiVUk0HEmDd
23
+ MpgW2Tu0CbPU8Vxd05yw/dnT9yh911fCALtypPVg06pzt3Ts1Pgq/if5i6e6/4Pd
24
+ HWKbobg8YpougHeYB5u7/m+EL0PdlIkPBR4PtYsqqZ0KsBmvc1WWUsMR9SilwpDZ
25
+ qIYqY5uwhIWVTF4yQsDtKkT+xbsM/kTk0TLEzY794b35zDzlK2iAbzj+4MGKibyK
26
+ ZKzYhnagbiyxen0wbCBAwmX3ap9nz98BxE4gnWVbE8TiUIxuKUaaawc6ggZq70zh
27
+ 70TYjYeGTvA74B3siyQJED4I6opm7yuAcehbjYLuwYdrIERnWQ0IHB6QKAsT/Zl9
28
+ P05NbYwj0xa0e8GWj8dNbdRc5ljpfVnTvIeaeyue61c1caO2eRA=
29
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN CERTIFICATE REQUEST-----
2
+ MIIEijCCAnICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx
3
+ ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCAiIwDQYJKoZIhvcN
4
+ AQEBBQADggIPADCCAgoCggIBAP2umWMRulak+TvdWuguPDtQdh6an7urtxKhbOoC
5
+ 46sjRsNkrY4nc7JJEBl5RpMpfLoApvLudiB6ZBwa3/16AIku/yxt2qyLxzdcZbEi
6
+ e0PAoD1Px9jkHWy0qkdfURhc5M5cz3DyBsAq2JrYmIfGyeS/dvbcC+cuIaAVoUkZ
7
+ pzgZvR1po5bPmsDAw4UCNLJGu2EBSe/ygI33Id+q/MlHFC7qAHMOjouM/+LVdF2S
8
+ 6hRPpICk17yPfwwcQmTtv+s7V/QO+bfXu/Bab2MO7OsU49Wd6SyeU5NhXLgybjeI
9
+ hikuMt2/KARzDqE9+H/eRbRVKd66bcIEDsxkMGN432A5BNemCeVA4KsrIHG7S5bj
10
+ wYy9a1/frjTAdEHdtJ/xVw3aGE72rU1h2GPAj/PtPYmkacug86ZkUxd1bUwMy+kM
11
+ asEOG0ELFGyR538bv32pbUmnwsfyj91lAnh0AEo9/UnJBbHuj20tsrOqXW48w/c6
12
+ yHcNBue+I4NcCSI6FozJWk7Hi+N8oKHY5WWVyFq7or4kOUcxnYTZ3V8LLp9ukOSi
13
+ /o+w8SUO7yMuvF2VO1KLYzF/fJ8C5HIIf6PXyDzOa2d8I3x0NH7TDUgtl59Pqquc
14
+ tS7XHWMvnGptbhMNLGHZSvDOeg1Bj2wt4odtRxFRzFwKX1hkEboPaUZDo5XqpObY
15
+ n6SRAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAgEAUcknKPWbeKeeWJHht17x7dNc
16
+ POyAAADbKBIEnqQZ3gLdqcrQ3IFi/alr3M0v8g0SrPc4Jcwyf+tNzOsCiuHWIFSr
17
+ EGqoZtvdgRqmZ2ZmBEKGKAS1QSLc3rtbbNDRqIk5Oaoza2GRFqsy/tGg20ZCeLbZ
18
+ PV7tkR0WKs7D8Q9Q4Bgyo6IqMbVWb79FOKvhftg3NGO99MjtggDIHmCH3kNIkQNG
19
+ frU1ARtQwYYcXYNYoZa33G3A42lwPJkJlwpcQggf19rze9GElM2JYRCVDjb8nHRl
20
+ yR9QfwyGYu0Q9vT+BKkH5iGxt0u6r43lGMxUpukFUToLPv9YurQvJXoMpgxgCqS/
21
+ lBB08gdo3mqgiYMLwUyq1vgJgYt9PvA0sSr+oV8htfFMpk05pu23MRcL+geulvg3
22
+ ku9OngRsEmWp9kDK8Q99M1w9oAWazJ1AUyhYehhHbku0mQ8PxJeeyBfX+n23mdMn
23
+ j0GETUKg+KRzEF1TqdUyLC8Qbl6nJP/gLHoW+tinLU+EKWSoIqYcUJ3M4as3Abkk
24
+ mcrYyYA2DxOG+ns8KtPi9iQJplag9a7ApeEMbq+Sr4fWlehCVQrBwQvTr4okaqkC
25
+ 8chNScu5IvzHkZZSzC10lhEd0Yxiaf91ItRbgijWs1WSOo3o4agvG0PDJgldKiW2
26
+ 6VcPT7y+C0C9HaOa2rg=
27
+ -----END CERTIFICATE REQUEST-----
@@ -0,0 +1,51 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ 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
51
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,4 @@
1
+ {
2
+ "website.json": "96838c40594f632cc25d7760fa404c728886b3a8",
3
+ "icon.iconset/icon_16x16.png": "865f103703cbb85e1867793e1c798d96a63417e1"
4
+ }
File without changes
Binary file
@@ -0,0 +1,40 @@
1
+ require File.expand_path '../../test_helper.rb', __FILE__
2
+
3
+ require 'crusade/apns/push_package_generator'
4
+
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require 'zip_support'
8
+
9
+ describe Crusade::APNS::PushPackageGenerator do
10
+ let(:options) { Fixtures.default_configuration }
11
+ subject { Crusade::APNS::PushPackageGenerator.new options }
12
+
13
+ describe 'generate' do
14
+ let(:user_id) { '1234' }
15
+
16
+ let(:generated) { subject.generate user_id }
17
+ let(:push_package) { generated[1] }
18
+ let(:user_token) { generated[0] }
19
+
20
+ let(:tmp_dir) { Dir.mktmpdir }
21
+
22
+ after do
23
+ FileUtils.remove_entry_secure push_package
24
+ FileUtils.remove_entry_secure tmp_dir
25
+ end
26
+
27
+ it 'generates the push packages' do
28
+ File.exists?(push_package).must_be_truthy
29
+
30
+ files = ZipSupport.file_names(push_package)
31
+
32
+ icons = %w(16x16 16x16@2x 32x32 32x32@2x 128x128 128x128@2x).map do |size|
33
+ "icon.iconset/icon_#{size}.png"
34
+ end
35
+
36
+ files.must_equal_contents %w(manifest.json website.json signature icon.iconset/) + icons
37
+ user_token.wont_be_nil
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path '../../test_helper.rb', __FILE__
2
+
3
+ require 'crusade/apns/crypto/user_token_generator'
4
+
5
+ describe Crusade::APNS::UserTokenGenerator do
6
+ subject { Crusade::APNS::UserTokenGenerator.new(146) }
7
+
8
+ it 'always generate a different token even for the same user' do
9
+ tokens = (0...1000).map { subject.generate }
10
+
11
+ tokens.uniq.length.must_equal 1000
12
+ end
13
+
14
+ it 'generate token of at least 16 characters' do
15
+ greater = subject.generate.length >= 16
16
+
17
+ greater.must_be_truthy
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require 'tmpdir'
2
+
3
+ class Fixtures
4
+ def self.default_configuration
5
+ OpenStruct.new({
6
+ site_name: 'Bay Airlines',
7
+ push_id: 'web.com.example.domain',
8
+ url_format: 'http://domain.example.com/%@/?flight=%@',
9
+ webservice_url: 'https://example.com/push',
10
+ allowed_domains: ['http://example.com'],
11
+ temp_dir: Dir.mktmpdir,
12
+ iconset_dir: 'test/fixtures/icons',
13
+
14
+ certificate: 'test/fixtures/ssl/certificate.p12',
15
+ certificate_password: 'test'
16
+ })
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ require 'openssl'
2
+
3
+ module SslSupport
4
+ module_function
5
+
6
+ def certificate(certificate_file, certificate_password)
7
+ OpenSSL::PKCS12.new(File.read(certificate_file), certificate_password)
8
+ end
9
+
10
+ def verify_signature(certificate, file, signature)
11
+ signed = OpenSSL::PKCS7.new(File.read(signature))
12
+
13
+ p7 = OpenSSL::PKCS7.new(signed.to_der)
14
+ p7.verify([certificate.certificate],
15
+ OpenSSL::X509::Store.new,
16
+ File.read(file),
17
+ OpenSSL::PKCS7::DETACHED | OpenSSL::PKCS7::NOVERIFY)
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ require 'zip'
2
+
3
+ module ZipSupport
4
+ module_function
5
+
6
+ def entries(zip_file)
7
+ Zip::File.open(zip_file) {|zipfile| zipfile }
8
+ end
9
+
10
+ def file_names(zip_file)
11
+ entries(zip_file).map(&:to_s)
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/spec'
3
+ require 'minitest/mock'
4
+ require 'minitest/great_expectations'
5
+
6
+ $:.unshift 'test/support'
7
+
8
+ require 'ostruct'
9
+ require 'fixtures'
@@ -0,0 +1,155 @@
1
+ require File.expand_path '../../test_helper.rb', __FILE__
2
+
3
+ require 'crusade/apns/configuration'
4
+
5
+ describe Crusade::APNS::Configuration do
6
+ let(:described_class) { Crusade::APNS::Configuration }
7
+
8
+ describe 'initialize' do
9
+ let(:attributes) do
10
+ {
11
+ site_name: 'the website',
12
+ push_id: 'web.example.com',
13
+ url_format: 'http://example.com/%@',
14
+ webservice_url: 'https://www.example.com/push',
15
+ allowed_domains: ['http://acme.com'],
16
+ iconset_dir: '/config/icons'
17
+ }
18
+ end
19
+
20
+ subject { described_class.new attributes }
21
+
22
+ describe 'minimum attributes' do
23
+ it 'has a default certificate' do
24
+ subject.certificate.must_equal 'config/push_certificate.p12'
25
+ end
26
+
27
+ it 'has no certificate password' do
28
+ subject.certificate_password.must_be_nil
29
+ end
30
+
31
+ it 'sets the certificate' do
32
+ subject = described_class.new attributes.merge(certificate: '/cert.p12')
33
+
34
+ subject.certificate.must_equal '/cert.p12'
35
+ end
36
+
37
+ it 'sets the certificate password' do
38
+ subject = described_class.new attributes.merge(certificate_password: 'pass')
39
+
40
+ subject.certificate_password.must_equal 'pass'
41
+ end
42
+
43
+ it 'sets the site_name' do
44
+ subject.site_name.must_equal 'the website'
45
+ end
46
+
47
+ it 'sets the push_id' do
48
+ subject.push_id.must_equal 'web.example.com'
49
+ end
50
+
51
+ it 'sets the url_format' do
52
+ subject.url_format.must_equal 'http://example.com/%@'
53
+ end
54
+
55
+ it 'sets the webservice_url' do
56
+ subject.webservice_url.must_equal 'https://www.example.com/push'
57
+ end
58
+
59
+ it 'sets the allowed domains' do
60
+ subject.allowed_domains.must_equal ['http://acme.com']
61
+ end
62
+
63
+ it 'sets the iconset_sir' do
64
+ subject.iconset_dir.must_equal '/config/icons'
65
+ end
66
+ end
67
+
68
+ describe 'iconset_files' do
69
+ let(:iconset_files) { subject.iconset_files }
70
+
71
+ it 'returns the 16x16 icons' do
72
+ iconset_files.include?('/config/icons/icon_16x16.png').must_be_truthy
73
+ end
74
+
75
+ it 'returns the 16x1?6@2x icons' do
76
+ iconset_files.include?('/config/icons/icon_16x16@2x.png').must_be_truthy
77
+ end
78
+
79
+ it 'returns the 32x32 icons' do
80
+ iconset_files.include?('/config/icons/icon_32x32.png').must_be_truthy
81
+ end
82
+
83
+ it 'returns the 2x3?2@2x icons' do
84
+ iconset_files.include?('/config/icons/icon_32x32@2x.png').must_be_truthy
85
+ end
86
+
87
+ it 'returns the 128x128 icons' do
88
+ iconset_files.include?('/config/icons/icon_128x128.png').must_be_truthy
89
+ end
90
+
91
+ it 'returns the 128x12?8@2x icons' do
92
+ iconset_files.include?('/config/icons/icon_128x128@2x.png').must_be_truthy
93
+ end
94
+ end
95
+
96
+ describe 'tmp_dir' do
97
+ it 'returns a temp directory' do
98
+ Dir.stub(:mktmpdir, '/tmp/t') do
99
+ subject.temp_dir.must_equal '/tmp/t'
100
+ end
101
+ end
102
+ end
103
+
104
+ describe 'load' do
105
+ let(:config_file) { 'test/fixtures/config.yml' }
106
+ let(:env) { 'test' }
107
+
108
+ subject { described_class.load config_file, env }
109
+
110
+ it 'loads the site_name' do
111
+ subject.site_name.must_equal 'Apns config fixture'
112
+ end
113
+
114
+ it 'loads the push_id' do
115
+ subject.push_id.must_equal 'web.com.example.push.id'
116
+ end
117
+
118
+ it 'loads the iconset_dir' do
119
+ subject.iconset_dir.must_equal 'lib/icon.iconset'
120
+ end
121
+
122
+ it 'loads the certificate' do
123
+ subject.certificate.must_equal 'config/certificate.p12'
124
+ end
125
+
126
+ it 'loads the certificate_password' do
127
+ subject.certificate_password.must_be_nil
128
+ end
129
+
130
+ it 'loads the url_format' do
131
+ subject.url_format.must_equal 'http://localhost/push/%@'
132
+ end
133
+
134
+ it 'loads the webservice_url' do
135
+ subject.webservice_url.must_equal 'https://localhost/push'
136
+ end
137
+
138
+ it 'loads the allowed_domains' do
139
+ subject.allowed_domains.must_equal ['http://localhost', 'https://localhost']
140
+ end
141
+
142
+ describe 'load development if no env is provided' do
143
+ subject { described_class.load config_file }
144
+
145
+ it 'loads the certificate_password' do
146
+ subject.certificate_password.must_equal 'test'
147
+ end
148
+
149
+ it 'loads the url_format' do
150
+ subject.url_format.must_equal 'http://www.example.com/push/%@'
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end