touchpass 0.0.8.18 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -21
- data/Gemfile.lock +13 -7
- data/bin/touchpass +43 -19
- data/lib/touchpass/client.rb +245 -184
- data/lib/touchpass/crypt.rb +1 -1
- data/lib/touchpass/verification.rb +3 -1
- data/lib/touchpass/version.rb +1 -1
- data/spec/touchpass_client_spec.rb +80 -69
- data/test/claimed_vs_verified_token.rb +29 -0
- data/touchpass.gemspec +9 -0
- metadata +132 -2
data/Gemfile
CHANGED
@@ -1,22 +1,2 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
|
-
|
3
|
-
gem 'httparty', '~> 0.8.0'
|
4
|
-
gem 'thor', '~> 0.14.6'
|
5
|
-
gem 'geocoder', '~> 1.1.0'
|
6
|
-
gem 'json', '~> 1.6.5'
|
7
|
-
gem 'xml-simple', '~> 1.1.1'
|
8
|
-
|
9
|
-
group :development, :test do
|
10
|
-
gem 'guard'
|
11
|
-
gem 'growl'
|
12
|
-
gem 'guard-rspec'
|
13
|
-
gem 'rspec'
|
14
|
-
gem 'rspec-core'
|
15
|
-
gem 'rspec-mocks'
|
16
|
-
gem 'rspec-expectations'
|
17
|
-
end
|
18
|
-
|
19
|
-
group :test do
|
20
|
-
gem 'cover_me'
|
21
|
-
end
|
22
|
-
|
2
|
+
gemspec
|
data/Gemfile.lock
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
touchpass (0.0.8.18)
|
5
|
+
geocoder (~> 1.1.0)
|
6
|
+
httparty (~> 0.8.0)
|
7
|
+
json (~> 1.6.5)
|
8
|
+
thor (~> 0.14.6)
|
9
|
+
xml-simple (~> 1.1.1)
|
10
|
+
|
1
11
|
GEM
|
2
12
|
remote: http://rubygems.org/
|
3
13
|
specs:
|
@@ -8,7 +18,7 @@ GEM
|
|
8
18
|
hashie
|
9
19
|
diff-lcs (1.1.3)
|
10
20
|
ffi (1.0.11)
|
11
|
-
geocoder (1.1.
|
21
|
+
geocoder (1.1.2)
|
12
22
|
growl (1.0.3)
|
13
23
|
guard (1.0.2)
|
14
24
|
ffi (>= 0.5.0)
|
@@ -20,7 +30,7 @@ GEM
|
|
20
30
|
multi_json (~> 1.0)
|
21
31
|
multi_xml
|
22
32
|
json (1.6.7)
|
23
|
-
multi_json (1.3.
|
33
|
+
multi_json (1.3.6)
|
24
34
|
multi_xml (0.5.1)
|
25
35
|
rspec (2.10.0)
|
26
36
|
rspec-core (~> 2.10.0)
|
@@ -39,15 +49,11 @@ PLATFORMS
|
|
39
49
|
|
40
50
|
DEPENDENCIES
|
41
51
|
cover_me
|
42
|
-
geocoder (~> 1.1.0)
|
43
52
|
growl
|
44
53
|
guard
|
45
54
|
guard-rspec
|
46
|
-
httparty (~> 0.8.0)
|
47
|
-
json (~> 1.6.5)
|
48
55
|
rspec
|
49
56
|
rspec-core
|
50
57
|
rspec-expectations
|
51
58
|
rspec-mocks
|
52
|
-
|
53
|
-
xml-simple (~> 1.1.1)
|
59
|
+
touchpass!
|
data/bin/touchpass
CHANGED
@@ -23,7 +23,7 @@ class TpCLI < Thor
|
|
23
23
|
DFT_OUTPUT = "json"
|
24
24
|
|
25
25
|
attr_accessor :touchpass_client
|
26
|
-
|
26
|
+
|
27
27
|
desc "register_party", "Register new Verifying Party"
|
28
28
|
method_option :email, :aliases => "-e", :required => true
|
29
29
|
method_option :username, :aliases => "-u", :required => true
|
@@ -33,18 +33,20 @@ class TpCLI < Thor
|
|
33
33
|
method_option :debug, :aliases => "-d", :type => :boolean
|
34
34
|
def register_party
|
35
35
|
setup(options)
|
36
|
-
output @touchpass_client.register_party(options
|
36
|
+
output @touchpass_client.register_party(options[:username], options[:password],
|
37
|
+
options[:email], options)
|
37
38
|
end
|
38
39
|
|
39
40
|
desc "authenticate_party", "Authenticate Party"
|
40
|
-
method_option :
|
41
|
+
method_option :username, :aliases => "-u", :required => true
|
41
42
|
method_option :password, :aliases => "-p", :required => true
|
42
43
|
method_option :hostname, :aliases => "-h"
|
43
44
|
method_option :output, :aliases => "-o"
|
44
45
|
method_option :debug, :aliases => "-d", :type => :boolean
|
45
46
|
def authenticate_party
|
46
47
|
setup(options)
|
47
|
-
output @touchpass_client.authenticate_party(options
|
48
|
+
output @touchpass_client.authenticate_party(options[:username], options[:password],
|
49
|
+
options)
|
48
50
|
end
|
49
51
|
|
50
52
|
desc "show_party", "Show Party details"
|
@@ -56,7 +58,14 @@ class TpCLI < Thor
|
|
56
58
|
method_option :debug, :aliases => "-d", :type => :boolean
|
57
59
|
def show_party
|
58
60
|
setup(options)
|
59
|
-
|
61
|
+
if !options[:id].nil?
|
62
|
+
output @touchpass_client.get_party_by_id(options[:id], options)
|
63
|
+
elsif !options[:username].nil?
|
64
|
+
output @touchpass_client.get_party(options[:username], options)
|
65
|
+
else
|
66
|
+
puts "id or username required"
|
67
|
+
exit 1
|
68
|
+
end
|
60
69
|
end
|
61
70
|
|
62
71
|
desc "update_party", "Update Party details"
|
@@ -71,7 +80,14 @@ class TpCLI < Thor
|
|
71
80
|
method_option :debug, :aliases => "-d", :type => :boolean
|
72
81
|
def update_party
|
73
82
|
setup(options)
|
74
|
-
|
83
|
+
if !options[:id].nil?
|
84
|
+
output @touchpass_client.update_party_by_id(options[:id], options)
|
85
|
+
elsif !options[:username].nil?
|
86
|
+
output @touchpass_client.update_party(options[:username], options)
|
87
|
+
else
|
88
|
+
puts "id or username required"
|
89
|
+
exit 1
|
90
|
+
end
|
75
91
|
end
|
76
92
|
|
77
93
|
desc "register_device", "Register new Device"
|
@@ -81,13 +97,14 @@ class TpCLI < Thor
|
|
81
97
|
method_option :app_id, :aliases => '-a', :required => true
|
82
98
|
method_option :messaging_type, :aliases => "-mt"
|
83
99
|
method_option :messaging_value, :aliases => "-mv"
|
84
|
-
method_option :api_key, :required => true
|
100
|
+
method_option :api_key, :required => true, :default => DFT_API_KEY
|
85
101
|
method_option :hostname, :aliases => "-h"
|
86
102
|
method_option :output, :aliases => "-o"
|
87
103
|
method_option :debug, :aliases => "-d", :type => :boolean
|
88
104
|
def register_device
|
89
105
|
setup(options)
|
90
|
-
output @touchpass_client.register_device(options
|
106
|
+
output @touchpass_client.register_device(options[:username], options[:udid],
|
107
|
+
options[:name], options[:app_id], options)
|
91
108
|
end
|
92
109
|
|
93
110
|
desc "show_devices", "Show Party Devices"
|
@@ -98,7 +115,7 @@ class TpCLI < Thor
|
|
98
115
|
method_option :debug, :aliases => "-d", :type => :boolean
|
99
116
|
def show_devices
|
100
117
|
setup(options)
|
101
|
-
output @touchpass_client.get_devices(options)
|
118
|
+
output @touchpass_client.get_devices(options[:username], options)
|
102
119
|
end
|
103
120
|
|
104
121
|
desc "show_device", "Show Device details"
|
@@ -110,7 +127,7 @@ class TpCLI < Thor
|
|
110
127
|
method_option :debug, :aliases => "-d", :type => :boolean
|
111
128
|
def show_device
|
112
129
|
setup(options)
|
113
|
-
output @touchpass_client.get_device(options)
|
130
|
+
output @touchpass_client.get_device(options[:username], options[:id], options)
|
114
131
|
end
|
115
132
|
|
116
133
|
desc "update_device", "Update Device details"
|
@@ -126,7 +143,7 @@ class TpCLI < Thor
|
|
126
143
|
method_option :debug, :aliases => "-d", :type => :boolean
|
127
144
|
def update_device
|
128
145
|
setup(options)
|
129
|
-
output @touchpass_client.update_device(options)
|
146
|
+
output @touchpass_client.update_device(options[:username], options[:id], options)
|
130
147
|
end
|
131
148
|
|
132
149
|
desc "remove_device", "Remove Device"
|
@@ -138,7 +155,7 @@ class TpCLI < Thor
|
|
138
155
|
method_option :debug, :aliases => "-d", :type => :boolean
|
139
156
|
def remove_device
|
140
157
|
setup(options)
|
141
|
-
output @touchpass_client.remove_device(options)
|
158
|
+
output @touchpass_client.remove_device(options[:username], options[:id], options)
|
142
159
|
end
|
143
160
|
|
144
161
|
desc "create_verification", "Create new Verification"
|
@@ -160,7 +177,7 @@ class TpCLI < Thor
|
|
160
177
|
if options[:message_post_verification_location] && !options[:address]
|
161
178
|
warn "WARNING: post verification location message (-L) ignored as address (-a) not given"
|
162
179
|
end
|
163
|
-
output @touchpass_client.create_verification(options)
|
180
|
+
output @touchpass_client.create_verification(options[:to_party], options)
|
164
181
|
end
|
165
182
|
|
166
183
|
desc "show_verifications", "Show Verifications"
|
@@ -172,19 +189,23 @@ class TpCLI < Thor
|
|
172
189
|
method_option :debug, :aliases => "-d", :type => :boolean
|
173
190
|
def show_verifications
|
174
191
|
setup(options)
|
175
|
-
|
192
|
+
if !options[:username].nil?
|
193
|
+
output @touchpass_client.get_verifications(options[:username], options)
|
194
|
+
else
|
195
|
+
output @touchpass_client.get_verifications_by_party_id(options[:party_id], options)
|
196
|
+
end
|
176
197
|
end
|
177
198
|
|
178
199
|
desc "show_verification", "Show Verification details"
|
179
200
|
method_option :id, :aliases => "-i", :required => true
|
180
|
-
method_option :device_id # For decrypting message (optional)
|
201
|
+
#method_option :device_id # For decrypting message (optional)
|
181
202
|
method_option :api_key, :required => true, :default => DFT_API_KEY
|
182
203
|
method_option :hostname, :aliases => "-h"
|
183
204
|
method_option :output, :aliases => "-o"
|
184
205
|
method_option :debug, :aliases => "-d", :type => :boolean
|
185
206
|
def show_verification
|
186
207
|
setup(options)
|
187
|
-
output @touchpass_client.get_verification(options)
|
208
|
+
output @touchpass_client.get_verification(options[:id], options)
|
188
209
|
end
|
189
210
|
|
190
211
|
desc "update_verification", "Update Verification"
|
@@ -197,29 +218,32 @@ class TpCLI < Thor
|
|
197
218
|
method_option :debug, :aliases => "-d", :type => :boolean
|
198
219
|
def update_verification
|
199
220
|
setup(options)
|
200
|
-
output @touchpass_client.update_verification(options
|
221
|
+
output @touchpass_client.update_verification(options[:id], options[:device_id],
|
222
|
+
options)
|
201
223
|
end
|
202
224
|
|
203
225
|
desc "cancel_verification", "Cancel Verification"
|
204
226
|
method_option :id, :required => true
|
227
|
+
method_option :device_id, :required => true, :aliases => "-d"
|
205
228
|
method_option :api_key, :required => true, :default => DFT_API_KEY
|
206
229
|
method_option :hostname, :aliases => "-h"
|
207
230
|
method_option :output, :aliases => "-o"
|
208
231
|
method_option :debug, :aliases => "-d", :type => :boolean
|
209
232
|
def cancel_verification
|
210
233
|
setup(options)
|
211
|
-
output @touchpass_client.cancel_verification(options)
|
234
|
+
output @touchpass_client.cancel_verification(options[:id], options[:device_id],options)
|
212
235
|
end
|
213
236
|
|
214
237
|
desc "reject_verification", "Reject Verification"
|
215
238
|
method_option :id, :required => true
|
239
|
+
method_option :device_id, :required => true, :aliases => "-d"
|
216
240
|
method_option :api_key, :required => true, :default => DFT_API_KEY
|
217
241
|
method_option :hostname, :aliases => "-h"
|
218
242
|
method_option :output, :aliases => "-o"
|
219
243
|
method_option :debug, :aliases => "-d", :type => :boolean
|
220
244
|
def reject_verification
|
221
245
|
setup(options)
|
222
|
-
output @touchpass_client.reject_verification(options)
|
246
|
+
output @touchpass_client.reject_verification(options[:id], options[:device_id],options)
|
223
247
|
end
|
224
248
|
|
225
249
|
private
|
data/lib/touchpass/client.rb
CHANGED
@@ -21,131 +21,150 @@ module Touchpass
|
|
21
21
|
attr_accessor :hostname, :debug, :api_key
|
22
22
|
|
23
23
|
API_KEY_HEADER = "X-TouchPass-ApiKey"
|
24
|
-
ENVIRONMENT = ENV['RAILS_ENV']
|
24
|
+
ENVIRONMENT = (ENV['RAILS_ENV'] || "").to_sym
|
25
|
+
REQUEST_FORMAT = "json"
|
25
26
|
|
26
|
-
|
27
|
-
|
27
|
+
# Host and port to use for service invocations, default to the main Touchpass server
|
28
|
+
DFT_HOST_PROD = "https://touchpass.geodica.com"
|
29
|
+
DFT_HOST_DEV = "https://localhost:3000"
|
30
|
+
DFT_HOST = {
|
31
|
+
:production => DFT_HOST_PROD,
|
32
|
+
:development => DFT_HOST_DEV
|
33
|
+
}
|
28
34
|
|
29
|
-
# Default response output to json
|
30
|
-
DFT_OUTPUT = "json"
|
31
|
-
|
32
35
|
# Default debug state (on: dev|test, off: prod)
|
33
|
-
DFT_DEBUG = ENV['TPC_DEBUG'] ? true : false
|
36
|
+
DFT_DEBUG = ENV['TPC_DEBUG'] && ENV['TPC_DEBUG'] != "" ? true : false
|
37
|
+
|
38
|
+
# Create a new Touchpass client instance
|
39
|
+
def initialize(hostname = nil, debug = DFT_DEBUG)
|
40
|
+
@hostname = hostname
|
41
|
+
@hostname ||= DFT_HOST[ENVIRONMENT]
|
42
|
+
@hostname ||= DFT_HOST_DEV
|
34
43
|
|
35
|
-
|
36
|
-
def initialize(hostname=DFT_HOSTNAME, debug=DFT_DEBUG)
|
37
|
-
@hostname = hostname.nil? ? DFT_HOSTNAME : hostname
|
38
|
-
@debug = debug
|
39
|
-
@output = DFT_OUTPUT # always use json internally
|
44
|
+
@debug = debug
|
40
45
|
end
|
41
46
|
|
42
47
|
# Register a new relying party with the Touchpass server
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
48
|
+
def register_party(username, password, email, options = {})
|
49
|
+
require_param(username, "username")
|
50
|
+
require_param(password, "password")
|
51
|
+
require_param(email, "email")
|
52
|
+
|
53
|
+
options = options.merge(:email => email, :username => username, :password => password)
|
54
|
+
http_options = standard_http_options(options, %W{email username password})
|
55
|
+
response = submit_request("post", "#{@hostname}/parties", http_options)
|
47
56
|
set_api_key_from_response(response)
|
48
57
|
response
|
49
58
|
end
|
50
|
-
|
59
|
+
|
51
60
|
# Authenticate a party to obtain the API key
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
http_options)
|
61
|
+
def authenticate_party(username, password, options = {})
|
62
|
+
require_param(username, "username")
|
63
|
+
require_param(password, "password")
|
64
|
+
|
65
|
+
options = options.merge(:login => username, :password => password)
|
66
|
+
http_options = standard_http_options(options, %W{login password})
|
67
|
+
response = submit_request("post", "#{@hostname}/parties/authenticate", http_options)
|
60
68
|
set_api_key_from_response(response)
|
61
69
|
response
|
62
70
|
end
|
63
71
|
|
64
72
|
# Get details for a party
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
def get_party_by_id(party_id, options = {})
|
74
|
+
require_api_key
|
75
|
+
require_param(party_id, "party id")
|
76
|
+
|
77
|
+
http_options = standard_http_options(options)
|
78
|
+
submit_request("get", party_url_id(party_id), http_options)
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_party(username, options = {})
|
82
|
+
require_api_key
|
83
|
+
require_param(username, "username")
|
84
|
+
|
85
|
+
http_options = standard_http_options(options)
|
86
|
+
submit_request("get", party_url_username(username), http_options)
|
77
87
|
end
|
78
88
|
|
79
89
|
# Update details for a party
|
80
|
-
#
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
90
|
+
# uses options: :email, :first_name, :last_name
|
91
|
+
def update_party_by_id(party_id, options = {})
|
92
|
+
require_api_key
|
93
|
+
require_param(party_id, "party id")
|
94
|
+
|
95
|
+
http_options = standard_http_options(options, %W{username email first_name last_name})
|
96
|
+
submit_request("put", party_url_id(party_id), http_options)
|
97
|
+
end
|
98
|
+
|
99
|
+
def update_party(username, options = {})
|
100
|
+
require_api_key
|
101
|
+
require_param(username, "username")
|
102
|
+
|
103
|
+
http_options = standard_http_options(options, %W{username email first_name last_name})
|
104
|
+
submit_request("put", party_url_username(username), http_options)
|
94
105
|
end
|
95
106
|
|
96
107
|
# Register a new device for a party
|
97
|
-
#
|
98
|
-
def register_device(
|
108
|
+
# uses: :messaging_type, :messaging_value
|
109
|
+
def register_device(username, udid, name, app_id, options = {})
|
110
|
+
require_api_key
|
111
|
+
require_param(username, "username")
|
112
|
+
require_param(udid, "udid")
|
113
|
+
require_param(name, "name")
|
114
|
+
require_param(app_id, "app id")
|
99
115
|
|
100
116
|
# Generate private & public key for this device
|
101
|
-
crypt = KeyFileCreator.new(
|
117
|
+
crypt = KeyFileCreator.new(udid)
|
102
118
|
crypt.generate_keys
|
103
119
|
|
104
120
|
# Collect attributes of new device
|
105
|
-
device_attributes =
|
106
|
-
:udid =>
|
107
|
-
:app_id =>
|
108
|
-
:name =>
|
121
|
+
device_attributes = options.merge({
|
122
|
+
:udid => udid,
|
123
|
+
:app_id => app_id,
|
124
|
+
:name => name,
|
109
125
|
:pub_key => crypt.public_key_text, # PEM format
|
110
|
-
:messaging_type =>
|
111
|
-
:messaging_value =>
|
126
|
+
:messaging_type => options[:messaging_type],
|
127
|
+
:messaging_value => options[:messaging_value]
|
112
128
|
})
|
113
|
-
http_options = standard_http_options(device_attributes,
|
129
|
+
http_options = standard_http_options(device_attributes, device_attributes.keys)
|
114
130
|
|
115
131
|
# Provision the new device with the Touchpass server
|
116
|
-
|
132
|
+
url = "#{@hostname}/#{username}/devices"
|
133
|
+
new_device = submit_request("post", url, http_options)
|
134
|
+
device_id = new_device["id"].to_s
|
117
135
|
|
118
136
|
# We made the key files for the new device earlier (see
|
119
137
|
# KeyFileCreator above) but at that stage we didn't know the
|
120
138
|
# :deviceid of the newly provisioned device. So now we need to
|
121
139
|
# move the cert directory around based on the :deviceid returned
|
122
140
|
# from TouchPass.
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
puts "error: updating key file location based on device id: udid:#{params[:udid]}, device_id:#{device_id}"
|
137
|
-
end
|
138
|
-
|
141
|
+
if device_id
|
142
|
+
begin
|
143
|
+
orig_file = crypt.keys_path
|
144
|
+
crypt.id = device_id
|
145
|
+
new_file = crypt.keys_path
|
146
|
+
puts "Renaming directory #{orig_file} to #{new_file}" if @debug
|
147
|
+
result = File.rename(orig_file, new_file)
|
148
|
+
rescue Exception => e
|
149
|
+
puts "Exception: #{e.message}"
|
150
|
+
puts "error: updating key file location based on device id: udid:#{udid}, device_id:#{device_id}"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
139
154
|
# Return details of the newly provisioned device
|
140
155
|
new_device
|
141
156
|
end
|
142
157
|
|
143
158
|
# Get all devices for a party
|
144
|
-
# needs: :username
|
145
|
-
def get_devices(
|
159
|
+
# needs: :username
|
160
|
+
def get_devices(username, options = {})
|
161
|
+
require_api_key
|
162
|
+
require_param(username, "username")
|
163
|
+
|
146
164
|
# Just return the device list for the specified user
|
147
|
-
http_options = standard_http_options(
|
148
|
-
|
165
|
+
http_options = standard_http_options(options)
|
166
|
+
url = "#{@hostname}/#{username}/devices"
|
167
|
+
devices = submit_request("get", url, http_options)
|
149
168
|
|
150
169
|
# Look for errors, and just build an empty device array hashed from 'devices'
|
151
170
|
if !devices['devices'].nil? or !devices['error'].nil?
|
@@ -155,149 +174,182 @@ module Touchpass
|
|
155
174
|
end
|
156
175
|
end
|
157
176
|
|
158
|
-
# Get details for a specific device, returns an 'errors' hash if
|
159
|
-
#
|
160
|
-
def get_device(
|
177
|
+
# Get details for a specific device, returns an 'errors' hash if
|
178
|
+
# the device cannot be found
|
179
|
+
def get_device(username, device_id, options = {})
|
180
|
+
require_api_key
|
181
|
+
require_param(username, "username")
|
182
|
+
require_param(device_id, "device id")
|
183
|
+
|
161
184
|
# Return the device for the specified user and device id
|
162
|
-
http_options = standard_http_options(
|
163
|
-
|
185
|
+
http_options = standard_http_options(options)
|
186
|
+
url = "#{@hostname}/#{username}/devices/#{device_id}"
|
187
|
+
submit_request("get", url, http_options)
|
164
188
|
end
|
165
189
|
|
166
190
|
# Update details of a device, returns an 'errors' hash if the device cannot be found
|
167
|
-
#
|
168
|
-
def update_device(
|
169
|
-
|
170
|
-
|
171
|
-
|
191
|
+
# uses options: :name, :messaging_type, :messaging_value, :update_pub_key
|
192
|
+
def update_device(username, device_id, options = {})
|
193
|
+
require_api_key
|
194
|
+
require_param(username, "username")
|
195
|
+
require_param(device_id, "device id")
|
196
|
+
|
197
|
+
update_pub_key = options[:update_pub_key] # TODO: Regenerate and update pub_key
|
172
198
|
|
173
|
-
|
199
|
+
http_options = standard_http_options(options, %W{name messaging_type messaging_value})
|
200
|
+
url = "#{@hostname}/#{username}/devices/#{device_id}"
|
201
|
+
submit_request("put", url, http_options)
|
174
202
|
end
|
175
203
|
|
176
204
|
# Remove device, returns an 'errors' hash if the device cannot be found
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
205
|
+
def remove_device(username, device_id, options = {})
|
206
|
+
require_api_key
|
207
|
+
require_param(username, "username")
|
208
|
+
require_param(device_id, "device id")
|
209
|
+
|
210
|
+
http_options = standard_http_options(options)
|
211
|
+
url = "#{@hostname}/#{username}/devices/#{device_id}"
|
212
|
+
submit_request("delete", url, http_options)
|
181
213
|
end
|
182
214
|
|
183
215
|
# Create a new verification
|
184
|
-
#
|
185
|
-
# uses:
|
216
|
+
# to_party: username of the VP
|
217
|
+
# uses options:
|
186
218
|
# :address (for LV), :resolution (for LV)
|
187
219
|
# :message, :message_post_verification
|
188
|
-
def create_verification(
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
220
|
+
def create_verification(to_party, options = {})
|
221
|
+
require_api_key
|
222
|
+
require_param(to_party, "to party")
|
223
|
+
|
224
|
+
# Get list of verifying party devices so we can encrypt data for
|
225
|
+
# them using each device's public key.
|
226
|
+
http_options = standard_http_options(options)
|
227
|
+
response = submit_request("get", "#{@hostname}/#{to_party}/devices", http_options)
|
194
228
|
vp_devices = response["devices"]
|
195
229
|
|
196
230
|
# create a verification object
|
197
|
-
|
231
|
+
options = options.merge(:to_party => to_party)
|
232
|
+
verification = Touchpass::Verification.new(vp_devices, options)
|
233
|
+
http_options = standard_http_options(options, %W{to_party to_device_id to_app_id})
|
198
234
|
http_options[:body].merge!(verification.http_params)
|
199
235
|
|
200
|
-
submit_request("post", "#{@hostname}/verifications
|
236
|
+
submit_request("post", "#{@hostname}/verifications", http_options)
|
201
237
|
end
|
202
238
|
|
203
|
-
# Get a page of verifications for a particular party
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
response = submit_request("get", "#{@hostname}/verifications.#{@output}", http_options)
|
213
|
-
else
|
214
|
-
response = {"error" => "Either username or id must be provided."}
|
215
|
-
end
|
216
|
-
response
|
239
|
+
# Get a page of verifications for a particular party id
|
240
|
+
def get_verifications_by_party_id(party_id, options = {})
|
241
|
+
require_api_key
|
242
|
+
require_param(party_id, "party id")
|
243
|
+
|
244
|
+
http_options = standard_http_options(options)
|
245
|
+
http_options[:body][:party_id] = options[:party_id]
|
246
|
+
url = "#{@hostname}/verifications"
|
247
|
+
submit_request("get", url, http_options)
|
217
248
|
end
|
218
249
|
|
219
|
-
# Get
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
250
|
+
# Get a page of verifications for a particular username
|
251
|
+
def get_verifications(username, options = {})
|
252
|
+
require_api_key
|
253
|
+
require_param(username, "username")
|
254
|
+
|
255
|
+
http_options = standard_http_options(options)
|
256
|
+
url = "#{@hostname}/#{username}/verifications"
|
257
|
+
submit_request("get", url, http_options)
|
258
|
+
end
|
259
|
+
|
260
|
+
# Get details of a specific verification
|
261
|
+
def get_verification(verification_id, options = {})
|
262
|
+
require_api_key
|
263
|
+
require_param(verification_id, "verification id")
|
264
|
+
|
265
|
+
http_options = standard_http_options(options)
|
266
|
+
url = "#{@hostname}/verifications/#{verification_id}"
|
267
|
+
submit_request("get", url, http_options)
|
237
268
|
end
|
238
269
|
|
239
270
|
# Update Verification
|
240
|
-
#
|
241
|
-
def update_verification(
|
242
|
-
|
243
|
-
|
244
|
-
|
271
|
+
# uses: options[:address]
|
272
|
+
def update_verification(verification_id, device_id, options = {})
|
273
|
+
require_api_key
|
274
|
+
require_param(verification_id, "verification id")
|
275
|
+
require_param(device_id, "device id")
|
276
|
+
|
277
|
+
options = options.merge(:id => verification_id, :device_id => device_id)
|
278
|
+
http_options = standard_http_options(options, %W{id})
|
245
279
|
|
246
|
-
verification
|
280
|
+
# Call show verification to get the crypted salts and resolution
|
281
|
+
# for the verification Note: crypted salts and resolution are
|
282
|
+
# also returned in the list verifications response
|
283
|
+
verification = get_verification(verification_id, options)
|
247
284
|
|
248
|
-
token = decrypt_salt(verification["crypted_tokens"],
|
285
|
+
token = decrypt_salt(verification["crypted_tokens"], device_id)
|
249
286
|
http_options[:body][:verified_token] = Crypt.hash(token) unless token.nil?
|
250
287
|
|
251
288
|
# Generate verified PRP for location verification
|
252
|
-
if !
|
253
|
-
prp = Proximity::PRP.new(:address =>
|
289
|
+
if !options[:address].nil?
|
290
|
+
prp = Proximity::PRP.new(:address => options[:address],
|
291
|
+
:resolution => verification["resolution"])
|
254
292
|
# puts prp.print_bbox # for debugging
|
255
293
|
|
256
|
-
salt = decrypt_salt(verification["crypted_salts"],
|
294
|
+
salt = decrypt_salt(verification["crypted_salts"], device_id)
|
257
295
|
# puts "Using salt: #{salt}"
|
258
296
|
verified_prp = prp.encrypt(salt)
|
259
297
|
|
260
298
|
http_options[:body][:verified_prp] = verified_prp
|
261
299
|
# puts "Verified PRP: #{verified_prp}"
|
262
300
|
end
|
263
|
-
submit_request("put", "#{@hostname}/verifications/#{
|
264
|
-
http_options)
|
301
|
+
submit_request("put", "#{@hostname}/verifications/#{verification_id}", http_options)
|
265
302
|
end
|
266
303
|
|
267
304
|
# Cancel an existing verification
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
305
|
+
def cancel_verification(verification_id, device_id, options = {})
|
306
|
+
require_api_key
|
307
|
+
require_param(verification_id, "verification id")
|
308
|
+
require_param(device_id, "device id")
|
272
309
|
|
273
|
-
|
310
|
+
verification = get_verification(verification_id)
|
311
|
+
token = decrypt_salt(verification["crypted_tokens"], device_id)
|
312
|
+
|
313
|
+
http_options = standard_http_options(options)
|
274
314
|
http_options[:body][:verified_token] = Crypt.hash(token) unless token.nil?
|
275
315
|
|
276
|
-
|
277
|
-
|
316
|
+
url = "#{@hostname}/verifications/#{verification_id}/cancel"
|
317
|
+
submit_request("put", url, http_options)
|
278
318
|
end
|
279
319
|
|
280
320
|
# Reject a verification
|
281
|
-
# needs: :
|
282
|
-
def reject_verification(
|
283
|
-
|
284
|
-
verification
|
321
|
+
# needs: :id
|
322
|
+
def reject_verification(verification_id, device_id, options = {})
|
323
|
+
require_api_key
|
324
|
+
require_param(verification_id, "verification id")
|
325
|
+
require_param(device_id, "device id")
|
326
|
+
|
327
|
+
verification = get_verification(verification_id)
|
328
|
+
token = decrypt_salt(verification["crypted_tokens"], device_id)
|
285
329
|
|
286
|
-
|
330
|
+
http_options = standard_http_options(options)
|
287
331
|
http_options[:body][:verified_token] = Crypt.hash(token) unless token.nil?
|
288
332
|
|
289
|
-
|
290
|
-
|
333
|
+
url = "#{@hostname}/verifications/#{verification_id}/reject"
|
334
|
+
submit_request("put", url, http_options)
|
291
335
|
end
|
292
336
|
|
293
337
|
private
|
294
338
|
|
295
|
-
|
296
|
-
|
339
|
+
def party_url_id(party_id)
|
340
|
+
"#{@hostname}/parties/#{party_id}"
|
341
|
+
end
|
342
|
+
|
343
|
+
def party_url_username(username)
|
344
|
+
"#{@hostname}/#{username}"
|
345
|
+
end
|
346
|
+
|
347
|
+
# Decrypt salt for a specific device
|
348
|
+
def decrypt_salt(crypted_salts, device_id)
|
297
349
|
return nil if crypted_salts.nil?
|
298
350
|
|
299
351
|
# Find crypted salt associated with the device
|
300
|
-
crypted_salt = crypted_salts.detect{|cs| cs["device_id"] == device_id.to_i}
|
352
|
+
crypted_salt = crypted_salts.detect { |cs| cs["device_id"] == device_id.to_i }
|
301
353
|
return nil if crypted_salt.nil?
|
302
354
|
device_id = crypted_salt["device_id"].to_s
|
303
355
|
ct = crypted_salt["value"]
|
@@ -327,13 +379,13 @@ module Touchpass
|
|
327
379
|
msg
|
328
380
|
end
|
329
381
|
|
330
|
-
def standard_http_options(
|
331
|
-
http_options = { :body => {}, :headers => api_key_header(
|
382
|
+
def standard_http_options(options, body_options = [])
|
383
|
+
http_options = { :body => {}, :headers => api_key_header(options) }
|
332
384
|
|
333
|
-
|
334
|
-
|
335
|
-
next if
|
336
|
-
http_options[:body][
|
385
|
+
body_options.each do |pname|
|
386
|
+
pname = pname.to_sym
|
387
|
+
next if pname == :api_key # this is now sent as a header field
|
388
|
+
http_options[:body][pname] = options[pname] unless options[pname].nil?
|
337
389
|
end
|
338
390
|
|
339
391
|
http_options
|
@@ -343,31 +395,40 @@ module Touchpass
|
|
343
395
|
self.api_key = response["api_key"] if response && response["api_key"]
|
344
396
|
end
|
345
397
|
|
346
|
-
def api_key_header(
|
398
|
+
def api_key_header(options)
|
347
399
|
self.api_key ? { API_KEY_HEADER => self.api_key } : {}
|
348
400
|
end
|
349
401
|
|
402
|
+
def require_api_key
|
403
|
+
require_param(self.api_key, "api key")
|
404
|
+
end
|
405
|
+
|
406
|
+
def require_param(value, name)
|
407
|
+
raise "#{name} required" unless value && value.to_s.length > 0
|
408
|
+
end
|
409
|
+
|
350
410
|
# Submit the request to the server and process the response (for errors)
|
351
|
-
def submit_request(http_verb, request,
|
411
|
+
def submit_request(http_verb, request, options)
|
412
|
+
|
413
|
+
request = request + "." + REQUEST_FORMAT
|
352
414
|
|
353
415
|
if @debug
|
354
416
|
puts "DEBUG: "
|
355
417
|
puts "DEBUG: hostname: #{@hostname}"
|
356
|
-
puts "DEBUG:
|
357
|
-
puts "DEBUG:
|
358
|
-
puts "DEBUG: params: #{params}"
|
418
|
+
puts "DEBUG: request: #{http_verb.upcase} #{request}"
|
419
|
+
puts "DEBUG: options: #{options}"
|
359
420
|
end
|
360
421
|
|
361
422
|
case http_verb
|
362
423
|
when "put"
|
363
|
-
response = HTTParty.put(request,
|
424
|
+
response = HTTParty.put(request, options)
|
364
425
|
when "delete"
|
365
|
-
response = HTTParty.delete(request,
|
426
|
+
response = HTTParty.delete(request, options)
|
366
427
|
when "post"
|
367
|
-
response = HTTParty.post(request,
|
428
|
+
response = HTTParty.post(request, options)
|
368
429
|
else
|
369
|
-
response = HTTParty.get(request, :query =>
|
370
|
-
:headers =>
|
430
|
+
response = HTTParty.get(request, :query => options[:body],
|
431
|
+
:headers => options[:headers])
|
371
432
|
end
|
372
433
|
|
373
434
|
if @debug
|