passbook-ruby 0.0.6 → 0.1.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.
- data/README.md +8 -1
- data/app/controllers/passbook/registrations_controller.rb +7 -0
- data/app/models/passbook/registration.rb +3 -0
- data/lib/passbook-ruby.rb +24 -9
- data/lib/passbook/config.rb +4 -1
- data/lib/passbook/engine.rb +3 -2
- data/lib/passbook/pkpass.rb +16 -0
- data/lib/rails/generators/passbook/config/templates/migration.rb +1 -1
- data/lib/rails/generators/passbook/pkpass/pkpass_generator.rb +1 -1
- data/spec/config_spec.rb +3 -3
- data/spec/pkpass_spec.rb +1 -1
- metadata +3 -2
data/README.md
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
# Passbook-Ruby
|
2
2
|
|
3
|
+
[](http://travis-ci.org/xtremelabs/xl-passbook-ruby)
|
4
|
+
|
3
5
|
[Passbook] is an app distributed on iOS6.
|
4
6
|
This is an implementation for management and signing of pkpasses for your Rails application.
|
5
7
|
The management of templates and all the other data is done in-memory. This gem does not write to the filesystem. This results in a speed boost.
|
6
8
|
|
9
|
+
**Quick Start Video:**<br/>
|
10
|
+
http://www.youtube.com/watch?v=GeWFk1FvEKc
|
11
|
+
|
7
12
|
## Usage
|
8
13
|
|
9
14
|
### Install
|
@@ -51,10 +56,12 @@ I would strongly advise specifying **model_name**, **pass_type_id** and **tead_i
|
|
51
56
|
rails g passbook:pkpass [model_name] [pass_type_id] [team_id] [cert_path] [cert_password]
|
52
57
|
```
|
53
58
|
This will generate a model, a migration, an initializer, a route and a sample pass (to data/templates/your_pass_type_id). Make sure to add your
|
54
|
-
.p12 into the path now if you use the defaults.
|
59
|
+
.p12 into the path now if you use the defaults. Also, if you didn't set the password for the cert in the above command, make sure you change the default to
|
60
|
+
your password in config/initializers/passbook_#{model_name}.rb.
|
55
61
|
|
56
62
|
|
57
63
|
```
|
64
|
+
rake db:migrate
|
58
65
|
rails s
|
59
66
|
```
|
60
67
|
and go to \passes\model_name on your iphone (make sure it is in debug mode and allows http connections)
|
@@ -59,6 +59,9 @@ module Passbook
|
|
59
59
|
:push_token => push_token,
|
60
60
|
:serial_number => params[:serial_number])
|
61
61
|
|
62
|
+
# spawn an event for registration creation
|
63
|
+
pass.register_handler if pass.respond_to? :register_handler
|
64
|
+
|
62
65
|
# Return a 201 CREATED status
|
63
66
|
# status 201
|
64
67
|
render :json => {}, :status => 201
|
@@ -90,6 +93,10 @@ module Passbook
|
|
90
93
|
registration = Registration.find_by_uuid(uuid)
|
91
94
|
unless registration.blank?
|
92
95
|
Registration.delete registration.id
|
96
|
+
|
97
|
+
# spawn an event for unregistration event
|
98
|
+
pass.unregister_handler if pass.respond_to? :unregister_handler
|
99
|
+
|
93
100
|
render :json => {}, :status => 200
|
94
101
|
else
|
95
102
|
puts 'Registration does not exist.'
|
data/lib/passbook-ruby.rb
CHANGED
@@ -21,25 +21,40 @@ require "passbook/pkpass"
|
|
21
21
|
require "passbook/engine"
|
22
22
|
|
23
23
|
require "action_controller"
|
24
|
-
|
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
|
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
|
24
|
+
|
33
25
|
|
34
26
|
module Passbook
|
27
|
+
# @private
|
35
28
|
def self.pass_type_id_to_class pass_type_id
|
36
29
|
Passbook::Config.instance.pass_config[pass_type_id]['class'].constantize
|
37
30
|
end
|
38
31
|
|
32
|
+
# @private
|
39
33
|
def self.class_name_to_pass_type_id class_name
|
40
34
|
Passbook::Config.instance.pass_config.each do |pass_type_id, config|
|
41
35
|
return pass_type_id if config['class']==class_name
|
42
36
|
end
|
43
37
|
end
|
38
|
+
|
39
|
+
# Registers a custom renderer for .pkpass files
|
40
|
+
# (executed at load time)
|
41
|
+
#
|
42
|
+
# example:
|
43
|
+
# render :pkpass ticket
|
44
|
+
#
|
45
|
+
# (where `ticket` is an instance of a model that is configured with passbook-ruby gem)
|
46
|
+
def self.register_pkpass
|
47
|
+
Mime::Type.register 'application/vnd.apple.pkpass', :pkpass
|
48
|
+
|
49
|
+
ActionController::Renderers.add :pkpass do |obj, options|
|
50
|
+
pkpass = Passbook::Pkpass.new Passbook.class_name_to_pass_type_id(obj.class.to_s), obj.serial_number
|
51
|
+
obj.update_pass pkpass if obj.respond_to? :update_pass
|
52
|
+
pkpass_io = pkpass.package
|
53
|
+
response.headers["last-modified"] = obj.updated_at.strftime("%Y-%m-%d %H:%M:%S")
|
54
|
+
send_data(pkpass_io.sysread, :type => 'application/vnd.apple.pkpass', :disposition=>'inline', :filename=>"#{obj.serial_number}.pkpass")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
self.register_pkpass
|
58
|
+
|
44
59
|
end
|
45
60
|
|
data/lib/passbook/config.rb
CHANGED
@@ -38,6 +38,7 @@ module Passbook
|
|
38
38
|
read_p12_certificates
|
39
39
|
end
|
40
40
|
|
41
|
+
# @private
|
41
42
|
def read_templates
|
42
43
|
self.pass_config.each do |pass_type_id, config|
|
43
44
|
raise(ArgumentError, "Please specify a template_path in your configuration (in initializer)") unless config['template_path']
|
@@ -56,6 +57,7 @@ module Passbook
|
|
56
57
|
files
|
57
58
|
end
|
58
59
|
|
60
|
+
# @private
|
59
61
|
def read_p12_certificates
|
60
62
|
pass_config.each do |pass_type_id, config|
|
61
63
|
raise(ArgumentError, "Please specify cert_path (certificate path) in your configuration (in initializer)") unless config['cert_path'] && !config['cert_path'].blank?
|
@@ -64,8 +66,9 @@ module Passbook
|
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
69
|
+
# @private
|
67
70
|
def read_wwdr_certificate
|
68
|
-
raise(ArgumentError, "Please specify the WWDR Intermediate certificate in your initializer") unless self.wwdr_intermediate_certificate_path
|
71
|
+
# raise(ArgumentError, "Please specify the WWDR Intermediate certificate in your initializer") unless self.wwdr_intermediate_certificate_path
|
69
72
|
self.wwdr_certificate||= OpenSSL::X509::Certificate.new(File.read(self.wwdr_intermediate_certificate_path))
|
70
73
|
end
|
71
74
|
|
data/lib/passbook/engine.rb
CHANGED
data/lib/passbook/pkpass.rb
CHANGED
@@ -23,6 +23,7 @@ require 'zip/zip'
|
|
23
23
|
require 'zip/zipfilesystem'
|
24
24
|
|
25
25
|
module Passbook
|
26
|
+
# Pkpass is the class responsible for managing the contect of a pkpass and also signing the package
|
26
27
|
class Pkpass
|
27
28
|
attr_accessor :files, :translations, :json, :pass_type_id, :serial_number, :config
|
28
29
|
|
@@ -48,6 +49,16 @@ module Passbook
|
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
52
|
+
# Add a file to your pkpass
|
53
|
+
#
|
54
|
+
# example:
|
55
|
+
# pass.add_file "stripe.png", image_content
|
56
|
+
#
|
57
|
+
# == Parameters:
|
58
|
+
# filename::
|
59
|
+
# A String for the name of the file. It can contain a folder, so it is really a relative path within the pkpass
|
60
|
+
# content::
|
61
|
+
# Binary content for what will be inside that file
|
51
62
|
def add_file filename, content
|
52
63
|
self.files[filename] = content
|
53
64
|
end
|
@@ -67,10 +78,12 @@ module Passbook
|
|
67
78
|
self.compress_pass_file
|
68
79
|
end
|
69
80
|
|
81
|
+
# @private
|
70
82
|
def write_json
|
71
83
|
self.files['pass.json'] = JSON.pretty_generate(self.json)
|
72
84
|
end
|
73
85
|
|
86
|
+
# @private
|
74
87
|
def write_translation_strings
|
75
88
|
self.translations.each do |language, trans|
|
76
89
|
self.files["#{language}.lproj/pass.strings"] ||= ""
|
@@ -81,6 +94,7 @@ module Passbook
|
|
81
94
|
end
|
82
95
|
end
|
83
96
|
|
97
|
+
# @private
|
84
98
|
def generate_json_manifest
|
85
99
|
manifest = {}
|
86
100
|
self.files.each do |filename, content|
|
@@ -89,12 +103,14 @@ module Passbook
|
|
89
103
|
self.files['manifest.json'] = JSON.pretty_generate(manifest)
|
90
104
|
end
|
91
105
|
|
106
|
+
# @private
|
92
107
|
def sign_manifest
|
93
108
|
flag = OpenSSL::PKCS7::BINARY|OpenSSL::PKCS7::DETACHED
|
94
109
|
signed = OpenSSL::PKCS7::sign(config['p12_certificate'].certificate, config['p12_certificate'].key, self.files['manifest.json'], [Config.instance.wwdr_certificate], flag)
|
95
110
|
self.files['signature'] = signed.to_der.force_encoding('UTF-8')
|
96
111
|
end
|
97
112
|
|
113
|
+
# @private
|
98
114
|
def compress_pass_file
|
99
115
|
stringio = Zip::ZipOutputStream::write_buffer do |z|
|
100
116
|
self.files.each do |filename, content|
|
@@ -29,7 +29,7 @@ module Passbook
|
|
29
29
|
def create_initializer_file
|
30
30
|
template 'initializer.rb', File.join('config', 'initializers', "passbook_#{plural_name.singularize}.rb")
|
31
31
|
template 'model.rb', File.join('app', 'models', "#{plural_name.singularize}.rb")
|
32
|
-
route "get '/v1/passes/#{plural_name.singularize}' => 'Passbook::
|
32
|
+
route "get '/v1/passes/#{plural_name.singularize}' => 'Passbook::Passes#get_pkpass', :defaults => { :pass_type_id => '#{pass_type_id}' }"
|
33
33
|
template 'migration.rb', File.join('db', 'migrate', "#{Time.now.strftime("%Y%m%d%H%M%S")}_create_#{plural_name}.rb")
|
34
34
|
template 'pass.json', File.join('data', 'templates', pass_type_id, "pass.json")
|
35
35
|
template 'icon.png', File.join('data', 'templates', pass_type_id, "icon.png")
|
data/spec/config_spec.rb
CHANGED
@@ -19,9 +19,9 @@
|
|
19
19
|
require 'spec_helper'
|
20
20
|
|
21
21
|
describe Passbook::Config do
|
22
|
-
it "should throw ArgumentError because wwdr_intermediate_certificate_path is missing" do
|
23
|
-
|
24
|
-
end
|
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
25
|
|
26
26
|
it "should throw ArgumentError because cert_path is missing" do
|
27
27
|
expect{ Passbook::Config.instance.add_pkpass do |passbook|
|
data/spec/pkpass_spec.rb
CHANGED
@@ -28,6 +28,7 @@ describe Passbook::Pkpass do
|
|
28
28
|
before :all do
|
29
29
|
Passbook::Config.instance.configure do |passbook|
|
30
30
|
passbook.wwdr_certificate = OpenSSL::X509::Certificate.new
|
31
|
+
passbook.wwdr_intermediate_certificate_path = "#{Dir.pwd}/spec/data/certificates/wwdr.pem"
|
31
32
|
end
|
32
33
|
|
33
34
|
Passbook::Config.instance.add_pkpass do |passbook|
|
@@ -39,7 +40,6 @@ describe Passbook::Pkpass do
|
|
39
40
|
"template_path"=>"#{template_path}/pass.com.acme",
|
40
41
|
"p12_certificate"=>create_p12
|
41
42
|
}
|
42
|
-
passbook.wwdr_intermediate_certificate_path = "#{Dir.pwd}/spec/data/certificates/wwdr.pem"
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passbook-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -163,3 +163,4 @@ signing_key:
|
|
163
163
|
specification_version: 3
|
164
164
|
summary: Passbook pkpass creation and management for Ruby projects
|
165
165
|
test_files: []
|
166
|
+
has_rdoc: false
|