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,396 @@
1
+ # forward classdefs for mapping
2
+ class DateTimeNode < XML::Mapping::SingleAttributeNode
3
+ def initialize(*args)
4
+ path,*args = super(*args)
5
+ @path = XML::XXPath.new(path)
6
+ args
7
+ end
8
+
9
+ def extract_attr_value(xml)
10
+ # without millisecs
11
+ r1 = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}-\d{2}:\d{2}/
12
+ # with millisecs
13
+ r2 = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}-\d{2}:\d{2}/
14
+ dt_format = ""
15
+ dt_string = default_when_xpath_err{ @path.first(xml).text }
16
+ if dt_string =~ r1
17
+ dt_format = "%Y-%m-%dT%H:%M:%S%z"
18
+ elsif dt_string =~ r2
19
+ dt_format = "%Y-%m-%dT%H:%M:%S.%L%z"
20
+ end
21
+ DateTime.strptime(dt_string, dt_format)
22
+ end
23
+
24
+ def set_attr_value(xml, value)
25
+ @path.first(xml,:ensure_created=>true).text = value
26
+ end
27
+ end
28
+
29
+ XML::Mapping.add_node_class DateTimeNode
30
+
31
+ module IntuitIdsAggcat
32
+ class Institution; end
33
+ class Address; end
34
+ class Key; end
35
+ class Credentials; end
36
+ class Credential; end
37
+ class Challenge; end
38
+ class ChallengeResponses; end
39
+ class Account; end
40
+ class BankingAccount < Account; end
41
+ class CreditAccount < Account; end
42
+ class Choice; end
43
+ class Transaction; end
44
+ class BankingTransaction < Transaction; end
45
+ class CreditCardTransaction < Transaction; end
46
+ class InvestmentBankingTransaction < Transaction; end
47
+ class InvestmentTransaction < Transaction; end
48
+ class LoanTransaction < Transaction; end
49
+ class RewardsTransaction < Transaction; end
50
+ class TransactionList; end
51
+ #class Common; end
52
+ class Context; end
53
+
54
+ class Institutions
55
+ include XML::Mapping
56
+ array_node :institutions, "institution", :class=>Institution, :default_value => []
57
+ end
58
+
59
+ class Institution
60
+ include XML::Mapping
61
+ numeric_node :id, "institutionId", :default_value => nil
62
+ text_node :name, "institutionName", :default_value => nil
63
+ text_node :url, "homeUrl", :default_value => nil
64
+ text_node :phone, "phoneNumber", :default_value => nil
65
+ boolean_node :virtual, "virtual", "true", "false", :default_value => true
66
+ end
67
+
68
+ class InstitutionDetail
69
+ include XML::Mapping
70
+ numeric_node :id, "institutionId", :default_value => nil
71
+ text_node :name, "institutionName", :default_value => nil
72
+ text_node :url, "homeUrl", :default_value => nil
73
+ text_node :phone, "phoneNumber", :default_value => nil
74
+ boolean_node :virtual, "virtual", "true", "false", :default_value => true
75
+ text_node :currency_code, "currencyCode", :default_value => nil
76
+ text_node :email_address, "emailAddress", :default_value => nil
77
+ text_node :special_text, "specialText", :default_value => nil
78
+ object_node :address, "address", :default_value => nil
79
+ array_node :keys, "keys/key", :class=>Key, :default_value => []
80
+ end
81
+
82
+ class Address
83
+ include XML::Mapping
84
+ text_node :address1, "address1", :default_value => nil
85
+ text_node :address2, "address2", :default_value => nil
86
+ text_node :address3, "address3", :default_value => nil
87
+ text_node :city, "city", :default_value => nil
88
+ text_node :state, "state", :default_value => nil
89
+ text_node :postal_code, "postalCode", :default_value => nil
90
+ text_node :country, "country", :default_value => nil
91
+ end
92
+
93
+ class Key
94
+ include XML::Mapping
95
+ text_node :name, "name", :default_value => nil
96
+ text_node :status, "status", :default_value => nil
97
+ text_node :min_length, "valueLengthMin", :default_value => nil
98
+ text_node :max_length, "valueLengthMax", :default_value => nil
99
+ boolean_node :is_displayed, "displayFlag", "true", "false", :default_value => true
100
+ boolean_node :is_masked, "mask", "true", "false", :default_value => false
101
+ text_node :display_order, "displayOrder", :default_value => nil
102
+ text_node :instructions, "instructions", :default_value => nil
103
+ text_node :description, "description", :default_value => nil
104
+ end
105
+
106
+ class InstitutionLogin
107
+ include XML::Mapping
108
+ # added namespaces to make root element compliant with Intuit's expectation
109
+ def post_save xml, options={:mapping=>:_default}
110
+ # using REXML's element namespace method doesn't seem to set the namespace correctly...?
111
+ xml.root.add_attributes("xmlns"=>"http://schema.intuit.com/platform/fdatafeed/institutionlogin/v1")
112
+ xml.root.add_namespace "xsi", "http://www.w3.org/2001/XMLSchema-instance"
113
+ xml.root.add_namespace "xsd", "http://www.w3.org/2001/XMLSchema"
114
+ # for challengeResponses/response
115
+ xml.each_element("//response") do |x|
116
+ x.add_namespace "v11", "http://schema.intuit.com/platform/fdatafeed/challenge/v1"
117
+ x.name = "v11:response"
118
+ end
119
+ # for challengeResponses root
120
+ xml.each_element("//challengeResponses") do |x|
121
+ x.add_namespace "v1", "http://schema.intuit.com/platform/fdatafeed/institutionlogin/v1"
122
+ x.name = "challengeResponses"
123
+ end
124
+ end
125
+
126
+ self.root_element_name "InstitutionLogin"
127
+ object_node :credentials, "credentials", :default_value => nil
128
+ object_node :challenge_responses, "challengeResponses", :default_value => nil
129
+ end
130
+
131
+ class Credentials
132
+ include XML::Mapping
133
+ array_node :credential, "credential", :default_value => nil
134
+ end
135
+
136
+ class Credential
137
+ include XML::Mapping
138
+ text_node :name, "name", :default_value => nil
139
+ text_node :value, "value", :default_value => nil
140
+ end
141
+
142
+ class Challenges
143
+ include XML::Mapping
144
+ array_node :challenge, "challenge", :class => Challenge, :default_value => nil
145
+ end
146
+
147
+ class Choice
148
+ include XML::Mapping
149
+ text_node :text, "text", :default_value => nil
150
+ text_node :val, "val", :default_value => nil
151
+ end
152
+
153
+ class Challenge
154
+ include XML::Mapping
155
+ text_node :text, "text", :default_value => nil
156
+ text_node :image, "image", :default_value => nil
157
+ array_node :choice, "choice", :class => Choice, :default_value => nil
158
+ end
159
+
160
+ class ChallengeResponses
161
+ include XML::Mapping
162
+ def post_save xml, options={:mapping=>:_default}
163
+ # using REXML's element na1espace method doesn't seem to set the namespace correctly...?
164
+ xml.root.add_namespace "v1", "http://schema.intuit.com/platform/fdatafeed/institutionlogin/v1"
165
+ xml.each_element("//response"){|x| x.add_namespace "v11", "http://schema.intuit.com/platform/fdatafeed/challenge/v1"}
166
+ xml
167
+ end
168
+ self.root_element_name "ChallengeResponses"
169
+ array_node :response, "response", :class => String
170
+ end
171
+
172
+ class AccountList
173
+ include XML::Mapping
174
+ array_node :banking_accounts, "BankingAccount", :class => BankingAccount, :default_value => nil
175
+ array_node :credit_accounts, "CreditAccount", :class => CreditAccount, :default_value => nil
176
+ #array_node :loan_accounts, "LoanAccount", :default_value => nil
177
+ #array_node :investment_accounts, "InvestmentAccount", :default_value => nil
178
+ #array_node :rewards_accounts, "RewardsAccount", :default_value => nil
179
+ #array_node :other_accounts, "OtherAccount", :default_value => nil
180
+ end
181
+
182
+ class Account
183
+ include XML::Mapping
184
+ numeric_node :account_id, "accountId", :default_value => nil
185
+ text_node :status, "status", :default_value => nil
186
+ text_node :account_number, "accountNumber", :default_value => nil
187
+ text_node :account_number_real, "accountNumberReal", :default_value => nil
188
+ text_node :account_nickname, "accountNickname", :default_value => nil
189
+ numeric_node :display_position, "displayPosition", :default_value => nil
190
+ numeric_node :institution_id, "institutionId", :default_value => nil
191
+ text_node :description, "description", :default_value => nil
192
+ text_node :registered_user_name, "registeredUserName", :default_value => nil
193
+ numeric_node :balance_amount, "balanceAmount", :default_value => nil
194
+ date_time_node :balance_date, "balanceDate", :default_value => nil
195
+ numeric_node :balance_previous_amount, "balancePreviousAmount", :default_value => nil
196
+ date_time_node :last_transaction_date, "lastTxnDate", :default_value => nil
197
+ date_time_node :aggregation_success_date, "aggrSuccessDate", :default_value => nil
198
+ date_time_node :aggregation_attempt_date, "aggrAttemptDate", :default_value => nil
199
+ text_node :currency_code, "currencyCode", :default_value => nil
200
+ text_node :bank_id, "bankId", :default_value => nil
201
+ numeric_node :institution_login_id, "institutionLongId", :default_value => nil
202
+ end
203
+
204
+ class BankingAccount < Account
205
+ include XML::Mapping
206
+ text_node :banking_account_type, "bankingAccountType", :default_value => nil
207
+ date_time_node :posted_date, "postedDate", :default_value => nil
208
+ numeric_node :available_balance_amount, "availableBalanceAmount", :default_value => nil
209
+ date_time_node :origination_date, "originationDate", :default_value => nil
210
+ date_time_node :open_date, "openDate", :default_value => nil
211
+ numeric_node :period_interest_rate, "periodInterestRate", :default_value => nil
212
+ numeric_node :period_deposit_amount, "periodDepositAmount", :default_value => nil
213
+ numeric_node :period_interest_amount, "periodInterestAmount", :default_value => nil
214
+ numeric_node :interest_amount_ytd, "interestAmountYtd", :default_value => nil
215
+ numeric_node :interest_prior_amount_ytd, "interestPriorAmountYtd", :default_value => nil
216
+ date_time_node :maturity_date, "maturityDate", :default_value => nil
217
+ numeric_node :maturity_amount, "maturityAmount", :default_value => nil
218
+ end
219
+
220
+ class CreditAccount < Account
221
+ include XML::Mapping
222
+ text_node :credit_account_type, "creditAccountType", :default_value => nil
223
+ text_node :detailed_description, "detailedDescription", :default_value => nil
224
+ numeric_node :interest_rate, "interestRate", :default_value => nil
225
+ numeric_node :credit_available_amount, "creditAvailableAmount", :default_value => nil
226
+ numeric_node :credit_max_amount, "creditMaxAmount", :default_value => nil
227
+ numeric_node :cash_advance_max_amount, "cashAdvanceMaxAmount", :default_value => nil
228
+ numeric_node :cash_advance_balance, "cashAdvanceBalance", :default_value => nil
229
+ numeric_node :cash_advance_interest_rate, "cashAdvanceInterestRate", :default_value => nil
230
+ numeric_node :current_balance, "currentBalance", :default_value => nil
231
+ numeric_node :payment_min_amount, "paymentMinAmount", :default_value => nil
232
+ date_time_node :payment_due_date, "paymentDueDate", :default_value => nil
233
+ numeric_node :previous_balance, "previousBalance", :default_value => nil
234
+ date_time_node :statement_end_date, "statementEndDate", :default_value => nil
235
+ numeric_node :statement_purchase_amount, "statementPurchaseAmount", :default_value => nil
236
+ numeric_node :statement_finance_amount, "statementFinanceAmount", :default_value => nil
237
+ numeric_node :past_due_amount, "pastDueAmount", :default_value => nil
238
+ numeric_node :last_payment_amount, "lastPaymentAmount", :default_value => nil
239
+ date_time_node :last_payment_date, "lastPaymentDate", :default_value => nil
240
+ numeric_node :statement_close_balance, "statementCloseBalance", :default_value => nil
241
+ numeric_node :statement_last_fee_amount, "statementLastFeeAmount", :default_value => nil
242
+ end
243
+
244
+ class Common
245
+ include XML::Mapping
246
+ text_node :normalized_payee_name, "normalizedPayeeName", :default_value => nil
247
+ end
248
+
249
+ class Context
250
+ include XML::Mapping
251
+ text_node :source, "source", :default_value => nil
252
+ text_node :category_name, "categoryName", :default_value => nil
253
+ end
254
+
255
+ class Categorization
256
+ include XML::Mapping
257
+ object_node :common, "common", :class => Common, :default_value => nil
258
+ object_node :context, "context", :class => Context, :default_value => nil
259
+ end
260
+
261
+ class Transaction
262
+ include XML::Mapping
263
+ numeric_node :id, "id", :default_value => nil
264
+ text_node :currency_type, "currencyType", :default_value => nil
265
+ text_node :institution_transaction_id, "institutionTransactionId", :default_value => nil
266
+ text_node :correct_institution_transaction_id, "correctInstitutionTransactionId", :default_value => nil
267
+ text_node :correct_action, "correctAction", :default_value => nil
268
+ text_node :server_transaction_id, "serverTransactionId", :default_value => nil
269
+ text_node :check_number, "checkNumber", :default_value => nil
270
+ text_node :ref_number, "refNumber", :default_value => nil
271
+ text_node :confirmation_number, "confirmationNumber", :default_value => nil
272
+ text_node :payee_id, "payeeId", :default_value => nil
273
+ text_node :payee_name, "payeeName", :default_value => nil
274
+ text_node :normalized_payee_name, "normalizedPayeeName", :default_value => nil
275
+ text_node :memo, "memo", :default_value => nil
276
+ text_node :category, "category", :default_value => nil
277
+ text_node :type, "type", :default_value => nil
278
+ text_node :value_type, "valueType", :default_value => nil
279
+ text_node :category_name, "categoryName", :default_value => nil
280
+ text_node :ofx_category_name, "ofxCategoryName", :default_value => nil
281
+ numeric_node :currency_rate, "currencyRate", :default_value => nil
282
+ boolean_node :original_currency, "originalCurrency", "true", "false", :default_value => nil
283
+ date_time_node :posted_date, "postedDate", :default_value => nil
284
+ date_time_node :user_date, "userDate", :default_value => nil
285
+ date_time_node :available_date, "availableDate", :default_value => nil
286
+ numeric_node :amount, "amount", :default_value => nil
287
+ numeric_node :running_balance_amount, "runningBalanceAmount", :default_value => nil
288
+ numeric_node :sic, "sic", :default_value => nil
289
+ boolean_node :pending, "pending", "true", "false", :default_value => nil
290
+ object_node :categorization, "categorization", :class => Categorization, :default_value => nil
291
+ end
292
+
293
+ class BankingTransaction < Transaction
294
+ include XML::Mapping
295
+ use_mapping :_default
296
+ end
297
+
298
+ class CreditCardTransaction < Transaction
299
+ include XML::Mapping
300
+ use_mapping :_default
301
+ end
302
+
303
+ class InvestmentBankingTransaction < Transaction
304
+ include XML::Mapping
305
+ text_node :banking_transaction_type, "bankingTransactionType", :default_value => nil
306
+ text_node :subaccount_fund_type, "subaccountFundType", :default_value => nil
307
+ text_node :banking_401k_source_type, "banking401KSourceType", :default_value => nil
308
+ end
309
+
310
+ class LoanTransaction < Transaction
311
+ include XML::Mapping
312
+ numeric_node :principal_amount, "principalAmount", :default_value => nil
313
+ numeric_node :interest_amount, "interestAmount", :default_value => nil
314
+ numeric_node :escrow_total_amount, "escrowTotalAmount", :default_value => nil
315
+ numeric_node :escrow_tax_amount, "escrowTaxAmount", :default_value => nil
316
+ numeric_node :escrow_insurance_amount, "escrowInsuranceAmount", :default_value => nil
317
+ numeric_node :escrow_pmi_amount, "escrowPmiAmount", :default_value => nil
318
+ numeric_node :escrow_fees_amount, "escrowFeesAmount", :default_value => nil
319
+ numeric_node :escrow_other_amount, "escrowOtherAmount", :default_value => nil
320
+ end
321
+
322
+ # TODO - map InvestmentTransaction
323
+ class InvestmentTransaction < Transaction
324
+ include XML::Mapping
325
+ text_node :reversal_institution_transaction_id, "reversalInstitutionTransactionId", :default_value => nil
326
+ text_node :description, "description", :default_value => nil
327
+ text_node :buy_type, "buyType", :default_value => nil
328
+ text_node :income_type, "incomeType", :default_value => nil
329
+ text_node :inv_401k_source, "inv401ksource", :default_value => nil
330
+ text_node :loan_id, "loadId", :default_value => nil
331
+ text_node :options_action_type, "optionsActionType", :default_value => nil
332
+ text_node :options_buy_type, "optionsBuyType", :default_value => nil
333
+ text_node :options_sell_type, "optionsSellType", :default_value => nil
334
+ text_node :position_type, "positionType", :default_value => nil
335
+ text_node :related_institution_trade_id, "relatedInstitutionTradeId", :default_value => nil
336
+ text_node :related_options_trans_type, "relatedOptionsTransType", :default_value => nil
337
+ text_node :secured_type, "securedType", :default_value => nil
338
+ text_node :sell_reason, "sellReason", :default_value => nil
339
+ text_node :sell_type, "sellType", :default_value => nil
340
+ text_node :subaccount_from_type, "subaccountFromType", :default_value => nil
341
+ text_node :subaccount_fund_type, "subaccountFundType", :default_value => nil
342
+ text_node :subaccount_security_type, "subaccountSecurityType", :default_value => nil
343
+ text_node :subaccount_to_type, "subaccountToType", :default_value => nil
344
+ text_node :transfer_action, "transferAction", :default_value => nil
345
+ text_node :unit_type, "unitType", :default_value => nil
346
+ text_node :cusip, "cusip", :default_value => nil
347
+ text_node :symbol, "symbol", :default_value => nil
348
+ text_node :unit_action, "unitAction", :default_value => nil
349
+ text_node :options_security, "optionsSecurity", :default_value => nil
350
+ date_time_node :trade_date, "tradeDate", :default_value => nil
351
+ date_time_node :settle_date, "settleDate", :default_value => nil
352
+ numeric_node :accrued_interest_amount, "accruedInterestAmount", :default_value => nil
353
+ numeric_node :average_cost_basis_amount, "averageCostBasisAmount", :default_value => nil
354
+ numeric_node :commission_amount, "commissionAmount", :default_value => nil
355
+ numeric_node :denominator, "denominator", :default_value => nil
356
+ date_time_node :payroll_date, "payrollDate", :default_value => nil
357
+ date_time_node :purchase_date, "purchaseDate", :default_value => nil
358
+ numeric_node :gain_amount, "gainAmount", :default_value => nil
359
+ numeric_node :fees_amount, "feesAmount", :default_value => nil
360
+ numeric_node :fractional_units_cash_amount, "fractionalUnitsCashAmount", :default_value => nil
361
+ numeric_node :load_amount, "loadAmount", :default_value => nil
362
+ numeric_node :loan_interest_amount, "loadInterestAmount", :default_value => nil
363
+ numeric_node :loan_principal_amount, "loanPrincipalAmount", :default_value => nil
364
+ numeric_node :markdown_amount, "markdownAmount", :default_value => nil
365
+ numeric_node :markup_amount, "markupAmount", :default_value => nil
366
+ numeric_node :new_units, "newUnits", :default_value => nil
367
+ numeric_node :numerator, "numerator", :default_value => nil
368
+ numeric_node :old_units, "oldUnits", :default_value => nil
369
+ numeric_node :penatly_amount, "penaltyAmount", :default_value => nil
370
+ boolean_node :prior_year_contribution, "priorYearContribution", :default_value => nil
371
+ numeric_node :shares_per_contract, "sharesPerContract", :default_value => nil
372
+ numeric_node :state_withholding, "stateWithholding", :default_value => nil
373
+ numeric_node :total_amount, "totalAmount", :default_value => nil
374
+ numeric_node :taxes_amount, "taxesAmount", :default_value => nil
375
+ boolean_node :tax_exmpty, "taxExmpty", :default_value => nil
376
+ numeric_node :unit_price, "unitPrice", :default_value => nil
377
+ numeric_node :units, "units", :default_value => nil
378
+ numeric_node :withholding_amount, "withholdingAmount", :default_value => nil
379
+ numeric_node :options_shares_per_contract, "optionsSharesPerContract", :default_value => nil
380
+ end
381
+
382
+ class RewardsTransaction < Transaction
383
+ include XML::Mapping
384
+ use_mapping :_default
385
+ end
386
+
387
+ class TransactionList
388
+ include XML::Mapping
389
+ array_node :banking_transactions, "BankingTransaction", :class => BankingTransaction, :default_value => nil
390
+ array_node :credit_card_transactions, "CreditCardTransaction", :class => CreditCardTransaction, :default_value => nil
391
+ array_node :investment_banking_transactions, "InvestmentBankingTransaction", :class => InvestmentBankingTransaction, :default_value => nil
392
+ array_node :loan_transactions, "LoanTransaction", :class => LoanTransaction, :default_value => nil
393
+ array_node :investment_transactions, "InvestmentTransaction", :class => InvestmentTransaction, :default_value => nil
394
+ array_node :rewards_transactions, "RewardsTransaction", :class => RewardsTransaction, :default_value => nil
395
+ end
396
+ end
@@ -0,0 +1,126 @@
1
+ require 'openssl'
2
+ require 'nokogiri'
3
+ require 'base64'
4
+ require 'securerandom'
5
+ require 'active_support'
6
+ require 'net/https'
7
+ require 'cgi'
8
+ require 'uri'
9
+
10
+ module IntuitIdsAggcat
11
+
12
+ module Client
13
+
14
+ class Saml
15
+ @token_timeout = 600
16
+ class << self
17
+
18
+ def get_saml_assertion_xml issuer_id, username = "default", private_key_path, private_key_string, private_key_password, instant
19
+ id = "_#{SecureRandom.uuid.gsub!(/-/, '')}"
20
+ time_format = "%Y-%m-%dT%T.%LZ"
21
+ before = instant - 5*60
22
+ after = instant + @token_timeout
23
+ saml_assertion_xml = <<-EOF_XML
24
+ <?xml version="1.0" encoding="UTF-8"?><saml2:Assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" ID="#{id}" IssueInstant="#{instant.utc.strftime(time_format)}" Version="2.0"><saml2:Issuer>#{issuer_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="##{id}"><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>%%DIGEST%%</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>%%SIGNATURE%%</ds:SignatureValue></ds:Signature><saml2:Subject><saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">#{username}</saml2:NameID><saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"/></saml2:Subject><saml2:Conditions NotBefore="#{before.utc.strftime(time_format)}" NotOnOrAfter="#{after.utc.strftime(time_format)}"><saml2:AudienceRestriction><saml2:Audience>#{issuer_id}</saml2:Audience></saml2:AudienceRestriction></saml2:Conditions><saml2:AuthnStatement AuthnInstant="#{instant.utc.strftime(time_format)}" SessionIndex="#{id}"><saml2:AuthnContext><saml2:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml2:AuthnContextClassRef></saml2:AuthnContext></saml2:AuthnStatement></saml2:Assertion>
25
+ EOF_XML
26
+ digestible_xml = get_digestible_xml(saml_assertion_xml)
27
+ digest = calc_digest(digestible_xml).strip
28
+ signed_info_xml = get_signed_info_xml(id, digest)
29
+ signature_value = get_signature_value(signed_info_xml, private_key_path, private_key_string, private_key_password)
30
+ saml_assertion_xml.gsub!(/%%DIGEST%%/, digest)
31
+ saml_assertion_xml.gsub!(/%%SIGNATURE%%/, signature_value)
32
+ return saml_assertion_xml
33
+
34
+ end
35
+
36
+ def get_signature_value(signed_info_xml, private_key_path, private_key_string, private_key_password)
37
+ if !private_key_path.nil?
38
+ pkey = OpenSSL::PKey::RSA.new(File.read(private_key_path), private_key_password)
39
+ else
40
+ pkey = OpenSSL::PKey::RSA.new(private_key_string, private_key_password)
41
+ end
42
+ signed_info_xml_canon = Nokogiri::XML(signed_info_xml).canonicalize
43
+ digest = OpenSSL::Digest::SHA1.new
44
+ signature = Base64.encode64 pkey.sign(digest, signed_info_xml_canon)
45
+ signature.gsub!(/\n/,'') #remove newline
46
+ return signature
47
+ end
48
+
49
+ def get_signed_info_xml(id, digest)
50
+ signed_info_xml = <<-EOF_XML
51
+ <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="##{id}"><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>#{digest.strip}</ds:DigestValue></ds:Reference></ds:SignedInfo>
52
+ EOF_XML
53
+ signed_info_xml = signed_info_xml.strip
54
+ return signed_info_xml
55
+ end
56
+
57
+ def calc_digest(digestible_xml)
58
+ doc = Nokogiri::XML(digestible_xml)
59
+ doc_canonicalized = doc.canonicalize(mode=Nokogiri::XML::XML_C14N_1_1)
60
+ digest = OpenSSL::Digest::SHA1.new.digest(doc_canonicalized)
61
+ digest_b64 = Base64.encode64(digest)
62
+ return digest_b64
63
+ end
64
+
65
+ def get_digestible_xml(saml_assertion_xml)
66
+ doc = Nokogiri::XML(saml_assertion_xml)
67
+ doc.xpath('//ds:Signature', 'ds' => "http://www.w3.org/2000/09/xmldsig#" ).each do |node|
68
+ node.remove
69
+ end
70
+ new_xml = doc.root.to_s
71
+ doc = Nokogiri::XML(new_xml)
72
+ doc.xpath('//text()[not(normalize-space())]').remove
73
+ doc_canonical = doc.canonicalize(mode=Nokogiri::XML::XML_C14N_1_1)
74
+ return doc_canonical.to_s.strip
75
+ end
76
+
77
+ def send_saml_assertion(saml_assertion_b64, oauth_consumer_key, oauth_consumer_secret)
78
+
79
+ oauth_url="https://oauth.intuit.com/oauth/v1/get_access_token_by_saml"
80
+
81
+ uri = URI.parse(oauth_url)
82
+ if IntuitIdsAggcat.config.proxy.nil?
83
+ http = Net::HTTP.new(uri.host, uri.port)
84
+ else
85
+ proxy_uri = URI.parse(IntuitIdsAggcat.config.proxy)
86
+ http = Net::HTTP::Proxy(proxy_uri.host,proxy_uri.port).new(uri.host, uri.port)
87
+ end
88
+ request = Net::HTTP::Post.new(uri.request_uri)
89
+ request["Content-Type"] = "application/x-www-form-urlencoded"
90
+ request["Content-Language"] = "en-US"
91
+ request["Content-Length"] = saml_assertion_b64.length
92
+ request["Authorization"] = "OAuth oauth_consumer_key=\"#{oauth_consumer_key}\""
93
+ request["Host"] = "financialdatafeed.platform.intuit.com"
94
+ request.set_form_data({"saml_assertion"=>saml_assertion_b64})
95
+ http.use_ssl = true
96
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
97
+ #http.set_debug_output($stdout)
98
+ response = http.request(request)
99
+ params = CGI::parse(response.body)
100
+ return {oauth_token_secret: params["oauth_token_secret"][0],
101
+ oauth_token: params["oauth_token"][0] }
102
+
103
+ end
104
+ def get_oauth_info issuer_id, username, oauth_consumer_key, oauth_consumer_secret, private_key_path, private_key_string, private_key_password
105
+ instant = Time.now
106
+ saml_assertion_xml = get_saml_assertion_xml issuer_id, username, private_key_path, private_key_string, private_key_password, instant
107
+ saml_assertion_b64 = Base64.strict_encode64(saml_assertion_xml)
108
+ oauth_token_info = send_saml_assertion saml_assertion_b64, oauth_consumer_key, oauth_consumer_secret
109
+ oauth_token_info[:token_expiry] = instant + @token_timeout
110
+ oauth_token_info
111
+ end
112
+
113
+ def get_tokens username, issuer_id = IntuitIdsAggcat.config.issuer_id, oauth_consumer_key = IntuitIdsAggcat.config.oauth_consumer_key, oauth_consumer_secret = IntuitIdsAggcat.config.oauth_consumer_secret, certificate_path = IntuitIdsAggcat.config.certificate_path, certificate_string = IntuitIdsAggcat.config.certificate_string, certificate_password = IntuitIdsAggcat.config.certificate_password
114
+ #if !IntuitIdsAggcat.config.oauth_token_info.nil? && !IntuitIdsAggcat.config.oauth_token_info[:oauth_token].nil? && IntuitIdsAggcat.config.oauth_token_info[:token_expiry] > (Time.now + 2)
115
+ # IntuitIdsAggcat.config.oauth_token_info
116
+ #else
117
+ oauth_token_info = get_oauth_info issuer_id, username, oauth_consumer_key, oauth_consumer_secret, certificate_path, certificate_string, certificate_password
118
+ # IntuitIdsAggcat.config(:oauth_token_info => oauth_token_info)
119
+ # oauth_token_info
120
+ #end
121
+ end
122
+
123
+ end
124
+ end
125
+ end
126
+ end