intuit_ids_aggcat 0.0.5

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.
@@ -0,0 +1,213 @@
1
+ require 'oauth'
2
+ require 'rexml/document'
3
+ require 'xml/mapping'
4
+ require 'intuit_ids_aggcat/client/intuit_xml_mappings'
5
+
6
+ module IntuitIdsAggcat
7
+
8
+ module Client
9
+
10
+ class Services
11
+
12
+ class << self
13
+
14
+ def initialize
15
+
16
+ end
17
+
18
+ ##
19
+ # Gets all institutions supported by Intuit. If oauth_token_info isn't provided, new tokens are provisioned using "default" user
20
+ # consumer_key and consumer_secret will be retrieved from the Configuration class if not provided
21
+ def get_institutions oauth_token_info = IntuitIdsAggcat::Client::Saml.get_tokens("default"), consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret
22
+ response = oauth_get_request "https://financialdatafeed.platform.intuit.com/rest-war/v1/institutions", oauth_token_info, consumer_key, consumer_secret
23
+ institutions = Institutions.load_from_xml(response[:response_xml].root)
24
+ institutions.institutions
25
+ end
26
+
27
+ ##
28
+ # Gets the institution details for id. If oauth_token_info isn't provided, new tokens are provisioned using "default" user
29
+ # consumer_key and consumer_secret will be retrieved from the Configuration class if not provided
30
+ def get_institution_detail id, oauth_token_info = IntuitIdsAggcat::Client::Saml.get_tokens("default"), consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret
31
+ response = oauth_get_request "https://financialdatafeed.platform.intuit.com/rest-war/v1/institutions/#{id}", oauth_token_info, consumer_key, consumer_secret
32
+ institutions = InstitutionDetail.load_from_xml(response[:response_xml].root)
33
+ institutions
34
+ end
35
+
36
+ ##
37
+ # Deletes the customer's accounts from aggregation at Intuit.
38
+ # username must be provided, if no oauth_token_info is provided, new tokens will be provisioned using username
39
+ def delete_customer username, oauth_token_info = IntuitIdsAggcat::Client::Saml.get_tokens(username), consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret
40
+ url = "https://financialdatafeed.platform.intuit.com/rest-war/v1/customers/"
41
+ oauth_delete_request url, oauth_token_info
42
+ end
43
+
44
+ ##
45
+ # Deletes the a specific account for a customer from aggregation at Intuit.
46
+ # username and account ID must be provided, if no oauth_token_info is provided, new tokens will be provisioned using username
47
+ def delete_account username, account_id, oauth_token_info = IntuitIdsAggcat::Client::Saml.get_tokens(username), consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret
48
+ puts "in gem, username = #{username}, account = #{account_id}."
49
+ url = "https://financialdatafeed.platform.intuit.com/rest-war/v1/accounts/#{account_id}"
50
+ oauth_delete_request url, oauth_token_info
51
+ end
52
+
53
+ ##
54
+ # Discovers and adds accounts using credentials
55
+ # institution_id is the ID of the institution, username is the ID for this customer's accounts at Intuit and must be used for future requests,
56
+ # creds_hash is a hash object of key value pairs used for authentication
57
+ # If oauth_token is not provided, new tokens will be provisioned using the username provided
58
+ # Returns a hash produced by discover_account_data_to_hash with the following keys:
59
+ # discover_response : hash including the following keys:
60
+ # response_code: HTTP response code from Intuit
61
+ # response_xml : XML returned by Intuit
62
+ # accounts : Ruby hash with accounts if returned by discover call
63
+ # challenge_type : text description of the type of challenge requested, if applicable
64
+ # "none" | "choice" | "image" | "text"
65
+ # challenge : Ruby hash with the detail of the challenge if applicable
66
+ # challenge_session_id: challenge session ID to pass to challenge_response if this is a challenge
67
+ # challenge_node_id : challenge node ID to pass to challenge_response if this is a challenge
68
+ # description : text description of the result of the discover request
69
+ def discover_and_add_accounts_with_credentials institution_id, username, creds_hash, oauth_token_info = IntuitIdsAggcat::Client::Saml.get_tokens(username), consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret, timeout = 30
70
+ url = "https://financialdatafeed.platform.intuit.com/rest-war/v1/institutions/#{institution_id}/logins"
71
+ credentials_array = []
72
+ creds_hash.each do |k,v|
73
+ c = Credential.new
74
+ c.name = k
75
+ c.value = v
76
+ credentials_array.push c
77
+ end
78
+ creds = Credentials.new
79
+ creds.credential = credentials_array
80
+ il = InstitutionLogin.new
81
+ il.credentials = creds
82
+ daa = oauth_post_request url, il.save_to_xml.to_s, oauth_token_info
83
+ discover_account_data_to_hash daa
84
+ end
85
+
86
+ ##
87
+ # Given a username, response text, challenge session ID and challenge node ID, passes the credentials to Intuit to begin aggregation
88
+ def challenge_response institution_id, username, response, challenge_session_id, challenge_node_id, oauth_token_info = IntuitIdsAggcat::Client::Saml.get_tokens(username), consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret
89
+ url = "https://financialdatafeed.platform.intuit.com/rest-war/v1/institutions/#{institution_id}/logins"
90
+ if !(response.kind_of?(Array) || response.respond_to?('each'))
91
+ response = [response]
92
+ end
93
+
94
+ cr = IntuitIdsAggcat::ChallengeResponses.new
95
+ cr.response = response
96
+ il = IntuitIdsAggcat::InstitutionLogin.new
97
+ il.challenge_responses = cr
98
+ daa = oauth_post_request url, il.save_to_xml.to_s, oauth_token_info, { "challengeSessionId" => challenge_session_id, "challengeNodeId" => challenge_node_id }
99
+ discover_account_data_to_hash daa
100
+ end
101
+
102
+ ##
103
+ # Gets all accounts for a customer
104
+ def get_customer_accounts username, oauth_token_info = IntuitIdsAggcat::Client::Saml.get_tokens(username), consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret
105
+ url = "https://financialdatafeed.platform.intuit.com/rest-war/v1/accounts/"
106
+ response = oauth_get_request url, oauth_token_info
107
+ accounts = AccountList.load_from_xml(response[:response_xml].root)
108
+ end
109
+
110
+ ##
111
+ # Get transactions for a specific account and timeframe
112
+ def get_account_transactions username, account_id, start_date, end_date = nil, oauth_token_info = IntuitIdsAggcat::Client::Saml.get_tokens(username), consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret
113
+ txn_start = start_date.strftime("%Y-%m-%d")
114
+ url = "https://financialdatafeed.platform.intuit.com/rest-war/v1/accounts/#{account_id}/transactions?txnStartDate=#{txn_start}"
115
+ if !end_date.nil?
116
+ txn_end = end_date.strftime("%Y-%m-%d")
117
+ url = "#{url}&txnEndDate=#{txn_end}"
118
+ end
119
+ response = oauth_get_request url, oauth_token_info
120
+ xml = REXML::Document.new response[:response_xml].to_s
121
+ tl = IntuitIdsAggcat::TransactionList.load_from_xml xml.root
122
+ end
123
+
124
+ ##
125
+ # Helper method for parsing discover account response data
126
+ def discover_account_data_to_hash daa
127
+ challenge_type = "none"
128
+ if daa[:response_code] == "201"
129
+ # return account list
130
+ accounts = AccountList.load_from_xml(daa[:response_xml].root)
131
+ { discover_response: daa, accounts: accounts, challenge_type: challenge_type, challenge: nil, description: "Account information retrieved." }
132
+ elsif daa[:response_code] == "401" && daa[:challenge_session_id]
133
+ # return challenge
134
+ challenge = Challenges.load_from_xml(daa[:response_xml].root)
135
+ challenge_type = "unknown"
136
+ if challenge.save_to_xml.to_s.include?("<choice>")
137
+ challenge_type = "choice"
138
+ elsif challenge.save_to_xml.to_s.include?("image")
139
+ challenge_type ="image"
140
+ else
141
+ challenge_type = "text"
142
+ end
143
+ { discover_response: daa, accounts: nil, challenge_type: challenge_type, challenge: challenge, challenge_session_id: daa[:challenge_session_id], challenge_node_id: daa[:challenge_node_id], description: "Multi-factor authentication required to retrieve accounts." }
144
+ elsif daa[:response_code] == "404"
145
+ { discover_response: daa, accounts: nil, challenge_type: challenge_type, challenge: nil, description: "Institution not found." }
146
+ elsif daa[:response_code] == "408"
147
+ { discover_response: daa, accounts: nil, challenge_type: challenge_type, challenge: nil, description: "Multi-factor authentication session expired." }
148
+ elsif daa[:response_code] == "500"
149
+ { discover_response: daa, accounts: nil, challenge_type: challenge_type, challenge: nil, description: "Internal server error." }
150
+ elsif daa[:response_code] == "503"
151
+ { discover_response: daa, accounts: nil, challenge_type: challenge_type, challenge: nil, description: "Problem at the finanical institution." }
152
+ else
153
+ { discover_response: daa, accounts: nil, challenge_type: challenge_type, challenge: nil, description: "Unknown error." }
154
+ end
155
+ end
156
+
157
+ ##
158
+ # Helper method to issue post requests
159
+ def oauth_post_request url, body, oauth_token_info, headers = {}, consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret, timeout = 120
160
+ oauth_token = oauth_token_info[:oauth_token]
161
+ oauth_token_secret = oauth_token_info[:oauth_token_secret]
162
+
163
+ options = { :request_token_path => 'https://financialdatafeed.platform.intuit.com', :timeout => timeout }
164
+ options = options.merge({ :proxy => IntuitIdsAggcat.config.proxy}) if !IntuitIdsAggcat.config.proxy.nil?
165
+ consumer = OAuth::Consumer.new(consumer_key, consumer_secret, options)
166
+ access_token = OAuth::AccessToken.new(consumer, oauth_token, oauth_token_secret)
167
+ response = access_token.post(url, body, { "Content-Type"=>'application/xml', 'Host' => 'financialdatafeed.platform.intuit.com' }.merge(headers))
168
+ response_xml = REXML::Document.new response.body
169
+
170
+ # handle challenge responses from discoverAndAcccounts flow
171
+ challenge_session_id = challenge_node_id = nil
172
+ if !response["challengeSessionId"].nil?
173
+ challenge_session_id = response["challengeSessionId"]
174
+ challenge_node_id = response["challengeNodeId"]
175
+ end
176
+
177
+ { :challenge_session_id => challenge_session_id, :challenge_node_id => challenge_node_id, :response_code => response.code, :response_xml => response_xml }
178
+ end
179
+
180
+ ##
181
+ # Helper method to issue get requests
182
+ def oauth_get_request url, oauth_token_info, consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret, timeout = 120
183
+ oauth_token = oauth_token_info[:oauth_token]
184
+ oauth_token_secret = oauth_token_info[:oauth_token_secret]
185
+
186
+ options = { :request_token_path => 'https://financialdatafeed.platform.intuit.com', :timeout => timeout }
187
+ options = options.merge({ :proxy => IntuitIdsAggcat.config.proxy}) if !IntuitIdsAggcat.config.proxy.nil?
188
+ consumer = OAuth::Consumer.new(consumer_key, consumer_secret, options)
189
+ access_token = OAuth::AccessToken.new(consumer, oauth_token, oauth_token_secret)
190
+ response = access_token.get(url, { "Content-Type"=>'application/xml', 'Host' => 'financialdatafeed.platform.intuit.com' })
191
+ response_xml = REXML::Document.new response.body
192
+ { :response_code => response.code, :response_xml => response_xml }
193
+ end
194
+
195
+ ##
196
+ # Helper method to issue delete requests
197
+ def oauth_delete_request url, oauth_token_info, consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret, timeout = 120
198
+ oauth_token = oauth_token_info[:oauth_token]
199
+ oauth_token_secret = oauth_token_info[:oauth_token_secret]
200
+
201
+ options = { :request_token_path => 'https://financialdatafeed.platform.intuit.com', :timeout => timeout }
202
+ options = options.merge({ :proxy => IntuitIdsAggcat.config.proxy}) if !IntuitIdsAggcat.config.proxy.nil?
203
+ consumer = OAuth::Consumer.new(consumer_key, consumer_secret, options)
204
+ access_token = OAuth::AccessToken.new(consumer, oauth_token, oauth_token_secret)
205
+ response = access_token.delete(url, { "Content-Type"=>'application/xml', 'Host' => 'financialdatafeed.platform.intuit.com' })
206
+ response_xml = REXML::Document.new response.body
207
+ { :response_code => response.code, :response_xml => response_xml }
208
+ end
209
+
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,135 @@
1
+ require 'set'
2
+ require 'uri'
3
+
4
+ module IntuitIdsAggcat
5
+ module Core
6
+
7
+ # A configuration object for the Intuit interface.
8
+ #
9
+ # == Configuring Credentials
10
+ #
11
+ # In order to do anything with the AggCat services you will need to assign credentials.
12
+ # The simplest method is to assing your credentials into the default
13
+ # configuration:
14
+ #
15
+ # AWS.config(:access_key_id => 'KEY', :secret_access_key => 'SECRET')
16
+ #
17
+ # You can also export them into your environment and they will be picked up
18
+ # automatically:
19
+ #
20
+ # export AWS_ACCESS_KEY_ID='YOUR_KEY_ID_HERE'
21
+ # export AWS_SECRET_ACCESS_KEY='YOUR_SECRET_KEY_HERE'
22
+ #
23
+
24
+ class Configuration
25
+
26
+ # Creates a new Configuration object.
27
+ def initialize options = {}
28
+
29
+ @created = options.delete(:__created__) || {}
30
+ options.each_pair do |opt_name, value|
31
+ opt_name = opt_name.to_sym
32
+ if self.class.accepted_options.include?(opt_name)
33
+ supplied[opt_name] = value
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ # @return [Hash] Returns a hash with your configured credentials.
40
+ def credentials
41
+ credentials = {}
42
+ [:saml_idp_id, :user_id].each do |opt|
43
+ if value = credential_provider.send(opt)
44
+ credentials[opt] = value
45
+ end
46
+ end
47
+ credentials
48
+ end
49
+
50
+ def with options = {}
51
+
52
+ # symbolize option keys
53
+ options = options.inject({}) {|h,kv| h[kv.first.to_sym] = kv.last; h }
54
+
55
+ values = supplied.merge(options)
56
+
57
+ if supplied == values
58
+ self # nothing changed
59
+ else
60
+ self.class.new(values.merge(:__created__ => @created.dup))
61
+ end
62
+
63
+ end
64
+
65
+ # @return [Hash] Returns a hash of all configuration values.
66
+ def to_h
67
+ self.class.accepted_options.inject({}) do |h,k|
68
+ h.merge(k => send(k))
69
+ end
70
+ end
71
+ alias_method :to_hash, :to_h
72
+
73
+ # @return [Boolean] Returns true if the two configuration objects have
74
+ # the same values.
75
+ def eql? other
76
+ other.is_a?(self.class) and self.supplied == other.supplied
77
+ end
78
+ alias_method :==, :eql?
79
+
80
+ # @private
81
+ def inspect
82
+ "<#{self.class.name}>"
83
+ end
84
+
85
+ protected
86
+
87
+ def supplied
88
+ @supplied ||= {}
89
+ end
90
+
91
+ class << self
92
+
93
+ # @private
94
+ def accepted_options
95
+ @options ||= Set.new
96
+ end
97
+
98
+ # @private
99
+ def add_option name, default_value = nil, options = {}, &transform
100
+
101
+ accepted_options << name
102
+
103
+ define_method(name) do |&default_override|
104
+
105
+ value =
106
+ if supplied.has_key?(name)
107
+ supplied[name]
108
+ elsif default_override
109
+ default_override.call
110
+ else
111
+ default_value
112
+ end
113
+
114
+ transform ? transform.call(self, value) : value
115
+
116
+ end
117
+
118
+ alias_method("#{name}?", name) if options[:boolean]
119
+
120
+ end
121
+
122
+ end
123
+
124
+ add_option :certificate_path
125
+ add_option :certificate_string
126
+ add_option :certificate_password
127
+ add_option :issuer_id
128
+ add_option :oauth_consumer_key
129
+ add_option :oauth_consumer_secret
130
+ add_option :oauth_token_info
131
+ add_option :proxy
132
+
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,4 @@
1
+ require "intuit_ids_aggcat/core/configuration"
2
+ require "intuit_ids_aggcat/client/saml"
3
+ require "intuit_ids_aggcat/client/services"
4
+ require "intuit_ids_aggcat/rails"
@@ -0,0 +1,106 @@
1
+ require 'yaml'
2
+
3
+ module IntuitIdsAggcat
4
+
5
+ if Object.const_defined?(:Rails) and Rails.const_defined?(:Railtie)
6
+
7
+ # @private
8
+ class Railtie < Rails::Railtie
9
+
10
+ # configure our plugin on boot. other extension points such
11
+ # as configuration, rake tasks, etc, are also available
12
+ initializer "intuit_ids_aggcat.initialize" do |app|
13
+ IntuitIdsAggcat::Rails.setup
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ # A handful of useful Rails integration methods.
20
+ #
21
+ # If you require this gem inside a Rails application (via config.gem
22
+ # for rails 2 and bundler for rails 3) then {setup} is called
23
+ # automatically.
24
+ module Rails
25
+
26
+ # Adds extra functionality to Rails.
27
+ #
28
+ # Normailly this method is invoked automatically when you require this
29
+ # gem in a Rails Application:
30
+ #
31
+ # Rails 3+ (RAILS_ROOT/Gemfile)
32
+ #
33
+ # gem 'intuit_ids_aggcat'
34
+ #
35
+
36
+ # @return [nil]
37
+ def self.setup
38
+ load_yaml_config
39
+ log_to_rails_logger
40
+ nil
41
+ end
42
+
43
+ # Loads Intuit IDS AggCat configuration options from +RAILS_ROOT/config/intuit_ids_aggcat.yml+.
44
+ #
45
+ # This configuration file is optional. You can omit this file and instead
46
+ # use ruby to configure the gem inside a configuration initialization script
47
+ # (e.g. RAILS_ROOT/config/intializers/intuit_ids_aggcat.rb).
48
+ #
49
+ # If you have a yaml configuration file it should be formatted like the
50
+ # standard +database.yml+ file in a Rails application. This means there
51
+ # should be one section for Rails environment:
52
+ #
53
+ # development:
54
+ # certificate_path: path to private key
55
+ # issuer_id: SAML issuer ID provided by intuit
56
+ # oauth_consumer_key: OAuth consumer key
57
+ # oauth_consumer_secret: OAuth consumer secret
58
+ #
59
+ # production:
60
+ # certificate_path: path to private key
61
+ # issuer_id: SAML issuer ID provided by intuit
62
+ # oauth_consumer_key: OAuth consumer key
63
+ # oauth_consumer_secret: OAuth consumer secret
64
+
65
+ def self.load_yaml_config
66
+
67
+ path = Pathname.new("#{rails_root}/config/intuit_ids_aggcat.yml")
68
+
69
+ if File.exists?(path)
70
+ cfg = YAML::load(ERB.new(File.read(path)).result)
71
+ unless cfg[rails_env]
72
+ raise "config/intuit_ids_aggcat.yml is missing a section for `#{rails_env}`"
73
+ end
74
+ IntuitIdsAggcat.config(cfg[rails_env])
75
+ end
76
+
77
+ end
78
+
79
+
80
+ # Configures gem to log to the Rails default logger.
81
+ # @return [nil]
82
+ def self.log_to_rails_logger
83
+ AWS.config(:logger => rails_logger)
84
+ nil
85
+ end
86
+
87
+ # @private
88
+ protected
89
+ def self.rails_env
90
+ ::Rails.respond_to?(:env) ? ::Rails.env : RAILS_ENV
91
+ end
92
+
93
+ # @private
94
+ protected
95
+ def self.rails_root
96
+ ::Rails.respond_to?(:root) ? ::Rails.root.to_s : RAILS_ROOT
97
+ end
98
+
99
+ # @private
100
+ protected
101
+ def self.rails_logger
102
+ ::Rails.respond_to?(:logger) ? ::Rails.logger : ::RAILS_DEFAULT_LOGGER
103
+ end
104
+
105
+ end
106
+ end
@@ -0,0 +1,3 @@
1
+ module IntuitIdsAggcat
2
+ VERSION = "0.0.5"
3
+ end
@@ -0,0 +1,23 @@
1
+ require "intuit_ids_aggcat/version"
2
+ require "intuit_ids_aggcat/core"
3
+
4
+ module IntuitIdsAggcat
5
+ class << self
6
+
7
+ # @private
8
+ @@config = nil
9
+ @@client = nil
10
+
11
+ def config options = {}
12
+ @@config ||= Core::Configuration.new
13
+ @@config = @@config.with(options) unless options.empty?
14
+ @@config
15
+ end
16
+
17
+ def client
18
+ @@client ||= Client::Services.new
19
+ @@client
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ development:
2
+ certificate_path: test.key
3
+ issuer_id: rails_test_id
4
+ oauth_consumer_key: rails_test_key
5
+ oauth_consumer_secret: rails_test_secret
@@ -0,0 +1,17 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICvDCCAiWgAwIBAgIJAKqWuLF2VM4+MA0GCSqGSIb3DQEBBQUAMEkxCzAJBgNV
3
+ BAYTAlVTMRcwFQYDVQQIEw5Ob3J0aCBDYXJvbGluYTESMBAGA1UEBxMJQ2hhcmxv
4
+ dHRlMQ0wCwYDVQQKEwRUZXN0MB4XDTEyMTAyNjE4NDk1NloXDTEyMTEyNTE4NDk1
5
+ NlowSTELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRIwEAYD
6
+ VQQHEwlDaGFybG90dGUxDTALBgNVBAoTBFRlc3QwgZ8wDQYJKoZIhvcNAQEBBQAD
7
+ gY0AMIGJAoGBAL9zKDXCbw+Xc8IugYrK7ffJsHQYr8rZKr0hw3XksEYRHb/LqCSw
8
+ ZF5aUTY1ECGb0QlD9uYxYWTvmpqZcTRIJANQgqhr1CH4hpEXJAdTJVzdJMaxeCjO
9
+ F40cHTwyeMP5Ou5Vsq3gKWTnJkGvDkJXHCqRkwduLk6FiWOfat2I9CjjAgMBAAGj
10
+ gaswgagwHQYDVR0OBBYEFGdV8DGee/TMuZDgQW1wdZ1k0HuNMHkGA1UdIwRyMHCA
11
+ FGdV8DGee/TMuZDgQW1wdZ1k0HuNoU2kSzBJMQswCQYDVQQGEwJVUzEXMBUGA1UE
12
+ CBMOTm9ydGggQ2Fyb2xpbmExEjAQBgNVBAcTCUNoYXJsb3R0ZTENMAsGA1UEChME
13
+ VGVzdIIJAKqWuLF2VM4+MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEA
14
+ IdnfNuBftWE97JyhPiADYGsV8l+2KE2mxgqQacwGTgorxiwjBph1l26WY8fb3LCK
15
+ xKNDrMfcDJfSxgI8xqw3AsjDTWSF3tOqKTS6ApIwKf7l6BIMCTD2Xc6PTTmgNV20
16
+ NlLkzu6mXIXIuzBrUXfHUSXIsSUly+dX6fHKxMlToU8=
17
+ -----END CERTIFICATE-----
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe IntuitIdsAggcat::Core::Configuration do
4
+ it 'should configure issuer id' do
5
+ IntuitIdsAggcat.config(:issuer_id => "test_issuer")
6
+ IntuitIdsAggcat.config.issuer_id.should == "test_issuer"
7
+ end
8
+
9
+ it 'should configure oauth consumer key' do
10
+ IntuitIdsAggcat.config(:oauth_consumer_key => "consumer_key")
11
+ IntuitIdsAggcat.config.oauth_consumer_key.should == "consumer_key"
12
+ end
13
+
14
+ it 'should configure oauth consumer secret' do
15
+ IntuitIdsAggcat.config(:oauth_consumer_secret => "secret")
16
+ IntuitIdsAggcat.config.oauth_consumer_secret.should == "secret"
17
+ end
18
+
19
+ it 'should configure certificate path' do
20
+ IntuitIdsAggcat.config(:certificate_path => "cert")
21
+ IntuitIdsAggcat.config.certificate_path.should == "cert"
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe IntuitIdsAggcat::Rails do
4
+ it 'should load configuration from a YAML file' do
5
+ Rails = Object.new
6
+ ::Rails.stub(:root).and_return("#{Dir.pwd}/spec")
7
+ ::Rails.stub(:env).and_return("development")
8
+ IntuitIdsAggcat::Rails.load_yaml_config
9
+ IntuitIdsAggcat.config.issuer_id.should == "rails_test_id"
10
+ IntuitIdsAggcat.config.certificate_path.should == "test.key"
11
+ IntuitIdsAggcat.config.oauth_consumer_key.should == "rails_test_key"
12
+ IntuitIdsAggcat.config.oauth_consumer_secret.should == "rails_test_secret"
13
+
14
+ end
15
+ end
data/spec/saml_spec.rb ADDED
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe IntuitIdsAggcat::Client::Saml do
4
+ it 'should generate a SAML assertion' do
5
+ SecureRandom.stub(:uuid).and_return("6bf05546-89ee-4ec1-8cf7-e90c438cb147")
6
+ IntuitIdsAggcat::Client::Saml.get_saml_assertion_xml("rails_test_id", "test", "spec/config/test.key", nil, nil, Time.new(2008,6,21, 13,30,0, "+09:00")).should ==
7
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><saml2:Assertion xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\" ID=\"_6bf0554689ee4ec18cf7e90c438cb147\" IssueInstant=\"2008-06-21T04:30:00.000Z\" Version=\"2.0\"><saml2:Issuer>rails_test_id</saml2:Issuer><ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/><ds:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/><ds:Reference URI=\"#_6bf0554689ee4ec18cf7e90c438cb147\"><ds:Transforms><ds:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/><ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/></ds:Transforms><ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><ds:DigestValue>nzk4auzjFeqgAeWIKFAvtjxHKqc=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>Yv5BHxMttOlN+N+LQnEYXDvzCpTTpqWegDJQTnJtqyohH5WEllszOrDad0ZugO4NToa179aJkb0bhSHRlUZ83BAR2WqZjTG8a9tSEd/PGAbUkGmzNiGF8kYTuXAq//PmED6HYAO/PAXzaK9kubMLO+ZlOnyD0eW7+t913A0W0VY=</ds:SignatureValue></ds:Signature><saml2:Subject><saml2:NameID Format=\"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified\">test</saml2:NameID><saml2:SubjectConfirmation Method=\"urn:oasis:names:tc:SAML:2.0:cm:bearer\"/></saml2:Subject><saml2:Conditions NotBefore=\"2008-06-21T04:25:00.000Z\" NotOnOrAfter=\"2008-06-21T04:40:00.000Z\"><saml2:AudienceRestriction><saml2:Audience>rails_test_id</saml2:Audience></saml2:AudienceRestriction></saml2:Conditions><saml2:AuthnStatement AuthnInstant=\"2008-06-21T04:30:00.000Z\" SessionIndex=\"_6bf0554689ee4ec18cf7e90c438cb147\"><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml2:AuthnContextClassRef></saml2:AuthnContext></saml2:AuthnStatement></saml2:Assertion>\n"
8
+ end
9
+
10
+ it "should return signed XML" do
11
+ IntuitIdsAggcat::Client::Saml.get_signed_info_xml("123", "test").should ==
12
+ "<ds:SignedInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"><ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/><ds:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/><ds:Reference URI=\"#123\"><ds:Transforms><ds:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/><ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\"/></ds:Transforms><ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><ds:DigestValue>test</ds:DigestValue></ds:Reference></ds:SignedInfo>"
13
+ end
14
+
15
+ it "should return tokens" do
16
+ path = Pathname.new("spec/config/real_config.yml")
17
+ config = YAML::load(ERB.new(File.read(path)).result)
18
+ IntuitIdsAggcat.config(config)
19
+ tokens = IntuitIdsAggcat::Client::Saml.get_tokens "test"
20
+ tokens[:oauth_token_secret].should_not be_nil
21
+ tokens[:oauth_token].should_not be_nil
22
+ tokens[:token_expiry].should_not be_nil
23
+ end
24
+ end
25
+