-
-
Save rilian/0057d1898a9c311e38dddba46a752017 to your computer and use it in GitHub Desktop.
Revisions
-
Aupajo revised this gist
Mar 27, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,7 +5,7 @@ You can hook into authentication success by passing an `authentication_callback` If you're happy relying on an internal API call, you can make sure your token is fresh by calling: ```ruby restforce_client.authenticate! ``` ## Walkthrough -
Aupajo revised this gist
Mar 27, 2015 . 1 changed file with 5 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,11 @@ You can hook into authentication success by passing an `authentication_callback` to the client. If you're happy relying on an internal API call, you can make sure your token is fresh by calling: ```ruby client.authenticate! ``` ## Walkthrough -
Aupajo revised this gist
Mar 27, 2015 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,7 +2,7 @@ You can hook into authentication success by passing an `authentication_callback` to the client. There's no simple way to issue a straight OAuth token refresh. You always have to make some API request. ## Walkthrough -
Aupajo revised this gist
Mar 27, 2015 . 1 changed file with 22 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,11 @@ ## Summary You can hook into authentication success by passing an `authentication_callback` to the client. There's no simple way to issue a straight OAuth token refresh. It's assumed you're trying to make a RESTful request. ## Walkthrough Typical client instantiation looks like this: ```ruby @@ -150,3 +158,17 @@ end Interestingly, `connection` in this case refers to a separate `Faraday::Connection` than we saw previously. The reraising in the `rescue` block is for the verb method back in `Restforce::Concerns::Verbs`: ```ruby ... rescue Restforce::UnauthorizedError if retries > 0 retries -= 1 connection.url_prefix = options[:instance_url] retry end raise end ... ``` -
Aupajo revised this gist
Mar 27, 2015 . 1 changed file with 22 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -128,4 +128,25 @@ end It inherits from `Restforce::Middleware::Authentication`, which works like this: ```ruby def call(env) @app.call(env) rescue Restforce::UnauthorizedError authenticate! raise end def authenticate! response = connection.post '/services/oauth2/token' do |req| req.body = encode_www_form(params) end raise Restforce::AuthenticationError, error_message(response) if response.status != 200 @options[:instance_url] = response.body['instance_url'] @options[:oauth_token] = response.body['access_token'] @options[:authentication_callback].call(response.body) if @options[:authentication_callback] response.body end ``` Interestingly, `connection` in this case refers to a separate `Faraday::Connection` than we saw previously. -
Aupajo revised this gist
Mar 27, 2015 . 1 changed file with 51 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -54,8 +54,6 @@ end builder.use authentication_middleware, self, options if authentication_middleware # Sets the oauth token in the headers. builder.use Restforce::Middleware::Authorization, self, options ... # Raises errors for 40x responses. builder.use Restforce::Middleware::RaiseError @@ -64,9 +62,21 @@ end end ``` `authentication_middleware` is a module that's determined at run time: ```ruby def authentication_middleware if username_password? Restforce::Middleware::Authentication::Password elsif oauth_refresh? Restforce::Middleware::Authentication::Token end end ``` Let's look at the middleware. #### [Restforce::Middleware::Authorization](https://github.com/ejholmes/restforce/blob/92b2a0041984d3b4b058e2b4ee337a375056b598/lib/restforce/middleware/authorization.rb) This simply adds the `OAuth` header to each request: @@ -81,3 +91,41 @@ def token end ``` #### Restforce::Middleware::RaiseError This is a type of `Faraday::Response` middleware (it acts after a response has been made). ```ruby def on_complete(env) @env = env case env[:status] when 404 raise Faraday::Error::ResourceNotFound, message when 401 raise Restforce::UnauthorizedError, message when 413 raise Faraday::Error::ClientError.new("HTTP 413 - Request Entity Too Large", env[:response]) when 400...600 raise Faraday::Error::ClientError.new(message, env[:response]) end end ``` The key part to note here is that a `Restforce::UnauthorizedError` will be raised if a 401 response is returned. #### Restforce::Middleware::Authentication::Token This is an almost empty class, that just defines a `params` method: ```ruby def params { :grant_type => 'refresh_token', :refresh_token => @options[:refresh_token], :client_id => @options[:client_id], :client_secret => @options[:client_secret] } end ``` It inherits from `Restforce::Middleware::Authentication`, which works like this: ``` -
Aupajo revised this gist
Mar 27, 2015 . 1 changed file with 19 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -62,4 +62,22 @@ end ... end end ``` Let's look at the middleware. ### [`Restforce::Middleware::Authorization`](https://github.com/ejholmes/restforce/blob/92b2a0041984d3b4b058e2b4ee337a375056b598/lib/restforce/middleware/authorization.rb) This simply adds the `OAuth` header to each request: ```ruby def call(env) env[:request_headers][AUTH_HEADER] = %(OAuth #{token}) @app.call(env) end def token @options[:oauth_token] end ``` -
Aupajo revised this gist
Mar 27, 2015 . 1 changed file with 25 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,9 +7,13 @@ client = Restforce.new :oauth_token => 'oauth token', :instance_url => 'instanc Any method to interact with Salesforce (`query`, `find`, `search`, etc.) generally wrap around `api_get`: ```ruby def query(soql) response = api_get 'query', :q => soql mashify? ? response.body : response.body['records'] end ``` `api_get` is defined in [`Restforce::Concerns::Verbs`](https://github.com/ejholmes/restforce/blob/92b2a0041984d3b4b058e2b4ee337a375056b598/lib/restforce/concerns/verbs.rb): ```ruby def define_api_verb(verb) @@ -20,6 +24,8 @@ def define_api_verb(verb) end ``` `send` is calling `get`, which is defined in the same module: ```ruby def define_verb(verb) define_method verb do |*args, &block| @@ -38,5 +44,22 @@ def define_verb(verb) end ``` `connection` comes from [`Restforce::Concerns::Connection`](https://github.com/ejholmes/restforce/blob/92b2a0041984d3b4b058e2b4ee337a375056b598/lib/restforce/concerns/connection.rb), and is essentially just a Faraday connection automatically configured with a bunch of Middleware: ```ruby def connection @connection ||= Faraday.new(options[:instance_url], connection_options) do |builder| ... # Handles reauthentication for 403 responses. builder.use authentication_middleware, self, options if authentication_middleware # Sets the oauth token in the headers. builder.use Restforce::Middleware::Authorization, self, options # Ensures the instance url is set. builder.use Restforce::Middleware::InstanceURL, self, options ... # Raises errors for 40x responses. builder.use Restforce::Middleware::RaiseError ... end end ``` -
Aupajo revised this gist
Mar 27, 2015 . 1 changed file with 35 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,5 +4,39 @@ Typical client instantiation looks like this: client = Restforce.new :oauth_token => 'oauth token', :instance_url => 'instance url' ``` Any method to interact with Salesforce (`query`, `find`, `search`, etc.) generally wrap around `api_get`: ```ruby ``` defined in [`Restforce::Concerns::Verbs`](https://github.com/ejholmes/restforce/blob/92b2a0041984d3b4b058e2b4ee337a375056b598/lib/restforce/concerns/verbs.rb): ```ruby def define_api_verb(verb) define_method :"api_#{verb}" do |*args, &block| args[0] = api_path(args[0]) send(verb, *args, &block) end end ``` ```ruby def define_verb(verb) define_method verb do |*args, &block| retries = options[:authentication_retries] begin connection.send(verb, *args, &block) rescue Restforce::UnauthorizedError if retries > 0 retries -= 1 connection.url_prefix = options[:instance_url] retry end raise end end end ``` This simply converts the given request path to a full URL (with the Salesforce) -
Aupajo created this gist
Mar 27, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,8 @@ Typical client instantiation looks like this: ```ruby client = Restforce.new :oauth_token => 'oauth token', :instance_url => 'instance url' ``` Any method to interact with Salesforce (`query`, `find`, `search`, etc.) generally wrap around `api_get`, defined in [`Restforce::Concerns::Verbs`](https://github.com/ejholmes/restforce/blob/92b2a0041984d3b4b058e2b4ee337a375056b598/lib/restforce/concerns/verbs.rb).