restforce 4.0.0 → 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +2 -2
- data/CHANGELOG.md +21 -0
- data/Gemfile +1 -0
- data/README.md +32 -15
- data/lib/restforce.rb +7 -6
- data/lib/restforce/concerns/api.rb +1 -1
- data/lib/restforce/concerns/authentication.rb +10 -0
- data/lib/restforce/concerns/base.rb +2 -0
- data/lib/restforce/concerns/connection.rb +3 -3
- data/lib/restforce/concerns/streaming.rb +22 -7
- data/lib/restforce/config.rb +3 -0
- data/lib/restforce/mash.rb +1 -1
- data/lib/restforce/middleware/authentication.rb +7 -3
- data/lib/restforce/middleware/authentication/jwt_bearer.rb +38 -0
- data/lib/restforce/middleware/instance_url.rb +1 -1
- data/lib/restforce/version.rb +1 -1
- data/restforce.gemspec +4 -3
- data/spec/fixtures/test_private.key +27 -0
- data/spec/integration/abstract_client_spec.rb +2 -2
- data/spec/unit/concerns/api_spec.rb +1 -1
- data/spec/unit/concerns/authentication_spec.rb +35 -0
- data/spec/unit/concerns/streaming_spec.rb +58 -30
- data/spec/unit/mash_spec.rb +5 -0
- data/spec/unit/middleware/authentication/jwt_bearer_spec.rb +62 -0
- data/spec/unit/middleware/authentication_spec.rb +21 -0
- data/spec/unit/middleware/raise_error_spec.rb +10 -10
- data/spec/unit/sobject_spec.rb +2 -5
- metadata +37 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f24606173bf2365a1482e7ed764863aed6bf53ffad8f9e6c380144c5567a7541
|
4
|
+
data.tar.gz: fadc63d588d150937b9b4ff102adcdd2ab91691fc26f8bfaa9515b2eb79a4553
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25baee4f91c29f7f3210b23c9a79f9ac1a9ee12a3a6169e20090e860ec62d51b671ef87b84f8ffc25633a2df933cbed0e5e980fb5ef41c7af08db7aa20de4eda
|
7
|
+
data.tar.gz: 6ab7f0096e6931fb2a59febb88d84a3c51a2000d3e690402b9f42ae9b85073f0b2623100a6a106035a420d448f64969c39415411def1a8c4f5bc690ef281c591
|
data/.rubocop_todo.yml
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
# SupportedHashRocketStyles: key, separator, table
|
13
13
|
# SupportedColonStyles: key, separator, table
|
14
14
|
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
|
15
|
-
Layout/
|
15
|
+
Layout/HashAlignment:
|
16
16
|
Exclude:
|
17
17
|
- 'lib/restforce/middleware/logger.rb'
|
18
18
|
- 'restforce.gemspec'
|
@@ -23,7 +23,7 @@ Layout/AlignHash:
|
|
23
23
|
# Cop supports --auto-correct.
|
24
24
|
# Configuration parameters: EnforcedStyle, IndentationWidth.
|
25
25
|
# SupportedStyles: special_inside_parentheses, consistent, align_braces
|
26
|
-
Layout/
|
26
|
+
Layout/FirstHashElementIndentation:
|
27
27
|
Exclude:
|
28
28
|
- 'lib/restforce/concerns/connection.rb'
|
29
29
|
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
## 4.3.0 (Feb 10, 2021)
|
2
|
+
|
3
|
+
* Add compatability with Faraday versions up to but not including `v1.1.0` (@hongtron)
|
4
|
+
|
5
|
+
## 4.2.2 (Jan 23, 2020)
|
6
|
+
|
7
|
+
* Fix `NoMethodError: undefined method '[]' for nil:NilClass` error when generating objects to return (@apurkiss)
|
8
|
+
|
9
|
+
## 4.2.1 (Dec 4, 2019)
|
10
|
+
|
11
|
+
* Handle empty response bodies returned with authentication errors (@sylvandor)
|
12
|
+
* Fix Faraday deprecation warning in newer Faraday versions (`v0.17.1` onwards) caused by inheriting from a deprecated class
|
13
|
+
|
14
|
+
## 4.2.0 (Oct 23, 2019)
|
15
|
+
|
16
|
+
* Add support for platform events, CDC, generic events, etc. in the Streaming API (@nathanKramer)
|
17
|
+
|
18
|
+
## 4.1.0 (Oct 20, 2019)
|
19
|
+
|
20
|
+
* Add support for JWT authentication (@nathanKramer, @tagCincy)
|
21
|
+
|
1
22
|
## 4.0.0 (Oct 9, 2019)
|
2
23
|
|
3
24
|
* __Deprecate support for Ruby 2.3__, since [Ruby 2.3 reached its end-of-life](https://www.ruby-lang.org/en/news/2019/03/31/support-of-ruby-2-3-has-ended/) in March 2019. (This is the only breaking change included in this version.)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -25,7 +25,7 @@ Features include:
|
|
25
25
|
|
26
26
|
Add this line to your application's Gemfile:
|
27
27
|
|
28
|
-
gem 'restforce', '~> 4.
|
28
|
+
gem 'restforce', '~> 4.3.0'
|
29
29
|
|
30
30
|
And then execute:
|
31
31
|
|
@@ -111,6 +111,21 @@ client = Restforce.new(username: 'foo',
|
|
111
111
|
api_version: '41.0')
|
112
112
|
```
|
113
113
|
|
114
|
+
#### JWT Bearer Token
|
115
|
+
|
116
|
+
If you prefer to use a [JWT Bearer Token](https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com#Obtaining_an_Access_Token_using_a_JWT_Bearer_Token) to authenticate:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
client = Restforce.new(username: 'foo',
|
120
|
+
client_id: 'client_id',
|
121
|
+
instance_url: 'instance_url',
|
122
|
+
jwt_key: 'certificate_private_key',
|
123
|
+
api_version: '38.0')
|
124
|
+
```
|
125
|
+
|
126
|
+
The `jwt_key` option is the private key of the certificate uploaded to your Connected App in Salesforce.
|
127
|
+
Choose "use digital signatures" in the Connected App configuration screen to upload your certificate.
|
128
|
+
|
114
129
|
You can also set the username, password, security token, client ID, client
|
115
130
|
secret and API version in environment variables:
|
116
131
|
|
@@ -473,11 +488,11 @@ document = client.query('select Id, Name, Body from Document').first
|
|
473
488
|
File.open(document.Name, 'wb') { |f| f.write(document.Body) }
|
474
489
|
```
|
475
490
|
|
476
|
-
**Note:** The example above is only applicable if your SOQL query returns a single Document record. If more than one record is returned,
|
491
|
+
**Note:** The example above is only applicable if your SOQL query returns a single Document record. If more than one record is returned,
|
477
492
|
the Body field contains an URL to retrieve the BLOB content for the first 2000 records returned. Subsequent records contain the BLOB content
|
478
|
-
in the Body field. This is confusing and hard to debug. See notes in [Issue #301](https://github.com/restforce/restforce/issues/301#issuecomment-298972959) explaining this detail.
|
479
|
-
**Executive Summary:** Don't retrieve the Body field in a SOQL query; instead, use the BLOB retrieval URL documented
|
480
|
-
in [SObject BLOB Retrieve](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_sobject_blob_retrieve.htm)
|
493
|
+
in the Body field. This is confusing and hard to debug. See notes in [Issue #301](https://github.com/restforce/restforce/issues/301#issuecomment-298972959) explaining this detail.
|
494
|
+
**Executive Summary:** Don't retrieve the Body field in a SOQL query; instead, use the BLOB retrieval URL documented
|
495
|
+
in [SObject BLOB Retrieve](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_sobject_blob_retrieve.htm)
|
481
496
|
|
482
497
|
* * *
|
483
498
|
|
@@ -513,8 +528,10 @@ client.get('/services/apexrest/FieldCase', company: 'GenePoint')
|
|
513
528
|
|
514
529
|
### Streaming
|
515
530
|
|
516
|
-
Restforce supports the [Streaming API](
|
517
|
-
pub/sub with Salesforce a trivial task
|
531
|
+
Restforce supports the [Streaming API](https://trailhead.salesforce.com/en/content/learn/modules/api_basics/api_basics_streaming), and makes implementing
|
532
|
+
pub/sub with Salesforce a trivial task.
|
533
|
+
|
534
|
+
Here is an example of creating and subscribing to a `PushTopic`:
|
518
535
|
|
519
536
|
```ruby
|
520
537
|
# Restforce uses faye as the underlying implementation for CometD.
|
@@ -538,7 +555,7 @@ client.create!('PushTopic',
|
|
538
555
|
|
539
556
|
EM.run do
|
540
557
|
# Subscribe to the PushTopic.
|
541
|
-
client.
|
558
|
+
client.subscription '/topic/AllAccounts' do |message|
|
542
559
|
puts message.inspect
|
543
560
|
end
|
544
561
|
end
|
@@ -559,7 +576,7 @@ that event ID:
|
|
559
576
|
```ruby
|
560
577
|
EM.run {
|
561
578
|
# Subscribe to the PushTopic.
|
562
|
-
client.
|
579
|
+
client.subscription '/topic/AllAccounts', replay: 10 do |message|
|
563
580
|
puts message.inspect
|
564
581
|
end
|
565
582
|
}
|
@@ -574,14 +591,14 @@ There are two magic values for the replay ID accepted by Salesforce:
|
|
574
591
|
|
575
592
|
**Warning**: Only use a replay ID of a event from the last 24 hours otherwise
|
576
593
|
Salesforce will not send anything, including newer events. If in doubt, use one
|
577
|
-
of the two magic replay IDs mentioned above.
|
594
|
+
of the two magic replay IDs mentioned above.
|
578
595
|
|
579
|
-
You might want to store the replay ID in some sort of datastore so you can
|
596
|
+
You might want to store the replay ID in some sort of datastore so you can
|
580
597
|
access it, for example between application restarts. In that case, there is the
|
581
598
|
option of passing a custom replay handler which responds to `[]` and `[]=`.
|
582
599
|
|
583
600
|
Below is a sample replay handler that stores the replay ID for each channel in
|
584
|
-
memory using a Hash, stores a timestamp and has some rudimentary logic that
|
601
|
+
memory using a Hash, stores a timestamp and has some rudimentary logic that
|
585
602
|
will use one of the magic IDs depending on the value of the timestamp:
|
586
603
|
|
587
604
|
```ruby
|
@@ -633,13 +650,13 @@ of the subscription:
|
|
633
650
|
EM.run {
|
634
651
|
# Subscribe to the PushTopic and use the custom replay handler to store any
|
635
652
|
# received replay ID.
|
636
|
-
client.
|
653
|
+
client.subscription '/topic/AllAccounts', replay: SimpleReplayHandler.new do |message|
|
637
654
|
puts message.inspect
|
638
655
|
end
|
639
656
|
}
|
640
|
-
```
|
657
|
+
```
|
641
658
|
|
642
|
-
_See also_:
|
659
|
+
_See also_:
|
643
660
|
|
644
661
|
* [Force.com Streaming API docs](http://www.salesforce.com/us/developer/docs/api_streaming/index.htm)
|
645
662
|
* [Message Durability docs](https://developer.salesforce.com/docs/atlas.en-us.api_streaming.meta/api_streaming/using_streaming_api_durability.htm)
|
data/lib/restforce.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'faraday'
|
4
4
|
require 'faraday_middleware'
|
5
5
|
require 'json'
|
6
|
+
require 'jwt'
|
6
7
|
|
7
8
|
require 'restforce/version'
|
8
9
|
require 'restforce/config'
|
@@ -47,15 +48,15 @@ module Restforce
|
|
47
48
|
APIVersionError = Class.new(Error)
|
48
49
|
BatchAPIError = Class.new(Error)
|
49
50
|
|
50
|
-
# Inherit from Faraday::
|
51
|
-
# Consumers of this library that rescue and handle Faraday::
|
51
|
+
# Inherit from Faraday::ResourceNotFound for backwards-compatibility
|
52
|
+
# Consumers of this library that rescue and handle Faraday::ResourceNotFound
|
52
53
|
# can continue to do so.
|
53
|
-
NotFoundError = Class.new(Faraday::
|
54
|
+
NotFoundError = Class.new(Faraday::ResourceNotFound)
|
54
55
|
|
55
|
-
# Inherit from Faraday::
|
56
|
-
# Consumers of this library that rescue and handle Faraday::
|
56
|
+
# Inherit from Faraday::ClientError for backwards-compatibility
|
57
|
+
# Consumers of this library that rescue and handle Faraday::ClientError
|
57
58
|
# can continue to do so.
|
58
|
-
ResponseError = Class.new(Faraday::
|
59
|
+
ResponseError = Class.new(Faraday::ClientError)
|
59
60
|
MatchesMultipleError= Class.new(ResponseError)
|
60
61
|
EntityTooLargeError = Class.new(ResponseError)
|
61
62
|
|
@@ -19,6 +19,8 @@ module Restforce
|
|
19
19
|
Restforce::Middleware::Authentication::Password
|
20
20
|
elsif oauth_refresh?
|
21
21
|
Restforce::Middleware::Authentication::Token
|
22
|
+
elsif jwt?
|
23
|
+
Restforce::Middleware::Authentication::JWTBearer
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
@@ -38,6 +40,14 @@ module Restforce
|
|
38
40
|
options[:client_id] &&
|
39
41
|
options[:client_secret]
|
40
42
|
end
|
43
|
+
|
44
|
+
# Internal: Returns true if jwt bearer token flow should be used for
|
45
|
+
# authentication.
|
46
|
+
def jwt?
|
47
|
+
options[:jwt_key] &&
|
48
|
+
options[:username] &&
|
49
|
+
options[:client_id]
|
50
|
+
end
|
41
51
|
end
|
42
52
|
end
|
43
53
|
end
|
@@ -28,6 +28,8 @@ module Restforce
|
|
28
28
|
# password and oauth authentication
|
29
29
|
# :client_secret - The oauth client secret to use.
|
30
30
|
#
|
31
|
+
# :jwt_key - The private key for JWT authentication
|
32
|
+
#
|
31
33
|
# :host - The String hostname to use during
|
32
34
|
# authentication requests
|
33
35
|
# (default: 'login.salesforce.com').
|
@@ -72,9 +72,9 @@ module Restforce
|
|
72
72
|
# Internal: Faraday Connection options
|
73
73
|
def connection_options
|
74
74
|
{ request: {
|
75
|
-
|
76
|
-
|
77
|
-
},
|
75
|
+
timeout: options[:timeout],
|
76
|
+
open_timeout: options[:timeout]
|
77
|
+
},
|
78
78
|
proxy: options[:proxy_uri],
|
79
79
|
ssl: options[:ssl] }
|
80
80
|
end
|
@@ -5,13 +5,28 @@ module Restforce
|
|
5
5
|
module Streaming
|
6
6
|
# Public: Subscribe to a PushTopic
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# topics - The name of the PushTopic channel(s) to subscribe to.
|
9
9
|
# block - A block to run when a new message is received.
|
10
10
|
#
|
11
11
|
# Returns a Faye::Subscription
|
12
|
-
def
|
13
|
-
Array(
|
14
|
-
|
12
|
+
def legacy_subscribe(topics, options = {}, &block)
|
13
|
+
topics = Array(topics).map { |channel| "/topic/#{channel}" }
|
14
|
+
subscription(topics, options, &block)
|
15
|
+
end
|
16
|
+
alias subscribe legacy_subscribe
|
17
|
+
|
18
|
+
# Public: Subscribe to one or more Streaming API channels
|
19
|
+
#
|
20
|
+
# channels - The name of the Streaming API (cometD) channel(s) to subscribe to.
|
21
|
+
# block - A block to run when a new message is received.
|
22
|
+
#
|
23
|
+
# Returns a Faye::Subscription
|
24
|
+
def subscription(channels, options = {}, &block)
|
25
|
+
one_or_more_channels = Array(channels)
|
26
|
+
one_or_more_channels.each do |channel|
|
27
|
+
replay_handlers[channel] = options[:replay]
|
28
|
+
end
|
29
|
+
faye.subscribe(one_or_more_channels, &block)
|
15
30
|
end
|
16
31
|
|
17
32
|
# Public: Faye client to use for subscribing to PushTopics
|
@@ -49,7 +64,7 @@ module Restforce
|
|
49
64
|
|
50
65
|
def incoming(message, callback)
|
51
66
|
callback.call(message).tap do
|
52
|
-
channel = message.fetch('channel')
|
67
|
+
channel = message.fetch('channel')
|
53
68
|
replay_id = message.fetch('data', {}).fetch('event', {})['replayId']
|
54
69
|
|
55
70
|
handler = @replay_handlers[channel]
|
@@ -64,12 +79,12 @@ module Restforce
|
|
64
79
|
# Leave non-subscribe messages alone
|
65
80
|
return callback.call(message) unless message['channel'] == '/meta/subscribe'
|
66
81
|
|
67
|
-
channel = message['subscription']
|
82
|
+
channel = message['subscription']
|
68
83
|
|
69
84
|
# Set the replay value for the channel
|
70
85
|
message['ext'] ||= {}
|
71
86
|
message['ext']['replay'] = {
|
72
|
-
|
87
|
+
channel => replay_id(channel)
|
73
88
|
}
|
74
89
|
|
75
90
|
# Carry on and send the message to the server
|
data/lib/restforce/config.rb
CHANGED
@@ -108,6 +108,9 @@ module Restforce
|
|
108
108
|
# The OAuth client secret
|
109
109
|
option :client_secret, default: lambda { ENV['SALESFORCE_CLIENT_SECRET'] }
|
110
110
|
|
111
|
+
# The private key for JWT authentication
|
112
|
+
option :jwt_key
|
113
|
+
|
111
114
|
# Set this to true if you're authenticating with a Sandbox instance.
|
112
115
|
# Defaults to false.
|
113
116
|
option :host, default: lambda { ENV['SALESFORCE_HOST'] || 'login.salesforce.com' }
|
data/lib/restforce/mash.rb
CHANGED
@@ -6,8 +6,9 @@ module Restforce
|
|
6
6
|
# will attempt to either reauthenticate (username and password) or refresh
|
7
7
|
# the oauth access token (if a refresh token is present).
|
8
8
|
class Middleware::Authentication < Restforce::Middleware
|
9
|
-
autoload :Password,
|
10
|
-
autoload :Token,
|
9
|
+
autoload :Password, 'restforce/middleware/authentication/password'
|
10
|
+
autoload :Token, 'restforce/middleware/authentication/token'
|
11
|
+
autoload :JWTBearer, 'restforce/middleware/authentication/jwt_bearer'
|
11
12
|
|
12
13
|
# Rescue from 401's, authenticate then raise the error again so the client
|
13
14
|
# can reissue the request.
|
@@ -62,7 +63,10 @@ module Restforce
|
|
62
63
|
|
63
64
|
# Internal: The parsed error response.
|
64
65
|
def error_message(response)
|
65
|
-
|
66
|
+
return response.status.to_s unless response.body
|
67
|
+
|
68
|
+
"#{response.body['error']}: #{response.body['error_description']} " \
|
69
|
+
"(#{response.status})"
|
66
70
|
end
|
67
71
|
|
68
72
|
# Featured detect form encoding.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'jwt'
|
4
|
+
|
5
|
+
module Restforce
|
6
|
+
class Middleware
|
7
|
+
class Authentication
|
8
|
+
class JWTBearer < Restforce::Middleware::Authentication
|
9
|
+
def params
|
10
|
+
{
|
11
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
12
|
+
assertion: jwt_bearer_token
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def jwt_bearer_token
|
19
|
+
JWT.encode claim_set, private_key, 'RS256'
|
20
|
+
end
|
21
|
+
|
22
|
+
def claim_set
|
23
|
+
{
|
24
|
+
iss: @options[:client_id],
|
25
|
+
sub: @options[:username],
|
26
|
+
aud: @options[:host],
|
27
|
+
iat: Time.now.utc.to_i,
|
28
|
+
exp: Time.now.utc.to_i + 180
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def private_key
|
33
|
+
OpenSSL::PKey::RSA.new(@options[:jwt_key])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/restforce/version.rb
CHANGED
data/restforce.gemspec
CHANGED
@@ -28,13 +28,14 @@ Gem::Specification.new do |gem|
|
|
28
28
|
gem.add_dependency 'faraday_middleware', ['>= 0.8.8', '<= 1.0']
|
29
29
|
|
30
30
|
gem.add_dependency 'json', '>= 1.7.5'
|
31
|
+
gem.add_dependency 'jwt', ['>= 1.5.6']
|
31
32
|
|
32
|
-
gem.add_dependency 'hashie',
|
33
|
+
gem.add_dependency 'hashie', '>= 1.2.0', '< 5.0'
|
33
34
|
|
34
35
|
gem.add_development_dependency 'faye' unless RUBY_PLATFORM == 'java'
|
35
36
|
gem.add_development_dependency 'rspec', '~> 2.14.0'
|
36
|
-
gem.add_development_dependency 'rspec_junit_formatter', '~> 0.
|
37
|
-
gem.add_development_dependency 'rubocop', '~> 0.
|
37
|
+
gem.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1'
|
38
|
+
gem.add_development_dependency 'rubocop', '~> 0.77.0'
|
38
39
|
gem.add_development_dependency 'simplecov', '~> 0.17.1'
|
39
40
|
gem.add_development_dependency 'webmock', '~> 3.7.6'
|
40
41
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEpAIBAAKCAQEAy3KYqxZIgVDgFwdA+OQcKMJQu3iUTlyCSk9b3RLBOudnvk8u
|
3
|
+
n0ShtKkOKB4b4RZeedcrlKESoak/6NS+M7CDemRT0EagqUiz/ZsZxB2KUp7au+d8
|
4
|
+
0KWX99/loBjDttuon8ITDw2WFC9X0+TZqfsXcQ0iV1/9Sf8WHShd8ZqShjJBlEvf
|
5
|
+
7u7VdNW8dXrl+4cvpPzspVxg6jVotEpmp875jmGRvshgx0iz0jtfAyxaaKStITC6
|
6
|
+
MxufVNDgIYQDl6queh8b9noDLtt17Eq6YnropYN1hOjaLtoLBP7AN2gsXG7N3vqC
|
7
|
+
JG619W9X4zCmKztv4oGjymInrS2msC2J02dNGQIDAQABAoIBAAurTARsJ8Z7DA9m
|
8
|
+
FBzygIb59kV6eg8wkSyP9rXscHbfdPzeb88k0Z2aILy+VV0IumyEofRJdNce7RJ+
|
9
|
+
uVYfprrrbD9C/c4X5HMEZWrxQtDQWb1zXp5dESVfiz0ujnM7kCVxrUQsxFHuETyP
|
10
|
+
IMj2JPcQCMs4L0ACSJNtkE3eTs8xko5kwDHZGiLTi5jD1bLgaHl1A+9CTU8LosTy
|
11
|
+
hEIrNSZfNidDPU4QSbwoElYZxpDMSbtyHaIk1WHz7zLzWoogK3x5AIQh64wWAQVd
|
12
|
+
zzlp2j2jSM7oQ9j+k1aNiUBdDoRX53jmaIwE/1WDW/LT33qAoqRw+5qHeLRoRcfu
|
13
|
+
3uj/WI0CgYEA6wnpIUhqqWT+febhXtCr1mAJlAJpzUUQncN6Zk0Kj/kE1V52OqgL
|
14
|
+
gtOactII7J3+0zK7KGptqseTank0ghmGNdRBQ7+1JTQhpjLrCm/huKDhl+sBk95u
|
15
|
+
opxw/ZTwMFYPwsmZlFcy4uWRjtI+QzaV+2Xk5JF57H8vUiX/+XqseQcCgYEA3Zdw
|
16
|
+
zVHpcVPlyiXCbSvwb9IYXiJaQl/Rg96Klxah3MZNyRRKe5IoKUTJwEDuQ1MAHrve
|
17
|
+
cWrNLcXhX6r/PzIXSSLe71wgwpn7UcaqWzZJqqN7OIGEeTzYWbB6tGhse7Dw7tWB
|
18
|
+
hRkQSE0LPzZqboHz5msRM02sa61qiI5+ASJvIN8CgYEAvT+IoEzv3R89ruBVPQPm
|
19
|
+
KMHBVJSw3iArJex8xJxp0c0fMDJUHhyq0BdTd/pYRzVcNm/VtNAlJ2p07zlSpyKo
|
20
|
+
JvWV61gUIjWclnbPO+MkK4YWvzzxUz+5c2NlszjWQQU6wYuUBpZDmeBg2E++5F2y
|
21
|
+
W+8KY2QjeOJbltiUCCvXbccCgYEAqARYB5aARumyZqBS16xlVqQazeWGQqWcmzx2
|
22
|
+
ITGL8XZ7LGgyQZgE06XQw/F3t5yLjsIsXBr7ECXmST/C4gv9E/tYxm04edV/dfYI
|
23
|
+
3bhACx6CI8owxCyabwcdQwWam/8B8FX7KwxiCDBCwt9ju/7VDHVKSXgvsEWBbaF9
|
24
|
+
cSbG1EkCgYBZFztTUnD/cLMcvLUegN0K+6Qa3x3nRSrlrJ+v51mU1X8G8qNyFO67
|
25
|
+
gUq9h4xbCl4Z5ZTuFKXwPM4XaMzfYdrWNS2zl5IG14FXS077GhDKe062b9mFoxtm
|
26
|
+
aViCit4Hm8xpLTS8x9KB7yYAiF9sR/GklW1SUCIqnpL9JShkhzjfZw==
|
27
|
+
-----END RSA PRIVATE KEY-----
|
@@ -125,7 +125,7 @@ shared_examples_for Restforce::AbstractClient do
|
|
125
125
|
|
126
126
|
it {
|
127
127
|
should raise_error(
|
128
|
-
Faraday::
|
128
|
+
Faraday::ResourceNotFound,
|
129
129
|
"#{error.first['errorCode']}: #{error.first['message']}"
|
130
130
|
)
|
131
131
|
}
|
@@ -239,7 +239,7 @@ shared_examples_for Restforce::AbstractClient do
|
|
239
239
|
status: 404
|
240
240
|
|
241
241
|
subject { lambda { destroy! } }
|
242
|
-
it { should raise_error Faraday::
|
242
|
+
it { should raise_error Faraday::ResourceNotFound }
|
243
243
|
end
|
244
244
|
|
245
245
|
context 'with success' do
|
@@ -274,7 +274,7 @@ describe Restforce::Concerns::API do
|
|
274
274
|
end
|
275
275
|
|
276
276
|
it 'rescues exceptions' do
|
277
|
-
[Faraday::
|
277
|
+
[Faraday::ClientError].each do |exception_klass|
|
278
278
|
client.should_receive(:"#{method}!").
|
279
279
|
with(*args).
|
280
280
|
and_raise(exception_klass.new(nil))
|
@@ -52,6 +52,16 @@ describe Restforce::Concerns::Authentication do
|
|
52
52
|
|
53
53
|
it { should eq Restforce::Middleware::Authentication::Token }
|
54
54
|
end
|
55
|
+
|
56
|
+
context 'when jwt option is provided' do
|
57
|
+
before do
|
58
|
+
client.stub username_password?: false
|
59
|
+
client.stub oauth_refresh?: false
|
60
|
+
client.stub jwt?: true
|
61
|
+
end
|
62
|
+
|
63
|
+
it { should eq Restforce::Middleware::Authentication::JWTBearer }
|
64
|
+
end
|
55
65
|
end
|
56
66
|
|
57
67
|
describe '.username_password?' do
|
@@ -100,4 +110,29 @@ describe Restforce::Concerns::Authentication do
|
|
100
110
|
it { should_not be_true }
|
101
111
|
end
|
102
112
|
end
|
113
|
+
|
114
|
+
describe '.jwt?' do
|
115
|
+
subject { client.jwt? }
|
116
|
+
let(:options) do
|
117
|
+
{}
|
118
|
+
end
|
119
|
+
|
120
|
+
before do
|
121
|
+
client.stub options: options
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'when jwt options are provided' do
|
125
|
+
let(:options) do
|
126
|
+
{ jwt_key: 'JWT_PRIVATE_KEY',
|
127
|
+
username: 'foo',
|
128
|
+
client_id: 'client' }
|
129
|
+
end
|
130
|
+
|
131
|
+
it { should be_true }
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'when jwt options are not provided' do
|
135
|
+
it { should_not be_true }
|
136
|
+
end
|
137
|
+
end
|
103
138
|
end
|
@@ -4,18 +4,19 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe Restforce::Concerns::Streaming, event_machine: true do
|
6
6
|
describe '.subscribe' do
|
7
|
-
let(:channels)
|
8
|
-
|
7
|
+
let(:channels) do
|
8
|
+
['/topic/topic1', '/event/MyCustomEvent__e', '/data/ChangeEvents']
|
9
|
+
end
|
9
10
|
let(:subscribe_block) { lambda { 'subscribe' } }
|
10
11
|
let(:faye_double) { double('Faye') }
|
11
12
|
|
12
13
|
it 'subscribes to the topics with faye' do
|
13
14
|
faye_double.
|
14
15
|
should_receive(:subscribe).
|
15
|
-
with(
|
16
|
+
with(channels, &subscribe_block)
|
16
17
|
client.stub faye: faye_double
|
17
18
|
|
18
|
-
client.
|
19
|
+
client.subscription(channels, &subscribe_block)
|
19
20
|
end
|
20
21
|
|
21
22
|
context "replay_handlers" do
|
@@ -25,24 +26,51 @@ describe Restforce::Concerns::Streaming, event_machine: true do
|
|
25
26
|
}
|
26
27
|
|
27
28
|
it 'registers nil handlers when no replay option is given' do
|
28
|
-
client.
|
29
|
-
client.replay_handlers.should eq(
|
29
|
+
client.subscription(channels, &subscribe_block)
|
30
|
+
client.replay_handlers.should eq(
|
31
|
+
'/topic/topic1' => nil,
|
32
|
+
'/event/MyCustomEvent__e' => nil,
|
33
|
+
'/data/ChangeEvents' => nil
|
34
|
+
)
|
30
35
|
end
|
31
36
|
|
32
37
|
it 'registers a replay_handler for each channel given' do
|
33
|
-
client.
|
34
|
-
client.replay_handlers.should eq(
|
38
|
+
client.subscription(channels, replay: -2, &subscribe_block)
|
39
|
+
client.replay_handlers.should eq(
|
40
|
+
'/topic/topic1' => -2,
|
41
|
+
'/event/MyCustomEvent__e' => -2,
|
42
|
+
'/data/ChangeEvents' => -2
|
43
|
+
)
|
35
44
|
end
|
36
45
|
|
37
46
|
it 'replaces earlier handlers in subsequent calls' do
|
38
|
-
client.
|
39
|
-
|
47
|
+
client.subscription(
|
48
|
+
['/topic/channel1', '/topic/channel2'],
|
49
|
+
replay: 2,
|
50
|
+
&subscribe_block
|
51
|
+
)
|
52
|
+
client.subscription(
|
53
|
+
['/topic/channel2', '/topic/channel3'],
|
54
|
+
replay: 3,
|
55
|
+
&subscribe_block
|
56
|
+
)
|
57
|
+
|
40
58
|
client.replay_handlers.should eq(
|
41
|
-
'channel1' => 2,
|
42
|
-
'channel2' => 3,
|
43
|
-
'channel3' => 3
|
59
|
+
'/topic/channel1' => 2,
|
60
|
+
'/topic/channel2' => 3,
|
61
|
+
'/topic/channel3' => 3
|
44
62
|
)
|
45
63
|
end
|
64
|
+
|
65
|
+
context 'backwards compatibility' do
|
66
|
+
it 'it assumes channels are push topics' do
|
67
|
+
client.subscribe(%w[channel1 channel2], replay: -2, &subscribe_block)
|
68
|
+
client.replay_handlers.should eq(
|
69
|
+
'/topic/channel1' => -2,
|
70
|
+
'/topic/channel2' => -2
|
71
|
+
)
|
72
|
+
end
|
73
|
+
end
|
46
74
|
end
|
47
75
|
end
|
48
76
|
|
@@ -87,41 +115,41 @@ describe Restforce::Concerns::Streaming, event_machine: true do
|
|
87
115
|
let(:extension) { Restforce::Concerns::Streaming::ReplayExtension.new(handlers) }
|
88
116
|
|
89
117
|
it 'sends nil without a specified handler' do
|
90
|
-
output = subscribe(extension, to: "channel1")
|
118
|
+
output = subscribe(extension, to: "/topic/channel1")
|
91
119
|
read_replay(output).should eq('/topic/channel1' => nil)
|
92
120
|
end
|
93
121
|
|
94
122
|
it 'with a scalar replay id' do
|
95
|
-
handlers['channel1'] = -2
|
96
|
-
output = subscribe(extension, to: "channel1")
|
123
|
+
handlers['/topic/channel1'] = -2
|
124
|
+
output = subscribe(extension, to: "/topic/channel1")
|
97
125
|
read_replay(output).should eq('/topic/channel1' => -2)
|
98
126
|
end
|
99
127
|
|
100
128
|
it 'with a hash' do
|
101
|
-
hash_handler = { 'channel1' => -1, 'channel2' => -2 }
|
129
|
+
hash_handler = { '/topic/channel1' => -1, '/topic/channel2' => -2 }
|
102
130
|
|
103
|
-
handlers['channel1'] = hash_handler
|
104
|
-
handlers['channel2'] = hash_handler
|
131
|
+
handlers['/topic/channel1'] = hash_handler
|
132
|
+
handlers['/topic/channel2'] = hash_handler
|
105
133
|
|
106
|
-
output = subscribe(extension, to: "channel1")
|
134
|
+
output = subscribe(extension, to: "/topic/channel1")
|
107
135
|
read_replay(output).should eq('/topic/channel1' => -1)
|
108
136
|
|
109
|
-
output = subscribe(extension, to: "channel2")
|
137
|
+
output = subscribe(extension, to: "/topic/channel2")
|
110
138
|
read_replay(output).should eq('/topic/channel2' => -2)
|
111
139
|
end
|
112
140
|
|
113
141
|
it 'with an object' do
|
114
142
|
custom_handler = double('custom_handler')
|
115
143
|
custom_handler.should_receive(:[]).and_return(123)
|
116
|
-
handlers['channel1'] = custom_handler
|
144
|
+
handlers['/topic/channel1'] = custom_handler
|
117
145
|
|
118
|
-
output = subscribe(extension, to: "channel1")
|
146
|
+
output = subscribe(extension, to: "/topic/channel1")
|
119
147
|
read_replay(output).should eq('/topic/channel1' => 123)
|
120
148
|
end
|
121
149
|
|
122
150
|
it 'remembers the last replayId' do
|
123
|
-
handler = { 'channel1' => 41 }
|
124
|
-
handlers['channel1'] = handler
|
151
|
+
handler = { '/topic/channel1' => 41 }
|
152
|
+
handlers['/topic/channel1'] = handler
|
125
153
|
message = {
|
126
154
|
'channel' => '/topic/channel1',
|
127
155
|
'data' => {
|
@@ -130,12 +158,12 @@ describe Restforce::Concerns::Streaming, event_machine: true do
|
|
130
158
|
}
|
131
159
|
|
132
160
|
extension.incoming(message, ->(m) {})
|
133
|
-
handler.should eq('channel1' => 42)
|
161
|
+
handler.should eq('/topic/channel1' => 42)
|
134
162
|
end
|
135
163
|
|
136
164
|
it 'when an incoming message has no replayId' do
|
137
|
-
handler = { 'channel1' => 41 }
|
138
|
-
handlers['channel1'] = handler
|
165
|
+
handler = { '/topic/channel1' => 41 }
|
166
|
+
handlers['/topic/channel1'] = handler
|
139
167
|
|
140
168
|
message = {
|
141
169
|
'channel' => '/topic/channel1',
|
@@ -143,7 +171,7 @@ describe Restforce::Concerns::Streaming, event_machine: true do
|
|
143
171
|
}
|
144
172
|
|
145
173
|
extension.incoming(message, ->(m) {})
|
146
|
-
handler.should eq('channel1' => 41)
|
174
|
+
handler.should eq('/topic/channel1' => 41)
|
147
175
|
end
|
148
176
|
|
149
177
|
private
|
@@ -152,7 +180,7 @@ describe Restforce::Concerns::Streaming, event_machine: true do
|
|
152
180
|
output = nil
|
153
181
|
message = {
|
154
182
|
'channel' => '/meta/subscribe',
|
155
|
-
'subscription' =>
|
183
|
+
'subscription' => options[:to]
|
156
184
|
}
|
157
185
|
extension.outgoing(message, ->(m) {
|
158
186
|
output = m
|
data/spec/unit/mash_spec.rb
CHANGED
@@ -33,6 +33,11 @@ describe Restforce::Mash do
|
|
33
33
|
let(:input) { { 'attributes' => { 'type' => 'Document' } } }
|
34
34
|
it { should eq Restforce::Document }
|
35
35
|
end
|
36
|
+
|
37
|
+
context 'when the attributes value is nil' do
|
38
|
+
let(:input) { { 'attributes' => nil } }
|
39
|
+
it { should eq Restforce::SObject }
|
40
|
+
end
|
36
41
|
end
|
37
42
|
|
38
43
|
context 'else' do
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
describe Restforce::Middleware::Authentication::JWTBearer do
|
5
|
+
let(:jwt_key) { File.read('spec/fixtures/test_private.key') }
|
6
|
+
|
7
|
+
let(:options) do
|
8
|
+
{ host: 'login.salesforce.com',
|
9
|
+
client_id: 'client_id',
|
10
|
+
username: 'foo',
|
11
|
+
jwt_key: jwt_key,
|
12
|
+
instance_url: 'https://na1.salesforce.com',
|
13
|
+
adapter: :net_http }
|
14
|
+
end
|
15
|
+
|
16
|
+
it_behaves_like 'authentication middleware' do
|
17
|
+
let(:success_request) do
|
18
|
+
stub_login_request(
|
19
|
+
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
20
|
+
"assertion=abc1234567890"
|
21
|
+
).to_return(status: 200, body: fixture(:auth_success_response))
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:fail_request) do
|
25
|
+
stub_login_request(
|
26
|
+
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
27
|
+
"assertion=abc1234567890"
|
28
|
+
).to_return(status: 400, body: fixture(:refresh_error_response))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'allows jwt_key as string' do
|
33
|
+
let(:jwt_key) do
|
34
|
+
File.read('spec/fixtures/test_private.key')
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:options) do
|
38
|
+
{ host: 'login.salesforce.com',
|
39
|
+
client_id: 'client_id',
|
40
|
+
username: 'foo',
|
41
|
+
jwt_key: jwt_key,
|
42
|
+
instance_url: 'https://na1.salesforce.com',
|
43
|
+
adapter: :net_http }
|
44
|
+
end
|
45
|
+
|
46
|
+
it_behaves_like 'authentication middleware' do
|
47
|
+
let(:success_request) do
|
48
|
+
stub_login_request(
|
49
|
+
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
50
|
+
"assertion=abc1234567890"
|
51
|
+
).to_return(status: 200, body: fixture(:auth_success_response))
|
52
|
+
end
|
53
|
+
|
54
|
+
let(:fail_request) do
|
55
|
+
stub_login_request(
|
56
|
+
body: "grant_type=grant_type—urn:ietf:params:oauth:grant-type:jwt-bearer&" \
|
57
|
+
"assertion=abc1234567890"
|
58
|
+
).to_return(status: 400, body: fixture(:refresh_error_response))
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -89,4 +89,25 @@ describe Restforce::Middleware::Authentication do
|
|
89
89
|
connection.ssl[:version].should eq(:TLSv1_2)
|
90
90
|
end
|
91
91
|
end
|
92
|
+
|
93
|
+
describe '.error_message' do
|
94
|
+
context 'when response.body is present' do
|
95
|
+
let(:response) {
|
96
|
+
Faraday::Response.new(
|
97
|
+
body: { 'error' => 'error', 'error_description' => 'description' },
|
98
|
+
status: 401
|
99
|
+
)
|
100
|
+
}
|
101
|
+
|
102
|
+
subject { middleware.error_message(response) }
|
103
|
+
it { should eq "error: description (401)" }
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'when response.body is nil' do
|
107
|
+
let(:response) { Faraday::Response.new(status: 401) }
|
108
|
+
|
109
|
+
subject { middleware.error_message(response) }
|
110
|
+
it { should eq "401" }
|
111
|
+
end
|
112
|
+
end
|
92
113
|
end
|
@@ -18,8 +18,8 @@ describe Restforce::Middleware::RaiseError do
|
|
18
18
|
'INVALID_FIELD: error_message'
|
19
19
|
end
|
20
20
|
|
21
|
-
it 'raises an error that inherits from Faraday::
|
22
|
-
expect { on_complete }.to raise_error Faraday::
|
21
|
+
it 'raises an error that inherits from Faraday::ResourceNotFound' do
|
22
|
+
expect { on_complete }.to raise_error Faraday::ResourceNotFound
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -31,8 +31,8 @@ describe Restforce::Middleware::RaiseError do
|
|
31
31
|
/300: The external ID provided/
|
32
32
|
end
|
33
33
|
|
34
|
-
it 'raises an error that inherits from Faraday::
|
35
|
-
expect { on_complete }.to raise_error Faraday::
|
34
|
+
it 'raises an error that inherits from Faraday::ClientError' do
|
35
|
+
expect { on_complete }.to raise_error Faraday::ClientError
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -44,8 +44,8 @@ describe Restforce::Middleware::RaiseError do
|
|
44
44
|
'INVALID_FIELD: error_message'
|
45
45
|
end
|
46
46
|
|
47
|
-
it 'raises an error that inherits from Faraday::
|
48
|
-
expect { on_complete }.to raise_error Faraday::
|
47
|
+
it 'raises an error that inherits from Faraday::ClientError' do
|
48
|
+
expect { on_complete }.to raise_error Faraday::ClientError
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -66,8 +66,8 @@ describe Restforce::Middleware::RaiseError do
|
|
66
66
|
'413: Request Entity Too Large'
|
67
67
|
end
|
68
68
|
|
69
|
-
it 'raises an error that inherits from Faraday::
|
70
|
-
expect { on_complete }.to raise_error Faraday::
|
69
|
+
it 'raises an error that inherits from Faraday::ClientError' do
|
70
|
+
expect { on_complete }.to raise_error Faraday::ClientError
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -80,8 +80,8 @@ describe Restforce::Middleware::RaiseError do
|
|
80
80
|
"(error code missing): #{body}"
|
81
81
|
end
|
82
82
|
|
83
|
-
it 'raises an error that inherits from Faraday::
|
84
|
-
expect { on_complete }.to raise_error Faraday::
|
83
|
+
it 'raises an error that inherits from Faraday::ClientError' do
|
84
|
+
expect { on_complete }.to raise_error Faraday::ClientError,
|
85
85
|
"(error code missing): #{body}"
|
86
86
|
end
|
87
87
|
end
|
data/spec/unit/sobject_spec.rb
CHANGED
@@ -45,13 +45,10 @@ describe Restforce::SObject do
|
|
45
45
|
destroy: :destroy,
|
46
46
|
destroy!: :destroy! }.each do |method, receiver|
|
47
47
|
describe ".#{method}" do
|
48
|
-
subject(:send_method) { sobject.send(method) }
|
48
|
+
subject(:send_method) { lambda { sobject.send(method) } }
|
49
49
|
|
50
50
|
context 'when an Id was not queried' do
|
51
|
-
it
|
52
|
-
expect { send_method }.to raise_error ArgumentError,
|
53
|
-
/need to query the Id for the record/
|
54
|
-
end
|
51
|
+
it { should raise_error ArgumentError, /need to query the Id for the record/ }
|
55
52
|
end
|
56
53
|
|
57
54
|
context 'when an Id is present' do
|
metadata
CHANGED
@@ -1,36 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restforce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric J. Holmes
|
8
8
|
- Tim Rogers
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - ">="
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: 0.9.0
|
21
18
|
- - "<="
|
22
19
|
- !ruby/object:Gem::Version
|
23
20
|
version: '1.0'
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.9.0
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
26
|
version_requirements: !ruby/object:Gem::Requirement
|
27
27
|
requirements:
|
28
|
-
- - ">="
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: 0.9.0
|
31
28
|
- - "<="
|
32
29
|
- !ruby/object:Gem::Version
|
33
30
|
version: '1.0'
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.9.0
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: faraday_middleware
|
36
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -65,6 +65,20 @@ dependencies:
|
|
65
65
|
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
67
|
version: 1.7.5
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: jwt
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 1.5.6
|
75
|
+
type: :runtime
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.5.6
|
68
82
|
- !ruby/object:Gem::Dependency
|
69
83
|
name: hashie
|
70
84
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,7 +88,7 @@ dependencies:
|
|
74
88
|
version: 1.2.0
|
75
89
|
- - "<"
|
76
90
|
- !ruby/object:Gem::Version
|
77
|
-
version: '
|
91
|
+
version: '5.0'
|
78
92
|
type: :runtime
|
79
93
|
prerelease: false
|
80
94
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -84,7 +98,7 @@ dependencies:
|
|
84
98
|
version: 1.2.0
|
85
99
|
- - "<"
|
86
100
|
- !ruby/object:Gem::Version
|
87
|
-
version: '
|
101
|
+
version: '5.0'
|
88
102
|
- !ruby/object:Gem::Dependency
|
89
103
|
name: faye
|
90
104
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,28 +133,28 @@ dependencies:
|
|
119
133
|
requirements:
|
120
134
|
- - "~>"
|
121
135
|
- !ruby/object:Gem::Version
|
122
|
-
version: 0.
|
136
|
+
version: 0.4.1
|
123
137
|
type: :development
|
124
138
|
prerelease: false
|
125
139
|
version_requirements: !ruby/object:Gem::Requirement
|
126
140
|
requirements:
|
127
141
|
- - "~>"
|
128
142
|
- !ruby/object:Gem::Version
|
129
|
-
version: 0.
|
143
|
+
version: 0.4.1
|
130
144
|
- !ruby/object:Gem::Dependency
|
131
145
|
name: rubocop
|
132
146
|
requirement: !ruby/object:Gem::Requirement
|
133
147
|
requirements:
|
134
148
|
- - "~>"
|
135
149
|
- !ruby/object:Gem::Version
|
136
|
-
version: 0.
|
150
|
+
version: 0.77.0
|
137
151
|
type: :development
|
138
152
|
prerelease: false
|
139
153
|
version_requirements: !ruby/object:Gem::Requirement
|
140
154
|
requirements:
|
141
155
|
- - "~>"
|
142
156
|
- !ruby/object:Gem::Version
|
143
|
-
version: 0.
|
157
|
+
version: 0.77.0
|
144
158
|
- !ruby/object:Gem::Dependency
|
145
159
|
name: simplecov
|
146
160
|
requirement: !ruby/object:Gem::Requirement
|
@@ -210,6 +224,7 @@ files:
|
|
210
224
|
- lib/restforce/mash.rb
|
211
225
|
- lib/restforce/middleware.rb
|
212
226
|
- lib/restforce/middleware/authentication.rb
|
227
|
+
- lib/restforce/middleware/authentication/jwt_bearer.rb
|
213
228
|
- lib/restforce/middleware/authentication/password.rb
|
214
229
|
- lib/restforce/middleware/authentication/token.rb
|
215
230
|
- lib/restforce/middleware/authorization.rb
|
@@ -266,6 +281,7 @@ files:
|
|
266
281
|
- spec/fixtures/sobject/upsert_multiple_error_response.json
|
267
282
|
- spec/fixtures/sobject/upsert_updated_success_response.json
|
268
283
|
- spec/fixtures/sobject/write_error_response.json
|
284
|
+
- spec/fixtures/test_private.key
|
269
285
|
- spec/integration/abstract_client_spec.rb
|
270
286
|
- spec/integration/data/client_spec.rb
|
271
287
|
- spec/spec_helper.rb
|
@@ -291,6 +307,7 @@ files:
|
|
291
307
|
- spec/unit/data/client_spec.rb
|
292
308
|
- spec/unit/document_spec.rb
|
293
309
|
- spec/unit/mash_spec.rb
|
310
|
+
- spec/unit/middleware/authentication/jwt_bearer_spec.rb
|
294
311
|
- spec/unit/middleware/authentication/password_spec.rb
|
295
312
|
- spec/unit/middleware/authentication/token_spec.rb
|
296
313
|
- spec/unit/middleware/authentication_spec.rb
|
@@ -310,7 +327,7 @@ licenses:
|
|
310
327
|
metadata:
|
311
328
|
source_code_uri: https://github.com/restforce/restforce
|
312
329
|
changelog_uri: https://github.com/restforce/restforce/blob/master/CHANGELOG.md
|
313
|
-
post_install_message:
|
330
|
+
post_install_message:
|
314
331
|
rdoc_options: []
|
315
332
|
require_paths:
|
316
333
|
- lib
|
@@ -325,8 +342,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
325
342
|
- !ruby/object:Gem::Version
|
326
343
|
version: '0'
|
327
344
|
requirements: []
|
328
|
-
rubygems_version: 3.
|
329
|
-
signing_key:
|
345
|
+
rubygems_version: 3.2.5
|
346
|
+
signing_key:
|
330
347
|
specification_version: 4
|
331
348
|
summary: A lightweight ruby client for the Salesforce REST API.
|
332
349
|
test_files:
|
@@ -364,6 +381,7 @@ test_files:
|
|
364
381
|
- spec/fixtures/sobject/upsert_multiple_error_response.json
|
365
382
|
- spec/fixtures/sobject/upsert_updated_success_response.json
|
366
383
|
- spec/fixtures/sobject/write_error_response.json
|
384
|
+
- spec/fixtures/test_private.key
|
367
385
|
- spec/integration/abstract_client_spec.rb
|
368
386
|
- spec/integration/data/client_spec.rb
|
369
387
|
- spec/spec_helper.rb
|
@@ -389,6 +407,7 @@ test_files:
|
|
389
407
|
- spec/unit/data/client_spec.rb
|
390
408
|
- spec/unit/document_spec.rb
|
391
409
|
- spec/unit/mash_spec.rb
|
410
|
+
- spec/unit/middleware/authentication/jwt_bearer_spec.rb
|
392
411
|
- spec/unit/middleware/authentication/password_spec.rb
|
393
412
|
- spec/unit/middleware/authentication/token_spec.rb
|
394
413
|
- spec/unit/middleware/authentication_spec.rb
|