Class: Virgil::SDK::Client::VirgilClient

Inherits:
Object
  • Object
show all
Defined in:
lib/virgil/sdk/client/virgil_client.rb

Overview

Virgil API client

Contains methods for searching and managing cards.

Defined Under Namespace

Classes: InvalidCardException

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(access_token = nil, cards_service_url = Card::SERVICE_URL, cards_read_only_service_url = Card::READ_ONLY_SERVICE_URL, identity_service_url = Virgil::SDK::HighLevel::VirgilIdentity::IDENTITY_SERVICE_URL, ra_service_url = Card::RA_SERVICE_URL) ⇒ VirgilClient

Constructs new VirgilClient object



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/virgil/sdk/client/virgil_client.rb', line 59

def initialize(
    access_token=nil,
    cards_service_url=Card::SERVICE_URL,
    cards_read_only_service_url=Card::READ_ONLY_SERVICE_URL,
    identity_service_url=Virgil::SDK::HighLevel::VirgilIdentity::IDENTITY_SERVICE_URL,
    ra_service_url=Card::RA_SERVICE_URL
)
  self.access_token = access_token
  self.cards_service_url = cards_service_url
  self.cards_read_only_service_url = cards_read_only_service_url
  self.identity_service_url = identity_service_url
  self.ra_service_url = ra_service_url
end

Instance Attribute Details

#access_tokenObject

Returns the value of attribute access_token.



55
56
57
# File 'lib/virgil/sdk/client/virgil_client.rb', line 55

def access_token
  @access_token
end

#card_validatorObject

Returns the value of attribute card_validator.



55
56
57
# File 'lib/virgil/sdk/client/virgil_client.rb', line 55

def card_validator
  @card_validator
end

#cards_read_only_service_urlObject

Returns the value of attribute cards_read_only_service_url.



55
56
57
# File 'lib/virgil/sdk/client/virgil_client.rb', line 55

def cards_read_only_service_url
  @cards_read_only_service_url
end

#cards_service_urlObject

Returns the value of attribute cards_service_url.



55
56
57
# File 'lib/virgil/sdk/client/virgil_client.rb', line 55

def cards_service_url
  @cards_service_url
end

#identity_service_urlObject

Returns the value of attribute identity_service_url.



55
56
57
# File 'lib/virgil/sdk/client/virgil_client.rb', line 55

def identity_service_url
  @identity_service_url
end

#ra_service_urlObject

Returns the value of attribute ra_service_url.



55
56
57
# File 'lib/virgil/sdk/client/virgil_client.rb', line 55

def ra_service_url
  @ra_service_url
end

Instance Method Details

#add_relation(request) ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/virgil/sdk/client/virgil_client.rb', line 213

def add_relation(request)
  unless (request.is_a?(Requests::AddRelationRequest) && !request.snapshot.nil? && request.signatures.count == 1)
    raise ArgumentError.new("Request is not valid. Request must have snapshot and exactly 1 relation signature.")
  end
  http_request = Virgil::SDK::Client::HTTP::Request.new(
      method: Virgil::SDK::Client::HTTP::Request::POST,
      endpoint: "/#{Card::VC_VERSION}/card/#{request.signatures.keys.first}/collections/relations",
      body: request.request_model
  )
  raw_response = self.cards_connection.send_request(http_request)
  card = Card.from_response(raw_response)
  self.validate_cards([card]) if self.card_validator
  card
end

#cards_connectionObject

Cards service connection used for creating and revoking cards.



424
425
426
427
428
429
# File 'lib/virgil/sdk/client/virgil_client.rb', line 424

def cards_connection
  @_cards_connection ||= HTTP::CardsServiceConnection.new(
      self.access_token,
      self.cards_service_url
  )
end

#confirm_identity(action_id, confirmation_code, time_to_live, count_to_live) ⇒ Object



314
315
316
317
# File 'lib/virgil/sdk/client/virgil_client.rb', line 314

def confirm_identity(action_id, confirmation_code, time_to_live, count_to_live)
  request = Requests::ConfirmIdentityRequest.new(confirmation_code, action_id, time_to_live, count_to_live)
  confirm_identity_from_request(request)
end

#confirm_identity_from_request(confirm_request) ⇒ Object



319
320
321
322
323
324
325
326
327
# File 'lib/virgil/sdk/client/virgil_client.rb', line 319

def confirm_identity_from_request(confirm_request)
  http_request = Virgil::SDK::Client::HTTP::Request.new(
      method: HTTP::Request::POST,
      endpoint: "/#{Card::VRA_VERSION}/confirm",
      body: confirm_request.request_model
  )
  raw_response = self.identity_service_connection.send_request(http_request)
  raw_response['validation_token']
