restforce 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of restforce might be problematic. Click here for more details.
- data/README.md +53 -6
- data/lib/restforce.rb +9 -0
- data/lib/restforce/client.rb +8 -2
- data/lib/restforce/config.rb +4 -0
- data/lib/restforce/middleware.rb +2 -0
- data/lib/restforce/middleware/authentication.rb +5 -1
- data/lib/restforce/middleware/authentication/password.rb +1 -1
- data/lib/restforce/middleware/authentication/token.rb +1 -1
- data/lib/restforce/middleware/caching.rb +11 -0
- data/lib/restforce/middleware/logger.rb +9 -0
- data/lib/restforce/sobject.rb +5 -0
- data/lib/restforce/version.rb +1 -1
- data/spec/lib/client_spec.rb +7 -0
- data/spec/lib/middleware/authentication/password_spec.rb +1 -1
- data/spec/lib/middleware/authentication/token_spec.rb +1 -1
- data/spec/lib/middleware/authentication_spec.rb +2 -2
- data/spec/lib/sobject_spec.rb +13 -0
- data/spec/support/basic_client.rb +3 -1
- data/spec/support/middleware.rb +1 -1
- metadata +4 -2
data/README.md
CHANGED
@@ -47,7 +47,7 @@ authentication method.
|
|
47
47
|
#### OAuth token authentication
|
48
48
|
|
49
49
|
```ruby
|
50
|
-
client = Restforce
|
50
|
+
client = Restforce.new :oauth_token => 'oauth token',
|
51
51
|
:instance_url => 'instance url'
|
52
52
|
```
|
53
53
|
|
@@ -55,7 +55,7 @@ Although the above will work, you'll probably want to take advantage of the
|
|
55
55
|
(re)authentication middleware by specifying a refresh token, client id and client secret:
|
56
56
|
|
57
57
|
```ruby
|
58
|
-
client = Restforce
|
58
|
+
client = Restforce.new :oauth_token => 'oauth token',
|
59
59
|
:refresh_token => 'refresh token',
|
60
60
|
:instance_url => 'instance url',
|
61
61
|
:client_id => 'client_id',
|
@@ -67,7 +67,7 @@ client = Restforce::Client.new :oauth_token => 'oauth token',
|
|
67
67
|
If you prefer to use a username and password to authenticate:
|
68
68
|
|
69
69
|
```ruby
|
70
|
-
client = Restforce
|
70
|
+
client = Restforce.new :username => 'foo',
|
71
71
|
:password => 'bar',
|
72
72
|
:security_token => 'security token'
|
73
73
|
:client_id => 'client_id',
|
@@ -80,12 +80,12 @@ You can connect to sandbox orgs by specifying a host. The default host is
|
|
80
80
|
'login.salesforce.com':
|
81
81
|
|
82
82
|
```ruby
|
83
|
-
client = Restforce
|
83
|
+
client = Restforce.new :host => 'test.salesforce.com'
|
84
84
|
```
|
85
85
|
|
86
86
|
#### Global configuration
|
87
87
|
|
88
|
-
You can set any of the options passed into Restforce
|
88
|
+
You can set any of the options passed into Restforce.new globally:
|
89
89
|
|
90
90
|
```ruby
|
91
91
|
Restforce.configure do |config|
|
@@ -185,7 +185,7 @@ pub/sub with Salesforce a trivial task:
|
|
185
185
|
|
186
186
|
```ruby
|
187
187
|
# Initialize a client with your username/password/oauth token/etc
|
188
|
-
client = Restforce
|
188
|
+
client = Restforce.new
|
189
189
|
|
190
190
|
# Force an authentication request
|
191
191
|
client.authenticate!
|
@@ -201,6 +201,53 @@ EM.run {
|
|
201
201
|
Boom, you're now receiving push notifications when Accounts are
|
202
202
|
created/updated.
|
203
203
|
|
204
|
+
### Caching
|
205
|
+
|
206
|
+
The gem supports easy caching of GET requests (e.g. queries):
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
# Memcached example:
|
210
|
+
|
211
|
+
cache = Dalli::Client.new
|
212
|
+
|
213
|
+
client = Restforce.new cache: cache
|
214
|
+
|
215
|
+
# or
|
216
|
+
|
217
|
+
Restforce.configure do |config|
|
218
|
+
config.cache = cache
|
219
|
+
end
|
220
|
+
```
|
221
|
+
|
222
|
+
### Logging/Debugging
|
223
|
+
|
224
|
+
You can easily inspect what Restforce is sending/receiving by setting
|
225
|
+
`Restforce.log = true`.
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
Restforce.log = true
|
229
|
+
client = Restforce.new.query('select Id, Name from Account')
|
230
|
+
|
231
|
+
# => I, [2012-09-11T21:54:00.488991 #24032] INFO -- : post https://login.salesforce.com/services/oauth2/token
|
232
|
+
# => D, [2012-09-11T21:54:00.489078 #24032] DEBUG -- request:
|
233
|
+
# => I, [2012-09-11T21:54:00.997295 #24032] INFO -- Status: 200
|
234
|
+
# => D, [2012-09-11T21:54:00.997391 #24032] DEBUG -- response headers: server: ""
|
235
|
+
# => content-type: "application/json; charset=UTF-8"
|
236
|
+
# => transfer-encoding: "chunked"
|
237
|
+
# => date: "Wed, 12 Sep 2012 04:53:59 GMT"
|
238
|
+
# => connection: "close"
|
239
|
+
# => D, [2012-09-11T21:54:00.997431 #24032] DEBUG -- response body: { ... }
|
240
|
+
# => I, [2012-09-11T21:54:00.998985 #24032] INFO -- : get https://na9.salesforce.com/services/data/v24.0/query?q=select+Id%2C+Name+from+Account
|
241
|
+
# => D, [2012-09-11T21:54:00.999040 #24032] DEBUG -- request: Authorization: "OAuth token"
|
242
|
+
# => I, [2012-09-11T21:54:01.622874 #24032] INFO -- Status: 200
|
243
|
+
# => D, [2012-09-11T21:54:01.623001 #24032] DEBUG -- response headers: server: ""
|
244
|
+
# => content-type: "application/json; charset=UTF-8"
|
245
|
+
# => transfer-encoding: "chunked"
|
246
|
+
# => date: "Wed, 12 Sep 2012 04:54:00 GMT"
|
247
|
+
# => connection: "close"
|
248
|
+
# => D, [2012-09-11T21:54:01.623058 #24032] DEBUG -- response body: { ... }
|
249
|
+
```
|
250
|
+
|
204
251
|
## Contributing
|
205
252
|
|
206
253
|
1. Fork it
|
data/lib/restforce.rb
CHANGED
@@ -14,6 +14,15 @@ require 'restforce/client'
|
|
14
14
|
require 'restforce/middleware'
|
15
15
|
|
16
16
|
module Restforce
|
17
|
+
class << self
|
18
|
+
# Alias for Restforce::Client.new
|
19
|
+
#
|
20
|
+
# Shamelessly pulled from https://github.com/pengwynn/octokit/blob/master/lib/octokit.rb
|
21
|
+
def new(options = {})
|
22
|
+
Restforce::Client.new(options)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
17
26
|
class AuthenticationError < StandardError; end
|
18
27
|
class UnauthorizedError < StandardError; end
|
19
28
|
class InstanceURLError < StandardError; end
|
data/lib/restforce/client.rb
CHANGED
@@ -52,7 +52,7 @@ module Restforce
|
|
52
52
|
raise 'Please specify a hash of options' unless options.is_a?(Hash)
|
53
53
|
@options = {}.tap do |options|
|
54
54
|
[:username, :password, :security_token, :client_id, :client_secret, :host,
|
55
|
-
:api_version, :oauth_token, :refresh_token, :instance_url].each do |option|
|
55
|
+
:api_version, :oauth_token, :refresh_token, :instance_url, :cache].each do |option|
|
56
56
|
options[option] = Restforce.configuration.send option
|
57
57
|
end
|
58
58
|
end
|
@@ -327,8 +327,9 @@ module Restforce
|
|
327
327
|
builder.use Restforce::Middleware::Authorization, self, @options
|
328
328
|
builder.use Restforce::Middleware::InstanceURL, self, @options
|
329
329
|
builder.use Restforce::Middleware::RaiseError
|
330
|
-
builder.response :logger, Restforce.configuration.logger if Restforce.log?
|
331
330
|
builder.response :json
|
331
|
+
builder.use Restforce::Middleware::Caching, cache if cache
|
332
|
+
builder.use Restforce::Middleware::Logger, Restforce.configuration.logger if Restforce.log?
|
332
333
|
builder.adapter Faraday.default_adapter
|
333
334
|
end
|
334
335
|
@connection
|
@@ -361,6 +362,11 @@ module Restforce
|
|
361
362
|
@options[:client_secret]
|
362
363
|
end
|
363
364
|
|
365
|
+
# Internal: Cache to use for the caching middleware
|
366
|
+
def cache
|
367
|
+
@options[:cache]
|
368
|
+
end
|
369
|
+
|
364
370
|
# Internal: Returns true if the middlware stack includes the
|
365
371
|
# Restforce::Middleware::Mashify middleware.
|
366
372
|
def mashify?
|
data/lib/restforce/config.rb
CHANGED
@@ -56,6 +56,10 @@ module Restforce
|
|
56
56
|
attr_accessor :refresh_token
|
57
57
|
attr_accessor :instance_url
|
58
58
|
|
59
|
+
# Set this to an object that responds to read, write and fetch and all GET
|
60
|
+
# requests will be cached.
|
61
|
+
attr_accessor :cache
|
62
|
+
|
59
63
|
def initialize
|
60
64
|
@api_version ||= '24.0'
|
61
65
|
@host ||= 'login.salesforce.com'
|
data/lib/restforce/middleware.rb
CHANGED
@@ -23,7 +23,7 @@ module Restforce
|
|
23
23
|
def connection
|
24
24
|
@connection ||= Faraday.new(:url => "https://#{@options[:host]}") do |builder|
|
25
25
|
builder.response :json
|
26
|
-
builder.
|
26
|
+
builder.use Restforce::Middleware::Logger, Restforce.configuration.logger if Restforce.log?
|
27
27
|
builder.adapter Faraday.default_adapter
|
28
28
|
end
|
29
29
|
end
|
@@ -31,6 +31,10 @@ module Restforce
|
|
31
31
|
def force_authenticate?(env)
|
32
32
|
env[:request_headers] && env[:request_headers]['X-ForceAuthenticate']
|
33
33
|
end
|
34
|
+
|
35
|
+
def error_message(response)
|
36
|
+
"#{response.body['error']}: #{response.body['error_description']}"
|
37
|
+
end
|
34
38
|
|
35
39
|
end
|
36
40
|
|
@@ -13,7 +13,7 @@ module Restforce
|
|
13
13
|
:password => password
|
14
14
|
)
|
15
15
|
end
|
16
|
-
raise Restforce::AuthenticationError if response.status != 200
|
16
|
+
raise Restforce::AuthenticationError, error_message(response) if response.status != 200
|
17
17
|
@options[:instance_url] = response.body['instance_url']
|
18
18
|
@options[:oauth_token] = response.body['access_token']
|
19
19
|
end
|
@@ -12,7 +12,7 @@ module Restforce
|
|
12
12
|
:client_secret => @options[:client_secret]
|
13
13
|
)
|
14
14
|
end
|
15
|
-
raise Restforce::AuthenticationError if response.status != 200
|
15
|
+
raise Restforce::AuthenticationError, error_message(response) if response.status != 200
|
16
16
|
@options[:instance_url] = response.body['instance_url']
|
17
17
|
@options[:oauth_token] = response.body['access_token']
|
18
18
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Restforce
|
2
|
+
class Middleware::Caching < FaradayMiddleware::Caching
|
3
|
+
|
4
|
+
# We don't want to cache requests for different clients, so append the
|
5
|
+
# oauth token to the cache key.
|
6
|
+
def cache_key(env)
|
7
|
+
super(env) + env[:request_headers][Restforce::Middleware::Authorization::AUTH_HEADER].gsub(/\s/, '')
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
data/lib/restforce/sobject.rb
CHANGED
data/lib/restforce/version.rb
CHANGED
data/spec/lib/client_spec.rb
CHANGED
@@ -326,6 +326,13 @@ shared_examples_for 'methods' do
|
|
326
326
|
subject { client.authenticate! }
|
327
327
|
specify { expect { subject }.to_not raise_error }
|
328
328
|
end
|
329
|
+
|
330
|
+
describe '.cache' do
|
331
|
+
let(:cache) { double('cache') }
|
332
|
+
|
333
|
+
subject { client.send :cache }
|
334
|
+
it { should eq cache }
|
335
|
+
end
|
329
336
|
end
|
330
337
|
|
331
338
|
describe 'with mashify middleware' do
|
@@ -26,7 +26,7 @@ describe Restforce::Middleware::Authentication::Password do
|
|
26
26
|
stub_request(:post, "https://login.salesforce.com/services/oauth2/token").
|
27
27
|
with(:body => "grant_type=password&client_id=client_id&client_secret=" \
|
28
28
|
"client_secret&username=foo&password=barsecurity_token").
|
29
|
-
to_return(:status => 400, :body => fixture(:
|
29
|
+
to_return(:status => 400, :body => fixture(:auth_error_response))
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
@@ -24,7 +24,7 @@ describe Restforce::Middleware::Authentication::Token do
|
|
24
24
|
stub_request(:post, "https://login.salesforce.com/services/oauth2/token").
|
25
25
|
with(:body => "grant_type=refresh_token&refresh_token=refresh_token&" \
|
26
26
|
"client_id=client_id&client_secret=client_secret").
|
27
|
-
to_return(:status => 400, :body => fixture(:
|
27
|
+
to_return(:status => 400, :body => fixture(:refresh_error_response))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -52,7 +52,7 @@ describe Restforce::Middleware::Authentication do
|
|
52
52
|
end
|
53
53
|
|
54
54
|
its(:handlers) { should include FaradayMiddleware::ParseJson, Faraday::Adapter::NetHttp }
|
55
|
-
its(:handlers) { should_not include
|
55
|
+
its(:handlers) { should_not include Restforce::Middleware::Logger }
|
56
56
|
end
|
57
57
|
|
58
58
|
context 'with logging enabled' do
|
@@ -60,7 +60,7 @@ describe Restforce::Middleware::Authentication do
|
|
60
60
|
Restforce.stub!(:log?).and_return(true)
|
61
61
|
end
|
62
62
|
|
63
|
-
its(:handlers) { should include FaradayMiddleware::ParseJson,
|
63
|
+
its(:handlers) { should include FaradayMiddleware::ParseJson, Restforce::Middleware::Logger, Faraday::Adapter::NetHttp }
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
data/spec/lib/sobject_spec.rb
CHANGED
@@ -90,4 +90,17 @@ describe Restforce::SObject do
|
|
90
90
|
specify { expect { subject }.to_not raise_error }
|
91
91
|
end
|
92
92
|
end
|
93
|
+
|
94
|
+
describe '.describe' do
|
95
|
+
before do
|
96
|
+
@request = stub_api_request 'sobject/Whizbang/describe', with: 'sobject/sobject_describe_success_response'
|
97
|
+
end
|
98
|
+
|
99
|
+
after do
|
100
|
+
@request.should have_been_requested
|
101
|
+
end
|
102
|
+
|
103
|
+
subject { sobject.describe }
|
104
|
+
it { should be_a Hash }
|
105
|
+
end
|
93
106
|
end
|
@@ -7,6 +7,7 @@ shared_context 'basic client' do
|
|
7
7
|
let(:security_token) { 'security_token' }
|
8
8
|
let(:client_id) { 'client_id' }
|
9
9
|
let(:client_secret) { 'client_secret' }
|
10
|
+
let(:cache) { nil }
|
10
11
|
|
11
12
|
let(:base_options) do
|
12
13
|
{
|
@@ -17,7 +18,8 @@ shared_context 'basic client' do
|
|
17
18
|
:password => password,
|
18
19
|
:security_token => security_token,
|
19
20
|
:client_id => client_id,
|
20
|
-
:client_secret => client_secret
|
21
|
+
:client_secret => client_secret,
|
22
|
+
:cache => cache
|
21
23
|
}
|
22
24
|
end
|
23
25
|
|
data/spec/support/middleware.rb
CHANGED
@@ -25,7 +25,7 @@ shared_examples_for 'authentication middleware' do
|
|
25
25
|
it 'raises an exception' do
|
26
26
|
expect {
|
27
27
|
middleware.authenticate!
|
28
|
-
}.to raise_error Restforce::AuthenticationError
|
28
|
+
}.to raise_error Restforce::AuthenticationError, /^invalid_grant: .*/
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restforce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -179,7 +179,9 @@ files:
|
|
179
179
|
- lib/restforce/middleware/authentication/password.rb
|
180
180
|
- lib/restforce/middleware/authentication/token.rb
|
181
181
|
- lib/restforce/middleware/authorization.rb
|
182
|
+
- lib/restforce/middleware/caching.rb
|
182
183
|
- lib/restforce/middleware/instance_url.rb
|
184
|
+
- lib/restforce/middleware/logger.rb
|
183
185
|
- lib/restforce/middleware/mashify.rb
|
184
186
|
- lib/restforce/middleware/multipart.rb
|
185
187
|
- lib/restforce/middleware/raise_error.rb
|