diff --git a/lib/yoti/data_type/document_details.rb b/lib/yoti/data_type/document_details.rb index 6f4dce7d..794436af 100644 --- a/lib/yoti/data_type/document_details.rb +++ b/lib/yoti/data_type/document_details.rb @@ -1,10 +1,10 @@ module Yoti class DocumentDetails # - # The values of the Document Details are in the format and order as defined in this pattern - # e.g PASS_CARD GBR 22719564893 - CITIZENCARD, the last two are optionals + # @deprecated 2.0.0 pattern is no longer used for validation. # VALIDATION_PATTERN = '^([A-Za-z_]*) ([A-Za-z]{3}) ([A-Za-z0-9]{1}).*$' + TYPE_INDEX = 0 COUNTRY_INDEX = 1 NUMBER_INDEX = 2 @@ -51,28 +51,20 @@ class DocumentDetails # @param [String] value # def initialize(value) - validate_value(value) parse_value(value) end private - # - # Asserts provided matches VALIDATION_PATTERN - # - # @param [String] value - # - def validate_value(value) - raise(ArgumentError, "Invalid value for #{self.class.name}") unless /#{VALIDATION_PATTERN}/.match?(value) - end - # # Parses provided value into separate attributes # # @param [String] value # def parse_value(value) - attributes = value.split(' ') + attributes = value.split(/ /) + raise(ArgumentError, "Invalid value for #{self.class.name}") if attributes.length < 3 || attributes.include?('') + @type = attributes[TYPE_INDEX] @issuing_country = attributes[COUNTRY_INDEX] @document_number = attributes[NUMBER_INDEX] diff --git a/lib/yoti/sandbox.rb b/lib/yoti/sandbox.rb index df966ee9..9f926d5e 100644 --- a/lib/yoti/sandbox.rb +++ b/lib/yoti/sandbox.rb @@ -2,4 +2,3 @@ require_relative 'sandbox/attribute' require_relative 'sandbox/profile' require_relative 'sandbox/sandbox_client' -require_relative 'sandbox/sandbox' diff --git a/lib/yoti/sandbox/sandbox.rb b/lib/yoti/sandbox/sandbox.rb deleted file mode 100644 index 4f1ecf78..00000000 --- a/lib/yoti/sandbox/sandbox.rb +++ /dev/null @@ -1,105 +0,0 @@ -# frozen_string_literal: true - -require 'yoti' -require 'yoti/configuration' -require 'yoti/http/signed_request' - -require_relative 'sandbox_client' -require_relative 'profile' -require_relative 'anchor' -require_relative 'attribute' - -require 'openssl' -require 'net/http' -require 'date' -require 'securerandom' - -require 'dotenv' -Dotenv.load - -# Singleton for sandbox test resources -module Sandbox - class << self - attr_accessor :sandbox_client - attr_accessor :dev_key - attr_accessor :application - end - - def self.setup! - return if application - - read_dev_key! - create_application! - self.sandbox_client = Client.new( - app_id: application['id'], - private_key: application['private_key'], - base_url: ENV['SANDBOX_BASE_URL'] - ) - configure_yoti( - app_id: sandbox_client.app_id, - pem: sandbox_client.key.to_pem - ) - nil - end - - def self.configure_yoti(app_id:, pem:) - Yoti.configuration = Yoti::Configuration.new - Yoti.configuration.client_sdk_id = app_id - Yoti.configuration.key = pem - Yoti.configuration.key_file_path = '' - Yoti.configuration.api_endpoint = "#{ENV['SANDBOX_BASE_URL']}/" - Yoti::SSL.reload! - end - - def self.create_application_uri - uri = URI( - "#{ENV['SANDBOX_BASE_URL']}/#{ENV['SANDBOX_ENDPOINT']}?\ -nonce=#{SecureRandom.uuid}×tamp=#{Time.now.to_i}" - ) - uri.port = 11_443 - uri - end - - def self.create_application! - Yoti.configure do |config| - config.key_file_path = ENV['SANDBOX_KEY'] - config.client_sdk_id = 'DUMMY' - end - - uri = create_application_uri - payload = { name: "Test Run #{DateTime.now.rfc3339}" } - - response = Net::HTTP.start( - uri.hostname, - uri.port, - use_ssl: true, - verify_mode: OpenSSL::SSL::VERIFY_NONE - ) do |http| - unsigned = Net::HTTP::Post.new uri - unsigned.body = payload.to_json - signed_request = Yoti::SignedRequest.new( - unsigned, - "#{ENV['SANDBOX_ENDPOINT']}?#{uri.query}", - payload - ).sign - Yoti::Log.logger.info("Creating application #{signed_request.body}") - http.request signed_request - end - - raise "Create application failed #{response.code}: #{response.body}" unless response.code == '201' - - self.application = JSON.parse(response.body) - nil - end - - def self.read_dev_key! - self.dev_key = OpenSSL::PKey::RSA.new( - File.read(ENV['SANDBOX_KEY'], encoding: 'utf-8') - ) - nil - end - - def self.share(profile) - sandbox_client.setup_sharing_profile profile - end -end diff --git a/lib/yoti/sandbox/sandbox_client.rb b/lib/yoti/sandbox/sandbox_client.rb index a5a7c67a..f9aba889 100644 --- a/lib/yoti/sandbox/sandbox_client.rb +++ b/lib/yoti/sandbox/sandbox_client.rb @@ -3,18 +3,14 @@ module Sandbox # Client is responsible for setting up test data in the sandbox instance class Client - attr_accessor :app_id - attr_accessor :key attr_accessor :base_url - def initialize(app_id:, private_key:, base_url:) - @app_id = app_id + def initialize(base_url:) @base_url = base_url - @key = OpenSSL::PKey::RSA.new(Base64.decode64(private_key)) end def setup_sharing_profile(profile) - endpoint = "/apps/#{app_id}/tokens?\ + endpoint = "/apps/#{Yoti.configuration.client_sdk_id}/tokens?\ nonce=#{SecureRandom.uuid}×tamp=#{Time.now.to_i}" uri = URI( "#{@base_url}/#{endpoint}" @@ -23,8 +19,7 @@ def setup_sharing_profile(profile) response = Net::HTTP.start( uri.hostname, uri.port, - use_ssl: true, - verify_mode: OpenSSL::SSL::VERIFY_NONE + use_ssl: true ) do |http| unsigned = Net::HTTP::Post.new uri unsigned.body = profile.to_json diff --git a/lib/yoti/ssl.rb b/lib/yoti/ssl.rb index 1f5f752c..f15a9a39 100644 --- a/lib/yoti/ssl.rb +++ b/lib/yoti/ssl.rb @@ -60,6 +60,7 @@ def decipher(key, user_iv, text) end # Reset and reload the Private Key used for SSL functions + # @deprecated 2.0.0 def reload! @private_key = nil @pem = nil diff --git a/lib/yoti/version.rb b/lib/yoti/version.rb index b10ec208..ed3d27ee 100644 --- a/lib/yoti/version.rb +++ b/lib/yoti/version.rb @@ -1,4 +1,4 @@ module Yoti # @return [String] the gem's current version - VERSION = '1.6.1'.freeze + VERSION = '1.6.2'.freeze end diff --git a/sonar-project.properties b/sonar-project.properties index b5efb7b6..dd638d4b 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,6 +1,6 @@ sonar.projectKey = yoti-web-sdk:ruby sonar.projectName = ruby-sdk -sonar.projectVersion = 1.6.1 +sonar.projectVersion = 1.6.2 sonar.language=ruby sonar.exclusions = **/protobuf/**.rb, coverage/**, spec/sample-data/** sonar.links.scm = https://github.com/getyoti/yoti-ruby-sdk diff --git a/spec/yoti/data_type/document_details_spec.rb b/spec/yoti/data_type/document_details_spec.rb index f2b1cfb6..0b72b87f 100644 --- a/spec/yoti/data_type/document_details_spec.rb +++ b/spec/yoti/data_type/document_details_spec.rb @@ -1,6 +1,13 @@ require 'spec_helper' describe 'Yoti::DocumentDetails' do + context 'when an empty value is provided' do + it 'should raise an error' do + expect { Yoti::DocumentDetails.new('') } + .to raise_error(ArgumentError, 'Invalid value for Yoti::DocumentDetails') + end + end + context 'when there is one optional attribute' do document_details = Yoti::DocumentDetails.new('PASSPORT GBR 01234567 2020-01-01') describe '.type' do @@ -89,20 +96,6 @@ end end - context 'when the country is invalid' do - it 'should raise ArgumentError' do - expect { Yoti::DocumentDetails.new('PASSPORT 13 1234abc 2016-05-01') } - .to raise_error(ArgumentError, 'Invalid value for Yoti::DocumentDetails') - end - end - - context 'when the document number is invalid' do - it 'should raise ArgumentError' do - expect { Yoti::DocumentDetails.new('PASSPORT GBR $%^$%^£ 2016-05-01') } - .to raise_error(ArgumentError, 'Invalid value for Yoti::DocumentDetails') - end - end - context 'when the expiration date is missing' do document_details = Yoti::DocumentDetails.new('PASS_CARD GBR 22719564893 - CITIZENCARD') describe '.expiration_date' do @@ -140,4 +133,36 @@ expect(document_details.expiration_date.to_s).to eql('2016-05-01T00:00:00+00:00') end end + + context 'when the document number is valid' do + [ + '****', + '~!@#$%^&*()-_=+[]{}|;\':,./<>?', + '""', + '\\', + '"', + '\'\'', + '\'', + "\t" + ].each do |value| + it "#{value} should be allowed as document number" do + document_details = Yoti::DocumentDetails.new("some-type some-country #{value} - some-authority") + expect(document_details.document_number).to eql(value) + end + end + end + + context 'when the value contains extra spaces' do + [ + 'some-type some-country some-doc-number - some-authority', + 'some-type some-country some-doc-number - some-authority', + 'some-type some-country some-doc-number - some-authority', + 'some-type some-country some-doc-number - some-authority' + ].each do |value| + it "should raise an ArgumentError for '#{value}''" do + expect { Yoti::DocumentDetails.new(value) } + .to raise_error(ArgumentError, 'Invalid value for Yoti::DocumentDetails') + end + end + end end diff --git a/spec/yoti/sandbox/sandbox_client_spec.rb b/spec/yoti/sandbox/sandbox_client_spec.rb index e3d81b22..5c850589 100644 --- a/spec/yoti/sandbox/sandbox_client_spec.rb +++ b/spec/yoti/sandbox/sandbox_client_spec.rb @@ -3,26 +3,17 @@ require 'spec_helper' describe 'Sandbox::Client' do - let :app_id do - '0000-0000-0000-0000' - end let :base_url do 'https://example.com' end - let :private_key do - key = OpenSSL::PKey::RSA.new 1024 - Base64.encode64(key.to_der) - end let :profile do {} end let :client do - Sandbox::Client.new(app_id: app_id, private_key: private_key, base_url: base_url) + Sandbox::Client.new(base_url: base_url) end describe '.initialize' do it 'Creates a client' do - expect(client.app_id).to eql app_id - expect(client.key).not_to be_nil expect(client.base_url).to eql base_url end end diff --git a/spec/yoti/sandbox/sandbox_spec.rb b/spec/yoti/sandbox/sandbox_spec.rb deleted file mode 100644 index aa1bf2b3..00000000 --- a/spec/yoti/sandbox/sandbox_spec.rb +++ /dev/null @@ -1,97 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe 'Sandbox' do - let :app_id do - '0000-0000-0000-0000' - end - let :base_url do - 'https://example.com' - end - let :private_key do - key = OpenSSL::PKey::RSA.new 1024 - Base64.encode64(key.to_der) - end - let :profile do - {} - end - - describe 'self.read_dev_key!' do - it 'Reads the private key' do - expect(File).to receive(:read).and_return private_key - expect { Sandbox.read_dev_key! }.to raise_error OpenSSL::PKey::RSAError - end - end - - describe 'self.share' do - before do - client = double(setup_sharing_profile: '00000') - Sandbox.instance_variable_set(:@sandbox_client, client) - end - it 'Calls Sandbox::Client.share' do - expect(Sandbox.sandbox_client).to receive(:setup_sharing_profile).with(profile) - Sandbox.share profile - end - end - - describe 'self.create_application!' do - before(:each) do - Yoti.configuration.key = private_key - ENV['SANDBOX_BASE_URL'] = base_url - stub_request(:any, %r{https:\/\/}).to_return( - status: 201, - body: File.read('spec/sample-data/responses/sandbox_create.json'), - headers: { 'Content-Type' => 'application/json' } - ) - end - it 'creates a Sandbox session' do - log_output = StringIO.new - Yoti::Log.output(log_output) - - Sandbox.create_application! - expect(Sandbox.application).not_to be_nil - - expect(log_output.string).to match(/INFO -- Yoti: Creating application {"name":"Test Run \d+-\d+-\d+T\d+:\d+:\d+\+\d+:\d+"}/) - end - end - - describe 'self.configure_yoti' do - it 'Sets the app ID' do - Sandbox.configure_yoti(app_id: app_id, pem: private_key) - expect(Yoti.configuration.client_sdk_id).not_to be_nil - end - - it 'Sets the private key' do - Sandbox.configure_yoti(app_id: app_id, pem: private_key) - expect(Yoti.configuration.key).not_to be_nil - end - - it 'Calls the SSL reload function' do - expect(Yoti::SSL).to receive(:reload!) - Sandbox.configure_yoti(app_id: app_id, pem: private_key) - end - end - - describe 'self.setup!' do - context 'With valid dev key' do - before :each do - allow(Sandbox).to receive(:read_dev_key!) - allow(Sandbox).to receive(:create_application!) { - Sandbox.application = {} - Sandbox.application['id'] = app_id - Sandbox.application['private_key'] = private_key - Sandbox.application['base_url'] = base_url - } - Sandbox.application = nil - end - it 'Configures the Sandbox session' do - expect(Sandbox).to receive(:read_dev_key!) - expect(Sandbox).to receive(:create_application!) - expect(Sandbox).to receive(:configure_yoti) - Sandbox.setup! - expect(Sandbox.sandbox_client).not_to be_nil - end - end - end -end diff --git a/spec/yoti/ssl_spec.rb b/spec/yoti/ssl_spec.rb index 4c7d3c41..c26fbff2 100644 --- a/spec/yoti/ssl_spec.rb +++ b/spec/yoti/ssl_spec.rb @@ -89,4 +89,19 @@ expect(Yoti::SSL.decipher(key, iv, ciphered_text)).to eql('cipher text') end end + + describe '.reload' do + let(:some_key) { 'some-key' } + let(:some_other_key) { 'some-other-key' } + it 'should reset pem' do + Yoti.configuration.key = some_key + expect(Yoti::SSL.pem).to eql(some_key) + + Yoti.configuration.key = some_other_key + expect(Yoti::SSL.pem).to eql(some_key) + + Yoti::SSL.reload! + expect(Yoti::SSL.pem).to eql(some_other_key) + end + end end