conjur-cli 4.27.0 → 4.28.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 269e8ed2d2f6b69c7562c3c40fb4f34ff96e0788
4
- data.tar.gz: db804ffbb9219ece6834a554aa142a76a731fab5
3
+ metadata.gz: 8e6ae515f092a2c41963452c0a2fcc0aa8ec0f2c
4
+ data.tar.gz: 0ecbfa2d23e3dcc763afa1be03e978b709c515c0
5
5
  SHA512:
6
- metadata.gz: 0b77f202ea2b76ec7593d1bd98c2799b4771ce6a9e05564cde88c6dc09150097dfd23fb9a72902c53886aa1f85d0472f32185a42d6ae230209066245fa80c91d
7
- data.tar.gz: 39a144652fc0ae5dbfc59af883bbfaab2deb6c87a8a59da62403500eecf1497f77f5797e81ccee68f21892efe185d0a1a53726133f48b990436472e6165a673b
6
+ metadata.gz: f587e417fdcb8a9f0832ce3682706e4363cf8a3b69c3e14eb965ffdff84f157c7578387dd9f5e8c860eb5fcd912d6e263ee28b71d6961c1015f45a64a70a4c0b
7
+ data.tar.gz: 558101ef2d363276511d821b217563ffaec1595b0c1799a4f785e3eec7663aec40a95d5fec8f20fc8d12ca19e21a680c5a96ffae194c4849b1433ab53fc3d10d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 4.28.0
2
+ * Add `conjur policy retire` to allow retiring a policy.
3
+ * Fix `--as-group` and `--as-role` options for `conjur policy load`. Either can now be used to specify ownership of the policy.
4
+ * Fix `--follow` option for `conjur audit`.
5
+ * Remove support for per-project `.conjurrc` files.
6
+
1
7
  # 4.27.0
2
8
 
3
9
  * New commands `elevate` and `reveal` for execution of privileged commands on Conjur 4.5+.
data/Gemfile CHANGED
@@ -1,5 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ #ruby=ruby-2.1.5
3
4
  #ruby-gemset=conjur-cli
4
5
 
5
6
  # Specify your gem's dependencies in conjur.gemspec