end

#create_card(identity, identity_type, key_pair, app_id, app_key) ⇒ Object

Create published new card from given attributes.

Args:

identity: Created card identity.
identity_type: Created card identity type.
key_pair: Key pair of the created card.
  Public key is stored in the card, private key is used for request signing.
app_id: Application identity for authority sign.
app_key: Application key for authority sign.

Returns:

Created card from server response.


85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/virgil/sdk/client/virgil_client.rb', line 85

def create_card(identity, identity_type, key_pair, app_id, app_key)
  request = Virgil::SDK::Client::Requests::CreateCardRequest.new(
      identity: identity,
      identity_type: identity_type,
      scope: Client::Card::APPLICATION,
      raw_public_key: self.crypto.export_public_key(key_pair.public_key)
  )
  self.request_signer.self_sign(request, key_pair.private_key)
  self.request_signer.authority_sign(request, app_id, app_key)

  return self.create_card_from_signed_request(request)
end

#create_card_from_signed_request(create_request) ⇒ Object

Create new card from signed creation request.

Args:

create_request: signed card creation request.

Returns:

Created card from server response.

Raises:

VirgilClient.InvalidCardException if client has validator
and returned card signatures are not valid.


191
192
193
194
195
196
197
198
199
200
201
# File 'lib/virgil/sdk/client/virgil_client.rb', line 191

def create_card_from_signed_request(create_request)
  http_request = Virgil::SDK::Client::HTTP::Request.new(
      method: Virgil::SDK::Client::HTTP::Request::POST,
      endpoint: "/#{Card::VRA_VERSION}/card",
      body: create_request.request_model
  )
  raw_response = self.ra_connection.send_request(http_request)
  card = Card.from_response(raw_response)
  self.validate_cards([card]) if self.card_validator
  card
end

#create_card_from_signed_request_async(create_request) ⇒ Object



203
204
205
206
207
208
209
210
# File 'lib/virgil/sdk/client/virgil_client.rb', line 203

def create_card_from_signed_request_async(create_request)
  thread = Thread.new do
    current = Thread.current
    current[:card] = create_card_from_signed_request(create_request)
  end
  thread.join
  thread[:card]
end

#cryptoObject

Crypto library wrapper.



460
461
462
# File 'lib/virgil/sdk/client/virgil_client.rb', line 460

def crypto
  @_crypto ||= Virgil::SDK::Cryptography::VirgilCrypto.new
end

#delete_relation(request) ⇒ Object



229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/virgil/sdk/client/virgil_client.rb', line 229

def delete_relation(request)
  unless (request.is_a?(Requests::DeleteRelationRequest) && !request.snapshot.nil? && request.signatures.count == 1)
    raise ArgumentError.new("Request is not valid. Request must have snapshot and exactly 1 relation signature.")
  end
  http_request = Virgil::SDK::Client::HTTP::Request.new(
      method: Virgil::SDK::Client::HTTP::Request::DELETE,
      endpoint: "/#{Card::VC_VERSION}/card/#{request.signatures.keys.first}/collections/relations",
      body: request.request_model
  )
  raw_response = self.cards_connection.send_request(http_request)
  card = Card.from_response(raw_response)
  self.validate_cards([card]) if self.card_validator
  card
end

#get_card(card_id) ⇒ Object

Get card by id.

Args:

card_id: id of the card to get.

Returns:

Found card from server response.

Raises:

VirgilClient::InvalidCardException if client has validator
and retrieved card signatures are not valid.


341
342
343
344
345
346
347
348
349
350
351
# File 'lib/virgil/sdk/client/virgil_client.rb', line 341

def get_card(card_id)
  # type: (str) -> Card
  http_request = Virgil::SDK::Client::HTTP::Request.new(
      method: HTTP::Request::GET,
      endpoint: "/#{Card::VC_VERSION}/card/#{card_id}",
  )
  raw_response = self.read_cards_connection.send_request(http_request)
  card = Card.from_response(raw_response)
  self.validate_cards([card]) if self.card_validator
  card
end

#identity_service_connectionObject



446
447
448
449
450
451
452
# File 'lib/virgil/sdk/client/virgil_client.rb', line 446

def identity_service_connection
  @identity_service_connection = HTTP::CardsServiceConnection.new(
      nil,
      self.identity_service_url
  )

end

#new_card(identity, identity_type, private_key, custom_data = {}) ⇒ Object

Create unpublished local card from given attributes.

