restforce 6.2.4 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +2 -2
- data/.github/workflows/faraday.yml +29 -1
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +50 -1
- data/Gemfile +6 -6
- data/README.md +37 -13
- data/UPGRADING.md +24 -0
- data/lib/restforce/collection.rb +2 -2
- data/lib/restforce/concerns/authentication.rb +8 -0
- data/lib/restforce/concerns/batch_api.rb +2 -2
- data/lib/restforce/concerns/composite_api.rb +8 -0
- data/lib/restforce/concerns/picklists.rb +1 -1
- data/lib/restforce/concerns/streaming.rb +4 -4
- data/lib/restforce/error_code.rb +4 -1
- data/lib/restforce/mash.rb +2 -2
- data/lib/restforce/middleware/authentication/client_credential.rb +15 -0
- data/lib/restforce/middleware/authentication.rb +1 -0
- data/lib/restforce/middleware/gzip.rb +1 -0
- data/lib/restforce/middleware/json_request.rb +1 -1
- data/lib/restforce/middleware/raise_error.rb +1 -1
- data/lib/restforce/patches/parts.rb +2 -0
- data/lib/restforce/version.rb +1 -1
- data/restforce.gemspec +3 -3
- data/spec/unit/concerns/authentication_spec.rb +33 -0
- data/spec/unit/concerns/composite_api_spec.rb +17 -0
- data/spec/unit/concerns/connection_spec.rb +3 -1
- data/spec/unit/config_spec.rb +27 -0
- data/spec/unit/middleware/authentication/client_credential_spec.rb +36 -0
- data/spec/unit/middleware/gzip_spec.rb +2 -0
- metadata +10 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d15210bc91589b14b39393257c157630f0e97a48f645182f859b111ff217c1ce
|
|
4
|
+
data.tar.gz: 6e53ae6ada7fcb4743e5e9ee5b42728007d878612bf7487a02510755786d6355
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c8eb88e8e6eb093808deaa1aa6def7c59d9e883069d3835a315b492903cab8b6a3f85bd14a3b0a27ee43376075bfa49ed5af97cf11149748f7e7f2947a29b54d
|
|
7
|
+
data.tar.gz: f74e373ce9c0c206541f1555fa822ae0b2ade70a05fdec3eb5d3f7cee2ffeb0da8876a33b20e2e7350af34cb97b6335c0eaa64bf5b207d905113aebd5b9095f7
|
data/.github/workflows/build.yml
CHANGED
|
@@ -6,7 +6,7 @@ jobs:
|
|
|
6
6
|
strategy:
|
|
7
7
|
fail-fast: false
|
|
8
8
|
matrix:
|
|
9
|
-
ruby_version: [
|
|
9
|
+
ruby_version: ["3.1", "3.2", "3.3", "3.4", "4.0"]
|
|
10
10
|
steps:
|
|
11
11
|
- name: Checkout code
|
|
12
12
|
uses: actions/checkout@v4
|
|
@@ -20,4 +20,4 @@ jobs:
|
|
|
20
20
|
- name: Lint Ruby files
|
|
21
21
|
run: bundle exec rubocop
|
|
22
22
|
- name: Run RSpec tests
|
|
23
|
-
run: bundle exec rspec
|
|
23
|
+
run: bundle exec rspec
|
|
@@ -10,7 +10,35 @@ jobs:
|
|
|
10
10
|
# For v2.0.x, we test v2.0.0 and v2.0.1 because v2.0.0 has a special behaviour where
|
|
11
11
|
# the Net::HTTP adapter is not included. See
|
|
12
12
|
# https://github.com/lostisland/faraday/blob/main/UPGRADING.md#faraday-20.
|
|
13
|
-
faraday_version:
|
|
13
|
+
faraday_version:
|
|
14
|
+
[
|
|
15
|
+
"1.1.0",
|
|
16
|
+
"1.2.0",
|
|
17
|
+
"1.3.1",
|
|
18
|
+
"1.4.3",
|
|
19
|
+
"1.5.1",
|
|
20
|
+
"1.6.0",
|
|
21
|
+
"1.7.2",
|
|
22
|
+
"1.8.0",
|
|
23
|
+
"1.9.3",
|
|
24
|
+
"1.10.3",
|
|
25
|
+
"2.0.0",
|
|
26
|
+
"2.0.1",
|
|
27
|
+
"2.1.0",
|
|
28
|
+
"2.2.0",
|
|
29
|
+
"2.3.0",
|
|
30
|
+
"2.4.0",
|
|
31
|
+
"2.5.2",
|
|
32
|
+
"2.6.0",
|
|
33
|
+
"2.7.12",
|
|
34
|
+
"2.8.1",
|
|
35
|
+
"2.9.2",
|
|
36
|
+
"2.10.1",
|
|
37
|
+
"2.11.0",
|
|
38
|
+
"2.12.3",
|
|
39
|
+
"2.13.4",
|
|
40
|
+
"2.14.0"
|
|
41
|
+
]
|
|
14
42
|
env:
|
|
15
43
|
FARADAY_VERSION: ~> ${{ matrix.faraday_version }}
|
|
16
44
|
steps:
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,53 @@
|
|
|
1
|
-
|
|
1
|
+
## 8.0.1 (December 29, 2025)
|
|
2
|
+
|
|
3
|
+
* Allow `faraday-follow_redirects` v0.4.x and v0.5.x to unlock Ruby 4.0 compatibility
|
|
4
|
+
|
|
5
|
+
## 8.0.0 (December 18, 2024)
|
|
6
|
+
|
|
7
|
+
**This version contains breaking changes. For help with upgrading, see [`UPGRADING.md`](https://github.com/restforce/restforce/blob/main/UPGRADING.md).**
|
|
8
|
+
|
|
9
|
+
- **⚠️ Drop support for Ruby 3.0**, since Ruby 3.0 has reached its end-of-life (@timrogers)
|
|
10
|
+
|
|
11
|
+
## 7.6.0 (December 18, 2024)
|
|
12
|
+
|
|
13
|
+
- **Allow all `faraday` versions up to, but not including, v3.0.0**: For more details, see https://github.com/restforce/restforce/pull/915 (@timrogers)
|
|
14
|
+
|
|
15
|
+
## 7.5.0 (September 4, 2024)
|
|
16
|
+
|
|
17
|
+
- Add support for `faraday` v2.11.x (@timrogers)
|
|
18
|
+
|
|
19
|
+
## 7.4.0 (July 10, 2024)
|
|
20
|
+
|
|
21
|
+
- Add support for `faraday` v2.10.x (@ryan-mcneil)
|
|
22
|
+
|
|
23
|
+
# 7.3.1 (Mar 30, 2024)
|
|
24
|
+
|
|
25
|
+
- Fix `uninitialized constant StringIO` error by explicitly requiring `StringIO` where it's used (@timrogers)
|
|
26
|
+
|
|
27
|
+
# 7.3.0 (Feb 14, 2024 🧡)
|
|
28
|
+
|
|
29
|
+
- Add support for making `GET` requests using the Composite API (@shravan097)
|
|
30
|
+
|
|
31
|
+
# 7.2.0 (Jan 23, 2024)
|
|
32
|
+
|
|
33
|
+
- Add support for `faraday` v2.9.x (@timrogers)
|
|
34
|
+
|
|
35
|
+
# 7.1.1 (Jan 23, 2024)
|
|
36
|
+
|
|
37
|
+
- Handle the `APEX_REST_SERVICES_DISABLED` error returned by the Salesforce API (@timrogers)
|
|
38
|
+
|
|
39
|
+
# 7.1.0 (Dec 20, 2023)
|
|
40
|
+
|
|
41
|
+
- Add support for the [OAuth 2.0 Client Credentials authentication flow](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_client_credentials_flow.htm&type=5) (@rh-taro)
|
|
42
|
+
- Add support for `faraday` v2.8.x (@timrogers)
|
|
43
|
+
|
|
44
|
+
# 7.0.0 (Oct 6, 2023)
|
|
45
|
+
|
|
46
|
+
__This version contains breaking changes. For help with upgrading, see [`UPGRADING.md`](https://github.com/restforce/restforce/blob/main/UPGRADING.md).__
|
|
47
|
+
|
|
48
|
+
* __⚠️ Drop support for Ruby 2.7__, since [Ruby 2.7 has reached its end-of-life](https://www.ruby-lang.org/en/downloads/) (@timrogers)
|
|
49
|
+
|
|
50
|
+
# 6.2.4 (Oct 6, 2023)
|
|
2
51
|
|
|
3
52
|
* Register the custom JSON middleware for Faraday with a more unique name to avoid clashes with other middleware (@dbackeus)
|
|
4
53
|
|
data/Gemfile
CHANGED
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
source 'https://rubygems.org'
|
|
4
4
|
gemspec
|
|
5
5
|
|
|
6
|
-
faraday_version = ENV.fetch('FARADAY_VERSION', '~> 2.
|
|
6
|
+
faraday_version = ENV.fetch('FARADAY_VERSION', '~> 2.12.2')
|
|
7
7
|
|
|
8
8
|
# Enable us to explicitly pick a Faraday version when running tests
|
|
9
9
|
gem 'faraday', faraday_version
|
|
10
|
-
gem 'faraday-typhoeus', '~> 1.
|
|
10
|
+
gem 'faraday-typhoeus', '~> 1.1.0' unless faraday_version.start_with?("~> 1")
|
|
11
11
|
gem 'faye' unless RUBY_PLATFORM == 'java'
|
|
12
12
|
gem 'guard-rspec'
|
|
13
13
|
gem 'guard-rubocop'
|
|
14
14
|
gem 'jruby-openssl', platforms: :jruby
|
|
15
15
|
gem 'rake'
|
|
16
|
-
gem 'rspec', '~> 3.
|
|
16
|
+
gem 'rspec', '~> 3.13.0'
|
|
17
17
|
gem 'rspec-collection_matchers', '~> 1.2.0'
|
|
18
|
-
gem 'rspec-its', '~>
|
|
18
|
+
gem 'rspec-its', '~> 2.0.0'
|
|
19
19
|
gem 'rspec_junit_formatter', '~> 0.6.0'
|
|
20
|
-
gem 'rubocop', '~> 1.
|
|
20
|
+
gem 'rubocop', '~> 1.70.0'
|
|
21
21
|
gem 'simplecov', '~> 0.22.0'
|
|
22
|
-
gem 'webmock', '~> 3.
|
|
22
|
+
gem 'webmock', '~> 3.24.0'
|
data/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://circleci.com/gh/restforce/restforce)
|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
Restforce is a ruby gem for the [Salesforce REST
|
|
6
|
+
Restforce is a ruby gem for the [Salesforce REST API](http://www.salesforce.com/us/developer/docs/api_rest/index.htm).
|
|
7
7
|
|
|
8
8
|
Features include:
|
|
9
9
|
|
|
@@ -27,7 +27,7 @@ Features include:
|
|
|
27
27
|
|
|
28
28
|
Add this line to your application's Gemfile:
|
|
29
29
|
|
|
30
|
-
gem 'restforce', '~>
|
|
30
|
+
gem 'restforce', '~> 8.0.1'
|
|
31
31
|
|
|
32
32
|
And then execute:
|
|
33
33
|
|
|
@@ -37,14 +37,16 @@ Or install it yourself as:
|
|
|
37
37
|
|
|
38
38
|
$ gem install restforce
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
**As of version 8.0.0, this gem is only compatible with Ruby 3.1.0 and later.** If you're using an earlier Ruby version:
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
- for Ruby 3.0, use version 7.6.0 or earlier
|
|
43
|
+
- for Ruby 2.7, use version 6.2.4 or earlier
|
|
44
|
+
- for Ruby 2.6, use version 5.3.1 or earlier
|
|
45
|
+
- for Ruby 2.5, use version 5.0.6 or earlier
|
|
46
|
+
- for Ruby 2.4, use version 4.3.0 or earlier
|
|
47
|
+
- for Ruby 2.3, use version 3.2.0 or earlier
|
|
48
|
+
- for Ruby versions 2.2, 2.1 and 2.0, use version 2.5.3 or earlier
|
|
49
|
+
- for Ruby 1.9.3, use version 2.4.2
|
|
48
50
|
|
|
49
51
|
This gem is versioned using [Semantic Versioning](http://semver.org/), so you can be confident when updating that there will not be breaking changes outside of a major version (following format MAJOR.MINOR.PATCH, so for instance moving from 3.1.0 to 4.0.0 would be allowed to include incompatible API changes). See the [changelog](https://github.com/restforce/restforce/tree/master/CHANGELOG.md) for details on what has changed in each version.
|
|
50
52
|
|
|
@@ -58,7 +60,7 @@ so you can do things like `client.query('select Id, (select Name from Children__
|
|
|
58
60
|
|
|
59
61
|
Which authentication method you use really depends on your use case. If you're
|
|
60
62
|
building an application where many users from different organizations are authenticated
|
|
61
|
-
through
|
|
63
|
+
through OAuth and you need to interact with data in their org on their behalf,
|
|
62
64
|
you should use the OAuth token authentication method.
|
|
63
65
|
|
|
64
66
|
If you're using the gem to interact with a single org (maybe you're building some
|
|
@@ -115,7 +117,7 @@ If you prefer to use a username and password to authenticate:
|
|
|
115
117
|
client = Restforce.new(username: config['username'],
|
|
116
118
|
password: config['password'],
|
|
117
119
|
instance_url: config['instance_url'],
|
|
118
|
-
host: config['host'], #
|
|
120
|
+
host: config['host'], # test.salesforce.com for sandbox (optional)
|
|
119
121
|
client_id: config['client_key'], # Salesforce Client Key
|
|
120
122
|
client_secret: config['client_secret'], # Salesforce Client Secret
|
|
121
123
|
api_version: '55.0')
|
|
@@ -154,6 +156,17 @@ client = Restforce.new
|
|
|
154
156
|
|
|
155
157
|
**Note:** Restforce library does not cache JWT Bearer tokens automatically. This means that every instantiation of the Restforce class will be treated as a new login by Salesforce. Remember that Salesforce enforces [rate limits on login requests](https://help.salesforce.com/s/articleView?id=000312767&type=1). If you are building an application that will instantiate the Restforce class more than this specified rate limit, you might want to consider caching the Bearer token either in-memory or in your own storage by leveraging the `authentication_callback` method.
|
|
156
158
|
|
|
159
|
+
#### Client Credentials
|
|
160
|
+
|
|
161
|
+
If you want to authenticate as an application, you can use the [Client Credentials flow](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_client_credentials_flow.htm&type=5):
|
|
162
|
+
|
|
163
|
+
```ruby
|
|
164
|
+
client = Restforce.new(client_id: 'client_id',
|
|
165
|
+
client_secret: 'client_secret',
|
|
166
|
+
api_version: '55.0',
|
|
167
|
+
host: 'MYDOMAIN.my.salesforce.com')
|
|
168
|
+
```
|
|
169
|
+
|
|
157
170
|
#### Sandbox Organizations
|
|
158
171
|
|
|
159
172
|
You can connect to sandbox organizations by specifying a host. The default host is
|
|
@@ -317,7 +330,7 @@ client.search('FIND {bar}')
|
|
|
317
330
|
# => #<Restforce::Collection >
|
|
318
331
|
|
|
319
332
|
# Find accounts matching the term 'genepoint' and return the `Name` field
|
|
320
|
-
client.search('FIND {genepoint} RETURNING Account (Name)').map(&:Name)
|
|
333
|
+
client.search('FIND {genepoint} RETURNING Account (Name)')["searchRecords"].map(&:Name)
|
|
321
334
|
# => ['GenePoint']
|
|
322
335
|
```
|
|
323
336
|
|
|
@@ -588,7 +601,6 @@ This feature permits the user to send a composite object—that is, a complex
|
|
|
588
601
|
object with nested children—in a single API call. Up to 25 requests may be
|
|
589
602
|
included in a single composite.
|
|
590
603
|
|
|
591
|
-
Note that `GET` is not yet implemented for this API.
|
|
592
604
|
|
|
593
605
|
```ruby
|
|
594
606
|
# build up an array of requests:
|
|
@@ -831,6 +843,18 @@ client.create!("CustomField", {
|
|
|
831
843
|
})
|
|
832
844
|
```
|
|
833
845
|
|
|
846
|
+
## Configuration Precedence
|
|
847
|
+
|
|
848
|
+
Here's the order of precedence from highest to lowest:
|
|
849
|
+
|
|
850
|
+
Arguments on new: passing configuration options directly as arguments has the highest precedence. These settings will override any other configuration.
|
|
851
|
+
|
|
852
|
+
Configuration block: using Restforce.configure to set configuration options is the next in line. They will take precedence over environment variables and defaults but will be overridden by direct arguments on instantiation.
|
|
853
|
+
|
|
854
|
+
Environment variables: has the lowest precedence. If you set options using environment variables, they will be overridden by any other configuration method.
|
|
855
|
+
|
|
856
|
+
Defaults: If none of the above methods are used, Restforce falls back to its default configuration values.
|
|
857
|
+
|
|
834
858
|
## Contributing
|
|
835
859
|
|
|
836
860
|
We welcome all contributions - they help us make Restforce the best gem possible.
|
data/UPGRADING.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
# Upgrading from Restforce 7.x to 8.x
|
|
2
|
+
|
|
3
|
+
## Ruby 3.0 is no longer supported
|
|
4
|
+
|
|
5
|
+
**Likelyhood of impact**: Moderate
|
|
6
|
+
|
|
7
|
+
Ruby 3.0 is no longer officially supported as an active version of the Ruby language. That means that it will not receive patches and security fixes.
|
|
8
|
+
|
|
9
|
+
Accordingly, we've dropped support for Ruby 3.0 in the Restforce library. The gemspec now specifies that only 3.1 onwards is supported, and this will be enforced by RubyGems.
|
|
10
|
+
|
|
11
|
+
Before you update to Restforce 8.x, you'll need to switch to Ruby 3.1.0 or later. The current version of Ruby at the time of writing is 3.3.6.
|
|
12
|
+
|
|
13
|
+
# Upgrading from Restforce 6.x to 7.x
|
|
14
|
+
|
|
15
|
+
## Ruby 2.7 is no longer supported
|
|
16
|
+
|
|
17
|
+
__Likelyhood of impact__: Moderate
|
|
18
|
+
|
|
19
|
+
Ruby 2.7 is no longer officially supported as an active version of the Ruby language. That means that it will not receive patches and security fixes.
|
|
20
|
+
|
|
21
|
+
Accordingly, we've dropped support for Ruby 2.7 in the Restforce library. The gemspec now specifies that only 3.0 onwards is supported, and this will be enforced by RubyGems.
|
|
22
|
+
|
|
23
|
+
Before you update to Restforce 7.x, you'll need to switch to Ruby 3.0.0 or later. The current version of Ruby at the time of writing is 3.2.2.
|
|
24
|
+
|
|
1
25
|
# Upgrading from Restforce 5.x to 6.x
|
|
2
26
|
|
|
3
27
|
__There are two breaking changes introduced in Restforce 6.x__. In this guide, you'll learn about these changes and what you should check in your code to make sure that it will work with the latest version of the library.
|
data/lib/restforce/collection.rb
CHANGED
|
@@ -12,12 +12,12 @@ module Restforce
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Yield each value on each page.
|
|
15
|
-
def each(&
|
|
15
|
+
def each(&)
|
|
16
16
|
@raw_page['records'].each { |record| yield Restforce::Mash.build(record, @client) }
|
|
17
17
|
|
|
18
18
|
np = next_page
|
|
19
19
|
while np
|
|
20
|
-
np.current_page.each(&
|
|
20
|
+
np.current_page.each(&)
|
|
21
21
|
np = np.next_page
|
|
22
22
|
end
|
|
23
23
|
end
|
|
@@ -21,6 +21,8 @@ module Restforce
|
|
|
21
21
|
Restforce::Middleware::Authentication::Token
|
|
22
22
|
elsif jwt?
|
|
23
23
|
Restforce::Middleware::Authentication::JWTBearer
|
|
24
|
+
elsif client_credential?
|
|
25
|
+
Restforce::Middleware::Authentication::ClientCredential
|
|
24
26
|
end
|
|
25
27
|
end
|
|
26
28
|
|
|
@@ -48,6 +50,12 @@ module Restforce
|
|
|
48
50
|
options[:username] &&
|
|
49
51
|
options[:client_id]
|
|
50
52
|
end
|
|
53
|
+
|
|
54
|
+
# Internal: Returns true if client credential flow should be used for
|
|
55
|
+
# authentication.
|
|
56
|
+
def client_credential?
|
|
57
|
+
options[:client_id] && options[:client_secret]
|
|
58
|
+
end
|
|
51
59
|
end
|
|
52
60
|
end
|
|
53
61
|
end
|
|
@@ -93,6 +93,14 @@ module Restforce
|
|
|
93
93
|
}
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
+
def find(sobject, reference_id, id)
|
|
97
|
+
requests << {
|
|
98
|
+
method: 'GET',
|
|
99
|
+
url: composite_api_path("#{sobject}/#{id}"),
|
|
100
|
+
referenceId: reference_id
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
|
|
96
104
|
private
|
|
97
105
|
|
|
98
106
|
def composite_api_path(path)
|
|
@@ -85,7 +85,7 @@ module Restforce
|
|
|
85
85
|
def valid?(picklist_entry)
|
|
86
86
|
valid_for = picklist_entry['validFor'].ljust(16, 'A').unpack1('m').
|
|
87
87
|
unpack('C*')
|
|
88
|
-
|
|
88
|
+
valid_for[index >> 3].anybits?((0x80 >> (index % 8)))
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
end
|
|
@@ -9,9 +9,9 @@ module Restforce
|
|
|
9
9
|
# block - A block to run when a new message is received.
|
|
10
10
|
#
|
|
11
11
|
# Returns a Faye::Subscription
|
|
12
|
-
def legacy_subscribe(topics, options = {}, &
|
|
12
|
+
def legacy_subscribe(topics, options = {}, &)
|
|
13
13
|
topics = Array(topics).map { |channel| "/topic/#{channel}" }
|
|
14
|
-
subscription(topics, options, &
|
|
14
|
+
subscription(topics, options, &)
|
|
15
15
|
end
|
|
16
16
|
alias subscribe legacy_subscribe
|
|
17
17
|
|
|
@@ -21,12 +21,12 @@ module Restforce
|
|
|
21
21
|
# block - A block to run when a new message is received.
|
|
22
22
|
#
|
|
23
23
|
# Returns a Faye::Subscription
|
|
24
|
-
def subscription(channels, options = {}, &
|
|
24
|
+
def subscription(channels, options = {}, &)
|
|
25
25
|
one_or_more_channels = Array(channels)
|
|
26
26
|
one_or_more_channels.each do |channel|
|
|
27
27
|
replay_handlers[channel] = options[:replay]
|
|
28
28
|
end
|
|
29
|
-
faye.subscribe(one_or_more_channels, &
|
|
29
|
+
faye.subscribe(one_or_more_channels, &)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# Public: Faye client to use for subscribing to PushTopics
|
data/lib/restforce/error_code.rb
CHANGED
|
@@ -19,6 +19,8 @@ module Restforce
|
|
|
19
19
|
|
|
20
20
|
class ApexError < ResponseError; end
|
|
21
21
|
|
|
22
|
+
class ApexRestServicesDisabled < ResponseError; end
|
|
23
|
+
|
|
22
24
|
class ApiCurrentlyDisabled < ResponseError; end
|
|
23
25
|
|
|
24
26
|
class ApiDisabledForOrg < ResponseError; end
|
|
@@ -429,6 +431,7 @@ module Restforce
|
|
|
429
431
|
"ALL_OR_NONE_OPERATION_ROLLED_BACK" => AllOrNoneOperationRolledBack,
|
|
430
432
|
"ALREADY_IN_PROCESS" => AlreadyInProcess,
|
|
431
433
|
"APEX_ERROR" => ApexError,
|
|
434
|
+
"APEX_REST_SERVICES_DISABLED" => ApexRestServicesDisabled,
|
|
432
435
|
"API_CURRENTLY_DISABLED" => ApiCurrentlyDisabled,
|
|
433
436
|
"API_DISABLED_FOR_ORG" => ApiDisabledForOrg,
|
|
434
437
|
"ASSIGNEE_TYPE_REQUIRED" => AssigneeTypeRequired,
|
|
@@ -663,7 +666,7 @@ module Restforce
|
|
|
663
666
|
"defined. If you're sure that this is a valid Salesforce error, then " \
|
|
664
667
|
"please create an issue on GitHub at <#{GITHUB_ISSUE_URL}>."
|
|
665
668
|
|
|
666
|
-
super
|
|
669
|
+
super
|
|
667
670
|
end
|
|
668
671
|
end
|
|
669
672
|
end
|
data/lib/restforce/mash.rb
CHANGED
|
@@ -46,10 +46,10 @@ module Restforce
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
def initialize(source_hash = nil, client = nil, default = nil, &
|
|
49
|
+
def initialize(source_hash = nil, client = nil, default = nil, &)
|
|
50
50
|
@client = client
|
|
51
51
|
deep_update(source_hash) if source_hash
|
|
52
|
-
default ? super(default) : super(&
|
|
52
|
+
default ? super(default) : super(&)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def dup
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Restforce
|
|
4
|
+
class Middleware
|
|
5
|
+
class Authentication
|
|
6
|
+
class ClientCredential < Restforce::Middleware::Authentication
|
|
7
|
+
def params
|
|
8
|
+
{ grant_type: 'client_credentials',
|
|
9
|
+
client_id: @options[:client_id],
|
|
10
|
+
client_secret: @options[:client_secret] }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -9,6 +9,7 @@ module Restforce
|
|
|
9
9
|
autoload :Password, 'restforce/middleware/authentication/password'
|
|
10
10
|
autoload :Token, 'restforce/middleware/authentication/token'
|
|
11
11
|
autoload :JWTBearer, 'restforce/middleware/authentication/jwt_bearer'
|
|
12
|
+
autoload :ClientCredential, 'restforce/middleware/authentication/client_credential'
|
|
12
13
|
|
|
13
14
|
# Rescue from 401's, authenticate then raise the error again so the client
|
|
14
15
|
# can reissue the request.
|
|
@@ -31,7 +31,7 @@ module Restforce
|
|
|
31
31
|
CONTENT_TYPE = 'Content-Type'
|
|
32
32
|
|
|
33
33
|
MIME_TYPE = 'application/json'
|
|
34
|
-
MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?json$}
|
|
34
|
+
MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?json$}
|
|
35
35
|
|
|
36
36
|
#
|
|
37
37
|
# Taken from `lib/faraday/middleware.rb` in the `faraday`
|
data/lib/restforce/version.rb
CHANGED
data/restforce.gemspec
CHANGED
|
@@ -22,10 +22,10 @@ Gem::Specification.new do |gem|
|
|
|
22
22
|
'rubygems_mfa_required' => 'true'
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
gem.required_ruby_version = '>=
|
|
25
|
+
gem.required_ruby_version = '>= 3.1'
|
|
26
26
|
|
|
27
|
-
gem.add_dependency 'faraday', '<
|
|
28
|
-
gem.add_dependency 'faraday-follow_redirects', '
|
|
27
|
+
gem.add_dependency 'faraday', '< 3.0.0', '>= 1.1.0'
|
|
28
|
+
gem.add_dependency 'faraday-follow_redirects', '< 0.6.0'
|
|
29
29
|
gem.add_dependency 'faraday-multipart', '>= 1.0.0', '< 2.0.0'
|
|
30
30
|
gem.add_dependency 'faraday-net_http', '< 4.0.0'
|
|
31
31
|
gem.add_dependency 'hashie', '>= 1.2.0', '< 6.0'
|
|
@@ -62,6 +62,17 @@ describe Restforce::Concerns::Authentication do
|
|
|
62
62
|
|
|
63
63
|
it { should eq Restforce::Middleware::Authentication::JWTBearer }
|
|
64
64
|
end
|
|
65
|
+
|
|
66
|
+
context 'when client_id and client_secret options are provided' do
|
|
67
|
+
before do
|
|
68
|
+
client.stub username_password?: false
|
|
69
|
+
client.stub oauth_refresh?: false
|
|
70
|
+
client.stub jwt?: false
|
|
71
|
+
client.stub client_credential?: true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it { should eq Restforce::Middleware::Authentication::ClientCredential }
|
|
75
|
+
end
|
|
65
76
|
end
|
|
66
77
|
|
|
67
78
|
describe '.username_password?' do
|
|
@@ -135,4 +146,26 @@ describe Restforce::Concerns::Authentication do
|
|
|
135
146
|
it { should_not be true }
|
|
136
147
|
end
|
|
137
148
|
end
|
|
149
|
+
|
|
150
|
+
describe '.client_credential?' do
|
|
151
|
+
subject { client.client_credential? }
|
|
152
|
+
let(:options) { {} }
|
|
153
|
+
|
|
154
|
+
before do
|
|
155
|
+
client.stub options: options
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
context 'when oauth client credential options are provided' do
|
|
159
|
+
let(:options) do
|
|
160
|
+
{ client_id: 'client',
|
|
161
|
+
client_secret: 'secret' }
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it { should be_truthy }
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
context 'when oauth client credential options are not provided' do
|
|
168
|
+
it { should_not be true }
|
|
169
|
+
end
|
|
170
|
+
end
|
|
138
171
|
end
|
|
@@ -82,6 +82,23 @@ describe Restforce::Concerns::CompositeAPI do
|
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
+
it '#find' do
|
|
86
|
+
client.
|
|
87
|
+
should_receive(:api_post).
|
|
88
|
+
with(endpoint, { compositeRequest: [
|
|
89
|
+
{
|
|
90
|
+
method: 'GET',
|
|
91
|
+
url: "/services/data/v38.0/sobjects/Object/00312345",
|
|
92
|
+
referenceId: 'find_ref'
|
|
93
|
+
}
|
|
94
|
+
], allOrNone: all_or_none, collateSubrequests: false }.to_json).
|
|
95
|
+
and_return(response)
|
|
96
|
+
|
|
97
|
+
client.send(method) do |subrequests|
|
|
98
|
+
subrequests.find('Object', 'find_ref', '00312345')
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
85
102
|
it 'multiple subrequests' do
|
|
86
103
|
client.
|
|
87
104
|
should_receive(:api_post).
|
data/spec/unit/config_spec.rb
CHANGED
|
@@ -70,6 +70,21 @@ describe Restforce do
|
|
|
70
70
|
expect(Restforce.configuration.send(attr)).to eq 'foobar'
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
|
+
|
|
74
|
+
it 'takes precedence over environment variables' do
|
|
75
|
+
{ 'SALESFORCE_USERNAME' => 'env_foo',
|
|
76
|
+
'SALESFORCE_CLIENT_ID' => 'env_client id' }.
|
|
77
|
+
each { |var, value| ENV.stub(:fetch).with(var, anything).and_return(value) }
|
|
78
|
+
|
|
79
|
+
{ username: 'config_foo', client_id: nil }.each do |attr, value|
|
|
80
|
+
Restforce.configure do |config|
|
|
81
|
+
config.send("#{attr}=", value)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
expect(Restforce.configuration.send(:username)).to eq 'config_foo'
|
|
86
|
+
expect(Restforce.configuration.send(:client_id)).to eq 'env_client id'
|
|
87
|
+
end
|
|
73
88
|
end
|
|
74
89
|
|
|
75
90
|
describe '#log?' do
|
|
@@ -138,5 +153,17 @@ describe Restforce do
|
|
|
138
153
|
checker.check!
|
|
139
154
|
end
|
|
140
155
|
end
|
|
156
|
+
|
|
157
|
+
it 'shows the precedence over config' do
|
|
158
|
+
ENV['SALESFORCE_USERNAME'] = 'env_foo'
|
|
159
|
+
Restforce.configure do |config|
|
|
160
|
+
config.username = 'config_foo'
|
|
161
|
+
end
|
|
162
|
+
client = Restforce.new(username: 'foo')
|
|
163
|
+
|
|
164
|
+
expect(client.options[:username]).to eq 'foo'
|
|
165
|
+
|
|
166
|
+
Restforce.instance_variable_set :@configuration, nil
|
|
167
|
+
end
|
|
141
168
|
end
|
|
142
169
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
describe Restforce::Middleware::Authentication::ClientCredential do
|
|
6
|
+
let(:options) do
|
|
7
|
+
{ host: 'login.salesforce.com',
|
|
8
|
+
client_id: 'client_id',
|
|
9
|
+
client_secret: 'client_secret',
|
|
10
|
+
adapter: :net_http }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it_behaves_like 'authentication middleware' do
|
|
14
|
+
let(:success_request) do
|
|
15
|
+
stub_login_request(
|
|
16
|
+
body: "grant_type=client_credentials&" \
|
|
17
|
+
"client_id=client_id&client_secret=client_secret"
|
|
18
|
+
).to_return(
|
|
19
|
+
status: 200,
|
|
20
|
+
body: fixture(:auth_success_response),
|
|
21
|
+
headers: { "Content-Type" => "application/json" }
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
let(:fail_request) do
|
|
26
|
+
stub_login_request(
|
|
27
|
+
body: "grant_type=client_credentials&" \
|
|
28
|
+
"client_id=client_id&client_secret=client_secret"
|
|
29
|
+
).to_return(
|
|
30
|
+
status: 400,
|
|
31
|
+
body: fixture(:refresh_error_response),
|
|
32
|
+
headers: { "Content-Type" => "application/json" }
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: restforce
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 8.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tim Rogers
|
|
8
8
|
- Eric J. Holmes
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: faraday
|
|
@@ -17,7 +16,7 @@ dependencies:
|
|
|
17
16
|
requirements:
|
|
18
17
|
- - "<"
|
|
19
18
|
- !ruby/object:Gem::Version
|
|
20
|
-
version:
|
|
19
|
+
version: 3.0.0
|
|
21
20
|
- - ">="
|
|
22
21
|
- !ruby/object:Gem::Version
|
|
23
22
|
version: 1.1.0
|
|
@@ -27,7 +26,7 @@ dependencies:
|
|
|
27
26
|
requirements:
|
|
28
27
|
- - "<"
|
|
29
28
|
- !ruby/object:Gem::Version
|
|
30
|
-
version:
|
|
29
|
+
version: 3.0.0
|
|
31
30
|
- - ">="
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
32
|
version: 1.1.0
|
|
@@ -35,22 +34,16 @@ dependencies:
|
|
|
35
34
|
name: faraday-follow_redirects
|
|
36
35
|
requirement: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
|
-
- - "<="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: 0.3.0
|
|
41
37
|
- - "<"
|
|
42
38
|
- !ruby/object:Gem::Version
|
|
43
|
-
version:
|
|
39
|
+
version: 0.6.0
|
|
44
40
|
type: :runtime
|
|
45
41
|
prerelease: false
|
|
46
42
|
version_requirements: !ruby/object:Gem::Requirement
|
|
47
43
|
requirements:
|
|
48
|
-
- - "<="
|
|
49
|
-
- !ruby/object:Gem::Version
|
|
50
|
-
version: 0.3.0
|
|
51
44
|
- - "<"
|
|
52
45
|
- !ruby/object:Gem::Version
|
|
53
|
-
version:
|
|
46
|
+
version: 0.6.0
|
|
54
47
|
- !ruby/object:Gem::Dependency
|
|
55
48
|
name: faraday-multipart
|
|
56
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -170,6 +163,7 @@ files:
|
|
|
170
163
|
- lib/restforce/mash.rb
|
|
171
164
|
- lib/restforce/middleware.rb
|
|
172
165
|
- lib/restforce/middleware/authentication.rb
|
|
166
|
+
- lib/restforce/middleware/authentication/client_credential.rb
|
|
173
167
|
- lib/restforce/middleware/authentication/jwt_bearer.rb
|
|
174
168
|
- lib/restforce/middleware/authentication/password.rb
|
|
175
169
|
- lib/restforce/middleware/authentication/token.rb
|
|
@@ -257,6 +251,7 @@ files:
|
|
|
257
251
|
- spec/unit/document_spec.rb
|
|
258
252
|
- spec/unit/error_code_spec.rb
|
|
259
253
|
- spec/unit/mash_spec.rb
|
|
254
|
+
- spec/unit/middleware/authentication/client_credential_spec.rb
|
|
260
255
|
- spec/unit/middleware/authentication/jwt_bearer_spec.rb
|
|
261
256
|
- spec/unit/middleware/authentication/password_spec.rb
|
|
262
257
|
- spec/unit/middleware/authentication/token_spec.rb
|
|
@@ -278,7 +273,6 @@ metadata:
|
|
|
278
273
|
source_code_uri: https://github.com/restforce/restforce
|
|
279
274
|
changelog_uri: https://github.com/restforce/restforce/blob/master/CHANGELOG.md
|
|
280
275
|
rubygems_mfa_required: 'true'
|
|
281
|
-
post_install_message:
|
|
282
276
|
rdoc_options: []
|
|
283
277
|
require_paths:
|
|
284
278
|
- lib
|
|
@@ -286,15 +280,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
286
280
|
requirements:
|
|
287
281
|
- - ">="
|
|
288
282
|
- !ruby/object:Gem::Version
|
|
289
|
-
version: '
|
|
283
|
+
version: '3.1'
|
|
290
284
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
291
285
|
requirements:
|
|
292
286
|
- - ">="
|
|
293
287
|
- !ruby/object:Gem::Version
|
|
294
288
|
version: '0'
|
|
295
289
|
requirements: []
|
|
296
|
-
rubygems_version: 3.
|
|
297
|
-
signing_key:
|
|
290
|
+
rubygems_version: 3.7.2
|
|
298
291
|
specification_version: 4
|
|
299
292
|
summary: A lightweight Ruby client for the Salesforce REST API
|
|
300
293
|
test_files: []
|