conjur-api 5.3.0 → 5.3.5
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/.codeclimate.yml +10 -0
- data/.github/CODEOWNERS +10 -0
- data/.github/ISSUE_TEMPLATE/bug.md +42 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +27 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +21 -0
- data/.gitignore +1 -0
- data/.gitleaks.toml +219 -0
- data/.overcommit.yml +16 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_settings.yml +86 -0
- data/.rubocop_todo.yml +709 -0
- data/CHANGELOG.md +373 -181
- data/CONTRIBUTING.md +141 -0
- data/Gemfile +1 -1
- data/Jenkinsfile +27 -29
- data/LICENSE +202 -0
- data/README.md +34 -117
- data/SECURITY.md +42 -0
- data/bin/parse-changelog.sh +12 -0
- data/ci/codeclimate.dockerfile +6 -0
- data/conjur-api.gemspec +4 -1
- data/docker-compose.yml +2 -0
- data/features/authenticators.feature +33 -0
- data/features/host.feature +39 -9
- data/features/step_definitions/api_steps.rb +14 -3
- data/features/step_definitions/policy_steps.rb +40 -0
- data/features/support/env.rb +2 -0
- data/features/update_password.feature +2 -2
- data/features/user.feature +47 -6
- data/features_v4/support/env.rb +2 -0
- data/lib/conjur-api/version.rb +2 -2
- data/lib/conjur/acts_as_role.rb +15 -19
- data/lib/conjur/acts_as_user.rb +5 -1
- data/lib/conjur/api.rb +1 -18
- data/lib/conjur/api/authenticators.rb +35 -0
- data/lib/conjur/api/authn.rb +3 -3
- data/lib/conjur/api/host_factories.rb +20 -19
- data/lib/conjur/api/resources.rb +17 -21
- data/lib/conjur/api/router/v4.rb +80 -23
- data/lib/conjur/api/router/v5.rb +117 -23
- data/lib/conjur/base.rb +19 -5
- data/lib/conjur/base_object.rb +31 -26
- data/lib/conjur/build_object.rb +13 -20
- data/lib/conjur/cert_utils.rb +14 -0
- data/lib/conjur/configuration.rb +46 -24
- data/lib/conjur/id.rb +22 -19
- data/lib/conjur/role_grant.rb +13 -18
- data/spec/api/host_factories_spec.rb +34 -0
- data/spec/api_spec.rb +55 -6
- data/spec/base_object_spec.rb +13 -0
- data/spec/cert_utils_spec.rb +92 -0
- data/spec/configuration_spec.rb +25 -3
- data/spec/id_spec.rb +29 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/ssl_spec.rb +50 -26
- data/spec/uri_escape_spec.rb +14 -2
- data/test.sh +23 -1
- metadata +31 -14
- data/LICENSE.md +0 -195
- data/lib/conjur/cast.rb +0 -41
- data/spec/cast_spec.rb +0 -21
- data/spec/vendor/rest_client_spec.rb +0 -41
data/lib/conjur/role_grant.rb
CHANGED
@@ -1,23 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2013-2018 CyberArk Ltd.
|
1
4
|
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# this software and associated documentation files (the "Software"), to deal in
|
6
|
-
# the Software without restriction, including without limitation the rights to
|
7
|
-
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
8
|
-
# the Software, and to permit persons to whom the Software is furnished to do so,
|
9
|
-
# subject to the following conditions:
|
10
|
-
#
|
11
|
-
# The above copyright notice and this permission notice shall be included in all
|
12
|
-
# copies or substantial portions of the Software.
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
13
8
|
#
|
14
|
-
#
|
15
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
16
|
-
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
17
|
-
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
18
|
-
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
19
|
-
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
20
10
|
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
21
17
|
module Conjur
|
22
18
|
# Represents the membership of a role. `RoleGrant`s are returned
|
23
19
|
# by {ActsAsRole#members} and represent members of the role on which the method was invoked.
|
@@ -28,7 +24,6 @@ module Conjur
|
|
28
24
|
#
|
29
25
|
class RoleGrant
|
30
26
|
extend BuildObject::ClassMethods
|
31
|
-
extend Cast
|
32
27
|
|
33
28
|
# The role which was granted.
|
34
29
|
# @return [Conjur::Role]
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'conjur/api/host_factories'
|
5
|
+
|
6
|
+
describe "Conjur::API.host_factory_create_host", api: :dummy do
|
7
|
+
it "returns a Host instance correctly on v4" do
|
8
|
+
token = "host factory token"
|
9
|
+
id = "test-host"
|
10
|
+
|
11
|
+
allow(Conjur::API).to receive(:url_for)
|
12
|
+
.with(:host_factory_create_host, token).and_return(
|
13
|
+
resource = instance_double(RestClient::Resource, "hosts")
|
14
|
+
)
|
15
|
+
|
16
|
+
allow(resource).to receive(:post).with(id: id).and_return(
|
17
|
+
instance_double(RestClient::Response, "host response", body: '
|
18
|
+
{
|
19
|
+
"id": "test-host",
|
20
|
+
"userid": "hosts",
|
21
|
+
"created_at": "2015-11-13T22:57:14Z",
|
22
|
+
"ownerid": "cucumber:group:ops",
|
23
|
+
"roleid": "cucumber:host:test-host",
|
24
|
+
"resource_identifier": "cucumber:host:test-host",
|
25
|
+
"api_key": "14x82x72syhnnd1h8jj24zj1kqd2j09sjy3tddwxc35cmy5nx33ph7"
|
26
|
+
}
|
27
|
+
')
|
28
|
+
)
|
29
|
+
|
30
|
+
host = Conjur::API.host_factory_create_host token, id
|
31
|
+
|
32
|
+
expect(host).to be_a Conjur::Host
|
33
|
+
end
|
34
|
+
end
|
data/spec/api_spec.rb
CHANGED
@@ -60,11 +60,11 @@ describe Conjur::API do
|
|
60
60
|
context "after expiration" do
|
61
61
|
it 'it reads a new token' do
|
62
62
|
expect(Time.parse(api.token['timestamp'])).to be_within(5.seconds).of(Time.now)
|
63
|
-
|
63
|
+
|
64
64
|
time_travel 6.minutes
|
65
65
|
new_token = token.merge "timestamp" => Time.now.to_s
|
66
66
|
write_token new_token
|
67
|
-
|
67
|
+
|
68
68
|
expect(api.token).to eq(new_token)
|
69
69
|
end
|
70
70
|
end
|
@@ -85,10 +85,10 @@ describe Conjur::API do
|
|
85
85
|
it 'by refreshing' do
|
86
86
|
allow(Conjur::API).to receive(:authenticate).with(login, api_key, account: account).and_return token
|
87
87
|
expect(Time.parse(api.token['timestamp'])).to be_within(5.seconds).of(Time.now)
|
88
|
-
|
88
|
+
|
89
89
|
time_travel 6.minutes
|
90
90
|
new_token = token.merge "timestamp" => Time.now.to_s
|
91
|
-
|
91
|
+
|
92
92
|
expect(Conjur::API).to receive(:authenticate).with(login, api_key, account: account).and_return new_token
|
93
93
|
expect(api.token).to eq(new_token)
|
94
94
|
end
|
@@ -118,7 +118,7 @@ describe Conjur::API do
|
|
118
118
|
subject { super().credentials }
|
119
119
|
it { is_expected.to eq({ headers: { authorization: "Token token=\"#{Base64.strict_encode64(token.to_json)}\"" }, username: login }) }
|
120
120
|
end
|
121
|
-
|
121
|
+
|
122
122
|
context "with remote_ip" do
|
123
123
|
let(:remote_ip) { "66.0.0.1" }
|
124
124
|
describe '#credentials' do
|
@@ -153,7 +153,7 @@ describe Conjur::API do
|
|
153
153
|
context 'basic functioning' do
|
154
154
|
it_behaves_like 'it can clone itself'
|
155
155
|
end
|
156
|
-
|
156
|
+
|
157
157
|
context "forwarded for" do
|
158
158
|
let(:forwarded_for_header) { "66.0.0.1" }
|
159
159
|
let(:headers) { base_headers.merge(x_forwarded_for: forwarded_for_header) }
|
@@ -172,6 +172,55 @@ describe Conjur::API do
|
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
175
|
+
describe "#username" do
|
176
|
+
let(:jwt_payload) do
|
177
|
+
'eyJzdWIiOiJ1c2VyLTlhYjBiYmZiOWJlNjA5Yzk2ZjUyN2Y1YiIsImlhdCI6MTYwMzQ5MDA4MH0='
|
178
|
+
end
|
179
|
+
|
180
|
+
let(:jwt_header) do
|
181
|
+
'eyJhbGciOiJjb25qdXIub3JnL3Nsb3NpbG8vdjIiLCJraWQiOiI2MWZjOGRiZDM4MjA4NDll' \
|
182
|
+
'ZDI4YTZhYTAwMzFjNjM5MjkxZjJmMDQzNDVjYTU0MWI5NzUxMGQ5NjkyM2I3NDlmIn0='
|
183
|
+
end
|
184
|
+
|
185
|
+
let(:conjur_token) do
|
186
|
+
{
|
187
|
+
'data' => 'conjur-user-1234',
|
188
|
+
'timestamp' => Time.now.to_s
|
189
|
+
}
|
190
|
+
end
|
191
|
+
|
192
|
+
let(:jwt_token) do
|
193
|
+
{
|
194
|
+
'protected' => jwt_header,
|
195
|
+
'payload' => jwt_payload,
|
196
|
+
}
|
197
|
+
end
|
198
|
+
|
199
|
+
it "can correctly extract the username from old Conjur token" do
|
200
|
+
expect(Conjur::API.new_from_token(conjur_token).username).to(
|
201
|
+
eq('conjur-user-1234')
|
202
|
+
)
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'when using JWT token' do
|
206
|
+
it "can correctly extract username" do
|
207
|
+
expect(Conjur::API.new_from_token(jwt_token).username).to(
|
208
|
+
eq('user-9ab0bbfb9be609c96f527f5b')
|
209
|
+
)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "returns nil when JWT token has no payload field" do
|
213
|
+
no_payload_jwt_token = { 'protected' => jwt_header }
|
214
|
+
expect(Conjur::API.new_from_token(no_payload_jwt_token).username).to be_nil
|
215
|
+
end
|
216
|
+
|
217
|
+
it "returns nil when JWT token has no 'sub' field in payload" do
|
218
|
+
no_sub_token = { 'payload' => 'eyJpYXQiOjE2MDM0OTAwODB9' }
|
219
|
+
expect(Conjur::API.new_from_token(no_sub_token).username).to be_nil
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
175
224
|
describe "#current_role", logged_in: true do
|
176
225
|
context "when logged in as user" do
|
177
226
|
let(:login) { 'joerandom' }
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Conjur::BaseObject do
|
6
|
+
|
7
|
+
it "returns custom string for #inspect" do
|
8
|
+
id_str = 'foo:bar:baz'
|
9
|
+
base_obj = Conjur::BaseObject.new(Conjur::Id.new(id_str), { username: 'foo' })
|
10
|
+
expect(base_obj.inspect).to include("id='#{id_str}'")
|
11
|
+
expect(base_obj.inspect).to include(Conjur::BaseObject.name)
|
12
|
+
end
|
13
|
+
end
|
data/spec/cert_utils_spec.rb
CHANGED
@@ -78,4 +78,96 @@ RjvSxre4Xg2qlI9Laybb4oZ4g6DI8hRbL0VdFAsveg6SXg2RxgJcXeJUFw==
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
81
|
+
|
82
|
+
describe '.add_chained_cert' do
|
83
|
+
let(:one_certificate_chain) do
|
84
|
+
"""-----BEGIN CERTIFICATE-----
|
85
|
+
MIIDPjCCAiagAwIBAgIVAKW1gdmOFrXt6xB0iQmYQ4z8Pf+kMA0GCSqGSIb3DQEB
|
86
|
+
CwUAMD0xETAPBgNVBAoTCGN1Y3VtYmVyMRIwEAYDVQQLEwlDb25qdXIgQ0ExFDAS
|
87
|
+
BgNVBAMTC2N1a2UtbWFzdGVyMB4XDTE1MTAwNzE2MzAwNloXDTI1MTAwNDE2MzAw
|
88
|
+
NlowFjEUMBIGA1UEAwwLY3VrZS1tYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
89
|
+
DwAwggEKAoIBAQC9e8bGIHOLOypKA4lsLcAOcDLAq+ICuVxn9Vg0No0m32Ok/K7G
|
90
|
+
uEGtlC8RidObntblUwqdX2uP7mqAQm19j78UTl1KT97vMmmFrpVZ7oQvEm1FUq3t
|
91
|
+
FBmJglthJrSbpdZjLf7a7eL1NnunkfBdI1DK9QL9ndMjNwZNFbXhld4fC5zuSr/L
|
92
|
+
PxawSzTEsoTaB0Nw0DdRowaZgrPxc0hQsrj9OF20gTIJIYO7ctZzE/JJchmBzgI4
|
93
|
+
CdfAYg7zNS+0oc0ylV0CWMerQtLICI6BtiQ482bCuGYJ00NlDcdjd3w+A2cj7PrH
|
94
|
+
wH5UhtORL5Q6i9EfGGUCDbmfpiVD9Bd3ukbXAgMBAAGjXDBaMA4GA1UdDwEB/wQE
|
95
|
+
AwIFoDAdBgNVHQ4EFgQU2jmj7l5rSw0yVb/vlWAYkK/YBwkwKQYDVR0RBCIwIIIL
|
96
|
+
Y3VrZS1tYXN0ZXKCCWxvY2FsaG9zdIIGY29uanVyMA0GCSqGSIb3DQEBCwUAA4IB
|
97
|
+
AQBCepy6If67+sjuVnT9NGBmjnVaLa11kgGNEB1BZQnvCy0IN7gpLpshoZevxYDR
|
98
|
+
3DnPAetQiZ70CSmCwjL4x6AVxQy59rRj0Awl9E1dgFTYI3JxxgLsI9ePdIRVEPnH
|
99
|
+
dhXqPY5ZIZhvdHlLStjsXX7laaclEtMeWfSzxe4AmP/Sm/er4ks0gvLQU6/XJNIu
|
100
|
+
RnRH59ZB1mZMsIv9Ii790nnioYFR54JmQu1JsIib77ZdSXIJmxAtraJSTLcZbU1E
|
101
|
+
+SM3XCE423Xols7onyluMYDy3MCUTFwoVMRBcRWCAk5gcv6XvZDfLi6Zwdne6x3Y
|
102
|
+
bGenr4vsPuSFsycM03/EcQDT
|
103
|
+
-----END CERTIFICATE-----
|
104
|
+
"""
|
105
|
+
end
|
106
|
+
|
107
|
+
let(:two_certificates_chain) do
|
108
|
+
"""-----BEGIN CERTIFICATE-----
|
109
|
+
MIIDPjCCAiagAwIBAgIVAKW1gdmOFrXt6xB0iQmYQ4z8Pf+kMA0GCSqGSIb3DQEB
|
110
|
+
CwUAMD0xETAPBgNVBAoTCGN1Y3VtYmVyMRIwEAYDVQQLEwlDb25qdXIgQ0ExFDAS
|
111
|
+
BgNVBAMTC2N1a2UtbWFzdGVyMB4XDTE1MTAwNzE2MzAwNloXDTI1MTAwNDE2MzAw
|
112
|
+
NlowFjEUMBIGA1UEAwwLY3VrZS1tYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
113
|
+
DwAwggEKAoIBAQC9e8bGIHOLOypKA4lsLcAOcDLAq+ICuVxn9Vg0No0m32Ok/K7G
|
114
|
+
uEGtlC8RidObntblUwqdX2uP7mqAQm19j78UTl1KT97vMmmFrpVZ7oQvEm1FUq3t
|
115
|
+
FBmJglthJrSbpdZjLf7a7eL1NnunkfBdI1DK9QL9ndMjNwZNFbXhld4fC5zuSr/L
|
116
|
+
PxawSzTEsoTaB0Nw0DdRowaZgrPxc0hQsrj9OF20gTIJIYO7ctZzE/JJchmBzgI4
|
117
|
+
CdfAYg7zNS+0oc0ylV0CWMerQtLICI6BtiQ482bCuGYJ00NlDcdjd3w+A2cj7PrH
|
118
|
+
wH5UhtORL5Q6i9EfGGUCDbmfpiVD9Bd3ukbXAgMBAAGjXDBaMA4GA1UdDwEB/wQE
|
119
|
+
AwIFoDAdBgNVHQ4EFgQU2jmj7l5rSw0yVb/vlWAYkK/YBwkwKQYDVR0RBCIwIIIL
|
120
|
+
Y3VrZS1tYXN0ZXKCCWxvY2FsaG9zdIIGY29uanVyMA0GCSqGSIb3DQEBCwUAA4IB
|
121
|
+
AQBCepy6If67+sjuVnT9NGBmjnVaLa11kgGNEB1BZQnvCy0IN7gpLpshoZevxYDR
|
122
|
+
3DnPAetQiZ70CSmCwjL4x6AVxQy59rRj0Awl9E1dgFTYI3JxxgLsI9ePdIRVEPnH
|
123
|
+
dhXqPY5ZIZhvdHlLStjsXX7laaclEtMeWfSzxe4AmP/Sm/er4ks0gvLQU6/XJNIu
|
124
|
+
RnRH59ZB1mZMsIv9Ii790nnioYFR54JmQu1JsIib77ZdSXIJmxAtraJSTLcZbU1E
|
125
|
+
+SM3XCE423Xols7onyluMYDy3MCUTFwoVMRBcRWCAk5gcv6XvZDfLi6Zwdne6x3Y
|
126
|
+
bGenr4vsPuSFsycM03/EcQDT
|
127
|
+
-----END CERTIFICATE-----
|
128
|
+
-----BEGIN CERTIFICATE-----
|
129
|
+
MIIDhzCCAm+gAwIBAgIJAJnsrJ1+j9MhMA0GCSqGSIb3DQEBCwUAMD0xETAPBgNV
|
130
|
+
BAoTCGN1Y3VtYmVyMRIwEAYDVQQLEwlDb25qdXIgQ0ExFDASBgNVBAMTC2N1a2Ut
|
131
|
+
bWFzdGVyMB4XDTE1MTAwNzE2MzAwM1oXDTI1MTAwNDE2MzAwM1owPTERMA8GA1UE
|
132
|
+
ChMIY3VjdW1iZXIxEjAQBgNVBAsTCUNvbmp1ciBDQTEUMBIGA1UEAxMLY3VrZS1t
|
133
|
+
YXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsuZ06Ld4JDhxZ
|
134
|
+
FcxKVxu7MTjXVv6W8pI7qFKmgr39aNqmDpKYJ1H9aM+r9zaTAeithpM4wJpVswkJ
|
135
|
+
d0RSuKdm1LOx11yHLyZ1OvlPHFhsVWdZIQZ6R9srhPYBUCMem4sHR5IAcBBX+HkR
|
136
|
+
35gaPYUl1uFV/9zCniekt92Kdta+it1WL7XinXTBURlhDawiD/kv1C9x6dICEJVe
|
137
|
+
IT/jRohmqHAoM/JSOQTthaDli3Qvu5K8XAx8UXvWVmv3eStZFVDbC4ZEueRd9KAe
|
138
|
+
4IZ5FxdpFYkPBgt2lBYeydYKRShyYrDKye1uJBDkeplNaYW4cS4mOhYuRkdKn7MH
|
139
|
+
uY/xb1lFAgMBAAGjgYkwgYYwKQYDVR0RBCIwIIILY3VrZS1tYXN0ZXKCCWxvY2Fs
|
140
|
+
aG9zdIIGY29uanVyMB0GA1UdDgQWBBRHpGF7aQbHdORYgQKDC2hV6NzEKzAfBgNV
|
141
|
+
HSMEGDAWgBRHpGF7aQbHdORYgQKDC2hV6NzEKzAMBgNVHRMEBTADAQH/MAsGA1Ud
|
142
|
+
DwQEAwIB5jANBgkqhkiG9w0BAQsFAAOCAQEAGZT9Wek1hYluIVaxu03wSKCKIJ4p
|
143
|
+
KxTHw+mLDapg1y9t3Fa/5IQQK0Bx0xGU2qWiQKjda3vdFPJWO6l6XJvsUY5Nwtm5
|
144
|
+
Gcsk8l3L/zWCrjrFTH3TdVad5E+DTwVhThelmEjw68AyM+WuOL61j0MItd9mLW74
|
145
|
+
Lv2zouj9nQBdnUBHWQ0EL/9d5cfaCVu/bFlDfYt7Yj0IzXCuaWZfJeHodU1hmqVX
|
146
|
+
BvYRjnTB2LSxfmSnkrCeFPmhE11bWVtsLIdrGIgtEMX0/s9xg58QuNnva1U3pJsW
|
147
|
+
RjvSxre4Xg2qlI9Laybb4oZ4g6DI8hRbL0VdFAsveg6SXg2RxgJcXeJUFw==
|
148
|
+
-----END CERTIFICATE-----
|
149
|
+
"""
|
150
|
+
end
|
151
|
+
|
152
|
+
let(:store){ double('default store') }
|
153
|
+
|
154
|
+
context 'with one certificate in the chain' do
|
155
|
+
subject{ Conjur::CertUtils.add_chained_cert(store, one_certificate_chain) }
|
156
|
+
|
157
|
+
it 'adds one certificate to the store' do
|
158
|
+
expect(store).to receive(:add_cert).once
|
159
|
+
expect(subject).to be_truthy
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'with two certificate in the chain' do
|
164
|
+
subject{ Conjur::CertUtils.add_chained_cert(store, two_certificates_chain) }
|
165
|
+
|
166
|
+
it 'adds both certificate to the store' do
|
167
|
+
expect(store).to receive(:add_cert).twice
|
168
|
+
expect(subject).to be_truthy
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
81
173
|
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -29,6 +29,28 @@ describe Conjur::Configuration do
|
|
29
29
|
configuration.account = "the-account"
|
30
30
|
configuration.appliance_url = "https://conjur/api"
|
31
31
|
}
|
32
|
+
|
33
|
+
it "rest_client_options defaults" do
|
34
|
+
expected = {
|
35
|
+
ssl_cert_store: OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE
|
36
|
+
}
|
37
|
+
expect(configuration.rest_client_options).to eq(expected)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "rest_client_options propagate to RestClient::Resource" do
|
41
|
+
expected = {
|
42
|
+
ssl_ca_file: "ca_certificate.pem",
|
43
|
+
proxy: "http://proxy.example.com/"
|
44
|
+
}
|
45
|
+
configuration.rest_client_options = {
|
46
|
+
ssl_ca_file: "ca_certificate.pem",
|
47
|
+
proxy: "http://proxy.example.com/"
|
48
|
+
}
|
49
|
+
|
50
|
+
resource = Conjur::API.url_for(:authn_login, *["account", "username", "password"])
|
51
|
+
expect(resource.options).to include(expected)
|
52
|
+
end
|
53
|
+
|
32
54
|
it "can still be changed by changing the appliance_url" do
|
33
55
|
configuration.appliance_url = "https://other/api"
|
34
56
|
expect(configuration.core_url).to eq "https://other/api"
|
@@ -40,7 +62,7 @@ describe Conjur::Configuration do
|
|
40
62
|
expect(configuration.authn_url).to eq "http://authn-docker"
|
41
63
|
end
|
42
64
|
|
43
|
-
context "and duplicated" do
|
65
|
+
context "and duplicated" do
|
44
66
|
subject { configuration.clone override_options }
|
45
67
|
let(:override_options) { Hash.new }
|
46
68
|
|
@@ -72,7 +94,7 @@ describe Conjur::Configuration do
|
|
72
94
|
end
|
73
95
|
end
|
74
96
|
end
|
75
|
-
|
97
|
+
|
76
98
|
describe "url generation" do
|
77
99
|
describe 'authn_url' do
|
78
100
|
before {
|
@@ -281,7 +303,7 @@ RjvSxre4Xg2qlI9Laybb4oZ4g6DI8hRbL0VdFAsveg6SXg2RxgJcXeJUFw==
|
|
281
303
|
expect(subject).to be_truthy
|
282
304
|
end
|
283
305
|
end
|
284
|
-
|
306
|
+
|
285
307
|
end
|
286
308
|
|
287
309
|
context 'when cert file is not readable' do
|
data/spec/id_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Conjur::Id do
|
6
|
+
it 'requires the id to be fully qualified' do
|
7
|
+
expect { Conjur::Id.new 'foo:bar' }.to raise_error ArgumentError
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'can be constructed from a string' do
|
11
|
+
id = Conjur::Id.new 'foo:bar:baz'
|
12
|
+
expect(id).to be
|
13
|
+
{
|
14
|
+
account: 'foo',
|
15
|
+
kind: 'bar',
|
16
|
+
identifier: 'baz'
|
17
|
+
}.each { |k, v| expect(id.send(k)).to eq v }
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'can be constructed from an array' do
|
21
|
+
id = Conjur::Id.new %w(foo bar baz)
|
22
|
+
expect(id).to be
|
23
|
+
{
|
24
|
+
account: 'foo',
|
25
|
+
kind: 'bar',
|
26
|
+
identifier: 'baz'
|
27
|
+
}.each { |k, v| expect(id.send(k)).to eq v }
|
28
|
+
end
|
29
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
require 'simplecov'
|
2
|
+
require 'simplecov-cobertura'
|
3
|
+
|
4
|
+
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
|
2
5
|
SimpleCov.start
|
3
6
|
|
4
7
|
require 'rubygems'
|
@@ -81,7 +84,7 @@ end
|
|
81
84
|
require 'conjur/api'
|
82
85
|
|
83
86
|
KIND="asset_kind"
|
84
|
-
ID="unique_id"
|
87
|
+
ID="unique_id"
|
85
88
|
ROLE='<role>'
|
86
89
|
MEMBER='<member>'
|
87
90
|
PRIVILEGE='<privilege>'
|
data/spec/ssl_spec.rb
CHANGED
@@ -16,16 +16,14 @@ describe 'SSL connection' do
|
|
16
16
|
|
17
17
|
context 'with certificate added to the default OpenSSL cert store' do
|
18
18
|
before do
|
19
|
-
|
20
|
-
store.add_cert cert
|
21
|
-
stub_const 'OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE', store
|
19
|
+
cert_store.add_cert(cert)
|
22
20
|
end
|
23
21
|
|
24
22
|
it 'works' do
|
25
23
|
expect { Conjur::API.login 'foo', 'bar', account: "the-account" }.to raise_error RestClient::ResourceNotFound
|
26
24
|
end
|
27
25
|
end
|
28
|
-
|
26
|
+
|
29
27
|
let(:server) do
|
30
28
|
server = WEBrick::HTTPServer.new \
|
31
29
|
Port: 0, SSLEnable: true,
|
@@ -33,8 +31,14 @@ describe 'SSL connection' do
|
|
33
31
|
SSLCertificate: cert, SSLPrivateKey: key
|
34
32
|
end
|
35
33
|
let(:port) { server.config[:Port] }
|
34
|
+
let(:cert_store) { OpenSSL::X509::Store.new }
|
36
35
|
|
37
36
|
before do
|
37
|
+
# Reset configuration to allow each test to use its own stub
|
38
|
+
# of OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE.
|
39
|
+
Conjur.configuration = nil
|
40
|
+
stub_const 'OpenSSL::SSL::SSLContext::DEFAULT_CERT_STORE', cert_store
|
41
|
+
|
38
42
|
allow(Conjur.configuration).to receive(:authn_url).and_return "https://localhost:#{port}"
|
39
43
|
end
|
40
44
|
|
@@ -50,15 +54,23 @@ describe 'SSL connection' do
|
|
50
54
|
let(:cert) do
|
51
55
|
OpenSSL::X509::Certificate.new """
|
52
56
|
-----BEGIN CERTIFICATE-----
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
MIIDCzCCAfOgAwIBAgIUaApjB95cJZlMTwDg4EBk4Mf1y4swDQYJKoZIhvcNAQEL
|
58
|
+
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTIxMDQyODIxNTA1OFoYDzQ3NTkw
|
59
|
+
MzI1MjE1MDU4WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
|
60
|
+
AQUAA4IBDwAwggEKAoIBAQC+MIx1LCzBeAl7kHfI21wYmA6W8luyq14+DecaQPMd
|
61
|
+
bW7fMlHSMJC/nlFDQyqmfYfKlVCiJRV/QTdUtA9hCytPlEKjlVmm4WIYLKfjj8Sp
|
62
|
+
A+X9VURk75Fz+Z7UsF8u2J3pF9wFfhBzznwePlFdcWYyQMIRtghoHk/WSsbJVXVQ
|
63
|
+
so7+0BLFyMYB3otfCyK+H/iyoXWLZll2irYZJedVm/lyTlnc9dT1XDAWWI8kSeUV
|
64
|
+
lCkEulqOf8qZyU7wNUafRkzBuYkR7ddp1Qdkq+QYw7blmfZXyJbAYSt4gEMyDMk8
|
65
|
+
ArScP8j+Efz5D54wS7fZFwmQp41+iP5WTxGsSU3dh44fAgMBAAGjUzBRMB0GA1Ud
|
66
|
+
DgQWBBS4ZJDxXOs8rK3+SyfLopDFqK0IWDAfBgNVHSMEGDAWgBS4ZJDxXOs8rK3+
|
67
|
+
SyfLopDFqK0IWDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAE
|
68
|
+
WuzjqQ/gyho/pluX31hq7EMAFgqqz7ECN6DqmvpqabMD6s1kQ662KTo7gCBEcNtA
|
69
|
+
nC7QycFp4v/Cr8+aUEa1W3+q2MqbmshORonUrLE/vxejK+NUvhSCWnmrM8v60zhR
|
70
|
+
pn9lSSgQCBKWDgaU0VQVn0I9MuexeAj64Qv2uUHnZK3QUx+Gk3uurTmhKEN5FI+D
|
71
|
+
sC7xO0qquTZ1Vv1EkLEso4dnFVW84EjdfmfeiW6JmHO7z1p1ebGsRwoQead/qTKw
|
72
|
+
ze+Y1A1w3GzuhDo55aHlWE/Wvnou0aM3O9gUd++a2j+XJ2P7qaTB/L7SJk4qZ9RA
|
73
|
+
t2PbKVP+tyZjXKtXmgzp
|
62
74
|
-----END CERTIFICATE-----
|
63
75
|
""".lines.map(&:strip).join("\n")
|
64
76
|
end
|
@@ -66,19 +78,31 @@ describe 'SSL connection' do
|
|
66
78
|
let(:key) do
|
67
79
|
OpenSSL::PKey.read """
|
68
80
|
-----BEGIN RSA PRIVATE KEY-----
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
81
|
+
MIIEowIBAAKCAQEAvjCMdSwswXgJe5B3yNtcGJgOlvJbsqtePg3nGkDzHW1u3zJR
|
82
|
+
0jCQv55RQ0Mqpn2HypVQoiUVf0E3VLQPYQsrT5RCo5VZpuFiGCyn44/EqQPl/VVE
|
83
|
+
ZO+Rc/me1LBfLtid6RfcBX4Qc858Hj5RXXFmMkDCEbYIaB5P1krGyVV1ULKO/tAS
|
84
|
+
xcjGAd6LXwsivh/4sqF1i2ZZdoq2GSXnVZv5ck5Z3PXU9VwwFliPJEnlFZQpBLpa
|
85
|
+
jn/KmclO8DVGn0ZMwbmJEe3XadUHZKvkGMO25Zn2V8iWwGEreIBDMgzJPAK0nD/I
|
86
|
+
/hH8+Q+eMEu32RcJkKeNfoj+Vk8RrElN3YeOHwIDAQABAoIBAQCnW0ctkDqt3/fQ
|
87
|
+
MHcHWue2iI9GCmvgU+WxC0DSHFcSDQrkAn53S98DjseJPaBZMtr7y9pRY/p/qR6M
|
88
|
+
PYnO5iotc5QUKEbkjy1nglwV5Zuy8kg+XPq7Kwg+GmjGVZDcQybpRuKIPr8xeIBF
|
89
|
+
iKbGaBP6ontjZGAPZqTwN4qm/bkm0QRQkMEVQLpBaOlXjl0BCknhCMgyNA1F0jGc
|
90
|
+
HLqJpFO46qvWDkDaKriMY/ezrkGYxlvV8xGJ2lzoaNWBsQeMXtcDJXuFMJO3lZl4
|
91
|
+
VUjeNbyPprUzL6/kLZGMVFdRWhzKAluJEy3B6zybY4xxmgmifqn8/OxIaT172IXN
|
92
|
+
KACuEorpAoGBAOYZEfuON+73dcstpjq3062+XUOxAAc77aFcGFQ2pqDTUtvoR05R
|
93
|
+
o0uXrSuQqt0/FJVdZqdDx1and6idI7j/LfkOwvmPPg2dJIwKV73T2HdR7BpJaYlI
|
94
|
+
KS6Bgl0AiW2ibjZJbBFJMiINb2tRGeYcOPfWlis309D2DXxl1f1TJTKTAoGBANOZ
|
95
|
+
aDH1VJXh7rdAHrwNonTjoCeYKG7oAh0WTfqmCqcBjAkXsVc7dBd/98XKGS5LPRtl
|
96
|
+
dIaJdYngeYyH5Ey5O2l/63tk0d4sqE8l+GVy+OHFn2AZMuaVXS0JXIQspn4s/U7F
|
97
|
+
CuawmFszE8fv41WgVNhF00ijheoRz/X19yu0ULHFAoGAYmJZ1AutUtowXZ25M+Yh
|
98
|
+
9motCqKF9pHjO1lbdbagbKevCCQ7SPuTLOE/xB7pUAyGyo7TM7XBaAXXHhuCiLlj
|
99
|
+
eNic+YQL7lpApDhP5/TK28oFf//fxjk6ko4Bpa5zFJOdOE0QjhuT+gdwmpxkzIVI
|
100
|
+
vn/cWcJXKUPr5ELOyrBgeU0CgYBWqIUbsLWrjJQPSJtNuOfHp1F35cDpausyrmfR
|
101
|
+
Nx81tlR7hNCEQT0SQr5eqp4Vb4rfJXXLg5A3n08oVp8RLOtAEbuHFYs9ylxDzfEk
|
102
|
+
2ylCjYTv/mHyPUmjoCnbl8237wTutZP5VmmPMCPxxjT8ZGVbDX2ySgYWDqV0vf80
|
103
|
+
TuydYQKBgG24Wpes1CJmKiuWGnPi5I/+iIKZRfpEGidpjnsktkr3O+VZSZNQtDfC
|
104
|
+
uWp/NgMxzxXxYdmmaQTwektB5axrsPUnxxiHmb8KkVU1IcMpYvUulFYiKVvFx+JJ
|
105
|
+
bx/fkItCZ4AP3CG2Onz8xZdosg+c+MEdIlCrg94dA1EmHewCt2Hv
|
82
106
|
-----END RSA PRIVATE KEY-----
|
83
107
|
""".lines.map(&:strip).join("\n")
|
84
108
|
end
|