Args:

identity: Created card identity.
identity_type: Created card identity type.
private_key: Private key of the created card.
  Public key is stored in the card, private key is used for request signing.
app_id: Application identity for authority sign.
app_key: Application key for authority sign.
custom_data(optional): is an associative array that contains application specific
                       parameters(under key :data) and information about the device
                       on which the keypair was created(under key :device and :device_name).
                       example: {data: {my_key1: "my_val1", my_key2: "my_val2"}, device: "iPhone6s", device_name: "Space grey one"}

Returns:

Created local card that is not published to Virgil Security services


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/virgil/sdk/client/virgil_client.rb', line 115

def new_card(identity, identity_type, private_key, custom_data={})
  data = custom_data[:data]
  custom_data.delete(:data)
  request = Virgil::SDK::Client::Requests::CreateCardRequest.new(
      identity: identity,
      identity_type: identity_type,
      scope: Client::Card::APPLICATION,
      raw_public_key: self.crypto.extract_public_key(private_key).value,
      info: custom_data,
      data: data
  )
  self.request_signer.self_sign(request, private_key)

  return Client::Card.from_request_model(request.request_model)
end

#new_global_card(identity, identity_type, private_key, custom_data = {}) ⇒ Object

Create unpublished global card from given attributes.

Args:

identity: Created card identity.
identity_type: Created card identity type.
private_key: Key pair of the created card.
  Public key is stored in the card, private key is used for request signing.
custom_data(optional): is an associative array that contains application specific
                       parameters(under key :data) and information about the device
                       on which the keypair was created(under key :device and :device_name).
                       example: {data: {my_key1: "my_val1", my_key2: "my_val2"}, device: "iPhone6s", device_name: "Space grey one"}

Returns:

Created global card that is not published to Virgil Security services


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/virgil/sdk/client/virgil_client.rb', line 146

def new_global_card(identity, identity_type, private_key, custom_data={})
  data = custom_data[:data]
  custom_data.delete(:data)
  request = Virgil::SDK::Client::Requests::CreateCardRequest.new(
      identity: identity,
      identity_type: identity_type,
      scope: Client::Card::GLOBAL,
      raw_public_key: self.crypto.extract_public_key(private_key).value,
      info: custom_data,
      data: data
  )
  self.request_signer.self_sign(request, private_key)

  return Client::Card.from_request_model(request.request_model)
end

#publish_as_global_card(card) ⇒ Object



174
175
176
177
# File 'lib/virgil/sdk/client/virgil_client.rb', line 174

def publish_as_global_card(card)
  request = card.to_request
  create_card_from_signed_request(request)
end

#ra_connectionObject



431
432
433
434
435
436
# File 'lib/virgil/sdk/client/virgil_client.rb', line 431

def ra_connection
  @_ra_connection ||= HTTP::CardsServiceConnection.new(
      self.access_token,
      self.ra_service_url
  )
end

#read_cards_connectionObject

Cards service connection used for getting and searching cards.



438
439
440
441
442
443
# File 'lib/virgil/sdk/client/virgil_client.rb', line 438

def read_cards_connection
  @_read_cards_connection = HTTP::CardsServiceConnection.new(
      self.access_token,
      self.cards_read_only_service_url
  )
end

#request_signerObject

Request signer for signing constructed requests.



455
456
457
# File 'lib/virgil/sdk/client/virgil_client.rb', line 455

def request_signer
  @_request_signer ||= RequestSigner.new(self.crypto)
end

#revoke_card(card_id, app_id, app_key, reason = Requests::RevokeCardRequest::Reasons::Unspecified) ⇒ Object

Revoke card by id.

Args:

card_id: id of the revoked card.
reason: card revocation reason.
  The possible values can be found in RevokeCardRequest::Reasons class.
app_id: Application identity for authority sign.
app_key: Application key for authority sign.


253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/virgil/sdk/client/virgil_client.rb', line 253

def revoke_card(
    card_id,
    app_id,
    app_key,
    reason=Requests::RevokeCardRequest::Reasons::Unspecified
)
  request = Requests::RevokeCardRequest.new(
      card_id: card_id,
      reason: reason
  )
  self.request_signer.authority_sign(request, app_id, app_key)

  self.revoke_card_from_signed_request(request)
end

#revoke_card_from_signed_request(revocation_request) ⇒ Object

Revoke card using signed revocation request.

Args:

revocation_request: signed card revocation request.


289
290
291
292
293
294
295
296
# File 'lib/virgil/sdk/client/virgil_client.rb', line 289

