I am completely new to salesforce and its API(s). I have rails application with an existing users table. I need to start synchronizing data over to our new salesforce account.
Currently, I am trying to convert existing 'Leads' to 'Accounts'. As I understand it, this can only be accomplished with the old SOAP API. I am trying to use the rforce gem.
I am able to authenticate according to the documentation, like this:
binding = RForce::Binding.new \
'https://www.salesforce.com/services/Soap/u/20.0'
binding.login \
'email', 'password' + 'token'
Then I try to call the convert lead action like this:
binding.convertLead "leadId" => lead_id
but I get the error:
:errors=>{:message=>"valid leadId is required", :statusCode=>"INVALID_CROSS_REFERENCE_KEY"}
I know for sure that the leadId I am using is indeed valid, because I have actually retrieved it just prior to this call (using the REST API).
I believe that the problem may be that the rforce gem is not structuring the underlying SOAP call properly -- which I think is being described in this SO post.
I appreciate any additional information anyone can provide.
Thanks very much,
Matt
Try using lead.Id instead of lead_Id.
The input hash needs to have the key 'leadConverts':
binding.convertLead 'leadConverts' => { 'leadId' => lead_id, 'convertedStatus' => 'Status' }
You may need to add other arguments depending on what is required to convert a Lead on your Salesforce platform.
Related
I have a couple of questions about the WebAuthn gem and the use of U2fMigrator.
I hope someone can point me in the right direction about it.
I am in the step just after converting my old U2F credentials using U2fMigrator.
migrated_credential = WebAuthn::U2fMigrator.new(
app_id: my_domain,
certificate: u2f_registration.certificate,
key_handle: u2f_registration.key_handle,
public_key: u2f_registration.binary_public_key,
counter: u2f_registration.counter
)
The documentation says: āU2fMigrator class quacks like WebAuthn::AuthenticatorAttestationResponseā but without verify implementation.
Does that mean I need to create an instance of this AuthenticatorAttestationResponse for authentication?
If so. Where I should get this data from?
assertion_response = WebAuthn::AuthenticatorAssertionResponse.new(
credential_id: '',
authenticator_data: '',
client_data_json: '',
signature: '',
)
I am guessing that will allow me to authenticate the new migrated credentials like this:
assertion_response.verify(
WebAuthn::Credential.options_for_get(:extensions => { appid: my_domain }).challenge,
allowed_creadentials: migrated_credential.credential,
rp_id: my_domain
)
And also, I am guessing I don't need to re-register these credentials yet.
I am following this documentation:
https://github.com/cedarcode/webauthn-ruby/blob/master/docs/u2f_migration.md
https://github.com/castle/ruby-u2f
https://github.com/cedarcode/webauthn-ruby/blob/master/README.md#authentication
UPDATE 1
I've found this cool explanation in this guide
I will dig into it and I'll post the solution if I can find it.
UPDATE 2
I've spent the whole week trying to get the authenticatorAssertionResponse
from
Unfortunately, I only get a message saying I don't have a key registered:
I'm passing through the extension and appid where the U2F credential was registered originally. I wonder if it stoped working now the deprecation is complete.
U2fMigrator is instantiated with data that's already stored in your database. Instances of it respond to the same methods as AuthenticatorAttestationResponse, except it misses a verify method since the data was already verified in the past. In other words: the migrator behaves nearly the same as a freshly WebAuthn registered authenticator and it is meant to be used as such.
Does that mean I need to create an instance of this
AuthenticatorAttestationResponse for authentication?
Yes. The AuthenticatorAttestationResponse is instantiated with browser data from the WebAuthn navigator.credentials.get call. This in itself is unrelated to the U2F migration question, except for the part where the data comes from for its verify method. This comes either from a migrator instance (in the "real time conversion" approach) or is retrieved from the database.
Hope that makes sense, PRs welcome to improve the docs!
I am trying to read and display activities of a G+ user. Using Google oauth2 I could able to recieve the access_token of a user after authorization has completed.
I use google_plus gem to make calls to G+, i could able to recieve user information using below code
#person = GooglePlus::Person.get("user_id_goes_here", :key => "google_api_key_here")
but when i try to get the activities using below
activity = GooglePlus::Activity.get("user_id_goes_here")
i could able to see the below error,
i tried searching the web for a solution, and some suggest that the api call limit exceeded. (10,000 hits/day is default). But i am sure i have used this only with 20-30 calls today.
Any suggestions for this issue is appreciated.
FYI : I have just added config code for google_oauth2 in /config/initializers/omniauth.rb file as below provider :google_oauth2,Rails.application.config.client_id , Rails.application.config.client_secret
Note: Below is the screenshot when i try to authenticate with Oauth2.
I hope this doesnot include Google plus scope, to make it i know i should add {:scope => "REQUIRED_URL_HERE_GOOGLE_PLUS_RELATED"} in omniauth.rb. But not sure what url should i give in there.
Thanks,
Balan
The Google_Plus gem requires you to pass your app key with every request. You can either do this inline:
GooglePlus::Activity.get("user_id_goes_here", key: "api_key_goes_here")
Or set up a global variable in an initializer
GooglePlus.api_key = 'api_key_goes_here'
The examples in the gem spec assume you have included a global variable, and hence don't show the key: strings. This may be what is causing you problems?
In answer to your second question, you will need to specify a scope with your oauth requests. A list of scopes is given here https://developers.google.com/gdata/faq#AuthScopes, but it is worth noting that the url format seems to have changed from that published. Try https://www.googleapis.com/auth/xxxxx instead, where xxx is the service you require.
I could able to find a solution for my question..
1) Used {:scope => "https://www.googleapis.com/auth/plus.me"} in /config/initializers/omniauth.rb file
2) Used the code
activities = GooglePlus::Activity.for_person("user_id", :key => "GOOGLE_API_KEY").items
Hope someone will find this useful.
I want to play around with the Yahoo Fantasy Sports API. I have no idea where to start. What do I need to do in order to start playing with the API in IRB and start calling and retrieving different players or stats? This is my first attempt at tackling an API that does not have a readily available Ruby gem.
Yahoo Fantasy Sports API: http://developer.yahoo.com/fantasysports/guide/
I've followed the steps detailed in the dev guide and set up my developer Consumer key and Secret key. Not sure what to do with this information though.
I'm using Rails 3.2.2 and Ruby 1.9.2
I've been spending many hours the past couple weeks trying to get a site to tie in with the Yahoo fantasysports API and only recently got over the hurdle of being able to get authenticated through OAuth, make valid requests, and refresh access tokens indefinitely. Here are the steps you need to take to be able to mess around in IRB:
Gem stuff
Include oauth-plugin in your Gemfile. This will also install the OAuth/OAuth2 ruby gems as dependencies. This will handle the request/access tokens needed, but won't be fully compatible right out of the box.
The oauth-plugin requires an authentication system to be in place for your app. I would highly recommend devise both for its ease of use and the fact that the oauth-plugin pretty much works along with it with very little setup. I found it easier to connect the two if I first generate 'User' through devise before I generated a consumer with the oauth-plugin. There are tons of guides for devise if you run into issues.
Migration stuff
A quirk of the Yahoo version of OAuth is that you need to store a 'session_handle' for a user in order to refresh the access token when it expires after 60 minutes. I just edited the existing OauthConsumerToken migration to include t.string :session_handle. I'm not sure what the issue was with MYSQL when I did this, but I had to also specify a limit of 190 for the consumer_tokens index that oauth created. So my full add index is add_index :consumer_tokens, :token, :unique => true, :length => 190. I would recommend also adding a :guid string column to the users table, since that is what Yahoo uses as a unique identifier.
To accommodate the two extra columns we are tracking that oauth doesn't know about (session handle and guid), you need to override some of the oauth-plugin default behaviour. I've already forked the project and made the necessary changes if you want to just use my version (https://github.com/JamesSwift/oauth-plugin). The three dependencies for my version are a session_handle column in the ConsumerTokens table, a yahoo_guid column in the Users table, and set the variable CB_URL in your development.rb to be the url that you registered your app under with Yahoo. Also remember that if you use my version of the plugin you need to specify the path/github url depending on how you want to include it.
Configuration stuff
You need to set the :key and :secret in config/intializers/oauth_consumers.rb. I call my consumer a YahooToken, so mine looks like this:
OAUTH_CREDENTIALS={
:yahoo => {
:key => "the key given to me by yahoo"
:secret => "the secret given to me by yahoo"
}
}
load 'oauth/models/consumers/service_loader.rb'
You also need to specify the global yahoo settings in the custom token class you created. Again, mine is a YahooToken, so in app/models/yahoo_token.rb my first few lines are:
class YahooToken < ConsumerToken
YAHOO_SETTINGS={
:site=>"http://fantasysports.yahooapis.com/fantasy/v2",
:authorize_url =>"https://api.login.yahoo.com/oauth/v2/request_auth",
:request_token_url => "https://api.login.yahoo.com/oauth/v2/get_request_token",
:access_token_url => "https://api.login.yahoo.com/oauth/v2/get_token",
:oauth_version=>"1.0"
}
Tell your user model it has a token:
has_one :yahoo, :class_name=>"YahooToken", :dependent=>:destroy
Actually doing stuff, stuff
Now you can load up your server, create a user, and go to http://localhost:3000/oauth_consumers/yahoo to get your token. Yahoo refuses to redirect you back to localhost, so you will end up getting redirected to CB_URL/parameters-that-yahoo-returns. Copy the parameter string and go to http://localhost:3000/oauth_consumers/yahoo/callback/paste-the-string-here. This should successfully complete the initial retrieval of the access token. Don't worry, you only need to do this once per local user while developing locally. It automatically redirects in production environments.
Now that you have a token you can use it in IRB for the next hour as much as you want. Here is an example of using the token from the console:
t = User.first.yahoo
resp = t.client.get("http://fantasysports.yahooapis.com/fantasy/v2/users;use_login=1")
puts resp.body
You can also put &format=json at the end to get it in json instead of xml
After 60 minutes you need to get a new access token. I have a refresh function in my YahooToken:
def refresh!
old_one = self
request_token = OAuth::RequestToken.new(YahooToken.consumer, self.token, self.secret)
options={}
options[:oauth_session_handle]=self.session_handle
access_token = request_token.get_access_token options
new_one = YahooToken.find_or_create_from_access_token self.user, access_token
if new_one
old_one.delete
return new_one
end
return nil
end
Whenever my token expires I just t = t.refresh!. I would also recommend an age method on your tokens which will facilitate creating a rake task that will refresh tokens every hour for you automatically.
All the available fantasysports related resources are listed here:(http://developer.yahoo.com/fantasysports/guide/)
To get started, I would suggest you familiarize yourself with OAuth, which the Yahoo Fantasy Sports API uses for authentication. You will also need to know how to make HTTP requests in Ruby. Most of the rest of work will be in reading the API documentation and experimenting.
If you're looking for Ruby libraries for using OAuth or making HTTP requests, or anything else you run into, you may find The Ruby Toolbox helpful.
I prefer pelle/oauth-plugin save session_handle in refresh! rather then fork it.
consumer wrapper
model/YahooToken.rb inspired by #JamesSwift.
Migration
I authorizate with omniauth-yahoo, so the guid save in Authorization model and you need to add session_handle(:string) and change token(:text) column in consumer_tokens.
enjoy.
I'm working on an API wrapper for Viddler, which will eventually be made public, and I'm trying to figure out the best way to deal with authentication/API keys, specifically with usage within Rails applications in mind.
The easiest way to write the wrapper would be to just have the code create a new client each time, and the developer could store the API key in a constant for future use:
#client = Viddler::Client.new(VIDDLER_API_KEY)
The problem with this is, it's kind of clunky to have to keep creating client objects and passing in the API key. This gets even more complicated when you throw user authentication into the mix.
I'm thinking some sort of solution where I all the the API key to be set in the environment file and then the authentication would be done in a before_filter.
Viddler::Client.api_key = 'abc123'
Viddler::Client.authenticate! 'username', 'password'
Viddler::Client would then store this in a class variable, and you could call Viddler::Client.new without any parameters and make authenticated calls. One thing I'd be concerned about is that this means the developer would have to be sure to clear out the authentication before or after each request, since the class variables would persist between requests.
Any thoughts?
Storing the API key globally would for sure be pretty useful and certainly is the way to go for that kind of information. User authentication on the other hand I think shouldn't be stored globally, never ever, especially for a high level API, because telling your users to "ensure to add an after_filter :reset_viddler_auth" might lead to some unexpected security risks.
# in a config/initializer/*.rb file or something
Viddler::Client.api_key = "abc123"
# in the controller/action/model/wherever
#client = Viddler::Client.new # anonymous
#client.authenticate!("username", "password") # authenticate anon client
#client_auth = Viddler::Client.new("username", "password") # authenticated client
Guess like that you've best of both worlds :) Maybe even provide a way to create a new client with another API key like,
#client_other = Viddler::Client.new("username", "password", :api_key => "xyz890")
So... just my 2 cents.
PS: not sure how up-to-date it is, but there's already a ruby viddler wrapper, just FYI, http://viddler.rubyforge.org/rdoc/
I've been attempting to hook a Rails application up to ActiveDirectory. I'll be synchronizing data about users between AD and a database, currently MySQL (but may turn into SQL Server or PostgreSQL).
I've checked out activedirectory-ruby, and it looks really buggy (for a 1.0 release!?). It wraps Net::LDAP, so I tried using that instead, but it's really close to the actual syntax of LDAP, and I enjoyed the abstraction of ActiveDirectory-Ruby because of its ActiveRecord-like syntax.
Is there an elegant ORM-type tool for a directory server? Better yet, if there were some kind of scaffolding tool for LDAP (CRUD for users, groups, organizational units, and so on). Then I could quickly integrate that with my existing authentication code though Authlogic, and keep all of the data synchronized.
Here is sample code I use with the net-ldap gem to verify user logins from the ActiveDirectory server at my work:
require 'net/ldap' # gem install net-ldap
def name_for_login( email, password )
email = email[/\A\w+/].downcase # Throw out the domain, if it was there
email << "#mycompany.com" # I only check people in my company
ldap = Net::LDAP.new(
host: 'ldap.mycompany.com', # Thankfully this is a standard name
auth: { method: :simple, email: email, password:password }
)
if ldap.bind
# Yay, the login credentials were valid!
# Get the user's full name and return it
ldap.search(
base: "OU=Users,OU=Accounts,DC=mycompany,DC=com",
filter: Net::LDAP::Filter.eq( "mail", email ),
attributes: %w[ displayName ],
return_result:true
).first.displayName.first
end
end
The first.displayName.first code at the end looks a little goofy, and so might benefit from some explanation:
Net::LDAP#search always returns an array of results, even if you end up matching only one entry. The first call to first finds the first (and presumably only) entry that matched the email address.
The Net::LDAP::Entry returned by the search conveniently lets you access attributes via method name, so some_entry.displayName is the same as some_entry['displayName'].
Every attribute in a Net::LDAP::Entry is always an array of values, even when only one value is present. Although it might be silly to have a user with multiple "displayName" values, LDAP's generic nature means that it's possible. The final first invocation turns the array-of-one-string into just the string for the user's full name.
Have you tried looking at these:
http://saush.wordpress.com/2006/07/18/rubyrails-user-authentication-with-microsoft-active-directory/
http://xaop.com/blog/2008/06/17/simple-windows-active-directory-ldap-authentication-with-rails/
This is more anecdotal than a real answer...
I had a similar experience using Samba and OpenLDAP server. I couldn't find a library to really do what I wanted so I rolled my own helper classes.
I used ldapbrowser to see what fields Samba filled in when I created a user the "official" way and and basically duplicated that.
The only tricky/non-standard LDAP thing was the crazy password encryption we have:
userPass:
"{MD5}" + Base64.encode64(Digest::MD5.digest(pass))
sambaNTPassword:
OpenSSL::Digest::MD4.hexdigest(Iconv.iconv("UCS-2", "UTF-8", pass).join).upcase
For the def authenticate(user, pass) function I try to get LDAP to bind to the domain using their credentials, if I catch an exception then the login failed, otherwise let them in.
Sorry, cannot comment yet... perhaps someone can relocate this appropriately.
#Phrogz's solution works well, but bind_simple (inside bind) raises an Net::LDAP::LdapError exception due to auth[:username] not being set as shown here:
https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap.rb
The corrected replaces:
auth: { method: :simple, email: email, password:password }
with:
auth: { method: :simple, username: email, password:password }
I began using ruby-activedirectory, and even extended it/fixed a few things, hosting judy-activedirectory in Github.
Doing the next iteration, I've discovered ActiveLdap has a much better code base, and I'm seriously contemplating switching to it. Does anyone have personal experience with this?
Have you checked out thoughtbot's ldap-activerecord-gateway? It might be something for you to consider...
http://github.com/thoughtbot/ldap-activerecord-gateway/tree/master