kdonovan-trufina 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +116 -0
- data/Rakefile +53 -0
- data/TODO +8 -0
- data/VERSION +1 -0
- data/init.rb +1 -0
- data/lib/config.rb +62 -0
- data/lib/elements.rb +170 -0
- data/lib/exceptions.rb +15 -0
- data/lib/requests.rb +132 -0
- data/lib/responses.rb +90 -0
- data/lib/trufina.rb +143 -0
- data/rails/init.rb +12 -0
- data/tasks/trufina_tasks.rake +4 -0
- data/test/fixtures/requests/access_request.xml +16 -0
- data/test/fixtures/requests/info_request.xml +6 -0
- data/test/fixtures/requests/login_info_request.xml +6 -0
- data/test/fixtures/requests/login_request.xml +32 -0
- data/test/fixtures/requests/login_request_simple.xml +11 -0
- data/test/fixtures/responses/access_notification.xml +5 -0
- data/test/fixtures/responses/access_response.xml +13 -0
- data/test/fixtures/responses/info_response.xml +19 -0
- data/test/fixtures/responses/login_info_response.xml +15 -0
- data/test/fixtures/responses/login_response.xml +5 -0
- data/test/fixtures/schema.xsd +1064 -0
- data/test/test_helper.rb +15 -0
- data/test/trufina_test.rb +8 -0
- data/trufina.yml.template +31 -0
- metadata +92 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rdoc/
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
= Trufina
|
2
|
+
|
3
|
+
The Trufina gem provides a DSL allowing you to easily interface with {Trufina.com}[http://www.trufina.com]'s identity verification API.
|
4
|
+
Trufina[http://www.trufina.com] provides an identity verification service, and this DSL basically lets you request verified information
|
5
|
+
from the user (who provides that information directly to Trufina[http://www.trufina.com], and then uses their website to control
|
6
|
+
permissions of who can access what parts of their personal data).
|
7
|
+
|
8
|
+
== Requirements
|
9
|
+
|
10
|
+
Before you begin you'll need to fill out some paperwork with Trufina[http://www.trufina.com] and, after a bit of administrative mucking around,
|
11
|
+
you'll be given two important identifiers: a PID (Partner ID) and a PAK (Partner Authentication Key). Place these in
|
12
|
+
your +config/trufina.yml+ file, replace the other defaults, and you'll be good to go.
|
13
|
+
|
14
|
+
== Installation
|
15
|
+
|
16
|
+
Getting the code on your system is as simple as
|
17
|
+
|
18
|
+
script/plugin install git://github.com/kdonovan/trufina.git
|
19
|
+
|
20
|
+
or
|
21
|
+
|
22
|
+
gem sources -a http://gems.github.com
|
23
|
+
sudo gem install kdonovan-trufina
|
24
|
+
|
25
|
+
|
26
|
+
Once you have the code, you'll need to create a +trufina.yml+ file in your project's config directory. If you don't
|
27
|
+
do this by hand, a template file will be created automatically the first time you load your application after installation.
|
28
|
+
Trufina will raise a ConfigFileError until you fill out the config file with meaningful data.
|
29
|
+
|
30
|
+
|
31
|
+
== Example
|
32
|
+
|
33
|
+
Once installation has been completed, using the code itself is really easy -- the most complicated step is understanding
|
34
|
+
Trufina[http://www.trufina.com]'s various flows. We'll walk through an example:
|
35
|
+
|
36
|
+
# We'll skip it here for verbosity, but note that you can turn on debugging
|
37
|
+
# to print out pretty versions of any XML sent or received.
|
38
|
+
# Trufina::Config.debug = true
|
39
|
+
|
40
|
+
Say we have a user in our database for whom we want verified information. The first step is to
|
41
|
+
establish a session key with Trufina[http://www.trufina.com] so we can associate later responses with this request. This
|
42
|
+
is done by sending them a PRT (Partner Request Token), which can be any arbitrary value. In a real app
|
43
|
+
I'd probably use a user-id + timestamp combination, but for this demo we'll use the {random number}[http://xkcd.com/221/] 4.
|
44
|
+
|
45
|
+
Note that you can also specify what data you want access to (name, address, country of birth, etcetera),
|
46
|
+
as well as any default values you may already know to prefill the form on the Trufina[http://www.trufina.com] website. See
|
47
|
+
Trufina.login_url or Trufina.login_request for more details, but the default is to request the user's first and last name.
|
48
|
+
|
49
|
+
Trufina.login_url(4, :demo => true) # => http://staging.trufina.com/DemoPartnerLogin/DemoLogin/6ZEeENWWD8@K
|
50
|
+
|
51
|
+
|
52
|
+
You can now visit this URL to create an account for a fake user on Trufina[http://www.trufina.com]'s demo server. When you're done,
|
53
|
+
you'll be redirected to whatever you put as your success endpoint in +trufina.yml+, and there will be a TLID
|
54
|
+
(Temporary Login ID) appended. In my case it was 870. You have 15 minutes to use this TLID to access the
|
55
|
+
information about the user Trufina[http://www.trufina.com] has verified.
|
56
|
+
|
57
|
+
info = Trufina.login_info_request(870)
|
58
|
+
info.data.present_and_verified # => [{:name=>[{:first=>"TEST_FIRNAME"}, {:surname=>"TEST_SURNAME"}]}] (or whatever names you entered on the staging server)
|
59
|
+
|
60
|
+
|
61
|
+
That completes the simplest use-case. Say we decide we want more information about the user, like their middle
|
62
|
+
name. We send Trufina[http://www.trufina.com] an access request, and if the user has already provided the information and given us
|
63
|
+
permission we'll get the info back immediately.
|
64
|
+
|
65
|
+
new_info = Trufina.access_request(info, {:name => [:middle]})
|
66
|
+
new_info.data.present_and_verified # => [{:name=>[{:middle=>"SomeMiddleName"}]}]
|
67
|
+
|
68
|
+
|
69
|
+
Note that here our demo user has already given Trufina[http://www.trufina.com] permission to see all the name components, so we get
|
70
|
+
the middle name back immediately. For a different component where Trufina[http://www.trufina.com] needs to ask the user there's no
|
71
|
+
useful data in the response (the XML contains a "pending" node, but the gem doesn't bother parsing it out).
|
72
|
+
|
73
|
+
Trufina.access_request(info, [:phone]).data.present_and_verified # => []
|
74
|
+
|
75
|
+
|
76
|
+
In this case we would receive an AccessNotification to our servers once the user gave us permission to access
|
77
|
+
the requested data, and at that point we'd be able to re-request the data with another Trufina.access_request
|
78
|
+
call, for which the newly requested data would show up like the middle name did above.
|
79
|
+
|
80
|
+
|
81
|
+
== Advanced Topics
|
82
|
+
|
83
|
+
=== Seed Info
|
84
|
+
|
85
|
+
Trufina.login_request (and therefore Trufina.login_url, which is just a wrapper) allows you to pass along seed
|
86
|
+
data used to prepopulate the fields the user will encounter on Trufina.com (see Trufina::Elements::SeedInfoGroup
|
87
|
+
for all options). Prepopulated data will be specified as the value of a :seed key in the options hash of either
|
88
|
+
method. Example:
|
89
|
+
|
90
|
+
Trufina.login_request(4, :seed => {:name => {:first => 'Foo', :surname => 'Bar'}})
|
91
|
+
|
92
|
+
=== Request Data
|
93
|
+
|
94
|
+
A number of the API calls allow you to supply a list of the data you'd like returned about the user in question.
|
95
|
+
You may do this as follows:
|
96
|
+
|
97
|
+
Trufina.login_request(4, :requested => [:age, {:name => [:first, :middle, :surname]}])
|
98
|
+
|
99
|
+
or
|
100
|
+
|
101
|
+
Trufina.access_request({:pur => 4, :prt => 4}, [:age, {:name => [:first, :middle, :surname]}])
|
102
|
+
|
103
|
+
|
104
|
+
== Unsupported functionality
|
105
|
+
|
106
|
+
* Does not handle requesting comparisons or other request attributes
|
107
|
+
* (Note that Trufina[http://www.trufina.com] itself doesn't support maxAge or timeframe yet)
|
108
|
+
* Setting ResidenceAddress seed data isn't yet supported
|
109
|
+
|
110
|
+
== Compatibility
|
111
|
+
|
112
|
+
The goal of this module is to be relatively framework agnostic. That being said, I've personally only tried to use it
|
113
|
+
in conjunction with a Rails application. If you run into problems trying to use it elsewhere, well... patches happily
|
114
|
+
accepted. :)
|
115
|
+
|
116
|
+
Copyright (c) 2009 Kali Donovan, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'jeweler'
|
7
|
+
Jeweler::Tasks.new do |gem|
|
8
|
+
gem.name = "trufina"
|
9
|
+
gem.summary = %Q{DSL to easily interact with Trufina's verification API}
|
10
|
+
gem.description = %Q{Provides a DSL to easily interact with the XML API offered by Trufina.com, an identity verification company.}
|
11
|
+
gem.email = "kali.donovan@gmail.com"
|
12
|
+
gem.homepage = "http://github.com/kdonovan/trufina"
|
13
|
+
gem.authors = ["Kali Donovan"]
|
14
|
+
gem.add_dependency "jimmyz-happymapper"
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Default: run unit tests.'
|
21
|
+
task :default => :test
|
22
|
+
|
23
|
+
desc 'Test the trufina plugin.'
|
24
|
+
Rake::TestTask.new(:test) do |t|
|
25
|
+
t.libs << 'lib'
|
26
|
+
t.libs << 'test'
|
27
|
+
t.pattern = 'test/**/*_test.rb'
|
28
|
+
t.verbose = true
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Generate documentation for the trufina plugin.'
|
32
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
33
|
+
rdoc.rdoc_dir = 'rdoc'
|
34
|
+
rdoc.title = 'Trufina API'
|
35
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
36
|
+
rdoc.rdoc_files.include('README.rdoc')
|
37
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
38
|
+
rdoc.rdoc_files.exclude('init.rb')
|
39
|
+
rdoc.rdoc_files.exclude('rails/init.rb')
|
40
|
+
end
|
41
|
+
|
42
|
+
# gem 'darkfish-rdoc'
|
43
|
+
# require 'darkfish-rdoc'
|
44
|
+
#
|
45
|
+
# Rake::RDocTask.new(:darkfish) do |rdoc|
|
46
|
+
# rdoc.title = "Trufina API"
|
47
|
+
# rdoc.rdoc_files.include 'README.rdoc'
|
48
|
+
#
|
49
|
+
# rdoc.options += [
|
50
|
+
# '-SHN',
|
51
|
+
# '-f', 'darkfish', # This is the important bit
|
52
|
+
# ]
|
53
|
+
# end
|
data/TODO
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
PENDING:
|
2
|
+
* Schema validation against the provided .xsd fails
|
3
|
+
* Unable to set ResidenceAddress in seed data (e.g. Trufina.login_request(4, :seed => {:residence_address => {:state => 'CA'}}))
|
4
|
+
Yields error: Attribute 'timeframe' must appear on element 'ResidenceAddress' (noted in README)
|
5
|
+
|
6
|
+
UNSUPPORTED:
|
7
|
+
* Setting StreetAddress seed data is unsupported (will generate extra <.> tags, and it is unclear how to set multiple lines)
|
8
|
+
* Comparison or other request attributes (note that maxAge and timeframe are not even supported by Trufina yet)
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'rails', 'init')
|
data/lib/config.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
class Trufina
|
2
|
+
# Reads in configuration data from config/trufina.yml (and handles creating it if missing / complaining if it looks unfilled).
|
3
|
+
class Config
|
4
|
+
cattr_accessor :credentials, :staging_access, :endpoints,
|
5
|
+
:app_root, :config_file, :mode, :debug
|
6
|
+
|
7
|
+
# Allow range of config locations
|
8
|
+
self.app_root = RAILS_ROOT if defined?(RAILS_ROOT)
|
9
|
+
self.app_root = Merb.root if defined?(Merb)
|
10
|
+
self.app_root ||= app_root
|
11
|
+
self.app_root ||= Dir.pwd
|
12
|
+
self.config_file = File.join(self.app_root, 'config', 'trufina.yml')
|
13
|
+
|
14
|
+
# Symbolize hash keys - defined here so we don't rely on Rails
|
15
|
+
def self.symbolize_keys!(hash) # :nodoc:
|
16
|
+
return hash unless hash.is_a?(Hash)
|
17
|
+
|
18
|
+
hash.keys.each do |key|
|
19
|
+
unless key.is_a?(Symbol)
|
20
|
+
hash[key.to_sym] = hash[key]
|
21
|
+
hash.delete(key)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
hash
|
25
|
+
end
|
26
|
+
|
27
|
+
# Ensure config exists
|
28
|
+
unless File.exists?(self.config_file)
|
29
|
+
config_template = File.join(File.dirname(__FILE__), '..', 'trufina.yml.template')
|
30
|
+
File.copy(config_template, self.config_file)
|
31
|
+
raise Exceptions::ConfigFileError.new("Unable to create configuration template at #{self.config_file}") unless File.exists?(self.config_file)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Load keys from config file into the class
|
35
|
+
YAML.load(ERB.new(File.read(self.config_file)).result).each do |key, value|
|
36
|
+
self.send("#{key}=", symbolize_keys!(value)) if self.methods.include?("#{key}=")
|
37
|
+
end
|
38
|
+
|
39
|
+
# Set default mode unless already set in the config file
|
40
|
+
unless %w(production staging).include?(self.mode)
|
41
|
+
env = defined?(Merb) ? ENV['MERB_ENV'] : ENV['RAILS_ENV']
|
42
|
+
@@mode = env && env == 'production' ? 'production' : 'staging'
|
43
|
+
end
|
44
|
+
|
45
|
+
# Ensure template file has been modified with (hopefully) real data
|
46
|
+
if self.credentials.any?{|k,v| v == 'YOUR_DATA_HERE'}
|
47
|
+
raise Exceptions::ConfigFileError.new("Don't forget to update the Trufina config file with your own data! File is located at #{self.config_file}")
|
48
|
+
end
|
49
|
+
|
50
|
+
# Syntactic sugar for setting and checking the current operating mode
|
51
|
+
class << self
|
52
|
+
%w(staging production).each do |mode|
|
53
|
+
define_method("#{mode}!"){ @@mode = mode }
|
54
|
+
define_method("#{mode}?"){ @@mode == mode }
|
55
|
+
end
|
56
|
+
def debug?
|
57
|
+
!!@@debug
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/lib/elements.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
# Contains smaller classes (essentially HappyMapper element classes) used to create and
|
2
|
+
# parse API calls and responses.
|
3
|
+
|
4
|
+
class Trufina
|
5
|
+
|
6
|
+
# Handle creating a HappyMapper object from array or hash (creating empty nodes as required).
|
7
|
+
module AllowCreationFromHash
|
8
|
+
|
9
|
+
def initialize(seed_data = {})
|
10
|
+
seed_data.is_a?(Array) ? create_empty_nodes(seed_data) : create_nodes(seed_data)
|
11
|
+
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
# e.g. Trufina::Name.new([:first, :suffix]) - no values provided, print empty nodes
|
16
|
+
#
|
17
|
+
# <Name>
|
18
|
+
# <First/>
|
19
|
+
# <Suffix/>
|
20
|
+
# </Name>
|
21
|
+
def create_empty_nodes(nodes)
|
22
|
+
nodes.each do |node|
|
23
|
+
create_node(node)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# e.g. Trufina::Name.new({:first => 'Bob', :suffix => 'III'}) - print nodes with values
|
28
|
+
#
|
29
|
+
# <Name>
|
30
|
+
# <First>Bob</First>
|
31
|
+
# <Suffix>III</Suffix>
|
32
|
+
# </Name>
|
33
|
+
def create_nodes(nodes)
|
34
|
+
nodes.each do |node, content|
|
35
|
+
create_node(node, content)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Handle the actual node creation
|
40
|
+
def create_node(name, content = nil)
|
41
|
+
case name
|
42
|
+
when Array then create_empty_nodes(name)
|
43
|
+
when Hash then create_nodes(name)
|
44
|
+
else
|
45
|
+
element = self.class.elements.detect{|e| e.method_name.to_sym == name}
|
46
|
+
raise Exceptions::InvalidElement.new("No known element named '#{name}'") unless element
|
47
|
+
|
48
|
+
value = if HappyMapper::Item::Types.include?(element.type)
|
49
|
+
content ? content : ''
|
50
|
+
else
|
51
|
+
content ? element.type.new(content) : element.type.new
|
52
|
+
end
|
53
|
+
self.send("#{name}=", value)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
module Elements
|
60
|
+
RESPONSE_XML_ATTRIBUTES = {:state => String, :age => String, :charged => String, :status => String, :errors => String }
|
61
|
+
|
62
|
+
module EasyElementAccess
|
63
|
+
|
64
|
+
# Shortcut to collecting any information that's present and available
|
65
|
+
def present_and_verified
|
66
|
+
yes = []
|
67
|
+
self.class.elements.map(&:method_name).each do |p|
|
68
|
+
next unless val = self.send(p)
|
69
|
+
|
70
|
+
if val.respond_to?(:present_and_verified)
|
71
|
+
yes << {p.to_sym => val.present_and_verified}
|
72
|
+
else
|
73
|
+
yes << {p.to_sym => val} if val.state == 'verified' && val.status == 'present'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
yes
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
# Encapsulates the various name components Trufina accepts
|
82
|
+
class Name
|
83
|
+
include AllowCreationFromHash
|
84
|
+
include HappyMapper
|
85
|
+
include EasyElementAccess
|
86
|
+
tag 'Name'
|
87
|
+
|
88
|
+
element :prefix, String, :tag => 'Prefix', :attributes => RESPONSE_XML_ATTRIBUTES
|
89
|
+
element :first, String, :tag => 'First', :attributes => RESPONSE_XML_ATTRIBUTES
|
90
|
+
element :middle, String, :tag => 'MiddleName', :attributes => RESPONSE_XML_ATTRIBUTES
|
91
|
+
element :middle_initial, String, :tag => 'MiddleInitial', :attributes => RESPONSE_XML_ATTRIBUTES
|
92
|
+
element :surname, String, :tag => 'Surname', :attributes => RESPONSE_XML_ATTRIBUTES
|
93
|
+
element :suffix, String, :tag => 'Suffix', :attributes => RESPONSE_XML_ATTRIBUTES
|
94
|
+
end
|
95
|
+
|
96
|
+
# Wrapper attempting to allow access to multiple StreetAddress tags per single ResidenceAddress
|
97
|
+
class StreetAddress
|
98
|
+
include AllowCreationFromHash
|
99
|
+
include HappyMapper
|
100
|
+
include EasyElementAccess
|
101
|
+
tag 'StreetAddress'
|
102
|
+
|
103
|
+
element :name, String, :tag => '.', :attributes => RESPONSE_XML_ATTRIBUTES
|
104
|
+
end
|
105
|
+
|
106
|
+
# Encapsulates Trufina's address fields
|
107
|
+
class ResidenceAddress
|
108
|
+
include AllowCreationFromHash
|
109
|
+
include HappyMapper
|
110
|
+
include EasyElementAccess
|
111
|
+
tag 'ResidenceAddress'
|
112
|
+
|
113
|
+
has_many :street_addresses, StreetAddress, :tag => 'StreetAddress', :attributes => RESPONSE_XML_ATTRIBUTES
|
114
|
+
element :city, String, :tag => 'City', :attributes => RESPONSE_XML_ATTRIBUTES
|
115
|
+
element :state, String, :tag => 'State', :attributes => RESPONSE_XML_ATTRIBUTES
|
116
|
+
element :postal_code, String, :tag => 'PostalCode', :attributes => RESPONSE_XML_ATTRIBUTES
|
117
|
+
end
|
118
|
+
|
119
|
+
# Encapsulates all response data Trufina may send back
|
120
|
+
class AccessResponseGroup
|
121
|
+
include AllowCreationFromHash
|
122
|
+
include HappyMapper
|
123
|
+
include EasyElementAccess
|
124
|
+
tag 'AccessResponse'
|
125
|
+
|
126
|
+
element :name, Name, :single => true, :attributes => RESPONSE_XML_ATTRIBUTES
|
127
|
+
# element :birth_date, Date, :tag => 'DateOfBirth', :attributes => RESPONSE_XML_ATTRIBUTES
|
128
|
+
# element :birth_country, String, :tag => 'CountryOfBirth', :attributes => RESPONSE_XML_ATTRIBUTES
|
129
|
+
element :phone, String, :tag => 'Phone', :attributes => RESPONSE_XML_ATTRIBUTES
|
130
|
+
element :residence_address, ResidenceAddress, :single => true, :attributes => RESPONSE_XML_ATTRIBUTES
|
131
|
+
element :ssn, String, :tag => 'fullSSN', :attributes => RESPONSE_XML_ATTRIBUTES
|
132
|
+
element :last_4_ssn, String, :tag => 'Last4SSN', :attributes => RESPONSE_XML_ATTRIBUTES
|
133
|
+
element :age, String, :tag => 'Age', :attributes => RESPONSE_XML_ATTRIBUTES
|
134
|
+
end
|
135
|
+
|
136
|
+
# Encapsulates all data we can request from Trufina
|
137
|
+
class AccessRequest
|
138
|
+
include AllowCreationFromHash
|
139
|
+
include HappyMapper
|
140
|
+
tag 'AccessRequest'
|
141
|
+
|
142
|
+
element :name, Name, :single => true
|
143
|
+
element :birth_date, Date, :tag => 'DateOfBirth'
|
144
|
+
element :birth_country, String, :tag => 'CountryOfBirth'
|
145
|
+
element :phone, String, :tag => 'Phone' # If Trufina implemented it, could have timeframe and maxAge attributes
|
146
|
+
element :residence_address, ResidenceAddress, :single => true # If Trufina implemented it, could have timeframe and maxAge attributes
|
147
|
+
element :ssn, String, :tag => 'fullSSN'
|
148
|
+
element :last_4_ssn, String, :tag => 'Last4SSN'
|
149
|
+
element :age, String, :tag => 'Age', :attributes => {:comparison => String}
|
150
|
+
end
|
151
|
+
|
152
|
+
# Encapsulates all seed data Trufina accepts
|
153
|
+
class SeedInfoGroup
|
154
|
+
include AllowCreationFromHash
|
155
|
+
include HappyMapper
|
156
|
+
tag 'SeedInfo'
|
157
|
+
|
158
|
+
element :name, Name, :single => true
|
159
|
+
element :email, String, :single => true
|
160
|
+
element :birth_date, Date, :tag => 'DateOfBirth'
|
161
|
+
element :birth_country, String, :tag => 'CountryOfBirth'
|
162
|
+
element :phone, String, :tag => 'Phone'
|
163
|
+
element :residence_address, ResidenceAddress, :single => true
|
164
|
+
element :ssn, String, :tag => 'fullSSN'
|
165
|
+
element :last_4_ssn, String, :tag => 'Last4SSN'
|
166
|
+
element :age, String, :tag => 'Age'
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
end
|
data/lib/exceptions.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# This file defines all Trufina Exceptions
|
2
|
+
|
3
|
+
class Trufina
|
4
|
+
module Exceptions
|
5
|
+
class TrufinaException < StandardError; end
|
6
|
+
class ConfigFileError < TrufinaException; end
|
7
|
+
class MissingToken < TrufinaException; end
|
8
|
+
class MissingRequiredElements < TrufinaException; end
|
9
|
+
class MissingRequiredAttributes < TrufinaException; end
|
10
|
+
class InvalidElement < TrufinaException; end
|
11
|
+
class NetworkError < TrufinaException; end
|
12
|
+
class UnknownResponseType < TrufinaException; end
|
13
|
+
class TrufinaResponseException < TrufinaException; end
|
14
|
+
end
|
15
|
+
end
|