def revoke_card_from_signed_request(revocation_request)
  http_request = Virgil::SDK::Client::HTTP::Request.new(
      method: HTTP::Request::DELETE,
      endpoint: "/#{Card::VRA_VERSION}/card/#{revocation_request.card_id}",
      body: revocation_request.request_model
  )
  self.ra_connection.send_request(http_request)
end

#revoke_global_card(card_id, key_pair, validation_token, reason = Requests::RevokeCardRequest::Reasons::Unspecified) ⇒ Object



269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/virgil/sdk/client/virgil_client.rb', line 269

def revoke_global_card(
    card_id,
    key_pair,
    validation_token,
    reason=Requests::RevokeCardRequest::Reasons::Unspecified
)
  request = Requests::RevokeCardRequest.new(
      card_id: card_id,
      reason: reason
  )
  request.restore(validation_token)
  self.request_signer.authority_sign(request, card_id, key_pair.private_key)
  self.revoke_card_from_signed_request(request)
end

#search_cards_by_app_bundle(bundle) ⇒ Object

Search cards by specified app bundle.

Args:

bundle: application bundle for search.

Returns:

Found cards from server response.


373
374
375
376
377
# File 'lib/virgil/sdk/client/virgil_client.rb', line 373

def search_cards_by_app_bundle(bundle)
  return self.search_cards_by_criteria(
      SearchCriteria.by_app_bundle(bundle)
  )
end

#search_cards_by_criteria(search_criteria) ⇒ Object

Search cards by specified search criteria.

Args:

search_criteria: constructed search criteria.

Returns:

Found cards from server response.

Raises:

VirgilClient.InvalidCardException if client has validator
and cards are not valid.


390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'lib/virgil/sdk/client/virgil_client.rb', line 390

def search_cards_by_criteria(search_criteria)
  body = {identities: search_criteria.identities}
  if search_criteria.identity_type
    body[:identity_type] = search_criteria.identity_type
  end
  if search_criteria.scope == Card::GLOBAL
    body[:scope] = Card::GLOBAL
  end
  http_request = Virgil::SDK::Client::HTTP::Request.new(
      method: HTTP::Request::POST,
      endpoint: "/#{Card::VC_VERSION}/card/actions/search",
      body: body,
  )
  response = self.read_cards_connection.send_request(http_request)
  cards = response.map { |card| Card.from_response(card) }
  self.validate_cards(cards) if self.card_validator
  return cards
end

#search_cards_by_identities(*identities) ⇒ Object

Search cards by specified identities.

Args:

identities: identity values for search.

Returns:

Found cards from server response.


360
361
362
363
364
# File 'lib/virgil/sdk/client/virgil_client.rb', line 360

def search_cards_by_identities(*identities)
  return self.search_cards_by_criteria(
      SearchCriteria.by_identities(identities)
  )
end

#sign_and_publish_card(card, app_id, app_key) ⇒ Object



163
164
165
166
167
168
169
170
171
172
# File 'lib/virgil/sdk/client/virgil_client.rb', line 163

def sign_and_publish_card(card, app_id, app_key)
  request = card.to_request
  request_signer.authority_sign(
      request,
      app_id,
      app_key
  )
  create_card_from_signed_request(request)

end

#validate_cards(cards) ⇒ Object

Validate cards signatures. Args:

cards: list of cards to validate.

Raises:

VirgilClient::InvalidCardException if some cards are not valid.


416
417
418
419
420
421
# File 'lib/virgil/sdk/client/virgil_client.rb', line 416

def validate_cards(cards)
  invalid_cards = cards.select { |card| !card_validator.is_valid?(card) }
  if invalid_cards.any?
    raise InvalidCardException.new(invalid_cards)
  end
end

#verify_identity(identity, identity_type) ⇒ Object



298
299
300
301
# File 'lib/virgil/sdk/client/virgil_client.rb', line 298

def verify_identity(identity, identity_type)
  verify_identity_request = Requests::VerifyIdentityRequest.new(identity, identity_type)
  verify_identity_from_request(verify_identity_request)
end

#verify_identity_from_request(identity_request) ⇒ Object



303
304
305
306
307
308
309
310
311
312
# File 'lib/virgil/sdk/client/virgil_client.rb', line 303

def verify_identity_from_request(identity_request)
  http_request = Virgil::SDK::Client::HTTP::Request.new(
      method: HTTP::Request::POST,
      endpoint: "/#{Card::VRA_VERSION}/verify",
      body: identity_request.request_model
  )
  raw_response = self.identity_service_connection.send_request(http_request)
  raw_response['action_id']

end