dilisense_pep_client 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.
- checksums.yaml +7 -0
- data/.env.example +2 -0
- data/CLAUDE.md +141 -0
- data/LICENSE +21 -0
- data/Makefile +98 -0
- data/README.md +500 -0
- data/Rakefile +37 -0
- data/dilisense_pep_client.gemspec +51 -0
- data/lib/dilisense_pep_client/audit_logger.rb +653 -0
- data/lib/dilisense_pep_client/circuit_breaker.rb +257 -0
- data/lib/dilisense_pep_client/client.rb +254 -0
- data/lib/dilisense_pep_client/configuration.rb +15 -0
- data/lib/dilisense_pep_client/errors.rb +488 -0
- data/lib/dilisense_pep_client/logger.rb +207 -0
- data/lib/dilisense_pep_client/metrics.rb +505 -0
- data/lib/dilisense_pep_client/validator.rb +456 -0
- data/lib/dilisense_pep_client/version.rb +5 -0
- data/lib/dilisense_pep_client.rb +107 -0
- metadata +246 -0
@@ -0,0 +1,456 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dry-validation"
|
4
|
+
|
5
|
+
module DilisensePepClient
|
6
|
+
# Industrial-grade input validation and sanitization system
|
7
|
+
#
|
8
|
+
# This class provides comprehensive input validation and sanitization specifically designed
|
9
|
+
# for financial services applications that handle sensitive PEP/sanctions screening data.
|
10
|
+
# It ensures data integrity, prevents injection attacks, and maintains compliance with
|
11
|
+
# security standards for financial institutions.
|
12
|
+
#
|
13
|
+
# Features:
|
14
|
+
# - Declarative validation contracts using dry-validation
|
15
|
+
# - Comprehensive input sanitization with security focus
|
16
|
+
# - API key format validation and security logging
|
17
|
+
# - Response data sanitization with size limits
|
18
|
+
# - Unicode normalization and dangerous character removal
|
19
|
+
# - Detailed error messages with context for debugging
|
20
|
+
# - Audit logging for validation events and security incidents
|
21
|
+
# - Protection against oversized responses and DoS attacks
|
22
|
+
#
|
23
|
+
# The validator handles two main screening types:
|
24
|
+
# - Individual screening: Personal data with DOB, gender, names
|
25
|
+
# - Entity screening: Company/organization names and identifiers
|
26
|
+
#
|
27
|
+
# All validation failures are logged as security events for monitoring and compliance.
|
28
|
+
# Sensitive data is automatically redacted in logs and error messages.
|
29
|
+
#
|
30
|
+
# @example Individual screening validation
|
31
|
+
# params = { names: "John Smith", dob: "01/01/1980", gender: "male" }
|
32
|
+
# validated = Validator.validate_individual_params(params)
|
33
|
+
#
|
34
|
+
# @example Entity screening validation
|
35
|
+
# params = { names: "Apple Inc", fuzzy_search: 1 }
|
36
|
+
# validated = Validator.validate_entity_params(params)
|
37
|
+
#
|
38
|
+
# @example API key validation
|
39
|
+
# sanitized_key = Validator.sanitize_api_key(raw_api_key)
|
40
|
+
class Validator
|
41
|
+
# Individual screening parameters validation contract
|
42
|
+
# Defines validation rules for person-based PEP screening with comprehensive checks
|
43
|
+
# for data format, mutual exclusivity, and security constraints
|
44
|
+
IndividualContract = Dry::Validation.Contract do
|
45
|
+
params do
|
46
|
+
optional(:names).maybe(:string)
|
47
|
+
optional(:search_all).maybe(:string)
|
48
|
+
optional(:dob).maybe(:string)
|
49
|
+
optional(:gender).maybe(:string)
|
50
|
+
optional(:fuzzy_search).maybe(:integer)
|
51
|
+
optional(:includes).maybe(:string)
|
52
|
+
end
|
53
|
+
|
54
|
+
rule(:names, :search_all) do
|
55
|
+
if values[:names] && values[:search_all]
|
56
|
+
key.failure("cannot use both 'names' and 'search_all' parameters")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
rule(:names, :search_all) do
|
61
|
+
unless values[:names] || values[:search_all]
|
62
|
+
key.failure("either 'names' or 'search_all' parameter is required")
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
rule(:dob) do
|
67
|
+
if value && !valid_date_format?(value)
|
68
|
+
key.failure("must be in format DD/MM/YYYY, 00/MM/YYYY, DD/00/YYYY, or 00/00/YYYY")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
rule(:gender) do
|
73
|
+
if value && !%w[male female].include?(value.downcase)
|
74
|
+
key.failure("must be 'male' or 'female'")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
rule(:fuzzy_search) do
|
79
|
+
if value && ![1, 2].include?(value)
|
80
|
+
key.failure("must be 1 or 2")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
rule(:names) do
|
85
|
+
if value && (value.length > 200 || value.strip.empty?)
|
86
|
+
key.failure("must be between 1 and 200 characters")
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
rule(:search_all) do
|
91
|
+
if value && (value.length > 200 || value.strip.empty?)
|
92
|
+
key.failure("must be between 1 and 200 characters")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def valid_date_format?(date_str)
|
99
|
+
# Validate DD/MM/YYYY format with flexible day/month
|
100
|
+
return false unless date_str.match?(/^\d{2}\/\d{2}\/\d{4}$/)
|
101
|
+
|
102
|
+
parts = date_str.split("/")
|
103
|
+
day, month, year = parts.map(&:to_i)
|
104
|
+
|
105
|
+
# Validate year (reasonable range)
|
106
|
+
return false if year < 1900 || year > Date.today.year + 10
|
107
|
+
|
108
|
+
# Allow 00 for unknown day/month
|
109
|
+
return false if day > 31 || month > 12
|
110
|
+
return false if day < 0 || month < 0
|
111
|
+
|
112
|
+
true
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# Entity screening parameters validation contract
|
117
|
+
# Defines validation rules for company/organization-based screening with focus
|
118
|
+
# on entity name formats and organizational identifier validation
|
119
|
+
EntityContract = Dry::Validation.Contract do
|
120
|
+
params do
|
121
|
+
optional(:names).maybe(:string)
|
122
|
+
optional(:search_all).maybe(:string)
|
123
|
+
optional(:fuzzy_search).maybe(:integer)
|
124
|
+
end
|
125
|
+
|
126
|
+
rule(:names, :search_all) do
|
127
|
+
if values[:names] && values[:search_all]
|
128
|
+
key.failure("cannot use both 'names' and 'search_all' parameters")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
rule(:names, :search_all) do
|
133
|
+
unless values[:names] || values[:search_all]
|
134
|
+
key.failure("either 'names' or 'search_all' parameter is required")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
rule(:fuzzy_search) do
|
139
|
+
if value && ![1, 2].include?(value)
|
140
|
+
key.failure("must be 1 or 2")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
rule(:names) do
|
145
|
+
if value && (value.length > 300 || value.strip.empty?)
|
146
|
+
key.failure("must be between 1 and 300 characters")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
rule(:search_all) do
|
151
|
+
if value && (value.length > 300 || value.strip.empty?)
|
152
|
+
key.failure("must be between 1 and 300 characters")
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class << self
|
158
|
+
# Validate and sanitize individual screening parameters
|
159
|
+
# Applies comprehensive validation rules and sanitization for person-based screening
|
160
|
+
#
|
161
|
+
# @param params [Hash] Raw input parameters from user/API
|
162
|
+
# @return [Hash] Validated and sanitized parameters
|
163
|
+
# @raise [ValidationError] When validation rules fail
|
164
|
+
#
|
165
|
+
# @example Valid individual parameters
|
166
|
+
# params = {
|
167
|
+
# names: "John Smith",
|
168
|
+
# dob: "15/06/1985",
|
169
|
+
# gender: "male",
|
170
|
+
# fuzzy_search: 1
|
171
|
+
# }
|
172
|
+
# validated = validate_individual_params(params)
|
173
|
+
def validate_individual_params(params)
|
174
|
+
sanitized_params = sanitize_individual_params(params)
|
175
|
+
result = IndividualContract.call(sanitized_params)
|
176
|
+
|
177
|
+
if result.failure?
|
178
|
+
error_messages = extract_error_messages(result.errors)
|
179
|
+
raise ValidationError.new(
|
180
|
+
"Invalid individual screening parameters",
|
181
|
+
validation_errors: error_messages,
|
182
|
+
context: {
|
183
|
+
sanitized_params: sanitized_params,
|
184
|
+
original_params_keys: params.keys
|
185
|
+
}
|
186
|
+
)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Log validation success for audit trail
|
190
|
+
Logger.logger.debug("Individual params validation successful", {
|
191
|
+
sanitized_params: sanitized_params,
|
192
|
+
validation_rules_applied: %w[
|
193
|
+
mutual_exclusion name_format length_limits
|
194
|
+
date_format gender_values fuzzy_search_range
|
195
|
+
]
|
196
|
+
})
|
197
|
+
|
198
|
+
result.to_h
|
199
|
+
end
|
200
|
+
|
201
|
+
def validate_entity_params(params)
|
202
|
+
sanitized_params = sanitize_entity_params(params)
|
203
|
+
result = EntityContract.call(sanitized_params)
|
204
|
+
|
205
|
+
if result.failure?
|
206
|
+
error_messages = extract_error_messages(result.errors)
|
207
|
+
raise ValidationError.new(
|
208
|
+
"Invalid entity screening parameters",
|
209
|
+
validation_errors: error_messages,
|
210
|
+
context: {
|
211
|
+
sanitized_params: sanitized_params,
|
212
|
+
original_params_keys: params.keys
|
213
|
+
}
|
214
|
+
)
|
215
|
+
end
|
216
|
+
|
217
|
+
# Log validation success for audit
|
218
|
+
Logger.logger.debug("Entity params validation successful", {
|
219
|
+
sanitized_params: sanitized_params,
|
220
|
+
validation_rules_applied: %w[
|
221
|
+
mutual_exclusion name_format length_limits fuzzy_search_range
|
222
|
+
]
|
223
|
+
})
|
224
|
+
|
225
|
+
result.to_h
|
226
|
+
end
|
227
|
+
|
228
|
+
def sanitize_api_key(api_key)
|
229
|
+
return nil if api_key.nil? || api_key.to_s.strip.empty?
|
230
|
+
|
231
|
+
key = api_key.to_s.strip
|
232
|
+
|
233
|
+
# Validate API key format (basic checks)
|
234
|
+
unless valid_api_key_format?(key)
|
235
|
+
raise ConfigurationError.new(
|
236
|
+
"Invalid API key format",
|
237
|
+
config_key: "api_key",
|
238
|
+
context: {
|
239
|
+
key_length: key.length,
|
240
|
+
key_format: detect_key_format(key)
|
241
|
+
}
|
242
|
+
)
|
243
|
+
end
|
244
|
+
|
245
|
+
# Log API key validation (without exposing the key)
|
246
|
+
Logger.log_security_event(
|
247
|
+
event_type: "api_key_validation",
|
248
|
+
details: {
|
249
|
+
key_length: key.length,
|
250
|
+
key_format: detect_key_format(key),
|
251
|
+
validation_result: "success"
|
252
|
+
},
|
253
|
+
severity: :low
|
254
|
+
)
|
255
|
+
|
256
|
+
key
|
257
|
+
end
|
258
|
+
|
259
|
+
def sanitize_response_data(data, max_size: 1_048_576) # 1MB default
|
260
|
+
return nil unless data
|
261
|
+
|
262
|
+
# Check response size
|
263
|
+
data_size = data.to_s.bytesize
|
264
|
+
if data_size > max_size
|
265
|
+
Logger.log_security_event(
|
266
|
+
event_type: "oversized_response",
|
267
|
+
details: {
|
268
|
+
response_size: data_size,
|
269
|
+
max_allowed: max_size,
|
270
|
+
truncated: true
|
271
|
+
},
|
272
|
+
severity: :medium
|
273
|
+
)
|
274
|
+
|
275
|
+
# Truncate large responses
|
276
|
+
truncated_data = data.to_s[0, max_size]
|
277
|
+
return "#{truncated_data}... [TRUNCATED: original size #{data_size} bytes]"
|
278
|
+
end
|
279
|
+
|
280
|
+
# Sanitize potentially sensitive data patterns
|
281
|
+
sanitized = data.to_s.gsub(
|
282
|
+
/\b(?:api[_-]?key|token|secret|password)\s*[=:]\s*[^\s&]+/i,
|
283
|
+
'[REDACTED_CREDENTIAL]'
|
284
|
+
)
|
285
|
+
|
286
|
+
sanitized
|
287
|
+
end
|
288
|
+
|
289
|
+
private
|
290
|
+
|
291
|
+
def sanitize_individual_params(params)
|
292
|
+
return {} unless params.is_a?(Hash)
|
293
|
+
|
294
|
+
sanitized = {}
|
295
|
+
|
296
|
+
params.each do |key, value|
|
297
|
+
sanitized_key = key.to_sym
|
298
|
+
sanitized_value = case sanitized_key
|
299
|
+
when :names, :search_all
|
300
|
+
sanitize_name_input(value)
|
301
|
+
when :dob
|
302
|
+
sanitize_date_input(value)
|
303
|
+
when :gender
|
304
|
+
sanitize_gender_input(value)
|
305
|
+
when :fuzzy_search
|
306
|
+
sanitize_integer_input(value, min: 1, max: 2)
|
307
|
+
when :includes
|
308
|
+
sanitize_includes_input(value)
|
309
|
+
else
|
310
|
+
# Unknown parameter - log and ignore
|
311
|
+
Logger.log_security_event(
|
312
|
+
event_type: "unknown_parameter",
|
313
|
+
details: {
|
314
|
+
parameter_name: key,
|
315
|
+
parameter_value: value.to_s[0, 50],
|
316
|
+
context: "individual_screening"
|
317
|
+
},
|
318
|
+
severity: :low
|
319
|
+
)
|
320
|
+
next
|
321
|
+
end
|
322
|
+
|
323
|
+
sanitized[sanitized_key] = sanitized_value if sanitized_value
|
324
|
+
end
|
325
|
+
|
326
|
+
sanitized
|
327
|
+
end
|
328
|
+
|
329
|
+
def sanitize_entity_params(params)
|
330
|
+
return {} unless params.is_a?(Hash)
|
331
|
+
|
332
|
+
sanitized = {}
|
333
|
+
|
334
|
+
params.each do |key, value|
|
335
|
+
sanitized_key = key.to_sym
|
336
|
+
sanitized_value = case sanitized_key
|
337
|
+
when :names, :search_all
|
338
|
+
sanitize_name_input(value, max_length: 300)
|
339
|
+
when :fuzzy_search
|
340
|
+
sanitize_integer_input(value, min: 1, max: 2)
|
341
|
+
else
|
342
|
+
# Unknown parameter - log and ignore
|
343
|
+
Logger.log_security_event(
|
344
|
+
event_type: "unknown_parameter",
|
345
|
+
details: {
|
346
|
+
parameter_name: key,
|
347
|
+
parameter_value: value.to_s[0, 50],
|
348
|
+
context: "entity_screening"
|
349
|
+
},
|
350
|
+
severity: :low
|
351
|
+
)
|
352
|
+
next
|
353
|
+
end
|
354
|
+
|
355
|
+
sanitized[sanitized_key] = sanitized_value if sanitized_value
|
356
|
+
end
|
357
|
+
|
358
|
+
sanitized
|
359
|
+
end
|
360
|
+
|
361
|
+
def sanitize_name_input(value, max_length: 200)
|
362
|
+
return nil if value.nil?
|
363
|
+
|
364
|
+
name = value.to_s.strip
|
365
|
+
return nil if name.empty?
|
366
|
+
|
367
|
+
# Remove potentially dangerous characters
|
368
|
+
name = name.gsub(/[<>\"'&\x00-\x1F\x7F-\x9F]/, '')
|
369
|
+
|
370
|
+
# Normalize unicode and whitespace
|
371
|
+
name = name.unicode_normalize(:nfc).squeeze(' ')
|
372
|
+
|
373
|
+
# Truncate if too long
|
374
|
+
name = name[0, max_length] if name.length > max_length
|
375
|
+
|
376
|
+
# Final validation
|
377
|
+
return nil if name.strip.empty?
|
378
|
+
|
379
|
+
name
|
380
|
+
end
|
381
|
+
|
382
|
+
def sanitize_date_input(value)
|
383
|
+
return nil if value.nil?
|
384
|
+
|
385
|
+
date_str = value.to_s.strip
|
386
|
+
return nil if date_str.empty?
|
387
|
+
|
388
|
+
# Only allow specific date format
|
389
|
+
return nil unless date_str.match?(/^\d{2}\/\d{2}\/\d{4}$/)
|
390
|
+
|
391
|
+
date_str
|
392
|
+
end
|
393
|
+
|
394
|
+
def sanitize_gender_input(value)
|
395
|
+
return nil if value.nil?
|
396
|
+
|
397
|
+
gender = value.to_s.strip.downcase
|
398
|
+
return nil unless %w[male female].include?(gender)
|
399
|
+
|
400
|
+
gender
|
401
|
+
end
|
402
|
+
|
403
|
+
def sanitize_integer_input(value, min: nil, max: nil)
|
404
|
+
return nil if value.nil?
|
405
|
+
|
406
|
+
int_value = case value
|
407
|
+
when Integer then value
|
408
|
+
when String then value.to_i if value.match?(/^\d+$/)
|
409
|
+
else nil
|
410
|
+
end
|
411
|
+
|
412
|
+
return nil unless int_value
|
413
|
+
return nil if min && int_value < min
|
414
|
+
return nil if max && int_value > max
|
415
|
+
|
416
|
+
int_value
|
417
|
+
end
|
418
|
+
|
419
|
+
def sanitize_includes_input(value)
|
420
|
+
return nil if value.nil?
|
421
|
+
|
422
|
+
includes = value.to_s.strip
|
423
|
+
return nil if includes.empty?
|
424
|
+
|
425
|
+
# Basic validation for source IDs (alphanumeric, underscore, comma, space)
|
426
|
+
return nil unless includes.match?(/^[a-zA-Z0-9_,\s]+$/)
|
427
|
+
|
428
|
+
# Normalize and clean up
|
429
|
+
includes.gsub(/\s+/, ' ').strip
|
430
|
+
end
|
431
|
+
|
432
|
+
def valid_api_key_format?(key)
|
433
|
+
# Basic API key format validation
|
434
|
+
return false if key.length < 10 || key.length > 200
|
435
|
+
|
436
|
+
# Check for reasonable character set
|
437
|
+
key.match?(/^[a-zA-Z0-9._-]+$/)
|
438
|
+
end
|
439
|
+
|
440
|
+
def detect_key_format(key)
|
441
|
+
case key.length
|
442
|
+
when 10..50 then "short_key"
|
443
|
+
when 51..100 then "medium_key"
|
444
|
+
when 101..200 then "long_key"
|
445
|
+
else "unknown"
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
def extract_error_messages(errors)
|
450
|
+
errors.to_h.map do |field, messages|
|
451
|
+
Array(messages).map { |msg| "#{field}: #{msg}" }
|
452
|
+
end.flatten
|
453
|
+
end
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "dilisense_pep_client/version"
|
4
|
+
require_relative "dilisense_pep_client/configuration"
|
5
|
+
require_relative "dilisense_pep_client/errors"
|
6
|
+
require_relative "dilisense_pep_client/client"
|
7
|
+
|
8
|
+
# Main module for the Dilisense PEP/Sanctions screening Ruby client
|
9
|
+
# Provides a simple interface for screening individuals and entities
|
10
|
+
# against PEP (Politically Exposed Persons) and sanctions lists
|
11
|
+
#
|
12
|
+
# @example Basic configuration and usage
|
13
|
+
# # Configure the gem with your API key (usually done once at startup)
|
14
|
+
# DilisensePepClient.configure do |config|
|
15
|
+
# config.api_key = "your_api_key_here"
|
16
|
+
# config.timeout = 30 # Optional: customize timeout
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # Screen an individual
|
20
|
+
# results = DilisensePepClient.check_individual(
|
21
|
+
# names: "Vladimir Putin",
|
22
|
+
# dob: "07/10/1952",
|
23
|
+
# gender: "male"
|
24
|
+
# )
|
25
|
+
#
|
26
|
+
# # Screen an entity/company
|
27
|
+
# results = DilisensePepClient.check_entity(names: "Bank Rossiya")
|
28
|
+
#
|
29
|
+
module DilisensePepClient
|
30
|
+
class << self
|
31
|
+
# Access the configuration object
|
32
|
+
# Returns the configuration instance which holds all settings
|
33
|
+
#
|
34
|
+
# @return [Configuration] Configuration instance
|
35
|
+
def configuration
|
36
|
+
@configuration ||= Configuration.new
|
37
|
+
end
|
38
|
+
|
39
|
+
# Configure the gem with a block
|
40
|
+
# This is the main way to set up the gem with your API key and preferences
|
41
|
+
#
|
42
|
+
# @yield [config] Configuration block
|
43
|
+
# @yieldparam config [Configuration] The configuration object to modify
|
44
|
+
#
|
45
|
+
# @example Set API key and timeout
|
46
|
+
# DilisensePepClient.configure do |config|
|
47
|
+
# config.api_key = "your_api_key"
|
48
|
+
# config.timeout = 45
|
49
|
+
# end
|
50
|
+
def configure
|
51
|
+
yield(configuration)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Get or create the API client instance
|
55
|
+
# Uses singleton pattern to reuse the same client
|
56
|
+
#
|
57
|
+
# @return [Client] The API client instance
|
58
|
+
def client
|
59
|
+
@client ||= Client.new
|
60
|
+
end
|
61
|
+
|
62
|
+
# Convenience method to screen an individual
|
63
|
+
# Delegates to the client's check_individual method
|
64
|
+
#
|
65
|
+
# @param names [String, nil] Full name to search
|
66
|
+
# @param search_all [String, nil] Alternative search parameter
|
67
|
+
# @param dob [String, nil] Date of birth (DD/MM/YYYY)
|
68
|
+
# @param gender [String, nil] Gender (male/female)
|
69
|
+
# @param fuzzy_search [Integer, nil] Fuzzy search level (1 or 2)
|
70
|
+
# @param includes [String, nil] Source IDs to include
|
71
|
+
# @return [Array<Hash>] Array of matching individuals
|
72
|
+
#
|
73
|
+
# @example Screen with multiple parameters
|
74
|
+
# results = DilisensePepClient.check_individual(
|
75
|
+
# names: "John Smith",
|
76
|
+
# dob: "01/01/1980",
|
77
|
+
# fuzzy_search: 1
|
78
|
+
# )
|
79
|
+
def check_individual(names: nil, search_all: nil, dob: nil, gender: nil, fuzzy_search: nil, includes: nil)
|
80
|
+
client.check_individual(names: names, search_all: search_all, dob: dob, gender: gender, fuzzy_search: fuzzy_search, includes: includes)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Convenience method to screen an entity/company
|
84
|
+
# Delegates to the client's check_entity method
|
85
|
+
#
|
86
|
+
# @param names [String, nil] Entity name to search
|
87
|
+
# @param search_all [String, nil] Alternative search parameter
|
88
|
+
# @param fuzzy_search [Integer, nil] Fuzzy search level (1 or 2)
|
89
|
+
# @return [Array<Hash>] Array of matching entities
|
90
|
+
#
|
91
|
+
# @example Screen a company
|
92
|
+
# results = DilisensePepClient.check_entity(names: "Apple Inc")
|
93
|
+
def check_entity(names: nil, search_all: nil, fuzzy_search: nil)
|
94
|
+
client.check_entity(names: names, search_all: search_all, fuzzy_search: fuzzy_search)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Reset the gem to its initial state
|
98
|
+
# Clears configuration and client instance
|
99
|
+
# Useful for testing or reconfiguration
|
100
|
+
#
|
101
|
+
# @return [nil]
|
102
|
+
def reset!
|
103
|
+
@configuration = nil
|
104
|
+
@client = nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|