@@ -0,0 +1,16 @@
1
+ Feature: Fetch audit events
2
+
3
+ Background:
4
+ Given I successfully run `conjur variable create $ns/secret MY_SECRET`
5
+ And I successfully run `conjur variable value $ns/secret`
6
+
7
+ Scenario: Fetch works
8
+ When I successfully run `conjur audit resource -s variable:$ns/secret`
9
+ Then the output should match /checked that they can execute .*:variable:.*secret/
10
+
11
+ Scenario: Follow works
12
+ # Implementation constraints prevent an exit code of 0 when using
13
+ # --follow and --limit, so can't say "When I run successfully..."
14
+ When I run `conjur audit resource -s -f -l 2 variable:$ns/secret`
15
+ Then the output should match /checked that they can execute .*:variable:.*secret/
16
+
@@ -0,0 +1,31 @@
1
+ Feature: Loading a policy can specify the policy's admin
2
+
3
+ Background:
4
+ Given I successfully run `conjur group create $ns/admin`
5
+ And a file named "policy.rb" with:
6
+ """
7
+ policy 'test-policy-1.0' do
8
+ user "test_user"
9
+ end
10
+ """
11
+
12
+ Scenario: --as-group works
13
+ When I run `conjur policy load --as-group $ns/admin --collection $ns` interactively
14
+ And I pipe in the file "policy.rb"
15
+ And the exit status should be 0
16
+ When I run `conjur role members policy:$ns/test-policy-1.0`
17
+ Then the output from "conjur role members policy:$ns/test-policy-1.0" should match /group:.*$ns.admin/
18
+
19
+ Scenario: --as-role works
20
+ When I run `conjur policy load --as-role group:$ns/admin --collection $ns` interactively
21
+ And I pipe in the file "policy.rb"
22
+ And the exit status should be 0
23
+ When I run `conjur role members policy:$ns/test-policy-1.0`
24
+ Then the output from "conjur role members policy:$ns/test-policy-1.0" should match /group:.*$ns.admin/
25
+
26
+ Scenario: --as-group doesn't interfere with policy ownership of other resources
27
+ When I run `conjur policy load --as-group $ns/admin --collection $ns` interactively
28
+ And I pipe in the file "policy.rb"
29
+ And the exit status should be 0
30
+ When I run `conjur resource show user:test_user@$ns-test-policy-1-0 | jsonfield owner`
31
+ Then the output from "conjur resource show user:test_user@$ns-test-policy-1-0 | jsonfield owner" should match /policy:$ns.test-policy-1.0/
@@ -0,0 +1,17 @@
1
+ Feature: Resources created by a policy are owned by the policy
2
+
3
+ Background:
4
+ Given a file named "policy.rb" with:
5
+ """
6
+ policy 'test-policy-1.0' do
7
+ resource 'webservice', 'web1'
8
+ end
9
+ """
10
+
11
+ Scenario: resource is create with correct ownership
12
+ When I run `conjur policy load --collection $ns` interactively
13
+ And I pipe in the file "policy.rb"
14
+ And the exit status should be 0
15
+ When I run `conjur resource show webservice:$ns/test-policy-1.0/web1 | jsonfield owner`
16
+ Then the output from "conjur resource show webservice:$ns/test-policy-1.0/web1 | jsonfield owner" should match /policy:$ns.test-policy-1.0/
17
+
@@ -0,0 +1,15 @@
1
+ Feature: Retire a policy
2
+ Background:
3
+ Given a file named "policy.rb" with:
4
+ """
5
+ policy 'test-policy-1.0' do
6
+ end
7
+ """
8
+ And I run `conjur policy load --as-role user:admin@$ns --collection $ns` interactively
9
+ And I pipe in the file "policy.rb"
10
+ And the exit status should be 0
11
+
12
+ @wip
13
+ Scenario: Basic retirement
14
+ Then I successfully run `conjur policy retire -d user:attic@$ns $ns/test-policy-1.0`
15
+
@@ -19,3 +19,7 @@ Then /^it prints the path to temporary file which contains: '(.*)'$/ do |content
19
19
  actual_content=File.read(filename) rescue ""
20
20
  expect(actual_content).to match(content)
21
21
  end
22
+
23
+ Then /^the output from "([^"]*)" should match \/([^\/]*)\/$/ do |cmd, expected|
24
+ assert_matching_output(expected, output_from(cmd))
25
+ end
@@ -17,7 +17,11 @@ Then(/^the model should contain "(.*?)" \/(.*?)\/$/) do |kind, id|
17
17
  end
18
18
  Then(/^the "(.*?)" "(.*?)" should be owned by "(.*?)"$/) do |kind, id, owner|
19
19
  step "the model should contain \"#{kind}\" \"#{id}\""
20
- @mock_api.thing(kind, id).ownerid.should == owner
20
+ if kind == 'role' || kind == 'resource'
21
+ @mock_api.thing(kind, id).acting_as.should == owner
22
+ else
23
+ @mock_api.thing(kind, id).ownerid.should == owner
24
+ end
21
25
  end
22
26
 
23
27
  Then(/^the "(.*?)" "(.*?)" should not have an owner$/) do |kind, id|
@@ -22,7 +22,8 @@ class Conjur::Command
22
22
  message_part = e[:audit_message] ? "; message: #{e[:audit_message]}" : ""
23
23
  statement = [ action_part, actor_part, resource_part, allowed_part ].compact.join(" ")
24
24
  "reported #{statement}"+ message_part
25
- }
25
+ },
26
+ 'conjur:use_extra_privilege' => lambda{|e| "requested extra privilege #{e[:privilege]}"}
26
27
  }
27
28
 
28
29
  def ssh_sudo_message(e)
@@ -70,13 +71,26 @@ class Conjur::Command
70
71
  end
71
72
 
72
73
  def show_audit_events events, options
