kinetic_sdk 7.0.0.rc4 → 7.0.0.rc5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ab81a960e1aebbf2e7cd839fdf3fd60c33ca71e985e0c6530c7e84ca8e8ec6f
4
- data.tar.gz: d485a88f2085aa142c0015c2899999d46c403f66b8b460efffb0918730ca51aa
3
+ metadata.gz: 3fb9f7ab44be718c7df520bdb50bf97e0b33d184340d610608393ab9847834a0
4
+ data.tar.gz: d8331e8aeefdf808cc55ff2546df6e8edacde76835300d733b32f1cd72eb528b
5
5
  SHA512:
6
- metadata.gz: dbd1dbf0607dc20f54e2cbea981496d1fbc8088c8b00fa8ce6483317577fe15bff2b8ae3328d7e797506dea4db66a9cc5c6d3b3ca491bdc99a0ff6fd144e9725
7
- data.tar.gz: 86092ddc85c919ace2d1bb3133c8feb9aa320969162e471cc100617b81fef05fa0dc5b644c770dbb1a41ebc8c4b6e8aa53586bcc31463b966caef2fb44aa74fe
6
+ metadata.gz: ef422ca2c44ff3b50d13de5a01aeb2c72bd3f1fd76797979da7e30668183591c8919d7d3d3a958db6dfe77010414bcf182ec72fbc108db9c3e875fde249fae2b
7
+ data.tar.gz: 93edce1847353966e76ef873ab96969dafcadf47ea923f13a492a8def392c6933700d0a44b22d1e790fa956d36ded1abe77bd3c8e4d9d3aa6e4b64f663f95f13
data/CHANGELOG.md CHANGED
@@ -1,6 +1,31 @@
1
1
  # Change Log
2
2
 
3
3
 
4
+ ## [7.0.0.rc5](https://github.com/kineticdata/kinetic-sdk-rb/tree/7.0.0.rc5) (2026-09-01)
5
+
6
+ **Fixed bugs:**
7
+
8
+ - Fixed `401 invalid_client` when retrieving a JWT with a client secret containing `+`, `%`
9
+ or a space, despite correct credentials. The token request now authenticates with
10
+ `client_secret_post`, sending `client_id` and `client_secret` as form parameters.
11
+
12
+ `client_secret_basic` requires both values to be form-urlencoded before base64 encoding
13
+ (RFC 6749 section 2.3.1), and Spring Authorization Server's
14
+ `ClientSecretBasicAuthenticationConverter` correspondingly URL-decodes them. The SDK sent
15
+ them raw, so a `+` in a secret was decoded to a space and the bcrypt comparison failed.
16
+ Kinetic Coordinator generates integration user passwords from a character set containing
17
+ `+`, which is why the failure appeared intermittently across tenants.
18
+
19
+ `header_basic_auth` is deliberately unchanged. It is shared by every ordinary HTTP Basic
20
+ user authentication call site, and Core authenticates those with Spring Security's
21
+ `BasicAuthenticationConverter`, which does not URL-decode. Adding encoding there would
22
+ break any user whose password contains `+` or `%`.
23
+
24
+ - The token request no longer sends an Authorization header, and strips any header inherited
25
+ from the caller, so it cannot compete with the form credentials. This also keeps the client
26
+ secret out of the SDK's debug log, which prints request headers.
27
+
28
+
4
29
  ## [7.0.0.rc4](https://github.com/kineticdata/kinetic-sdk-rb/tree/7.0.0.rc4) (2026-09-01)
5
30
 
6
31
  **Breaking changes:**
@@ -14,24 +14,39 @@ module KineticSdk
14
14
  # `client_credentials` grant. Public clients and the built in system client support
15
15
  # only `authorization_code`, and will be rejected here.
16
16
  #
17
+ # The client authenticates with `client_secret_post`, sending its credentials as form
18
+ # parameters rather than in an Authorization header. `client_secret_basic` requires the
19
+ # credentials to be form-urlencoded before base64 encoding (RFC 6749 section 2.3.1), which
20
+ # the shared `header_basic_auth` helper does not do - and must not start doing, because
21
+ # ordinary HTTP Basic user authentication takes credentials raw. A secret containing "+"
22
+ # would otherwise reach the server with that "+" decoded to a space.
23
+ #
17
24
  # @param client_id [String] the oauth client id
18
25
  # @param client_secret [String] the oauth client secret
19
- # @param headers [Hash] additional headers to send. The Accept, Authorization and
20
- # Content-Type headers required by the token endpoint always take precedence.
26
+ # @param headers [Hash] additional headers to send. The Accept and Content-Type headers
27
+ # required by the token endpoint always take precedence, and any Authorization header
28
+ # is removed so it cannot compete with the form credentials.
21
29
  # @param scope [String] scope to request, defaults to the +:oauth_scope+ option (+full+)
22
30
  # @return [KineticSdk::Utils::KineticHttpResponse] object, with +code+, +message+, +content_string+, and +content+ properties
23
31
  def jwt_token(client_id, client_secret, headers = {}, scope = oauth_scope)
24
32
  @logger.info("Retrieving JWT authorization token")
25
33
  url = "#{@oauth_url}/token"
26
34
 
27
- # The required headers are merged last so that a caller passing the SDK default
28
- # headers cannot replace the client's basic authentication with the user's.
35
+ # The required headers are merged last so a caller cannot override them. Any inherited
36
+ # Authorization header (the SDK user's basic auth, for instance) is dropped: the
37
+ # authorization server would read it as a competing client authentication.
29
38
  token_headers = headers
30
39
  .merge(header_accept_json)
31
- .merge(header_basic_auth(client_id, client_secret))
32
40
  .merge({ "Content-Type" => "application/x-www-form-urlencoded" })
41
+ token_headers.delete_if { |key, _value| key.to_s.casecmp("authorization").zero? }
33
42
 
34
- payload = { "grant_type" => "client_credentials" }
43
+ # URI.encode_www_form applies the same application/x-www-form-urlencoded rules the
44
+ # server decodes with, so "+", "%", ":" and spaces in a secret survive the round trip.
45
+ payload = {
46
+ "grant_type" => "client_credentials",
47
+ "client_id" => client_id,
48
+ "client_secret" => client_secret,
49
+ }
35
50
  payload["scope"] = scope unless scope.nil? || scope.to_s.empty?
36
51
 
37
52
  # Redirects are not followed: the token endpoint has no reason to redirect, and
@@ -3,5 +3,5 @@ module KineticSdk
3
3
  # Version of Kinetic SDK
4
4
  #
5
5
  # @return [String] Version of the SDK
6
- VERSION = "7.0.0.rc4"
6
+ VERSION = "7.0.0.rc5"
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kinetic_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.0.rc4
4
+ version: 7.0.0.rc5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kinetic Data
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-01 00:00:00.000000000 Z
11
+ date: 2026-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: slugify