conjur-api 5.3.0 → 5.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +10 -0
  3. data/.github/CODEOWNERS +10 -0
  4. data/.github/ISSUE_TEMPLATE/bug.md +42 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +27 -0
  6. data/.github/PULL_REQUEST_TEMPLATE.md +21 -0
  7. data/.gitignore +1 -0
  8. data/.gitleaks.toml +219 -0
  9. data/.overcommit.yml +16 -0
  10. data/.rubocop.yml +3 -0
  11. data/.rubocop_settings.yml +86 -0
  12. data/.rubocop_todo.yml +709 -0
  13. data/CHANGELOG.md +373 -181
  14. data/CONTRIBUTING.md +141 -0
  15. data/Gemfile +1 -1
  16. data/Jenkinsfile +27 -29
  17. data/LICENSE +202 -0
  18. data/README.md +34 -117
  19. data/SECURITY.md +42 -0
  20. data/bin/parse-changelog.sh +12 -0
  21. data/ci/codeclimate.dockerfile +6 -0
  22. data/conjur-api.gemspec +4 -1
  23. data/docker-compose.yml +2 -0
  24. data/features/authenticators.feature +33 -0
  25. data/features/host.feature +39 -9
  26. data/features/step_definitions/api_steps.rb +14 -3
  27. data/features/step_definitions/policy_steps.rb +40 -0
  28. data/features/support/env.rb +2 -0
  29. data/features/update_password.feature +2 -2
  30. data/features/user.feature +47 -6
  31. data/features_v4/support/env.rb +2 -0
  32. data/lib/conjur-api/version.rb +2 -2
  33. data/lib/conjur/acts_as_role.rb +15 -19
  34. data/lib/conjur/acts_as_user.rb +5 -1
  35. data/lib/conjur/api.rb +1 -18
  36. data/lib/conjur/api/authenticators.rb +35 -0
  37. data/lib/conjur/api/authn.rb +3 -3
  38. data/lib/conjur/api/host_factories.rb +20 -19
  39. data/lib/conjur/api/resources.rb +17 -21
  40. data/lib/conjur/api/router/v4.rb +80 -23
  41. data/lib/conjur/api/router/v5.rb +117 -23
  42. data/lib/conjur/base.rb +19 -5
  43. data/lib/conjur/base_object.rb +31 -26
  44. data/lib/conjur/build_object.rb +13 -20
  45. data/lib/conjur/cert_utils.rb +14 -0
  46. data/lib/conjur/configuration.rb +46 -24
  47. data/lib/conjur/id.rb +22 -19
  48. data/lib/conjur/role_grant.rb +13 -18
  49. data/spec/api/host_factories_spec.rb +34 -0
  50. data/spec/api_spec.rb +55 -6
  51. data/spec/base_object_spec.rb +13 -0
  52. data/spec/cert_utils_spec.rb +92 -0
  53. data/spec/configuration_spec.rb +25 -3
  54. data/spec/id_spec.rb +29 -0
  55. data/spec/spec_helper.rb +4 -1
  56. data/spec/ssl_spec.rb +50 -26
  57. data/spec/uri_escape_spec.rb +14 -2
  58. data/test.sh +23 -1
  59. metadata +31 -14
  60. data/LICENSE.md +0 -195
  61. data/lib/conjur/cast.rb +0 -41
  62. data/spec/cast_spec.rb +0 -21
  63. data/spec/vendor/rest_client_spec.rb +0 -41
@@ -1,23 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2013-2018 CyberArk Ltd.
1
4
  #
2
- # Copyright 2013-2017 Conjur Inc
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy of
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
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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
@@ -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
@@ -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
- store = OpenSSL::X509::Store.new
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
- MIIBpDCCAQ2gAwIBAgIJALVPXQuF0w39MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
54
- BAMMCWxvY2FsaG9zdDAeFw0xNTAyMTQxNTE0MDFaFw0yNTAyMTExNTE0MDFaMBQx
55
- EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
56
- n+IqEsmbuZk7E2GdPZpBxETjXC+dGze5XlZHPyKviekQ9sachAsBWApVrjM2QDtf
57
- KOwa6GuBqGQ0bdl4Ui7I0CIGB4a0UJHU/EvuDhI1cTzAVVWemW1QaqKxI/2xDgs9
58
- bqY471iVirRiSYD+6lm2pFYqOnnR/d+QKIMXhPOi0DMCAwEAATANBgkqhkiG9w0B
59
- AQsFAAOBgQCSPchDKAiVPNJlRkaY9KPIXfPbFX6h/+ilJRl1xtHqY+y4SxURbnU0
60
- fbYVnapKiuMnrnxTWXwl1z1iMbuuzjUC0RDz8F9pZkQ9IJpBSOaSfyUmk1JrrBRU
61
- INyaxnJjtc7YIzW1Yz7+aKtzZAQuFXNhiQa+CIIGeWrpzbExo2ce3Q==
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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
82
106
  -----END RSA PRIVATE KEY-----
83
107
  """.lines.map(&:strip).join("\n")
84
108
  end