74
+ @count ||= 0
75
+
73
76
  events = [events] unless events.kind_of?(Array)
74
77
  # offset and limit options seem to be broken. this is a temporary workaround (should be applied on server-side eventually)
75
78
  events = events.drop(options[:offset]) if options[:offset]
76
79
  events = events.take(options[:limit]) if options[:limit]
77
80
 
78
81
  if options[:short]
79
- events.each{|e| puts short_event_format(e)}
82
+ events.each do |e|
83
+ puts short_event_format(e)
84
+
85
+ # Undocumented, but for the sake of testing.... Allow
86
+ # --limit with --follow. When we hit the limit, bail out
87
+ # immediately: don't raise any exceptions, don't print any
88
+ # messages, just exit with status 0.
89
+ @count += 1
90
+ if options[:follow] && @count == options[:limit]
91
+ exit_now! 0
92
+ end
93
+ end
80
94
  else
81
95
  events.each{|e| puts JSON.pretty_generate(e) }
82
96
  end
@@ -50,7 +50,7 @@ ids.
50
50
 
51
51
  The first path element of each id is the collection. Policies are separated into collections
52
52
  according to software development lifecycle. The default collection for a policy is $USER@$HOSTNAME,
53
- in other words, the username and hostname on which the policy is created. This is approriate for
53
+ in other words, the username and hostname on which the policy is created. This is appropriate for
54
54
  policy development and local testing. Once tested, policies can be created in more official
55
55
  environments such as ci, stage, and production.
56
56
 
@@ -84,5 +84,33 @@ owner of the policy role is the logged-in user (you), as always.
84
84
  end
85
85
  end
86
86
  end
87
+
88
+ policy.desc 'Decommision a policy'
89
+ policy.arg_name 'POLICY'
90
+ policy.command :retire do |c|
91
+ retire_options c
92
+
93
+ c.action do |global_options, options, args |
94
+ id = "policy:#{require_arg(args, 'POLICY')}"
95
+
96
+ # policy isn't a rolsource (yet), but we can pretend
97
+ Policy = Struct.new(:role, :resource)
98
+ policy = Policy.new(api.role(id), api.resource(id))
99
+
100
+ validate_retire_privileges(policy, options)
101
+
102
+ retire_resource(policy)
103
+
104
+ # The policy resource is owned by the policy role. Having the
105
+ # policy role is what allows us to administer it. So, we have
106
+ # to give the resource away before we can revoke the role.
107
+ give_away_resource(policy, options)
108
+
109
+ retire_role(policy)
110
+
111
+ puts 'Policy retired'
112
+ end
113
+ end
114
+
87
115
  end
88
116
  end
data/lib/conjur/config.rb CHANGED
@@ -37,11 +37,11 @@ module Conjur
37
37
  homefile = File.expand_path "~/.conjurrc"
38
38
  pwdfile = File.expand_path ".conjurrc"
39
39
  if homefile != pwdfile && File.file?(pwdfile)
