crusade-apns 0.5.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.
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