machina-auth 0.1.3 → 0.1.4
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/machina/middleware/authentication.rb +9 -7
- data/lib/machina/version.rb +1 -1
- data/lib/machina.rb +1 -0
- data/spec/machina/middleware/authentication_spec.rb +46 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8b85487ba807943451cf345d17e7aec7ee18a9b61a233adcdb213f86134cde0
|
|
4
|
+
data.tar.gz: 49908d36c4fb879354aa6c3b9ae96e33eaed76d98df2cd3dbfb8a51ce72b03a4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 97716d4c519933b65a8410615655adcf7e70a4013d9595e7ef5ca4a96ae2a57c44574640b33de5dc1adcd675b626c2ae39d09ffd0c5cf4fbcbb2932924988be9
|
|
7
|
+
data.tar.gz: 868b463264e64e8551c938704bcfad481714e0d6a9f4aa8dcc6152eb4d8df1bda0c6a01ff2ab55f89e534ceeb03b1d53abed3792dc2afaa1de660c6726dd2e2c
|
|
@@ -11,11 +11,11 @@ module Machina
|
|
|
11
11
|
|
|
12
12
|
def call(env)
|
|
13
13
|
request = ActionDispatch::Request.new(env)
|
|
14
|
-
|
|
14
|
+
# Skip paths allow the developer to disable the middleware from validating
|
|
15
|
+
# any token or headers on any matched URL or Path.
|
|
15
16
|
return @app.call(env) if skip_path?(request)
|
|
16
17
|
|
|
17
18
|
token = extract_token(request)
|
|
18
|
-
|
|
19
19
|
return @app.call(env) if token.blank?
|
|
20
20
|
|
|
21
21
|
session_data = resolve_session(token)
|
|
@@ -53,10 +53,7 @@ module Machina
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def extract_token(request)
|
|
56
|
-
request.cookies['machina_session'] ||
|
|
57
|
-
extract_bearer(request) ||
|
|
58
|
-
request.headers['X-Api-Key'] ||
|
|
59
|
-
request.params['token']
|
|
56
|
+
request.cookies['machina_session'] || extract_bearer(request) || request.headers['X-Api-Key'] || request.params['token']
|
|
60
57
|
end
|
|
61
58
|
|
|
62
59
|
def extract_bearer(request)
|
|
@@ -76,7 +73,11 @@ module Machina
|
|
|
76
73
|
|
|
77
74
|
def fetch_from_identity_service(token)
|
|
78
75
|
response = Machina.identity_client.resolve_session(token)
|
|
79
|
-
|
|
76
|
+
|
|
77
|
+
unless response.success?
|
|
78
|
+
Machina.cache.delete(cache_key(token))
|
|
79
|
+
return nil
|
|
80
|
+
end
|
|
80
81
|
|
|
81
82
|
data = unwrap_payload(response.parsed)
|
|
82
83
|
Machina.cache.write(cache_key(token), data, expires_in: Machina.config.cache_ttl)
|
|
@@ -91,6 +92,7 @@ module Machina
|
|
|
91
92
|
def cache_workspace_ref(data)
|
|
92
93
|
workspace = data['workspace']
|
|
93
94
|
organization = data['organization']
|
|
95
|
+
|
|
94
96
|
return unless workspace.is_a?(Hash) && organization.is_a?(Hash)
|
|
95
97
|
return unless defined?(Machina::WorkspaceRef) && Machina::WorkspaceRef.table_exists?
|
|
96
98
|
|
data/lib/machina/version.rb
CHANGED
data/lib/machina.rb
CHANGED
|
@@ -54,6 +54,52 @@ RSpec.describe Machina::Middleware::Authentication do
|
|
|
54
54
|
expect(JSON.parse(body.first)).to eq('error' => 'unauthorized')
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
it 'evicts cached session when Console returns non-200 on stale re-fetch' do
|
|
58
|
+
token = 'ps_stale_token'
|
|
59
|
+
cache_key = "machina:session:#{token}"
|
|
60
|
+
stale_data = MockResponses.session_resolution_minimal['data'].merge(stale: true)
|
|
61
|
+
|
|
62
|
+
Machina.cache.write(cache_key, stale_data, expires_in: 5.minutes)
|
|
63
|
+
|
|
64
|
+
allow(identity_client).to receive(:resolve_session).with(token).and_return(
|
|
65
|
+
Machina::IdentityClient::Response.new(status: 404, body: '{}'),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
env = Rack::MockRequest.env_for('/resource', 'HTTP_AUTHORIZATION' => "Bearer #{token}")
|
|
69
|
+
status, = middleware.call(env)
|
|
70
|
+
|
|
71
|
+
expect(status).to eq(401)
|
|
72
|
+
expect(Machina.cache.read(cache_key)).to be_nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'evicts cached session when Console returns non-200 after cache expires' do
|
|
76
|
+
token = 'ps_expired_cache'
|
|
77
|
+
cache_key = "machina:session:#{token}"
|
|
78
|
+
|
|
79
|
+
# First request: populate cache via successful resolution
|
|
80
|
+
allow(identity_client).to receive(:resolve_session).with(token).and_return(
|
|
81
|
+
Machina::IdentityClient::Response.new(status: 200, body: MockResponses.session_resolution_minimal),
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
env = Rack::MockRequest.env_for('/resource', 'HTTP_AUTHORIZATION' => "Bearer #{token}")
|
|
85
|
+
status, = middleware.call(env)
|
|
86
|
+
expect(status).to eq(200)
|
|
87
|
+
|
|
88
|
+
# Simulate cache expiry
|
|
89
|
+
Machina.cache.delete(cache_key)
|
|
90
|
+
|
|
91
|
+
# Console now rejects the token
|
|
92
|
+
allow(identity_client).to receive(:resolve_session).with(token).and_return(
|
|
93
|
+
Machina::IdentityClient::Response.new(status: 404, body: '{}'),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
env = Rack::MockRequest.env_for('/resource', 'HTTP_AUTHORIZATION' => "Bearer #{token}")
|
|
97
|
+
status, = middleware.call(env)
|
|
98
|
+
|
|
99
|
+
expect(status).to eq(401)
|
|
100
|
+
expect(Machina.cache.read(cache_key)).to be_nil
|
|
101
|
+
end
|
|
102
|
+
|
|
57
103
|
it 'uses the cache on subsequent requests' do
|
|
58
104
|
response = Machina::IdentityClient::Response.new(
|
|
59
105
|
status: 200,
|