intuit_ids_aggcat 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+