lib/rforce/binding.rb in rforce-0.4.1 vs lib/rforce/binding.rb in rforce-0.5
- old
+ new
@@ -1,19 +1,22 @@
require 'net/https'
require 'uri'
require 'zlib'
require 'stringio'
+require 'rexml/document'
require 'builder'
+require 'oauth'
-
module RForce
# Implements the connection to the SalesForce server.
class Binding
include RForce
-
- DEFAULT_BATCH_SIZE = 10
- attr_accessor :batch_size, :url, :assignment_rule_id, :use_default_rule, :update_mru, :client_id, :trigger_user_email,
+
+ # Increase the maximum fetch size to 2000, as allowed by Salesforce
+ # Added by Raymond Gao
+ DEFAULT_BATCH_SIZE = 2000
+ attr_accessor :batch_size, :url, :assignment_rule_id, :use_default_rule, :update_mru, :client_id, :trigger_user_email,
:trigger_other_email, :trigger_auto_response_email
# Fill in the guts of this typical SOAP envelope
# with the session ID and the body of the SOAP request.
Envelope = <<-HERE
@@ -41,54 +44,95 @@
AssignmentRuleHeaderUsingRuleId = '<partner:AssignmentRuleHeader soap:mustUnderstand="1"><partner:assignmentRuleId>%s</partner:assignmentRuleId></partner:AssignmentRuleHeader>'
AssignmentRuleHeaderUsingDefaultRule = '<partner:AssignmentRuleHeader soap:mustUnderstand="1"><partner:useDefaultRule>true</partner:useDefaultRule></partner:AssignmentRuleHeader>'
MruHeader = '<partner:MruHeader soap:mustUnderstand="1"><partner:updateMru>true</partner:updateMru></partner:MruHeader>'
ClientIdHeader = '<partner:CallOptions soap:mustUnderstand="1"><partner:client>%s</partner:client></partner:CallOptions>'
- # Connect to the server securely.
- def initialize(url, sid = nil)
- init_server(url)
-
+ # Connect to the server securely. If you pass an oauth hash, it
+ # must contain the keys :consumer_key, :consumer_secret,
+ # :access_token, :access_secret, and :login_url.
+ def initialize(url, sid = nil, oauth = nil)
@session_id = sid
+ @oauth = oauth
@batch_size = DEFAULT_BATCH_SIZE
+
+ init_server(url)
end
def show_debug
ENV['SHOWSOAP'] == 'true'
end
def init_server(url)
@url = URI.parse(url)
- @server = Net::HTTP.new(@url.host, @url.port)
- @server.use_ssl = @url.scheme == 'https'
- @server.verify_mode = OpenSSL::SSL::VERIFY_NONE
- # run ruby with -d or env variable SHOWSOAP=true to see SOAP wiredumps.
- @server.set_debug_output $stderr if show_debug
+ if (@oauth)
+ consumer = OAuth::Consumer.new \
+ @oauth[:consumer_key],
+ @oauth[:consumer_secret],
+ { :site => url }
+
+ consumer.http.set_debug_output $stderr if show_debug
+
+ @server = OAuth::AccessToken.new \
+ consumer,
+ @oauth[:access_token],
+ @oauth[:access_secret]
+
+ class << @server
+ alias_method :post2, :post
+ end
+ else
+ @server = Net::HTTP.new(@url.host, @url.port)
+ @server.use_ssl = @url.scheme == 'https'
+ @server.verify_mode = OpenSSL::SSL::VERIFY_NONE
+
+ # run ruby with -d or env variable SHOWSOAP=true to see SOAP wiredumps.
+ @server.set_debug_output $stderr if show_debug
+ end
end
- # Log in to the server and remember the session ID
- # returned to us by SalesForce.
+ # Log in to the server with a user name and password, remembering
+ # the session ID returned to us by SalesForce.
def login(user, password)
@user = user
@password = password
response = call_remote(:login, [:username, user, :password, password])
-
+
raise "Incorrect user name / password [#{response.fault}]" unless response.loginResponse
result = response[:loginResponse][:result]
@session_id = result[:sessionId]
init_server(result[:serverUrl])
response
end
+ # Log in to the server with OAuth, remembering
+ # the session ID returned to us by SalesForce.
+ def login_with_oauth
+ result = @server.post @oauth[:login_url], '', {}
+ case result
+ when Net::HTTPSuccess
+ doc = REXML::Document.new result.body
+ @session_id = doc.elements['*/sessionId'].text
+ server_url = doc.elements['*/serverUrl'].text
+ init_server server_url
+
+ return {:sessionId => @sessionId, :serverUrl => server_url}
+ when Net::HTTPUnauthorized
+ raise 'Invalid OAuth tokens'
+ else
+ raise "Unexpected error: #{response.inspect}"
+ end
+ end
+
# Call a method on the remote server. Arguments can be
# a hash or (if order is important) an array of alternating
# keys and values.
def call_remote(method, args)
@@ -102,25 +146,25 @@
extra_headers = ""
extra_headers << (AssignmentRuleHeaderUsingRuleId % assignment_rule_id) if assignment_rule_id
extra_headers << AssignmentRuleHeaderUsingDefaultRule if use_default_rule
extra_headers << MruHeader if update_mru
extra_headers << (ClientIdHeader % client_id) if client_id
-
+
if trigger_user_email or trigger_other_email or trigger_auto_response_email
extra_headers << '<partner:EmailHeader soap:mustUnderstand="1">'
-
+
extra_headers << '<partner:triggerUserEmail>true</partner:triggerUserEmail>' if trigger_user_email
extra_headers << '<partner:triggerOtherEmail>true</partner:triggerOtherEmail>' if trigger_other_email
extra_headers << '<partner:triggerAutoResponseEmail>true</partner:triggerAutoResponseEmail>' if trigger_auto_response_email
-
+
extra_headers << '</partner:EmailHeader>'
end
# Fill in the blanks of the SOAP envelope with our
# session ID and the expanded XML of our request.
request = (Envelope % [@session_id, @batch_size, extra_headers, expanded])
-
+
# reset the batch size for the next request
@batch_size = DEFAULT_BATCH_SIZE
# gzip request
request = encode(request)
@@ -207,6 +251,5 @@
call_remote method, args[0]
end
end
end
-