Class: Touchpass::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/touchpass/client.rb

Overview

Provide a simple Ruby interface to a Touchpass verification server

Constant Summary collapse

API_KEY_HEADER =
"X-TouchPass-ApiKey"
ENVIRONMENT =
(ENV['RAILS_ENV'] || "").to_sym
REQUEST_FORMAT =
"json"
DFT_HOST_PROD =

Host and port to use for service invocations, default to the main Touchpass server

"https://touchpass.geodica.com"
DFT_HOST_DEV =
"https://localhost:3000"
DFT_HOST =
{
  :production => DFT_HOST_PROD,
  :development => DFT_HOST_DEV
}
DFT_DEBUG =

Default debug state (on: dev|test, off: prod)

ENV['TPC_DEBUG'] && ENV['TPC_DEBUG'] != "" ? true : false

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hostname = nil, debug = DFT_DEBUG) ⇒ Client

Create a new Touchpass client instance



39
40
41
42
43
44
45
# File 'lib/touchpass/client.rb', line 39

def initialize(hostname = nil, debug = DFT_DEBUG)
  @hostname = hostname
  @hostname ||= DFT_HOST[ENVIRONMENT]
  @hostname ||= DFT_HOST_DEV

  @debug = debug
end

Instance Attribute Details

#api_keyObject

Returns the value of attribute api_key.



21
22
23
# File 'lib/touchpass/client.rb', line 21

def api_key
  @api_key
end

#debugObject

Returns the value of attribute debug.



21
22
23
# File 'lib/touchpass/client.rb', line 21

def debug
  @debug
end

#hostnameObject

Returns the value of attribute hostname.



21
22
23
# File 'lib/touchpass/client.rb', line 21

def hostname
  @hostname
end

Instance Method Details

#authenticate_party(username, password, options = {}) ⇒ Object

Authenticate a party to obtain the API key



61
62
63
64
65
66
67
68
69
70
# File 'lib/touchpass/client.rb', line 61

def authenticate_party(username, password, options = {})
  require_param(username, "username")
  require_param(password, "password")

  options = options.merge(:login => username, :password => password)
  http_options = standard_http_options(options, %W{login password})
  response = submit_request("post", "#{@hostname}/parties/authenticate", http_options)
  set_api_key_from_response(response)
  response
end

#cancel_verification(verification_id, device_id, options = {}) ⇒ Object

Cancel an existing verification



328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/touchpass/client.rb', line 328

def cancel_verification(verification_id, device_id, options = {})
  require_api_key
  require_param(verification_id, "verification id")
  require_param(device_id, "device id")

  verification = get_verification(verification_id)
  token = decrypt_salt(verification["crypted_tokens"], device_id)

  http_options = standard_http_options(options)
  http_options[:body][:verified_token] = Crypt.hash(token) unless token.nil?

  url = "#{@hostname}/verifications/#{verification_id}/cancel"
  submit_request("put", url, http_options)
end

#create_verification(to_party, options = {}) ⇒ Object

Create a new verification to_party: username of the VP uses options:

:address (for LV), :resolution (for LV)
:message, :message_post_verification


221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/touchpass/client.rb', line 221

def create_verification(to_party, options = {})
  require_api_key
  require_param(to_party, "to party")

  # Get list of verifying party devices so we can encrypt data for
  # them using each device's public key.
  http_options = standard_http_options(options)
  response = submit_request("get", "#{@hostname}/#{to_party}/devices", http_options)

  vp_devices = response["devices"] || []
  raise "VP has no registered devices" if vp_devices.empty?

  # create a verification object
  options = options.merge(:to_party => to_party)
  verification = Touchpass::Verification.new(vp_devices, options)
  http_options = standard_http_options(options, %W{to_party to_device_id to_app_id})
  http_options[:body].merge!(verification.http_params)

  response = submit_request("post", "#{@hostname}/verifications", http_options)

  verification.attributes = response
  verification
end

#get_device(username, device_id, options = {}) ⇒ Object

Get details for a specific device



180
181
182
183
184
185
186
187
188
189
# File 'lib/touchpass/client.rb', line 180

def get_device(username, device_id, options = {})
  require_api_key
  require_param(username, "username")
  require_param(device_id, "device id")

  # Return the device for the specified user and device id
  http_options = standard_http_options(options)
  url = "#{@hostname}/#{username}/devices/#{device_id}"
  submit_request("get", url, http_options)
end

#get_devices(username, options = {}) ⇒ Object

Get all devices for a party



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/touchpass/client.rb', line 162

def get_devices(username, options = {})
  require_api_key
  require_param(username, "username")

  # Just return the device list for the specified user
  http_options = standard_http_options(options)
  url = "#{@hostname}/#{username}/devices"
  devices = submit_request("get", url, http_options)

  # Look for errors, and just build an empty device array hashed from 'devices'
  if !devices['devices'].nil? or !devices['error'].nil?
    devices
  else
    { 'devices' => [] }
  end
