lib/databasedotcom/client.rb in databasedotcom-1.1.4 vs lib/databasedotcom/client.rb in databasedotcom-1.1.5

- old
+ new

@@ -27,10 +27,12 @@ attr_reader :user_id # The SalesForce username attr_accessor :username # The SalesForce password attr_accessor :password + # The SalesForce organization id for the authenticated user's Salesforce instance + attr_reader :org_id # Returns a new client object. _options_ can be one of the following # # * A String containing the name of a YAML file formatted like: # --- @@ -84,12 +86,11 @@ # * If _options_ contains the keys <tt>:token</tt> and <tt>:instance_url</tt>, those are assumed to be a valid OAuth2 token and instance URL for a Salesforce account, obtained from an external source. _options_ may also optionally contain the key <tt>:refresh_token</tt> # # Raises SalesForceError if an error occurs def authenticate(options = nil) if user_and_pass?(options) - req = Net::HTTP.new(self.host, 443) - req.use_ssl=true + req = https_request(self.host) user = self.username || options[:username] pass = self.password || options[:password] path = "/services/oauth2/token?grant_type=password&client_id=#{self.client_id}&client_secret=#{client_secret}&username=#{user}&password=#{pass}" log_request("https://#{self.host}/#{path}") result = req.post(path, "") @@ -98,11 +99,11 @@ self.username = user self.password = pass parse_auth_response(result.body) elsif options.is_a?(Hash) if options.has_key?("provider") - @user_id = options["extra"]["user_hash"]["user_id"] rescue nil + parse_user_id_and_org_id_from_identity_url(options["uid"]) self.instance_url = options["credentials"]["instance_url"] self.oauth_token = options["credentials"]["token"] self.refresh_token = options["credentials"]["refresh_token"] else raise ArgumentError unless options.has_key?(:token) && options.has_key?(:instance_url) @@ -115,10 +116,15 @@ self.version = "22.0" unless self.version self.oauth_token end + # The SalesForce organization id for the authenticated user's Salesforce instance + def org_id + @org_id ||= query_org_id # lazy query org_id when not set by login response + end + # Returns an Array of Strings listing the class names for every type of _Sobject_ in the database. Raises SalesForceError if an error occurs. def list_sobjects result = http_get("/services/data/v#{self.version}/sobjects") if result.is_a?(Net::HTTPOK) JSON.parse(result.body)["sobjects"].collect { |sobject| sobject["name"] } @@ -325,11 +331,11 @@ response end def ensure_expected_response(expected_result_class) response = yield - + unless response.is_a?(expected_result_class || Net::HTTPSuccess) if response.is_a?(Net::HTTPUnauthorized) if self.refresh_token response = with_encoded_path_and_checked_response("/services/oauth2/token", { :grant_type => "refresh_token", :refresh_token => self.refresh_token, :client_id => self.client_id, :client_secret => self.client_secret}, :host => self.host) do |encoded_path| response = https_request(self.host).post(encoded_path, nil) @@ -347,17 +353,17 @@ response end end if response.is_a?(Net::HTTPSuccess) - response = yield + response = yield end end - - raise SalesForceError.new(response) unless response.is_a?(expected_result_class || Net::HTTPSuccess) + + raise SalesForceError.new(response) unless response.is_a?(expected_result_class || Net::HTTPSuccess) end - + response end def https_request(host=nil) Net::HTTP.new(host || URI.parse(self.instance_url).host, 443).tap{|n| n.use_ssl = true } @@ -373,11 +379,11 @@ def log_request(path, options={}) base_url = options[:host] ? "https://#{options[:host]}" : self.instance_url puts "***** REQUEST: #{path.include?(':') ? path : URI.join(base_url, path)}#{options[:data] ? " => #{options[:data]}" : ''}" if self.debugging end - + def uri_escape(str) URI.escape(str.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) end def log_response(result) @@ -467,14 +473,24 @@ end def user_and_pass?(options) (self.username && self.password) || (options && options[:username] && options[:password]) end - + + def parse_user_id_and_org_id_from_identity_url(identity_url) + m = identity_url.match(/\/id\/([^\/]+)\/([^\/]+)$/) + @org_id = m[1] rescue nil + @user_id = m[2] rescue nil + end + def parse_auth_response(body) json = JSON.parse(body) - @user_id = json["id"].match(/\/([^\/]+)$/)[1] rescue nil + parse_user_id_and_org_id_from_identity_url(json["id"]) self.instance_url = json["instance_url"] self.oauth_token = json["access_token"] + end + + def query_org_id + query("select id from Organization")[0]["Id"] end end end