40
- $stderr.puts "WARNING: .conjurrc file from current directory is " +
41
- "used. This behaviour is deprecated. Use ENV['CONJURRC'] to " +
42
- "explicitly define custom configuration file if needed"
40
+ $stderr.puts """NOTE:\t.conjurrc file detected in the current directory.\n"\
41
+ "\tIt's no longer consulted in this version. Please explicitly\n"\
42
+ "\tset CONJURRC=./.conjurrc if you're sure you want to use it."
43
43
  end
44
- [ homefile, pwdfile ]
44
+ [ homefile ]
45
45
  end
46
46
  end
47
47
 
@@ -194,6 +194,13 @@ module Conjur
194
194
 
195
195
  unless (obj = api.send(find_method, id)) && obj.exists?
196
196
  options = expand_options(options)
197
+
198
+ # create_resource and create_role expect :acting_as to
199
+ # specify the "owning" role.
200
+ if create_method == :create_resource || create_method == :create_role
201
+ options[:acting_as] = options.delete(:ownerid) if options[:ownerid]
202
+ end
203
+
197
204
  obj = if create_method == :create_variable
198
205
  #NOTE: it duplicates logic of "create_variable" method above
199
206
  # https://basecamp.com/1949725/projects/4268938-api-version-4-x/todos/84972543-low-variable
@@ -19,6 +19,6 @@
19
19
  # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
20
  #
21
21
  module Conjur
22
- VERSION = "4.27.0"
22
+ VERSION = "4.28.0"
23
23
  ::Version=VERSION
24
24
  end
@@ -330,6 +330,17 @@ describe Conjur::Command::Audit, logged_in: true do
330
330
  end
331
331
  end
332
332
  end
333
+
334
+ describe '(conjur:use_extra_privilege)' do
335
+ let(:priv) { 'elevate' }
336
+ let(:test_event) { default_audit_event.merge('kind' => 'conjur', 'action' => 'use_extra_privilege', 'privilege' => priv) }
337
+
338
+ it_behaves_like 'it supports standard prefix:'
339
+ it_behaves_like 'it recognizes error messages:'
340
+ it 'prints the extra privilege' do
341
+ expect { invoke }.to write(" requested extra privilege #{priv}")
342
+ end
343
+ end
333
344
 
334
345
  end
335
346
  end
@@ -20,7 +20,7 @@ describe Conjur::Command::Elevate do
20
20
  url: "https://core.example.com/users/alice",
21
21
  username: "dknuth",
22
22
  headers: {:authorization=>"Token token=\"eyJsb2dpbiI6ImRrbnV0aCJ9\"", x_conjur_privilege: "elevate"}
23
- }.merge(cert_store_options)).and_return(double(:response, body: "[]"))
23
+ }).and_return(double(:response, body: "[]"))
24
24
 
25
25
  invoke
26
26
  end
@@ -35,7 +35,7 @@ describe Conjur::Command::Groups, logged_in: true do
35
35
  url: "https://authz.example.com/the-account/roles/group/group/?members&member=user:alice",
36
36
  headers: {},
37
37
  payload: nil
38
- }.merge(cert_store_options))
38
+ })
39
39
  invoke
40
40
  end
41
41
  end
@@ -47,7 +47,7 @@ describe Conjur::Command::Groups, logged_in: true do
47
47
  url: "https://authz.example.com/the-account/roles/group/group/?members&member=user:alice",
48
48
  headers: {},
49
49
  payload: { admin_option: true }
50
- }.merge(cert_store_options))
50
+ })
51
51
  invoke
52
52
  end
53
53
  end
@@ -58,7 +58,7 @@ describe Conjur::Command::Groups, logged_in: true do
58
58
  url: "https://authz.example.com/the-account/roles/group/group/?members&member=user:alice",
59
59
  headers: {},
60
60
  payload: { admin_option: true }
61
- }.merge(cert_store_options))
61
+ })
62
62
  invoke
63
63
  end
64
64
  end
@@ -70,7 +70,7 @@ describe Conjur::Command::Groups, logged_in: true do
70
70
  url: "https://authz.example.com/the-account/roles/group/group/?members&member=user:alice",
71
71
  headers: {},
72
72
  payload: { admin_option: false }
73
- }.merge(cert_store_options))
73
+ })
74
74
  invoke
75
75
  end
76
76
  end
@@ -10,7 +10,7 @@ describe Conjur::Command::Hosts, logged_in: true do
10
10
  url: collection_url,
11
11
  headers: {},
12
12
  payload: {}
13
- }.merge(cert_store_options)).and_return(post_response('assigned-id'))
13
+ }).and_return(post_response('assigned-id'))
14
14
 
15
15
  expect { invoke }.to write({ id: 'assigned-id' }).to(:stdout)
16
16
  end
@@ -22,9 +22,9 @@ describe Conjur::Command::Hosts, logged_in: true do
22
22
  url: collection_url,
23
23
  headers: {},
24
24
  payload: { id: 'the-id' }
25
- }.merge(cert_store_options)).and_return(post_response('the-id'))
25
+ }).and_return(post_response('the-id'))
26
26
 
27
27
  expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
28
28
  end
29
29
  end
30
- end
30
+ end
@@ -64,7 +64,7 @@ describe Conjur::Command::Users, logged_in: true do
64
64
  password: api_key,
65
65
  headers: { },
66
66
  payload: "new-password"
67
- }.merge(cert_store_options))
67
+ })
68
68
  end
69
69
 
70
70
  describe_command "user:update_password -p new-password" do
@@ -58,7 +58,7 @@ describe Conjur::Command::Variables, logged_in: true do
58
58
  url: collection_url,
59
59
  headers: {},
60
60
  payload: full_payload
61
- }.merge(cert_store_options)).and_return(variable)
61
+ }).and_return(variable)
62
62
  end
63
63
 
64
64
  describe_command "variable:create the-id the-different-value" do
@@ -144,7 +144,7 @@ describe Conjur::Command::Variables, logged_in: true do
144
144
  method: :head,
145
145
  url: 'https://authz.example.com/the-account/roles/group/the-group',
146
146
  headers: {}
147
- }.merge(cert_store_options)).and_return(OpenStruct.new(headers: {}, body: '{}'))
147
+ }).and_return(OpenStruct.new(headers: {}, body: '{}'))
148
148
  end
149
149
 
150
150
  let(:full_payload) { base_payload.merge(ownerid: 'the-account:group:the-group') }
@@ -158,7 +158,7 @@ describe Conjur::Command::Variables, logged_in: true do
158
158
  method: :head,
159
159
  url: 'https://authz.example.com/the-account/roles/group/the-group',
160
160
  headers: {}
161
- }.merge(cert_store_options)).and_return(OpenStruct.new(headers: {}, body: '{}'))
161
+ }).and_return(OpenStruct.new(headers: {}, body: '{}'))
162
162
  end
163
163
 
164
164
  let(:full_payload) { base_payload.merge(ownerid: 'the-account:group:the-group') }
data/spec/config_spec.rb CHANGED
@@ -16,7 +16,7 @@ describe Conjur::Config do
16
16
  ENV['HOME'] = realhome
17
17
  end
18
18
 
19
- let(:deprecation_warning) { "WARNING: .conjurrc file from current directory is used. This behaviour is deprecated. Use ENV['CONJURRC'] to explicitly define custom configuration file if needed" }
19
+ let(:deprecation_warning) { /\.conjurrc/ }
20
20
 
21
21
  shared_examples "no deprecation warning" do
22
22
  it "does not issue a deprecation warning" do
@@ -36,7 +36,6 @@ describe Conjur::Config do
36
36
 
37
37
  it { is_expected.to include('/etc/conjur.conf') }
38
38
  it { is_expected.to include("#{homedir}/.conjurrc") }
39
- it { is_expected.to include('.conjurrc') }
40
39
 
41
40
  before do
42
41
  allow(File).to receive(:expand_path).and_call_original
@@ -49,6 +48,10 @@ describe Conjur::Config do
49
48
  expect { subject }.to write(deprecation_warning).to(:stderr)
50
49
  end
51
50
 
51
+ it "doesn't use the file" do
52
+ expect(subject).to_not include '.conjurrc'
53
+ end
54
+
52
55
  context "but the current directory is home" do
53
56
  before do
54
57
  allow(File).to receive(:expand_path).and_call_original
@@ -114,7 +117,29 @@ describe Conjur::Config do
114
117
  }
115
118
 
116
119
  context "ssl_certificate string" do
117
- let(:ssl_certificate){ 'the-certificate' }
120
+ let(:ssl_certificate) do
121
+ """-----BEGIN CERTIFICATE-----
122
+ MIIDPjCCAiagAwIBAgIVAKW1gdmOFrXt6xB0iQmYQ4z8Pf+kMA0GCSqGSIb3DQEB
123
+ CwUAMD0xETAPBgNVBAoTCGN1Y3VtYmVyMRIwEAYDVQQLEwlDb25qdXIgQ0ExFDAS
124
+ BgNVBAMTC2N1a2UtbWFzdGVyMB4XDTE1MTAwNzE2MzAwNloXDTI1MTAwNDE2MzAw
125
+ NlowFjEUMBIGA1UEAwwLY3VrZS1tYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
126
+ DwAwggEKAoIBAQC9e8bGIHOLOypKA4lsLcAOcDLAq+ICuVxn9Vg0No0m32Ok/K7G
127
+ uEGtlC8RidObntblUwqdX2uP7mqAQm19j78UTl1KT97vMmmFrpVZ7oQvEm1FUq3t
128
+ FBmJglthJrSbpdZjLf7a7eL1NnunkfBdI1DK9QL9ndMjNwZNFbXhld4fC5zuSr/L
129
+ PxawSzTEsoTaB0Nw0DdRowaZgrPxc0hQsrj9OF20gTIJIYO7ctZzE/JJchmBzgI4
130
+ CdfAYg7zNS+0oc0ylV0CWMerQtLICI6BtiQ482bCuGYJ00NlDcdjd3w+A2cj7PrH
131
+ wH5UhtORL5Q6i9EfGGUCDbmfpiVD9Bd3ukbXAgMBAAGjXDBaMA4GA1UdDwEB/wQE
132
+ AwIFoDAdBgNVHQ4EFgQU2jmj7l5rSw0yVb/vlWAYkK/YBwkwKQYDVR0RBCIwIIIL
133
+ Y3VrZS1tYXN0ZXKCCWxvY2FsaG9zdIIGY29uanVyMA0GCSqGSIb3DQEBCwUAA4IB
134
+ AQBCepy6If67+sjuVnT9NGBmjnVaLa11kgGNEB1BZQnvCy0IN7gpLpshoZevxYDR
135
+ 3DnPAetQiZ70CSmCwjL4x6AVxQy59rRj0Awl9E1dgFTYI3JxxgLsI9ePdIRVEPnH
136
+ dhXqPY5ZIZhvdHlLStjsXX7laaclEtMeWfSzxe4AmP/Sm/er4ks0gvLQU6/XJNIu
137
+ RnRH59ZB1mZMsIv9Ii790nnioYFR54JmQu1JsIib77ZdSXIJmxAtraJSTLcZbU1E
138
+ +SM3XCE423Xols7onyluMYDy3MCUTFwoVMRBcRWCAk5gcv6XvZDfLi6Zwdne6x3Y
139
+ bGenr4vsPuSFsycM03/EcQDT
140
+ -----END CERTIFICATE-----
141
+ """
142
+ end
118
143
  let(:certificate){ double('Certificate') }
119
144
  before{
120
145
  Conjur::Config.class_variable_set('@@attributes', {'ssl_certificate' => ssl_certificate})
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: conjur-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.27.0
4
+ version: 4.28.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafal Rzepecki
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-08-28 00:00:00.000000000 Z
12
+ date: 2015-10-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -300,6 +300,7 @@ files:
300
300
  - README.md
301
301
  - Rakefile
302
302
  - acceptance-features/audit/audit_event_send.feature
303
+ - acceptance-features/audit/fetch.feature
303
304
  - acceptance-features/audit/send.feature
304
305
  - acceptance-features/authentication/authenticate.feature
305
306
  - acceptance-features/authentication/login.feature
@@ -337,6 +338,9 @@ files:
337
338
  - acceptance-features/directory/variable/retire.feature
338
339
  - acceptance-features/directory/variable/value.feature
339
340
  - acceptance-features/directory/variable/values-add.feature
341
+ - acceptance-features/dsl/policy_owner.feature
342
+ - acceptance-features/dsl/resource_owner.feature
343
+ - acceptance-features/dsl/retire.feature
340
344
  - acceptance-features/global-privilege/elevate.feature
341
345
  - acceptance-features/global-privilege/reveal.privilege
342
346
  - acceptance-features/pubkeys/add.feature