conjur-rack 1.4.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,107 +3,179 @@ require 'spec_helper'
3
3
  require 'conjur/rack/authenticator'
4
4
 
5
5
  describe Conjur::Rack::Authenticator do
6
- let(:app) { double(:app) }
7
- let(:options) { {} }
8
- let(:authenticator) { Conjur::Rack::Authenticator.new(app, options) }
9
- let(:call) { authenticator.call env }
10
-
11
- context "#call" do
12
- context "with Conjur authorization" do
13
- before{ stub_const 'Slosilo', Module.new }
14
- let(:env) {
15
- {
16
- 'HTTP_AUTHORIZATION' => "Token token=\"#{basic_64}\""
17
- }.tap do |e|
18
- e['HTTP_X_CONJUR_PRIVILEGE'] = privilege if privilege
19
- e['HTTP_X_FORWARDED_FOR'] = remote_ip if remote_ip
20
- end
6
+ include_context "with authenticator"
7
+
8
+ describe "#call" do
9
+ context "to an unprotected path" do
10
+ let(:except) { [ /^\/foo/ ] }
11
+ let(:env) { { 'SCRIPT_NAME' => '', 'PATH_INFO' => '/foo/bar' } }
12
+ before {
13
+ options[:except] = except
14
+ expect(app).to receive(:call).with(env).and_return app
21
15
  }
22
- let(:basic_64) { Base64.strict_encode64(token.to_json) }
23
- let(:token) { { "data" => "foobar" } }
24
- let(:sample_account) { "someacc" }
25
- let(:privilege) { nil }
26
- let(:remote_ip) { nil }
27
-
28
- context "of a valid token" do
29
-
30
- before(:each) {
31
- Slosilo.stub token_signer: 'authn:'+sample_account
32
- }
33
-
34
- it 'launches app' do
35
- app.should_receive(:call).with(env).and_return app
36
- call.should == app
16
+ context "without authorization" do
17
+ it "proceeds" do
18
+ expect(call).to eq(app)
19
+ expect(Conjur::Rack.identity?).to be(false)
20
+ end
21
+ end
22
+ context "with authorization" do
23
+ include_context "with authorization"
24
+ it "ignores the authorization" do
25
+ expect(call).to eq(app)
26
+ expect(Conjur::Rack.identity?).to be(false)
37
27
  end
28
+ end
29
+ end
38
30
 
39
- context 'Authable provides module method conjur_user' do
40
- let(:stubuser) { "some value" }
41
- before {
42
- app.stub(:call) { Conjur::Rack.user }
43
- }
44
-
45
- context 'when called in app context' do
46
- let(:invoke) {
47
- Conjur::Rack::User.should_receive(:new).
48
- with(token, sample_account, privilege, remote_ip).
49
- and_return(stubuser)
50
- Conjur::Rack.should_receive(:user).and_call_original
51
- call
52
- }
53
-
54
- shared_examples_for 'returns User built from token' do
55
- specify {
56
- invoke.should == stubuser
57
- }
58
- end
59
-
60
- it_should_behave_like 'returns User built from token'
61
-
62
- context 'with X-Conjur-Privilege' do
63
- let(:privilege) { "sudo" }
64
- it_should_behave_like 'returns User built from token'
31
+ context "to a protected path" do
32
+ let(:env) { { 'SCRIPT_NAME' => '/pathname' } }
33
+ context "without authorization" do
34
+ it "returns a 401 error" do
35
+ expect(call).to return_http 401, "Authorization missing"
36
+ end
37
+ end
38
+ context "with Conjur authorization" do
39
+ include_context "with authorization"
40
+
41
+ context "with CIDR restriction" do
42
+ let(:claims) { { 'sub' => 'test-user', 'cidr' => %w(192.168.2.0/24 2001:db8::/32) } }
43
+ let(:token) { Slosilo::JWT.new(claims) }
44
+ before do
45
+ allow(subject).to receive_messages \
46
+ parsed_token: token,
47
+ http_remote_ip: remote_ip
48
+ end
49
+
50
+ %w(10.0.0.2 fdda:5cc1:23:4::1f).each do |addr|
51
+ context "with address #{addr} out of range" do
52
+ let(:remote_ip) { addr }
53
+ it "returns 403" do
54
+ expect(call).to return_http 403, "IP address rejected"
55
+ end
65
56
  end
66
-
67
- context 'with X-Forwarded-For' do
68
- let(:remote_ip) { "66.0.0.1" }
69
- it_should_behave_like 'returns User built from token'
57
+ end
58
+
59
+ %w(192.168.2.3 2001:db8::22).each do |addr|
60
+ context "with address #{addr} in range" do
61
+ let(:remote_ip) { addr }
62
+ it "passes the request" do
63
+ expect(call.login).to eq 'test-user'
64
+ end
70
65
  end
71
66
  end
67
+ end
72
68
 
73
- context 'called out of app context' do
74
- it { lambda { Conjur::Rack.user }.should raise_error }
69
+ context "of a valid token" do
70
+ it 'launches app' do
71
+ expect(app).to receive(:call).with(env).and_return app
72
+ expect(call).to eq(app)
73
+ end
74
+ end
75
+ context "of an invalid token" do
76
+ it "returns a 401 error" do
77
+ allow(Slosilo).to receive(:token_signer).and_return(nil)
78
+ expect(call).to return_http 401, "Unauthorized: Invalid token"
79
+ end
80
+ end
81
+ context "of a token invalid for authn" do
82
+ it "returns a 401 error" do
83
+ allow(Slosilo).to receive(:token_signer).and_return('a-totally-different-key')
84
+ expect(call).to return_http 401, "Unauthorized: Invalid token"
85
+ end
86
+ end
87
+ context "of 'own' token" do
88
+ it "returns ENV['CONJUR_ACCOUNT']" do
89
+ expect(ENV).to receive(:[]).with("CONJUR_ACCOUNT").and_return("test-account")
90
+ expect(app).to receive(:call) do |*args|
91
+ expect(Conjur::Rack.identity?).to be(true)
92
+ expect(Conjur::Rack.user.account).to eq('test-account')
93
+ :done
94
+ end
95
+ allow(Slosilo).to receive(:token_signer).and_return('own')
96
+ expect(call).to eq(:done)
97
+ end
98
+ it "requires ENV['CONJUR_ACCOUNT']" do
99
+ expect(ENV).to receive(:[]).with("CONJUR_ACCOUNT").and_return(nil)
100
+ allow(Slosilo).to receive(:token_signer).and_return('own')
101
+ expect(call).to return_http 401, "Unauthorized: Invalid token"
75
102
  end
76
103
  end
77
104
  end
78
- context "of an invalid token" do
79
- it "returns a 401 error" do
80
- Slosilo.stub token_signer: nil
81
- call.should == [401, {"Content-Type"=>"text/plain", "Content-Length"=>"26"}, ["Unathorized: Invalid token"]]
105
+
106
+ context "with junk in token" do
107
+ let(:env) { { 'HTTP_AUTHORIZATION' => 'Token token="open sesame"' } }
108
+ it "returns 401" do
109
+ expect(call).to return_http 401, "Malformed authorization token"
82
110
  end
83
111
  end
84
- context "of a token invalid for authn" do
85
- it "returns a 401 error" do
86
- Slosilo.stub token_signer: 'a-totally-different-key'
87
- call.should == [401, {"Content-Type"=>"text/plain", "Content-Length"=>"26"}, ["Unathorized: Invalid token"]]
112
+
113
+ context "with JSON junk in token" do
114
+ let(:env) { { 'HTTP_AUTHORIZATION' => 'Token token="eyJmb28iOiAiYmFyIn0="' } }
115
+ before do
116
+ allow(Slosilo).to receive(:token_signer).and_return(nil)
117
+ end
118
+
119
+ it "returns 401" do
120
+ expect(call).to return_http 401, "Unauthorized: Invalid token"
88
121
  end
89
122
  end
90
123
  end
91
- end
92
- context "without authorization" do
93
- context "to a protected path" do
94
- let(:env) { { 'SCRIPT_NAME' => '/pathname' } }
95
- it "returns a 401 error" do
96
- call.should == [401, {"Content-Type"=>"text/plain", "Content-Length"=>"21"}, ["Authorization missing"]]
124
+ context "to an optional path" do
125
+ let(:optional) { [ /^\/foo/ ] }
126
+ let(:env) { { 'SCRIPT_NAME' => '', 'PATH_INFO' => '/foo/bar' } }
127
+ before {
128
+ options[:optional] = optional
129
+ }
130
+ context "without authorization" do
131
+ it "proceeds" do
132
+ expect(app).to receive(:call) do |*args|
133
+ expect(Conjur::Rack.identity?).to be(false)
134
+ :done
135
+ end
136
+ expect(call).to eq(:done)
137
+ end
138
+ end
139
+ context "with authorization" do
140
+ include_context "with authorization"
141
+ it "processes the authorization" do
142
+ expect(app).to receive(:call) do |*args|
143
+ expect(Conjur::Rack.identity?).to be(true)
144
+ :done
145
+ end
146
+ expect(call).to eq(:done)
147
+ end
97
148
  end
98
149
  end
99
- context "to an unprotected path" do
100
- let(:except) { [ /^\/foo/ ] }
101
- let(:env) { { 'SCRIPT_NAME' => '', 'PATH_INFO' => '/foo/bar' } }
102
- it "proceeds" do
103
- options[:except] = except
104
- app.should_receive(:call).with(env).and_return app
105
- call.should == app
150
+
151
+ RSpec::Matchers.define :return_http do |status, message|
152
+ match do |actual|
153
+ status, headers, body = actual
154
+ expect(status).to eq status
155
+ expect(headers).to eq "Content-Type" => "text/plain", "Content-Length" => message.length.to_s
156
+ expect(body.join).to eq message
106
157
  end
107
158
  end
108
159
  end
160
+
161
+ # protected internal methods
162
+
163
+ describe '#verify_authorization_and_get_identity' do
164
+ it "accepts JWT tokens without CIDR restrictions" do
165
+ mock_jwt sub: 'user'
166
+ expect { subject.send :verify_authorization_and_get_identity }.to_not raise_error
167
+ end
168
+
169
+ it "rejects JWT tokens with unrecognized claims" do
170
+ mock_jwt extra: 'field'
171
+ expect { subject.send :verify_authorization_and_get_identity }.to raise_error \
172
+ Conjur::Rack::Authenticator::AuthorizationError
173
+ end
174
+
175
+ def mock_jwt claims
176
+ token = Slosilo::JWT.new(claims).add_signature(alg: 'none') {}
177
+ allow(subject).to receive(:parsed_token) { token }
178
+ allow(Slosilo).to receive(:token_signer).with(token).and_return 'authn:test'
179
+ end
180
+ end
109
181
  end
@@ -17,21 +17,21 @@ describe Conjur::Rack::PathPrefix do
17
17
  context "/api/hosts" do
18
18
  let(:path) { "/api/hosts" }
19
19
  it "matches" do
20
- app.should_receive(:call).with({ 'PATH_INFO' => '/hosts' }).and_return app
20
+ expect(app).to receive(:call).with({ 'PATH_INFO' => '/hosts' }).and_return app
21
21
  call
22
22
  end
23
23
  end
24
24
  context "/api" do
25
25
  let(:path) { "/api" }
26
26
  it "doesn't erase the path completely" do
27
- app.should_receive(:call).with({ 'PATH_INFO' => '/' }).and_return app
27
+ expect(app).to receive(:call).with({ 'PATH_INFO' => '/' }).and_return app
28
28
  call
29
29
  end
30
30
  end
31
31
  context "with non-matching prefix" do
32
32
  let(:path) { "/hosts" }
33
33
  it "doesn't match" do
34
- app.should_receive(:call).with({ 'PATH_INFO' => '/hosts' }).and_return app
34
+ expect(app).to receive(:call).with({ 'PATH_INFO' => '/hosts' }).and_return app
35
35
  call
36
36
  end
37
37
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'conjur/rack/user'
2
3
 
3
4
  describe Conjur::Rack::User do
4
5
  let(:login){ 'admin' }
@@ -6,41 +7,50 @@ describe Conjur::Rack::User do
6
7
  let(:account){ 'acct' }
7
8
  let(:privilege) { nil }
8
9
  let(:remote_ip) { nil }
10
+ let(:audit_roles) { nil }
11
+ let(:audit_resources) { nil }
9
12
 
10
- subject{ described_class.new token, account, privilege, remote_ip }
13
+ subject(:user) {
14
+ described_class.new(token, account,
15
+ :privilege => privilege,
16
+ :remote_ip => remote_ip,
17
+ :audit_roles => audit_roles,
18
+ :audit_resources => audit_resources
19
+ )
20
+ }
11
21
 
12
- its(:token){ should == token }
13
- its(:account){ should == account }
14
- its(:conjur_account){ should == account }
15
- its(:login){ should == token['data'] }
16
-
17
- it "aliases setter for account to conjur_account" do
18
- subject.conjur_account = "changed!"
19
- subject.account.should == "changed!"
20
- end
21
-
22
- describe '#new_assocation' do
23
- let(:associate){ Class.new }
24
- let(:params){{foo: 'bar'}}
25
- it "calls cls.new with params including userid: login" do
26
- associate.should_receive(:new).with(params.merge(userid: subject.login))
27
- subject.new_association(associate, params)
28
- end
22
+ it 'provides field accessors' do
23
+ expect(user.token).to eq token
24
+ expect(user.account).to eq account
25
+ expect(user.conjur_account).to eq account
26
+ expect(user.login).to eq login
29
27
  end
30
28
 
31
29
  describe '#roleid' do
32
30
  let(:login){ tokens.join('/') }
33
- context "when login contains one token 'foobar'" do
34
- let(:tokens){ ['foobar'] }
35
- its(:roleid){ should == "#{account}:user:#{login}" }
31
+
32
+ context "when login contains one token" do
33
+ let(:tokens) { %w(foobar) }
34
+
35
+ it "is expanded to account:user:token" do
36
+ expect(subject.roleid).to eq "#{account}:user:foobar"
37
+ end
36
38
  end
37
- context "when login contains tokens ['foo', 'bar']" do
38
- let(:tokens){ ["foos", "bar"] }
39
- its(:roleid){ should == "#{account}:#{tokens[0]}:#{tokens[1]}"}
39
+
40
+ context "when login contains two tokens" do
41
+ let(:tokens) { %w(foo bar) }
42
+
43
+ it "is expanded to account:first:second" do
44
+ expect(subject.roleid).to eq "#{account}:foo:bar"
45
+ end
40
46
  end
41
- context "when login contains tokens ['foo','bar','baz']" do
42
- let(:tokens){ ['foo', 'bar', 'baz'] }
43
- its(:roleid){ should == "#{account}:#{tokens[0]}:#{tokens[1]}/#{tokens[2]}" }
47
+
48
+ context "when login contains three tokens" do
49
+ let(:tokens) { %w(foo bar baz) }
50
+
51
+ it "is expanded to account:first:second/third" do
52
+ expect(subject.roleid).to eq "#{account}:foo:bar/baz"
53
+ end
44
54
  end
45
55
  end
46
56
 
@@ -48,34 +58,46 @@ describe Conjur::Rack::User do
48
58
  let(:roleid){ 'the role id' }
49
59
  let(:api){ double('conjur api') }
50
60
  before do
51
- subject.stub(:roleid).and_return roleid
52
- subject.stub(:api).and_return api
61
+ allow(subject).to receive(:roleid).and_return roleid
62
+ allow(subject).to receive(:api).and_return api
53
63
  end
54
64
 
55
65
  it 'passes roleid to api.role' do
56
- api.should_receive(:role).with(roleid).and_return 'the role'
57
- subject.role.should == 'the role'
66
+ expect(api).to receive(:role).with(roleid).and_return 'the role'
67
+ expect(subject.role).to eq('the role')
58
68
  end
59
69
  end
60
70
 
61
71
  describe "#global_reveal?" do
72
+ let(:api){ double "conjur-api" }
73
+ before { allow(subject).to receive(:api).and_return(api) }
74
+
62
75
  context "with global privilege" do
63
76
  let(:privilege) { "reveal" }
64
- let(:api){ Conjur::API.new_from_token "the-token" }
65
- before do
66
- subject.stub(:api).and_return api
77
+
78
+ context "when not supported" do
79
+ before { expect(api).not_to respond_to :global_privilege_permitted? }
80
+ it "simply returns false" do
81
+ expect(subject.global_reveal?).to be false
82
+ end
67
83
  end
68
- it "checks the API function global_privilege_permitted?" do
69
- api.should_receive(:resource).with("!:!:conjur").and_return resource = double(:resource)
70
- resource.should_receive(:permitted?).with("reveal").and_return true
71
- expect(subject.global_reveal?).to be_true
72
- # The result is cached
73
- subject.global_reveal?
84
+
85
+ context "when supported" do
86
+ before do
87
+ allow(api).to receive(:global_privilege_permitted?).with('reveal') { true }
88
+ end
89
+ it "checks the API function global_privilege_permitted?" do
90
+ expect(subject.global_reveal?).to be true
91
+ # The result is cached
92
+ expect(api).not_to receive :global_privilege_permitted?
93
+ subject.global_reveal?
94
+ end
74
95
  end
75
96
  end
97
+
76
98
  context "without a global privilege" do
77
- it "simply returns nil" do
78
- expect(subject.global_reveal?).to be_false
99
+ it "simply returns false" do
100
+ expect(subject.global_reveal?).to be false
79
101
  end
80
102
  end
81
103
  end
@@ -84,38 +106,116 @@ describe Conjur::Rack::User do
84
106
  context "when given a class" do
85
107
  let(:cls){ double('API class') }
86
108
  it "calls cls.new_from_token with its token" do
87
- cls.should_receive(:new_from_token).with(token).and_return 'the api'
88
- subject.api(cls).should == 'the api'
109
+ expect(cls).to receive(:new_from_token).with(token).and_return 'the api'
110
+ expect(subject.api(cls)).to eq('the api')
89
111
  end
90
112
  end
113
+
91
114
  context 'when not given args' do
92
- shared_examples_for "builds the api" do
93
- specify {
94
- subject.api.should == 'the api'
95
- }
115
+ let(:api) { double :api }
116
+ before do
117
+ allow(Conjur::API).to receive(:new_from_token).with(token).and_return(api)
96
118
  end
97
-
98
- context "with no extra args" do
99
- before {
100
- Conjur::API.should_receive(:new_from_token).with(token).and_return 'the api'
101
- }
102
- it_should_behave_like "builds the api"
119
+
120
+ it "builds the api from token" do
121
+ expect(subject.api).to eq api
103
122
  end
123
+
104
124
  context "with remote_ip" do
105
125
  let(:remote_ip) { "the-ip" }
106
- before {
107
- Conjur::API.should_receive(:new_from_token).with(token, 'the-ip').and_return 'the api'
108
- }
109
- it_should_behave_like "builds the api"
126
+ it "passes the IP to the API constructor" do
127
+ expect(Conjur::API).to receive(:new_from_token).with(token, 'the-ip').and_return(api)
128
+ expect(subject.api).to eq api
129
+ end
110
130
  end
131
+
111
132
  context "with privilege" do
112
- let(:privilege) { "sudo" }
113
- before {
114
- Conjur::API.should_receive(:new_from_token).with(token).and_return api = double(:api)
115
- expect(api).to receive(:with_privilege).with("sudo").and_return('the api')
116
- }
117
- it_should_behave_like "builds the api"
133
+ let(:privilege) { "elevate" }
134
+ it "applies the privilege on the API object" do
135
+ expect(api).to receive(:with_privilege).with("elevate").and_return "privileged api"
136
+ expect(subject.api).to eq "privileged api"
137
+ end
118
138
  end
139
+
140
+ context "when audit supported" do
141
+ before do
142
+ # If we're testing on an API version that doesn't
143
+ # support audit this method will be missing, so stub.
144
+ unless Conjur::API.respond_to? :decode_audit_ids
145
+ # not exactly a faithful reimplementation, but good enough for here
146
+ allow(Conjur::API).to receive(:decode_audit_ids) {|x|[x]}
147
+ end
148
+ end
149
+
150
+ context "with audit resource" do
151
+ let (:audit_resources) { 'food:bacon' }
152
+ it "applies the audit resource on the API object" do
153
+ expect(api).to receive(:with_audit_resources).with(['food:bacon']).and_return('the api')
154
+ expect(subject.api).to eq 'the api'
155
+ end
156
+ end
157
+
158
+ context "with audit roles" do
159
+ let (:audit_roles) { 'user:cook' }
160
+ it "applies the audit role on the API object" do
161
+ expect(api).to receive(:with_audit_roles).with(['user:cook']).and_return('the api')
162
+ expect(subject.api).to eq 'the api'
163
+ end
164
+ end
165
+ end
166
+
167
+ context "when audit not supported" do
168
+ before do
169
+ expect(api).not_to respond_to :with_audit_resources
170
+ expect(api).not_to respond_to :with_audit_roles
171
+ end
172
+ let (:audit_resources) { 'food:bacon' }
173
+ let (:audit_roles) { 'user:cook' }
174
+ it "ignores audit roles and resources" do
175
+ expect(subject.api).to eq api
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ context "with invalid type payload" do
182
+ let(:token){ { "data" => :alice } }
183
+ it "raises an error on trying to access the content" do
184
+ expect{ subject.login }.to raise_error("Expecting String or Hash token data, got Symbol")
185
+ end
186
+ end
187
+
188
+ context "with hash payload" do
189
+ let(:token){ { "data" => { "login" => "alice", "capabilities" => { "fry" => "bacon" } } } }
190
+
191
+ it "processes the login and attributes" do
192
+ original_token = token.deep_dup
193
+
194
+ expect(subject.login).to eq('alice')
195
+ expect(subject.attributes).to eq({"capabilities" => { "fry" => "bacon" }})
196
+
197
+ expect(token).to eq original_token
198
+ end
199
+ end
200
+
201
+ context "with JWT token" do
202
+ let(:token) { {"protected"=>"eyJhbGciOiJ0ZXN0IiwidHlwIjoiSldUIn0=",
203
+ "payload"=>"eyJzdWIiOiJhbGljZSIsImlhdCI6MTUwNDU1NDI2NX0=",
204
+ "signature"=>"dGVzdHNpZw=="} }
205
+
206
+ it "processes the login and attributes" do
207
+ original_token = token.deep_dup
208
+
209
+ expect(subject.login).to eq('alice')
210
+
211
+ # TODO: should we only pass unrecognized attrs here?
212
+ expect(subject.attributes).to eq \
213
+ 'alg' => 'test',
214
+ 'iat' => 1504554265,
215
+ 'sub' => 'alice',
216
+ 'typ' => 'JWT'
217
+
218
+ expect(token).to eq original_token
119
219
  end
120
220
  end
121
- end
221
+ end
data/spec/rack_spec.rb ADDED
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+ require 'conjur/rack'
3
+
4
+ describe Conjur::Rack do
5
+ describe '.user' do
6
+ include_context "with authorization"
7
+ let(:stubuser) { double :stubuser }
8
+ before do
9
+ allow(Conjur::Rack::User).to receive(:new)
10
+ .with(token, 'someacc', {:privilege => privilege, :remote_ip => remote_ip, :audit_roles => audit_roles, :audit_resources => audit_resources})
11
+ .and_return(stubuser)
12
+ end
13
+
14
+ context 'when called in app context' do
15
+ shared_examples_for :returns_user do
16
+ it "returns user built from token" do
17
+ expect(call).to eq stubuser
18
+ end
19
+ end
20
+
21
+ include_examples :returns_user
22
+
23
+ context 'with X-Conjur-Privilege' do
24
+ let(:privilege) { "elevate" }
25
+ include_examples :returns_user
26
+ end
27
+
28
+ context 'with X-Forwarded-For' do
29
+ let(:remote_ip) { "66.0.0.1" }
30
+ include_examples :returns_user
31
+ end
32
+
33
+ context 'with Conjur-Audit-Roles' do
34
+ let (:audit_roles) { 'user%3Acook' }
35
+ include_examples :returns_user
36
+ end
37
+
38
+ context 'with Conjur-Audit-Resources' do
39
+ let (:audit_resources) { 'food%3Abacon' }
40
+ include_examples :returns_user
41
+ end
42
+
43
+ end
44
+
45
+ it "raises error if called out of app context" do
46
+ expect { Conjur::Rack.user }.to raise_error('No Conjur identity for current request')
47
+ end
48
+ end
49
+ end
data/spec/spec_helper.rb CHANGED
@@ -4,8 +4,44 @@ $:.unshift File.join(File.dirname(__FILE__), "lib")
4
4
 
5
5
  # Allows loading of an environment config based on the environment
6
6
  require 'rspec'
7
+ require 'rspec/its'
7
8
  require 'securerandom'
9
+ require 'slosilo'
8
10
 
9
11
  RSpec.configure do |config|
10
12
  end
11
13
 
14
+ RSpec.shared_context "with authenticator" do
15
+ let(:options) { {} }
16
+ let(:app) { double(:app) }
17
+ subject(:authenticator) { Conjur::Rack::Authenticator.new(app, options) }
18
+ let(:call) { authenticator.call env }
19
+ end
20
+
21
+ RSpec.shared_context "with authorization" do
22
+ include_context "with authenticator"
23
+ let(:token_signer) { "authn:someacc" }
24
+ let(:audit_resources) { nil }
25
+ let(:privilege) { nil }
26
+ let(:remote_ip) { nil }
27
+ let(:audit_roles) { nil }
28
+
29
+ before do
30
+ allow(app).to receive(:call) { Conjur::Rack.user }
31
+ allow(Slosilo).to receive(:token_signer).and_return(token_signer)
32
+ end
33
+
34
+ let(:env) do
35
+ {
36
+ 'HTTP_AUTHORIZATION' => "Token token=\"#{basic_64}\""
37
+ }.tap do |e|
38
+ e['HTTP_X_CONJUR_PRIVILEGE'] = privilege if privilege
39
+ e['HTTP_X_FORWARDED_FOR'] = remote_ip if remote_ip
40
+ e['HTTP_CONJUR_AUDIT_ROLES'] = audit_roles if audit_roles
41
+ e['HTTP_CONJUR_AUDIT_RESOURCES'] = audit_resources if audit_resources
42
+ end
43
+ end
44
+
45
+ let(:basic_64) { Base64.strict_encode64(token.to_json) }
46
+ let(:token) { { "data" => "foobar" } }
47
+ end