end

#get_party(username, options = {}) ⇒ Object

Get details for a party (by username)



82
83
84
85
86
87
88
# File 'lib/touchpass/client.rb', line 82

def get_party(username, options = {})
  require_api_key
  require_param(username, "username")

  http_options = standard_http_options(options)
  submit_request("get", party_url_username(username), http_options)
end

#get_party_by_id(party_id, options = {}) ⇒ Object

Get details for a party (by party id)



73
74
75
76
77
78
79
# File 'lib/touchpass/client.rb', line 73

def get_party_by_id(party_id, options = {})
  require_api_key
  require_param(party_id, "party id")

  http_options = standard_http_options(options)
  submit_request("get", party_url_id(party_id), http_options)
end

#get_verification(verification_id, options = {}) ⇒ Object

Get details of a specific verification



267
268
269
270
271
272
273
274
# File 'lib/touchpass/client.rb', line 267

def get_verification(verification_id, options = {})
  require_api_key
  require_param(verification_id, "verification id")

  http_options = standard_http_options(options)
  url = "#{@hostname}/verifications/#{verification_id}"
  submit_request("get", url, http_options)
end

#get_verifications(username, options = {}) ⇒ Object

Get a page of verifications for a particular username



257
258
259
260
261
262
263
264
# File 'lib/touchpass/client.rb', line 257

def get_verifications(username, options = {})
  require_api_key
  require_param(username, "username")

  http_options = standard_http_options(options)
  url = "#{@hostname}/#{username}/verifications"
  submit_request("get", url, http_options)
end

#get_verifications_by_party_id(party_id, options = {}) ⇒ Object

Get a page of verifications for a particular party id



246
247
248
249
250
251
252
253
254
# File 'lib/touchpass/client.rb', line 246

def get_verifications_by_party_id(party_id, options = {})
  require_api_key
  require_param(party_id, "party id")

  http_options = standard_http_options(options)
  http_options[:body][:party_id] = options[:party_id]
  url = "#{@hostname}/verifications"
  submit_request("get", url, http_options)
end

#poll_verification(verification_id, options = {}) ⇒ Object

fetch verification until state is not ‘created’



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/touchpass/client.rb', line 277

def poll_verification(verification_id, options = {})
  http_options = standard_http_options(options)
  timeout = options[:timeout] || 60   # default poll for 60 seconds
  sleep_time = 5
  response = nil

  while timeout > 0
    response = get_verification(verification_id)
    break if response['state'] != Verification::STATE_CREATED
    sleep sleep_time
    timeout -= sleep_time
  end

  response
end

#provision_party(username, email, app_id, options = {}) ⇒ Object



359
360
361
362
363
364
365
366
367
368
369
# File 'lib/touchpass/client.rb', line 359

def provision_party(username, email, app_id, options = {})
  require_api_key
  require_param(username, "username")
  require_param(email, "email")
  require_param(app_id, "application id")

  options = options.merge(:username => username, :email => email, :app_id => app_id)
  http_options = standard_http_options(options, %W{username email app_id mobile_number})
  url = "#{@hostname}/admin/configurations"
  response = submit_request("post", url, http_options)
end

#register_device(username, udid, name, app_id, options = {}) ⇒ Object

Register a new device for a party options: :messaging_type, :messaging_value



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/touchpass/client.rb', line 112

def register_device(username, udid, name, app_id, options = {})
  require_api_key
  require_param(username, "username")
  require_param(udid, "udid")
  require_param(name, "name")
  require_param(app_id, "app id")

  # Generate private & public key for this device
  crypt = KeyFileCreator.new(udid)
  crypt.generate_keys

  # Collect attributes of new device
  device_attributes = options.merge({
    :udid            => udid, 
    :app_id          => app_id,
    :name            => name, 
    :pub_key         => crypt.public_key_text,   # PEM format
    :messaging_type  => options[:messaging_type], 
    :messaging_value => options[:messaging_value]
  })
  http_options = standard_http_options(device_attributes, device_attributes.keys)

  # Provision the new device with the Touchpass server
  url = "#{@hostname}/#{username}/devices"
  new_device = submit_request("post", url, http_options)
  device_id = new_device["id"].to_s

  # We made the key files for the new device earlier (see
  # KeyFileCreator above) but at that stage we didn't know the
  # :deviceid of the newly provisioned device. So now we need to
  # move the cert directory around based on the :deviceid returned
  # from TouchPass.
  if device_id
    begin
      orig_file = crypt.keys_path
      crypt.id = device_id
      new_file = crypt.keys_path
      puts "Renaming directory #{orig_file} to #{new_file}" if @debug
      result = File.rename(orig_file, new_file)
    rescue Exception => e
      puts "Exception: #{e.message}"
      puts "error: updating key file location based on device id: udid:#{udid}, device_id:#{device_id}"
    end
  end

  # Return details of the newly provisioned device
  new_device
