mobile-pass 0.0.1
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/LICENSE +201 -0
- data/README.md +90 -0
- data/app/controllers/passbook/logs_controller.rb +33 -0
- data/app/controllers/passbook/passes_controller.rb +34 -0
- data/app/controllers/passbook/registrations_controller.rb +169 -0
- data/app/models/passbook/registration.rb +24 -0
- data/config/routes.rb +36 -0
- data/lib/passbook/config.rb +74 -0
- data/lib/passbook/engine.rb +23 -0
- data/lib/passbook/pkpass.rb +111 -0
- data/lib/passbook-ruby.rb +45 -0
- data/lib/rails/generators/passbook/config/config_generator.rb +36 -0
- data/lib/rails/generators/passbook/config/templates/initializer.rb +35 -0
- data/lib/rails/generators/passbook/config/templates/migration.rb +31 -0
- data/lib/rails/generators/passbook/pkpass/pkpass_generator.rb +40 -0
- data/lib/rails/generators/passbook/pkpass/templates/icon.png +0 -0
- data/lib/rails/generators/passbook/pkpass/templates/icon@2x.png +0 -0
- data/lib/rails/generators/passbook/pkpass/templates/initializer.rb +27 -0
- data/lib/rails/generators/passbook/pkpass/templates/migration.rb +29 -0
- data/lib/rails/generators/passbook/pkpass/templates/model.rb +54 -0
- data/lib/rails/generators/passbook/pkpass/templates/pass.json +38 -0
- data/spec/config_spec.rb +45 -0
- data/spec/data/templates/pass.com.acme/pass.json +26 -0
- data/spec/pkpass_spec.rb +117 -0
- data/spec/spec_helper.rb +82 -0
- metadata +165 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
module Passbook
|
20
|
+
class Engine < Rails::Engine
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,111 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
require 'digest/sha1'
|
20
|
+
require 'json'
|
21
|
+
require 'openssl'
|
22
|
+
require 'zip/zip'
|
23
|
+
require 'zip/zipfilesystem'
|
24
|
+
|
25
|
+
module Passbook
|
26
|
+
class Pkpass
|
27
|
+
attr_accessor :files, :translations, :json, :pass_type_id, :serial_number, :config
|
28
|
+
|
29
|
+
def initialize(pass_type_id, serial_number)
|
30
|
+
self.pass_type_id = pass_type_id
|
31
|
+
self.serial_number = serial_number
|
32
|
+
self.translations = Hash.new
|
33
|
+
raise(ArgumentError, "Don't forget to run the generator to create the initializer") unless Config.instance.pass_config
|
34
|
+
self.config = Config.instance.pass_config[self.pass_type_id]
|
35
|
+
raise(ArgumentError, "Could not find configuration for #{self.pass_type_id}") unless self.config
|
36
|
+
|
37
|
+
if self.config.include? :files
|
38
|
+
self.files = self.config['files'].dup
|
39
|
+
else
|
40
|
+
self.files = Config.instance.load_files self.config['template_path']
|
41
|
+
end
|
42
|
+
|
43
|
+
if self.files.include? 'pass.json'
|
44
|
+
self.json = JSON.parse(self.files['pass.json'])
|
45
|
+
else
|
46
|
+
self.json = {}
|
47
|
+
puts "Warning: your template_path does not contain pass.json"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_file filename, content
|
52
|
+
self.files[filename] = content
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_translation_string source, destination, language
|
56
|
+
self.translations[language] = Hash.new unless self.translations.include?(language)
|
57
|
+
self.translations[language][source] = destination
|
58
|
+
end
|
59
|
+
|
60
|
+
def package
|
61
|
+
#TODO: write a library that checks that all the right files are included in the package
|
62
|
+
#those requirements are going to be different depending on pass_type_id
|
63
|
+
self.write_json
|
64
|
+
self.write_translation_strings
|
65
|
+
self.generate_json_manifest
|
66
|
+
self.sign_manifest
|
67
|
+
self.compress_pass_file
|
68
|
+
end
|
69
|
+
|
70
|
+
def write_json
|
71
|
+
self.files['pass.json'] = JSON.pretty_generate(self.json)
|
72
|
+
end
|
73
|
+
|
74
|
+
def write_translation_strings
|
75
|
+
self.translations.each do |language, trans|
|
76
|
+
self.files["#{language}.lproj/pass.strings"] ||= ""
|
77
|
+
trans.each do |key, value|
|
78
|
+
#TODO: escape key and value
|
79
|
+
self.files["#{language}.lproj/pass.strings"] << "\n\"#{key}\" = \"#{value}\";"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def generate_json_manifest
|
85
|
+
manifest = {}
|
86
|
+
self.files.each do |filename, content|
|
87
|
+
manifest[filename] = Digest::SHA1.hexdigest(content)
|
88
|
+
end
|
89
|
+
self.files['manifest.json'] = JSON.pretty_generate(manifest)
|
90
|
+
end
|
91
|
+
|
92
|
+
def sign_manifest
|
93
|
+
flag = OpenSSL::PKCS7::BINARY|OpenSSL::PKCS7::DETACHED
|
94
|
+
signed = OpenSSL::PKCS7::sign(config['p12_certificate'].certificate, config['p12_certificate'].key, self.files['manifest.json'], [Config.instance.wwdr_certificate], flag)
|
95
|
+
self.files['signature'] = signed.to_der.force_encoding('UTF-8')
|
96
|
+
end
|
97
|
+
|
98
|
+
def compress_pass_file
|
99
|
+
stringio = Zip::ZipOutputStream::write_buffer do |z|
|
100
|
+
self.files.each do |filename, content|
|
101
|
+
z.put_next_entry filename
|
102
|
+
z.print content
|
103
|
+
end
|
104
|
+
end
|
105
|
+
stringio.set_encoding "binary"
|
106
|
+
stringio.rewind
|
107
|
+
stringio
|
108
|
+
# stringio.sysread
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
require "passbook/config"
|
20
|
+
require "passbook/pkpass"
|
21
|
+
require "passbook/engine"
|
22
|
+
|
23
|
+
require "action_controller"
|
24
|
+
Mime::Type.register 'application/vnd.apple.pkpass', :pkpass
|
25
|
+
|
26
|
+
ActionController::Renderers.add :pkpass do |obj, options|
|
27
|
+
pkpass = Passbook::Pkpass.new Passbook.class_name_to_pass_type_id(obj.class.to_s), obj.serial_number
|
28
|
+
obj.update_pass pkpass if obj.respond_to? :update_pass
|
29
|
+
pkpass_io = pkpass.package
|
30
|
+
response.headers["last-modified"] = obj.updated_at.strftime("%Y-%m-%d %H:%M:%S")
|
31
|
+
send_data(pkpass_io.sysread, :type => 'application/vnd.apple.pkpass', :disposition=>'inline', :filename=>"#{obj.serial_number}.pkpass")
|
32
|
+
end
|
33
|
+
|
34
|
+
module Passbook
|
35
|
+
def self.pass_type_id_to_class pass_type_id
|
36
|
+
Passbook::Config.instance.pass_config[pass_type_id]['class'].constantize
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.class_name_to_pass_type_id class_name
|
40
|
+
Passbook::Config.instance.pass_config.each do |pass_type_id, config|
|
41
|
+
return pass_type_id if config['class']==class_name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
require 'fileutils'
|
20
|
+
|
21
|
+
module Passbook
|
22
|
+
module Generators
|
23
|
+
class ConfigGenerator < Rails::Generators::Base
|
24
|
+
source_root File.expand_path('../templates', __FILE__)
|
25
|
+
argument :wwdr_certificate_path, type: :string, optional: true, banner: "Absolute path to your WWDR certification file"
|
26
|
+
|
27
|
+
desc 'Create Passbook initializer'
|
28
|
+
def create_initializer_file
|
29
|
+
path = "#{Rails.root}/data/certificates"
|
30
|
+
FileUtils.mkdir_p path if wwdr_certificate_path.blank? && !File.exists?(path)
|
31
|
+
template 'initializer.rb', File.join('config', 'initializers', 'passbook.rb')
|
32
|
+
template 'migration.rb', File.join('db', 'migrate', "#{Time.now.strftime("%Y%m%d%H%M%S")}_create_passbook_registrations.rb")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
Passbook::Config.instance.configure do |passbook|
|
20
|
+
# Templates are preloaded in production and dynamically loaded in development by default
|
21
|
+
# You can control the behaviour by setting the 'preload_templates'
|
22
|
+
#
|
23
|
+
# passbook.preload_templates = true
|
24
|
+
|
25
|
+
|
26
|
+
# Enables the routes necessary for passes to be able to:
|
27
|
+
# 1) register with the server
|
28
|
+
# 2) log errors
|
29
|
+
# 3) list pkpasses to be updated
|
30
|
+
# 4) let passbook request for update
|
31
|
+
passbook.enable_routes = true
|
32
|
+
|
33
|
+
|
34
|
+
passbook.wwdr_intermediate_certificate_path= "<%= wwdr_certificate_path.blank? ? "#{Rails.root}/data/certificates/wwdr.pem":wwdr_certificate_path %>"
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
class CreatePassbookRegistrations < ActiveRecord::Migration
|
20
|
+
def change
|
21
|
+
create_table :passbook_registrations do |t|
|
22
|
+
t.string :uuid
|
23
|
+
t.string :device_id
|
24
|
+
t.string :push_token
|
25
|
+
t.string :serial_number
|
26
|
+
t.string :pass_type_id
|
27
|
+
|
28
|
+
t.timestamps
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
module Passbook
|
20
|
+
module Generators
|
21
|
+
class PkpassGenerator < Rails::Generators::NamedBase
|
22
|
+
source_root File.expand_path('../templates', __FILE__)
|
23
|
+
argument :pass_type_id, type: :string, default: 'pass.com.acme', optional: true, banner: "The Pass Type ID you registered at iOS Provisioning Portal"
|
24
|
+
argument :team_id, type: :string, optional: true, banner: "Team ID you got at the iOS Provisioning Portal when you registered the pass type id"
|
25
|
+
argument :cert_path, type: :string, optional: true, banner: "Absolute path to your pass.com.acme.p12 file"
|
26
|
+
argument :cert_password, type: :string, default: 'password', optional: true, banner: "Password for your P12 certificate"
|
27
|
+
|
28
|
+
desc 'Create and configure a model for a particular pkpass (ie. ticket)'
|
29
|
+
def create_initializer_file
|
30
|
+
template 'initializer.rb', File.join('config', 'initializers', "passbook_#{plural_name.singularize}.rb")
|
31
|
+
template 'model.rb', File.join('app', 'models', "#{plural_name.singularize}.rb")
|
32
|
+
route "get '/v1/passes/#{plural_name.singularize}' => 'Passbook::passes#get_pkpass', :defaults => { :pass_type_id => '#{pass_type_id}' }"
|
33
|
+
template 'migration.rb', File.join('db', 'migrate', "#{Time.now.strftime("%Y%m%d%H%M%S")}_create_#{plural_name}.rb")
|
34
|
+
template 'pass.json', File.join('data', 'templates', pass_type_id, "pass.json")
|
35
|
+
template 'icon.png', File.join('data', 'templates', pass_type_id, "icon.png")
|
36
|
+
template 'icon@2x.png', File.join('data', 'templates', pass_type_id, "icon@2x.png")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,27 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
Passbook::Config.instance.add_pkpass do |passbook|
|
20
|
+
passbook.pass_config["<%= pass_type_id %>"]={
|
21
|
+
"cert_path"=>"<%= cert_path.blank? ? "#{Rails.root}/data/certificates/#{pass_type_id}.p12" : cert_path %>",
|
22
|
+
"cert_password"=>"<%= cert_password %>",
|
23
|
+
"template_path"=>"<%= "#{Rails.root}/data/templates/#{pass_type_id}" %>",
|
24
|
+
"class"=>"<%= class_name %>"
|
25
|
+
}
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
class Create<%= class_name.pluralize %> < ActiveRecord::Migration
|
20
|
+
def change
|
21
|
+
create_table :<%= plural_name %> do |t|
|
22
|
+
t.string :serial_number
|
23
|
+
t.string :authentication_token
|
24
|
+
t.string :card_id
|
25
|
+
|
26
|
+
t.timestamps
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
class <%= class_name %> < ActiveRecord::Base
|
20
|
+
attr_protected :serial_number, :authentication_token
|
21
|
+
attr_accessible :card_id
|
22
|
+
before_create :set_pass_fields
|
23
|
+
|
24
|
+
def set_pass_fields
|
25
|
+
self.authentication_token = Base64.urlsafe_encode64(SecureRandom.base64(36))
|
26
|
+
self.serial_number||= Base64.urlsafe_encode64(SecureRandom.base64(36))
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.update_or_create params
|
30
|
+
<%= plural_name.singularize %>_pass = find_by_card_id params[:card_id]
|
31
|
+
<%= plural_name.singularize %>_pass ||=new
|
32
|
+
params.slice(*attr_accessible[:default].map(&:to_sym)).each do |attr, val|
|
33
|
+
<%= plural_name.singularize %>_pass.send :"#{attr}=", val
|
34
|
+
end
|
35
|
+
<%= plural_name.singularize %>_pass.save!
|
36
|
+
<%= plural_name.singularize %>_pass
|
37
|
+
end
|
38
|
+
|
39
|
+
def check_for_updates
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_pass pkpass
|
44
|
+
update_json pkpass.json
|
45
|
+
end
|
46
|
+
|
47
|
+
def update_json pass_json
|
48
|
+
pass_json['authenticationToken'] = authentication_token
|
49
|
+
pass_json['serialNumber'] = serial_number
|
50
|
+
#don't forget to change the URL to whatever address your server is at
|
51
|
+
pass_json['webServiceURL'] = "http://192.168.x.x:3000"
|
52
|
+
#add more customization to your passbook's JSON right here
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
{
|
2
|
+
"formatVersion" : 1,
|
3
|
+
"passTypeIdentifier" : "<%= pass_type_id %>",
|
4
|
+
"serialNumber" : "12345",
|
5
|
+
"teamIdentifier" : "<%= team_id %>",
|
6
|
+
"webServiceURL" : "http://192.168.91.151:3000",
|
7
|
+
"authenticationToken" : "",
|
8
|
+
"barcode" : {
|
9
|
+
"message" : "34534636",
|
10
|
+
"format" : "PKBarcodeFormatPDF417",
|
11
|
+
"messageEncoding" : "iso-8859-1"
|
12
|
+
},
|
13
|
+
"organizationName" : "ACME Inc.",
|
14
|
+
"description" : "",
|
15
|
+
"logoText" : "ACME",
|
16
|
+
"foregroundColor" : "rgb(22, 55, 110)",
|
17
|
+
"backgroundColor" : "rgb(50, 91, 185)",
|
18
|
+
"coupon" : {
|
19
|
+
"headerFields" : [
|
20
|
+
{
|
21
|
+
"label" : "TEST",
|
22
|
+
"key" : "test",
|
23
|
+
"value" : "#1",
|
24
|
+
"changeMessage" : "Test number changed to %@."
|
25
|
+
}
|
26
|
+
],
|
27
|
+
"primaryFields" : [
|
28
|
+
{
|
29
|
+
"key" : "passbook",
|
30
|
+
"label" : "",
|
31
|
+
"value" : "<%= class_name %>"
|
32
|
+
}
|
33
|
+
],
|
34
|
+
"secondaryFields" : [],
|
35
|
+
"auxiliaryFields" : [],
|
36
|
+
"backFields" : []
|
37
|
+
}
|
38
|
+
}
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
require 'spec_helper'
|
20
|
+
|
21
|
+
describe Passbook::Config do
|
22
|
+
# it "should throw ArgumentError because wwdr_intermediate_certificate_path is missing" do
|
23
|
+
# expect {Passbook::Config.instance.configure {}}.to raise_error(ArgumentError)
|
24
|
+
# end
|
25
|
+
|
26
|
+
it "should throw ArgumentError because cert_path is missing" do
|
27
|
+
expect{ Passbook::Config.instance.add_pkpass do |passbook|
|
28
|
+
passbook.wwdr_intermediate_certificate_path = "test"
|
29
|
+
passbook.wwdr_certificate = OpenSSL::X509::Certificate.new
|
30
|
+
passbook.pass_config["pass.com.acme"] = {"template_path"=>"tmp"}
|
31
|
+
end}.to raise_error(ArgumentError)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should throw ArgumentError because cert_password is missing" do
|
35
|
+
expect{ Passbook::Config.instance.add_pkpass do |passbook|
|
36
|
+
passbook.wwdr_intermediate_certificate_path = "test"
|
37
|
+
passbook.wwdr_certificate = OpenSSL::X509::Certificate.new
|
38
|
+
passbook.pass_config["pass.com.acme"] = {
|
39
|
+
"cert_path"=>"tmp"
|
40
|
+
}
|
41
|
+
end}.to raise_error(ArgumentError)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{
|
2
|
+
"formatVersion" : 1,
|
3
|
+
"passTypeIdentifier" : "pass.com.acme",
|
4
|
+
"serialNumber" : "werwer",
|
5
|
+
"teamIdentifier" : "sdfsdfsdf",
|
6
|
+
"webServiceURL" : "https://acme.com/passes/",
|
7
|
+
"authenticationToken" : "werwfdsfd",
|
8
|
+
"barcode" : {
|
9
|
+
"message" : "",
|
10
|
+
"format" : "PKBarcodeFormatPDF417",
|
11
|
+
"messageEncoding" : "iso-8859-1"
|
12
|
+
},
|
13
|
+
"organizationName" : "Acme",
|
14
|
+
"description" : "test",
|
15
|
+
"logoText" : "test",
|
16
|
+
"foregroundColor" : "rgb(0, 0, 0)",
|
17
|
+
"backgroundColor" : "rgb(0, 0, 0)",
|
18
|
+
"boardingPass" : {
|
19
|
+
"transitType" : "PKTransitTypeAir",
|
20
|
+
"headerFields" : [],
|
21
|
+
"primaryFields" : [],
|
22
|
+
"secondaryFields" : [],
|
23
|
+
"auxiliaryFields" : [],
|
24
|
+
"backFields" : []
|
25
|
+
}
|
26
|
+
}
|
data/spec/pkpass_spec.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
|
2
|
+
# Copyright 2012 Xtreme Labs
|
3
|
+
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
require 'spec_helper'
|
20
|
+
require 'json'
|
21
|
+
|
22
|
+
|
23
|
+
RSpec.configure do |c|
|
24
|
+
c.include Helpers
|
25
|
+
end
|
26
|
+
|
27
|
+
describe Passbook::Pkpass do
|
28
|
+
before :all do
|
29
|
+
Passbook::Config.instance.configure do |passbook|
|
30
|
+
passbook.wwdr_certificate = OpenSSL::X509::Certificate.new
|
31
|
+
passbook.wwdr_intermediate_certificate_path = "#{Dir.pwd}/spec/data/certificates/wwdr.pem"
|
32
|
+
end
|
33
|
+
|
34
|
+
Passbook::Config.instance.add_pkpass do |passbook|
|
35
|
+
template_path = "#{Dir.pwd}/spec/data/templates"
|
36
|
+
cert_path = "#{Dir.pwd}/spec/data/certificates"
|
37
|
+
passbook.pass_config["pass.com.acme"]={
|
38
|
+
"cert_path"=>"#{cert_path}/pass.com.acme.p12",
|
39
|
+
"cert_password"=>"test",
|
40
|
+
"template_path"=>"#{template_path}/pass.com.acme",
|
41
|
+
"p12_certificate"=>create_p12
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
before :each do
|
47
|
+
@pass = Passbook::Pkpass.new("pass.com.acme", "test")
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
it "should throw ArgumentError because there is no config for 'test'" do
|
52
|
+
expect {Passbook::Pkpass.new("test", "test")}.to raise_error(ArgumentError, /configuration for test/)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should make an instance of Pkpass" do
|
56
|
+
expect {Passbook::Pkpass.new("pass.com.acme", "test")}.to_not raise_error
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should have the added file in zip file" do
|
60
|
+
@pass.add_file "andrei.png", "haha"
|
61
|
+
pkpass_io = @pass.package
|
62
|
+
check_file_in_zip(pkpass_io, "andrei.png").should be_true
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should have the added file in zip file(in a folder)" do
|
66
|
+
@pass.add_file "fr.lproj/andrei.png", "haha"
|
67
|
+
pkpass_io = @pass.package
|
68
|
+
check_file_in_zip(pkpass_io, "fr.lproj/andrei.png").should be_true
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should add an entry in the right pass.strings file" do
|
72
|
+
@pass.add_translation_string "yes", "qui", "fr"
|
73
|
+
pass_strings = file_from_zip(@pass.package, "fr.lproj/pass.strings")
|
74
|
+
pass_strings.should_not be_nil
|
75
|
+
pass_strings.should match /\"yes\" = \"qui\";/
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should only append to strings file" do
|
79
|
+
@pass.add_file "fr.lproj/pass.strings", "\"not\" = \"not\";"
|
80
|
+
@pass.add_translation_string "yes", "qui", "fr"
|
81
|
+
pass_strings = file_from_zip(@pass.package, "fr.lproj/pass.strings")
|
82
|
+
pass_strings.should_not be_nil
|
83
|
+
pass_strings.should match /\"not\" = \"not\";/
|
84
|
+
pass_strings.should match /\"yes\" = \"qui\";/
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should include all the files from template_path" do
|
88
|
+
pkpass_io = @pass.package
|
89
|
+
Dir.glob(@pass.config["template_path"]+"/**/**").each do |file|
|
90
|
+
next if File.directory? file
|
91
|
+
filename = Pathname.new(file).relative_path_from(Pathname.new(@pass.config['template_path']))
|
92
|
+
check_file_in_zip(pkpass_io, filename.to_s).should be_true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should include manifest.json" do
|
97
|
+
check_file_in_zip(@pass.package, "manifest.json").should be_true
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should have all the files in manifest.json and none more" do
|
101
|
+
files_json = JSON.parse(file_from_zip(@pass.package, "manifest.json"))
|
102
|
+
Dir.glob(@pass.config["template_path"]+"/**/**").each do |file|
|
103
|
+
next if File.directory? file
|
104
|
+
filename = Pathname.new(file).relative_path_from(Pathname.new(@pass.config['template_path'])).to_s
|
105
|
+
if files_json.include? filename
|
106
|
+
files_json.delete filename
|
107
|
+
else
|
108
|
+
fail
|
109
|
+
end
|
110
|
+
end
|
111
|
+
files_json.should be_empty
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should have a signature" do
|
115
|
+
check_file_in_zip(@pass.package, "signature").should be_true
|
116
|
+
end
|
117
|
+
end
|