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 +4 -4
- data/lib/stitches/calling_service_client.rb +15 -0
- data/lib/stitches/calling_service_middleware.rb +29 -0
- data/lib/stitches/calling_service_name.rb +10 -3
- data/lib/stitches/railtie.rb +2 -0
- data/lib/stitches/version.rb +1 -1
- data/spec/calling_service_middleware_spec.rb +72 -0
- data/spec/calling_service_name_spec.rb +7 -39
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5e1a4aefc1d0249b7b5c8caf2eb06aa6e0866afef4f1d4564d63efa239ef80ce
|
|
4
|
+
data.tar.gz: 322ab581e74df9bb933d8a1e23d2dc3973c6e3494ebfac23424f16c25cbf589a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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[
|
|
6
|
-
|
|
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
|
data/lib/stitches/railtie.rb
CHANGED
|
@@ -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
|
data/lib/stitches/version.rb
CHANGED
|
@@ -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(:
|
|
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
|
|
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
|
|
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
|
|
56
|
-
let(:
|
|
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
|
|
74
|
-
|
|
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.
|
|
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
|