end

#register_party(username, password, email, options = {}) ⇒ Object

Register a new relying party with the Touchpass server



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/touchpass/client.rb', line 48

def register_party(username, password, email, options = {}) 
  require_param(username, "username")
  require_param(password, "password")
  require_param(email, "email")

  options = options.merge(:email => email, :username => username, :password => password)
  http_options = standard_http_options(options, %W{email username password})
  response = submit_request("post", "#{@hostname}/parties", http_options)
  set_api_key_from_response(response)
  response
end

#reject_verification(verification_id, device_id, options = {}) ⇒ Object

Reject a verification



344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/touchpass/client.rb', line 344

def reject_verification(verification_id, device_id, options = {})
  require_api_key
  require_param(verification_id, "verification id")
  require_param(device_id, "device id")

  verification = get_verification(verification_id)
  token = decrypt_salt(verification["crypted_tokens"], device_id)

  http_options = standard_http_options(options)
  http_options[:body][:verified_token] = Crypt.hash(token) unless token.nil?

  url = "#{@hostname}/verifications/#{verification_id}/reject"
  submit_request("put", url, http_options)
end

#remove_device(username, device_id, options = {}) ⇒ Object

Remove device



206
207
208
209
210
211
212
213
214
# File 'lib/touchpass/client.rb', line 206

def remove_device(username, device_id, options = {})
  require_api_key
  require_param(username, "username")
  require_param(device_id, "device id")

  http_options = standard_http_options(options)
  url = "#{@hostname}/#{username}/devices/#{device_id}"
  submit_request("delete", url, http_options)
end

#update_device(username, device_id, options = {}) ⇒ Object

Update details of a device options: :name, :messaging_type, :messaging_value, :update_pub_key



193
194
195
196
197
198
199
200
201
202
203
# File 'lib/touchpass/client.rb', line 193

def update_device(username, device_id, options = {})
  require_api_key
  require_param(username, "username")
  require_param(device_id, "device id")

  update_pub_key  = options[:update_pub_key] # TODO: Regenerate and update pub_key

  http_options = standard_http_options(options, %W{name messaging_type messaging_value})
  url = "#{@hostname}/#{username}/devices/#{device_id}"
  submit_request("put", url, http_options)
end

#update_party(username, options = {}) ⇒ Object

Update details for a party options: :email, :first_name, :last_name, :username



102
103
104
105
106
107
108
# File 'lib/touchpass/client.rb', line 102

def update_party(username, options = {})
  require_api_key
  require_param(username, "username")

  http_options = standard_http_options(options, %W{username email first_name last_name})
  submit_request("put", party_url_username(username), http_options)
end

#update_party_by_id(party_id, options = {}) ⇒ Object

Update details for a party options: :email, :first_name, :last_name, :username



92
93
94
95
96
97
98
# File 'lib/touchpass/client.rb', line 92

def update_party_by_id(party_id, options = {}) 
  require_api_key
  require_param(party_id, "party id")

  http_options = standard_http_options(options, %W{username email first_name last_name})
  submit_request("put", party_url_id(party_id), http_options)
end

#update_verification(verification_id, device_id, options = {}) ⇒ Object

Update Verification options: :address



295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/touchpass/client.rb', line 295

def update_verification(verification_id, device_id, options = {})
  require_api_key
  require_param(verification_id, "verification id")
  require_param(device_id, "device id")

  options = options.merge(:id => verification_id, :device_id => device_id)
  http_options = standard_http_options(options, %W{id})

  # Call show verification to get the crypted salts and resolution
  # for the verification Note: crypted salts and resolution are
  # also returned in the list verifications response
  verification = get_verification(verification_id, options)

  token = decrypt_salt(verification["crypted_tokens"], device_id)
  http_options[:body][:verified_token] = Crypt.hash(token) unless token.nil?

  # Generate verified PRP for location verification
  if !options[:address].nil?
    prp = Proximity::PRP.new(:address => options[:address],
                             :resolution => verification["resolution"])
    # puts prp.print_bbox # for debugging

    salt = decrypt_salt(verification["crypted_salts"], device_id)
    # puts "Using salt: #{salt}"
    verified_prp = prp.encrypt(salt)

    http_options[:body][:verified_prp] = verified_prp
    # puts "Verified PRP: #{verified_prp}"
  end
  submit_request("put", "#{@hostname}/verifications/#{verification_id}", http_options)
end