stitches 5.1.0.RC3 → 5.1.0.RC4

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: e2b49b7056175fa55cc2b597754f143cca6e841a3aafe723fab3681fb646f4c2
4
- data.tar.gz: 87a15dcf53ad770755faec02eae327a9195c26b834babaef526dedffe4d9568e
3
+ metadata.gz: 5e1a4aefc1d0249b7b5c8caf2eb06aa6e0866afef4f1d4564d63efa239ef80ce
4
+ data.tar.gz: 322ab581e74df9bb933d8a1e23d2dc3973c6e3494ebfac23424f16c25cbf589a
5
5
  SHA512:
6
- metadata.gz: b076a27646bd5919cdcf1a2c066536888b90e9a851ce9828369891c3198cbdef8f3208ee1d643344b7f592057d72fefd1b855ab0de0705cdcb708a1d91aa1ccc
7
- data.tar.gz: e5d3445946a09d9e54f63060edea96fd5fd0b9156622f9f094850d7ae93cca9a7737d5c7d3800e3c722dbe87a69ea3911e332da1fe3d5ee8c680e4f045cca016
6
+ metadata.gz: 5da26d78de12b20c29f2cff453dae8b1b1712ab3f0bbcd373291082eeee1feae3f22dcfb841c512f6a351243f10894b1c91dbc6c5c58400c182be9c0e96ee93c
7
+ data.tar.gz: 1a2ef89f2e74dfd9478158dfa747c19989de5f32425363f77ae428058468e57d934e29decae0fb1b1bc39a60b1b18abb97c8c82bfd3dfde73ac0b449dc13c995
@@ -0,0 +1,15 @@
1
+ module Stitches
2
+ # Lightweight stand-in for ApiClient when the caller is identified by
3
+ # the X-StitchFix-Calling-Service header rather than an API key lookup.
4
+ # Implements the same interface (.name, .id, .key) so existing code
5
+ # that reads api_client.name continues to work.
6
+ CallingServiceClient = Struct.new(:name) do
7
+ def id
8
+ nil
9
+ end
10
+
11
+ def key
12
+ nil
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,29 @@
1
+ require_relative 'calling_service_client'
2
+
3
+ module Stitches
4
+ # Rack middleware that populates the api_client env var from the
5
+ # X-StitchFix-Calling-Service header when no other auth middleware
6
+ # has already set it. This allows existing code that reads
7
+ # api_client.name to work transparently after API keys are disabled.
8
+ class CallingServiceMiddleware
9
+ def initialize(app)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ client_key = Stitches.configuration.env_var_to_hold_api_client
15
+
16
+ unless env[client_key]
17
+ header_name = Stitches.configuration.calling_service_header
18
+ header_name = CallingServiceName::DEFAULT_CALLING_SERVICE_HEADER unless header_name.present?
19
+ rack_key = "HTTP_#{header_name.upcase.tr('-', '_')}"
20
+
21
+ if (name = env[rack_key]).present?
22
+ env[client_key] = CallingServiceClient.new(name)
23
+ end
24
+ end
25
+
26
+ @app.call(env)
27
+ end
28
+ end
29
+ end
@@ -1,10 +1,17 @@
1
1
  module Stitches
2
2
  module CallingServiceName
3
+ DEFAULT_CALLING_SERVICE_HEADER = "X-StitchFix-Calling-Service"
4
+
3
5
  def calling_service_name
4
6
  @calling_service_name ||=
5
- request.headers[Stitches.configuration.calling_service_header].presence ||
6
- request.env[Stitches.configuration.env_var_to_hold_api_client]&.name ||
7
- ""
7
+ request.headers[calling_service_header_name].presence || ""
8
+ end
9
+
10
+ private
11
+
12
+ def calling_service_header_name
13
+ configured = Stitches.configuration.calling_service_header
14
+ configured.present? ? configured : DEFAULT_CALLING_SERVICE_HEADER
8
15
  end
9
16
  end
10
17
  end
@@ -1,10 +1,12 @@
1
1
  require 'stitches/api_key'
2
2
  require 'stitches/valid_mime_type'
3
3
  require 'stitches/api_client_access_wrapper'
4
+ require 'stitches/calling_service_middleware'
4
5
 
5
6
  module Stitches
6
7
  class Railtie < Rails::Railtie
7
8
  config.app_middleware.use Stitches::ApiKey
9
+ config.app_middleware.use Stitches::CallingServiceMiddleware
8
10
  config.app_middleware.use Stitches::ValidMimeType
9
11
  end
10
12
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Stitches
4
- VERSION = '5.1.0.RC3'
4
+ VERSION = '5.1.0.RC4'
5
5
  end
@@ -0,0 +1,72 @@
1
+ require 'rails_helper'
2
+
3
+ describe Stitches::CallingServiceMiddleware do
4
+ let(:app) { ->(env) { [200, env, "OK"] } }
5
+ let(:middleware) { described_class.new(app) }
6
+ let(:env) { Rack::MockRequest.env_for("/api/test", method: "POST") }
7
+
8
+ let(:client_key) { Stitches.configuration.env_var_to_hold_api_client }
9
+
10
+ describe "#call" do
11
+ context "when the header is present and env var is not set" do
12
+ before { env["HTTP_X_STITCHFIX_CALLING_SERVICE"] = "kingmob" }
13
+
14
+ it "populates the env var with a CallingServiceClient" do
15
+ _status, result_env, _body = middleware.call(env)
16
+ client = result_env[client_key]
17
+
18
+ expect(client).to be_a(Stitches::CallingServiceClient)
19
+ expect(client.name).to eq("kingmob")
20
+ expect(client.id).to be_nil
21
+ expect(client.key).to be_nil
22
+ end
23
+ end
24
+
25
+ context "when the env var is already set (API key or JWT auth ran)" do
26
+ let(:existing_client) { double("ApiClient", name: "existing-client", id: 42) }
27
+
28
+ before do
29
+ env[client_key] = existing_client
30
+ env["HTTP_X_STITCHFIX_CALLING_SERVICE"] = "some-service"
31
+ end
32
+
33
+ it "does not overwrite the existing value" do
34
+ _status, result_env, _body = middleware.call(env)
35
+ expect(result_env[client_key]).to eq(existing_client)
36
+ end
37
+ end
38
+
39
+ context "when the header is absent and env var is not set" do
40
+ it "leaves the env var nil" do
41
+ _status, result_env, _body = middleware.call(env)
42
+ expect(result_env[client_key]).to be_nil
43
+ end
44
+ end
45
+
46
+ context "when the header is blank" do
47
+ before { env["HTTP_X_STITCHFIX_CALLING_SERVICE"] = "" }
48
+
49
+ it "leaves the env var nil" do
50
+ _status, result_env, _body = middleware.call(env)
51
+ expect(result_env[client_key]).to be_nil
52
+ end
53
+ end
54
+
55
+ context "with a custom configured header" do
56
+ before do
57
+ Stitches.configuration.calling_service_header = "X-Custom-Caller"
58
+ env["HTTP_X_CUSTOM_CALLER"] = "custom-service"
59
+ end
60
+
61
+ after { Stitches.configuration.reset_to_defaults! }
62
+
63
+ it "reads from the configured header" do
64
+ _status, result_env, _body = middleware.call(env)
65
+ client = result_env[client_key]
66
+
67
+ expect(client).to be_a(Stitches::CallingServiceClient)
68
+ expect(client.name).to eq("custom-service")
69
+ end
70
+ end
71
+ end
72
+ end
@@ -2,8 +2,7 @@ require 'rails_helper'
2
2
 
3
3
  describe Stitches::CallingServiceName do
4
4
  let(:headers) { {} }
5
- let(:env) { {} }
6
- let(:fake_request) { double("request", headers: headers, env: env) }
5
+ let(:fake_request) { double("request", headers: headers) }
7
6
  let(:fake_controller) {
8
7
  req = fake_request
9
8
  Object.new.tap { |c|
@@ -13,53 +12,27 @@ describe Stitches::CallingServiceName do
13
12
  }
14
13
 
15
14
  describe "#calling_service_name" do
16
- context "when X-StitchFix-Calling-Service header is present" do
15
+ context "when the header is present" do
17
16
  let(:headers) { {"X-StitchFix-Calling-Service" => "kingmob"} }
18
17
 
19
18
  it "returns the header value" do
20
19
  expect(fake_controller.calling_service_name).to eq("kingmob")
21
20
  end
22
-
23
- context "and env var client is also present" do
24
- let(:env) { {Stitches.configuration.env_var_to_hold_api_client => double(name: "other-service")} }
25
-
26
- it "prefers the header" do
27
- expect(fake_controller.calling_service_name).to eq("kingmob")
28
- end
29
- end
30
21
  end
31
22
 
32
- context "when header is absent but env var client is present" do
33
- let(:env) { {Stitches.configuration.env_var_to_hold_api_client => double(name: "mobile-service")} }
34
-
35
- it "returns the client name from env" do
36
- expect(fake_controller.calling_service_name).to eq("mobile-service")
37
- end
38
- end
39
-
40
- context "when header is blank" do
41
- let(:headers) { {"X-StitchFix-Calling-Service" => ""} }
42
- let(:env) { {Stitches.configuration.env_var_to_hold_api_client => double(name: "fallback-service")} }
43
-
44
- it "treats blank as absent and falls through to env var client" do
45
- expect(fake_controller.calling_service_name).to eq("fallback-service")
46
- end
47
- end
48
-
49
- context "when neither header nor env var client is present" do
23
+ context "when the header is absent" do
50
24
  it "returns empty string" do
51
25
  expect(fake_controller.calling_service_name).to eq("")
52
26
  end
53
27
  end
54
28
 
55
- context "when env var client is nil" do
56
- let(:env) { {Stitches.configuration.env_var_to_hold_api_client => nil} }
29
+ context "when the header is blank" do
30
+ let(:headers) { {"X-StitchFix-Calling-Service" => ""} }
57
31
 
58
32
  it "returns empty string" do
59
33
  expect(fake_controller.calling_service_name).to eq("")
60
34
  end
61
35
  end
62
-
63
36
  end
64
37
 
65
38
  describe "configurable header" do
@@ -70,13 +43,8 @@ describe Stitches::CallingServiceName do
70
43
  context "when configured to a custom header" do
71
44
  let(:headers) { {"X-Custom-Caller" => "my-service"} }
72
45
 
73
- before do
74
- Stitches.configuration.calling_service_header = "X-Custom-Caller"
75
- end
76
-
77
- after do
78
- Stitches.configuration.reset_to_defaults!
79
- end
46
+ before { Stitches.configuration.calling_service_header = "X-Custom-Caller" }
47
+ after { Stitches.configuration.reset_to_defaults! }
80
48
 
81
49
  it "reads from the configured header" do
82
50
  expect(fake_controller.calling_service_name).to eq("my-service")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stitches
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.0.RC3
4
+ version: 5.1.0.RC4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stitch Fix Engineering
@@ -174,6 +174,8 @@ files:
174
174
  - lib/stitches/api_key.rb
175
175
  - lib/stitches/api_migration_generator.rb
176
176
  - lib/stitches/api_version_constraint.rb
177
+ - lib/stitches/calling_service_client.rb
178
+ - lib/stitches/calling_service_middleware.rb
177
179
  - lib/stitches/calling_service_name.rb
178
180
  - lib/stitches/configuration.rb
179
181
  - lib/stitches/deprecation.rb
@@ -209,6 +211,7 @@ files:
209
211
  - owners.json
210
212
  - spec/api_key_middleware_spec.rb
211
213
  - spec/api_version_constraint_middleware_spec.rb
214
+ - spec/calling_service_middleware_spec.rb
212
215
  - spec/calling_service_name_spec.rb
213
216
  - spec/configuration_spec.rb
214
217
  - spec/deprecation_spec.rb
@@ -306,6 +309,7 @@ summary: You'll be in stitches at how easy it is to create a service at Stitch F
306
309
  test_files:
307
310
  - spec/api_key_middleware_spec.rb
308
311
  - spec/api_version_constraint_middleware_spec.rb
312
+ - spec/calling_service_middleware_spec.rb
309
313
  - spec/calling_service_name_spec.rb
310
314
  - spec/configuration_spec.rb
311
315
  - spec/deprecation_spec.rb