Skip to content
This repository has been archived by the owner on Aug 3, 2020. It is now read-only.

Using separate Restforce sessions using OAuth #71

Open
mezza opened this issue Sep 9, 2014 · 2 comments
Open

Using separate Restforce sessions using OAuth #71

mezza opened this issue Sep 9, 2014 · 2 comments

Comments

@mezza
Copy link

mezza commented Sep 9, 2014

I have an application where each user authenticates using omniauth to Salesforce to get their own Restforce client for requests to Salesforce.

What's the best way to override the active_force.SObject.client to allow for this to be used, rather than setting up a new Restforce connection that uses application wide environment variables?

@DanOlson
Copy link
Contributor

DanOlson commented Sep 9, 2014

One possibility would be to provide a setter at the class level of your SObject subclass. Then you could set using a Restforce client with any configuration you want:

class Territory < ActiveForce::SObject
  class << self
    def sfdc_client=(client)
      @client = client
    end
  end
end

> territory = Territory.new
=> #<Territory id: nil>
> territory.send(:sfdc_client)
=> #<Restforce::Data::Client @options={:api_version=>"26.0", :username=>nil, :password=>nil, :security_token=>nil, :client_id=>nil, :client_secret=>nil, :host=>"login.salesforce.com", :oauth_token=>nil, :refresh_token=>nil, :instance_url=>nil, :cache=>nil, :authentication_retries=>3, :compress=>nil, :timeout=>nil, :adapter=>:net_http, :proxy_uri=>nil, :authentication_callback=>nil}>

> Territory.sfdc_client = Object.new
=> #<Object:0x007fab432bf480>
> territory.send(:sfdc_client)
 => #<Object:0x007fab432bf480>

@olvap What do you think about providing this out of the box?

@eloyesp
Copy link
Contributor

eloyesp commented Sep 10, 2014

It is a very interesting issue, and is one of the advantages of restforce over active_force. Within restforce, every sobject have and associated client instance, so the knowledge is not at the class level, it is at the instance level.

# in the restforce world:
client_1 = RestForce::Client.new
client_2 = RestForce::Client.new(other_credentials)
account = client_1.find('Account', 'n11gg1')
account.client #=> client_1
account.update!('Name' => 'New Name')
#=> will do client_1.update!('Account', 'Id' => 'n11gg1', 'Name' => 'New Name')

We are currently storing the client at the class level, so we can provide finders and queries.

# In the active_force world there are a lot of ways of getting sobjects.
account = Account.find('n11gg1')
account2 = Account.where(name: 'New Name')

The problem with changing the client at the class level, is that it will not work with two user at the same time (as both will try to change the same class).

There are two possible strategies I can think of:

  • the first is really crazy and I'm not sure if it is even possible, we can use inheritance to build a different set of classes for different providers, that means storing classes in variables, so I'm not sure if ruby is capable of this:
client_1 = RestForce::Client.new custom_credentials
client_1.Account.where(name: 'New Name').first
#=> an instance of class.new(Account).sfdc_client = client_1
  • the second one is at least boring, it is just provide a query option to set the client, and store the client at the instance level.
Account.client(client_1).find('n11gg1').first
#=> <Account @client=client_1>

We would also need an option to require that being set (because it will be just easy to forget setting this)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants