conjur-cli 4.28.2 → 4.29.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +8 -0
- data/.gitignore +2 -0
- data/.overcommit.yml +10 -0
- data/.rubocop.yml +14 -0
- data/CHANGELOG.md +16 -0
- data/Dockerfile +10 -0
- data/Gemfile +2 -0
- data/Rakefile +1 -1
- data/acceptance-features/audit/audit_event_send.feature +46 -43
- data/acceptance-features/audit/send.feature +0 -19
- data/acceptance-features/authentication/login.feature +0 -2
- data/acceptance-features/authentication/logout.feature +0 -3
- data/acceptance-features/authorization/resource/check.feature +6 -4
- data/acceptance-features/authorization/resource/create.feature +4 -2
- data/acceptance-features/authorization/resource/exists.feature +8 -6
- data/acceptance-features/authorization/resource/give.feature +3 -1
- data/acceptance-features/authorization/resource/show.feature +3 -1
- data/acceptance-features/authorization/role/graph.feature +0 -1
- data/acceptance-features/conjurenv/check.feature +3 -10
- data/acceptance-features/conjurenv/run.feature +3 -3
- data/acceptance-features/conjurenv/template.feature +1 -1
- data/acceptance-features/directory/hostfactory/create.feature +13 -0
- data/acceptance-features/directory/hostfactory/tokens.feature +16 -0
- data/acceptance-features/directory/layer/retire.feature +43 -0
- data/acceptance-features/directory/user/update_password.feature +0 -1
- data/acceptance-features/directory/variable/value.feature +3 -2
- data/acceptance-features/dsl/policy_owner.feature +21 -7
- data/acceptance-features/dsl/resource_owner.feature +4 -4
- data/acceptance-features/pubkeys/add.feature +4 -2
- data/acceptance-features/pubkeys/names.feature +6 -3
- data/acceptance-features/pubkeys/show.feature +4 -2
- data/acceptance-features/step_definitions/{cli.rb → cli_steps.rb} +18 -4
- data/acceptance-features/step_definitions/user_steps.rb +13 -12
- data/acceptance-features/support/env.rb +0 -1
- data/acceptance-features/support/hooks.rb +11 -14
- data/acceptance-features/support/world.rb +16 -18
- data/build-deb.sh +19 -0
- data/ci/test.sh +19 -0
- data/conjur.gemspec +9 -12
- data/debify.sh +4 -0
- data/distrib/bin/_conjur +3 -0
- data/distrib/bin/conjur +3 -0
- data/distrib/bin/conjurize +3 -0
- data/distrib/bin/jsonfield +3 -0
- data/features/conjurize.feature +25 -25
- data/features/support/env.rb +5 -1
- data/features/support/hooks.rb +0 -1
- data/jenkins.sh +29 -1
- data/lib/conjur/cli.rb +27 -4
- data/lib/conjur/command.rb +36 -0
- data/lib/conjur/command/audit.rb +12 -0
- data/lib/conjur/command/bootstrap.rb +5 -9
- data/lib/conjur/command/host_factories.rb +187 -0
- data/lib/conjur/command/hosts.rb +82 -2
- data/lib/conjur/command/layers.rb +28 -0
- data/lib/conjur/command/resources.rb +1 -0
- data/lib/conjur/command/rspec/mock_services.rb +1 -1
- data/lib/conjur/command/server.rb +67 -0
- data/lib/conjur/command/users.rb +67 -12
- data/lib/conjur/command/variables.rb +101 -14
- data/lib/conjur/conjurize.rb +25 -69
- data/lib/conjur/conjurize/script.rb +133 -0
- data/lib/conjur/version.rb +1 -1
- data/publish.sh +6 -0
- data/spec/command/elevate_spec.rb +1 -1
- data/spec/command/host_factories_spec.rb +38 -0
- data/spec/command/hosts_spec.rb +86 -22
- data/spec/command/users_spec.rb +51 -3
- data/spec/command/variable_expiration_spec.rb +174 -0
- data/spec/command/variables_spec.rb +1 -1
- data/spec/conjurize_spec.rb +70 -0
- metadata +61 -64
data/lib/conjur/conjurize.rb
CHANGED
@@ -2,14 +2,7 @@ require 'methadone'
|
|
2
2
|
require 'json'
|
3
3
|
require 'open-uri'
|
4
4
|
require 'conjur/version.rb'
|
5
|
-
|
6
|
-
def latest_conjur_release
|
7
|
-
url = 'https://api.github.com/repos/conjur-cookbooks/conjur/releases'
|
8
|
-
resp = open(url)
|
9
|
-
json = JSON.parse(resp.read)
|
10
|
-
latest = json[0]['assets'].select {|asset| asset['name'] =~ /conjur-v\d.\d.\d.tar.gz/}[0]
|
11
|
-
latest['browser_download_url']
|
12
|
-
end
|
5
|
+
require "conjur/conjurize/script"
|
13
6
|
|
14
7
|
module Conjur
|
15
8
|
class Conjurize
|
@@ -31,77 +24,37 @@ DESC
|
|
31
24
|
else
|
32
25
|
STDIN.read
|
33
26
|
end
|
34
|
-
host = JSON.parse input
|
35
27
|
|
36
|
-
|
37
|
-
|
28
|
+
puts generate JSON.parse input
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.generate host
|
32
|
+
config = configuration host
|
38
33
|
|
39
|
-
|
34
|
+
if options[:json]
|
35
|
+
JSON.dump config
|
36
|
+
else
|
37
|
+
Script.generate config, options
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.apply_client_config
|
42
|
+
require "conjur/cli"
|
40
43
|
if conjur_config = options[:c]
|
41
44
|
Conjur::Config.load [ conjur_config ]
|
42
45
|
else
|
43
46
|
Conjur::Config.load
|
44
47
|
end
|
45
48
|
Conjur::Config.apply
|
49
|
+
end
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
conjur_run_list = options[:"conjur-run-list"]
|
50
|
-
conjur_cookbook_url = options[:"conjur-cookbook-url"]
|
51
|
-
chef_executable = options[:"chef-executable"]
|
52
|
-
|
53
|
-
if options[:ssh]
|
54
|
-
conjur_run_list ||= "conjur"
|
55
|
-
conjur_cookbook_url ||= latest_conjur_release()
|
56
|
-
end
|
57
|
-
|
58
|
-
sudo = lambda{|str|
|
59
|
-
[ options[:sudo] ? "sudo -n" : nil, str ].compact.join(" ")
|
60
|
-
}
|
61
|
-
|
62
|
-
header = <<-HEADER
|
63
|
-
#!/bin/sh
|
64
|
-
set -e
|
65
|
-
|
66
|
-
# Implementation note: 'tee' is used as a sudo-friendly 'cat' to populate a file with the contents provided below.
|
67
|
-
HEADER
|
68
|
-
|
69
|
-
configure_conjur = <<-CONFIGURE
|
70
|
-
#{sudo.call 'tee'} /etc/conjur.conf > /dev/null << CONJUR_CONF
|
71
|
-
account: #{Conjur.configuration.account}
|
72
|
-
appliance_url: #{Conjur.configuration.appliance_url}
|
73
|
-
cert_file: /etc/conjur-#{Conjur.configuration.account}.pem
|
74
|
-
netrc_path: /etc/conjur.identity
|
75
|
-
plugins: []
|
76
|
-
CONJUR_CONF
|
77
|
-
|
78
|
-
#{sudo.call 'tee'} /etc/conjur-#{Conjur.configuration.account}.pem > /dev/null << CONJUR_CERT
|
79
|
-
#{File.read(Conjur.configuration.cert_file).strip}
|
80
|
-
CONJUR_CERT
|
81
|
-
|
82
|
-
#{sudo.call 'tee'} /etc/conjur.identity > /dev/null << CONJUR_IDENTITY
|
83
|
-
machine #{Conjur.configuration.appliance_url}/authn
|
84
|
-
login host/#{login}
|
85
|
-
password #{api_key}
|
86
|
-
CONJUR_IDENTITY
|
87
|
-
#{sudo.call 'chmod'} 0600 /etc/conjur.identity
|
88
|
-
CONFIGURE
|
89
|
-
|
90
|
-
install_chef = if conjur_cookbook_url && !chef_executable
|
91
|
-
%Q(curl -L https://www.opscode.com/chef/install.sh | #{sudo.call 'bash'})
|
92
|
-
else
|
93
|
-
nil
|
94
|
-
end
|
95
|
-
|
96
|
-
chef_executable ||= "chef-solo"
|
97
|
-
|
98
|
-
run_chef = if conjur_cookbook_url
|
99
|
-
%Q(#{sudo.call "#{chef_executable} -r #{conjur_cookbook_url} -o #{conjur_run_list}"})
|
100
|
-
else
|
101
|
-
nil
|
102
|
-
end
|
51
|
+
def self.configuration host
|
52
|
+
apply_client_config
|
103
53
|
|
104
|
-
|
54
|
+
host.merge \
|
55
|
+
"account" => Conjur.configuration.account,
|
56
|
+
"appliance_url" => Conjur.configuration.appliance_url,
|
57
|
+
"certificate" => File.read(Conjur.configuration.cert_file).strip
|
105
58
|
end
|
106
59
|
|
107
60
|
on("-c CONJUR_CONFIG_FILE", "Overrides defaults (CONJURRC env var, ~/.conjurrc, /etc/conjur.conf).")
|
@@ -111,5 +64,8 @@ CONJUR_IDENTITY
|
|
111
64
|
on("--sudo", "Indicates that all commands should be run via 'sudo'.")
|
112
65
|
on("--conjur-cookbook-url NAME", "Overrides the default Chef cookbook URL for Conjur SSH.")
|
113
66
|
on("--conjur-run-list RUNLIST", "Overrides the default Chef run list for Conjur SSH.")
|
67
|
+
on \
|
68
|
+
"--json",
|
69
|
+
"Don't generate the script, instead just dump the configuration as JSON"
|
114
70
|
end
|
115
71
|
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require "json"
|
2
|
+
require "open-uri"
|
3
|
+
|
4
|
+
class Conjur::Conjurize
|
5
|
+
# generates a shell script to conjurize a host
|
6
|
+
class Script
|
7
|
+
COOKBOOK_RELEASES_URL =
|
8
|
+
"https://api.github.com/repos/conjur-cookbooks/conjur/releases".freeze
|
9
|
+
|
10
|
+
def self.latest_conjur_cookbook_release
|
11
|
+
json = JSON.parse open(COOKBOOK_RELEASES_URL).read
|
12
|
+
tarballs = json[0]["assets"].select do |asset|
|
13
|
+
asset["name"] =~ /conjur-v\d.\d.\d.tar.gz/
|
14
|
+
end
|
15
|
+
tarballs.first["browser_download_url"]
|
16
|
+
end
|
17
|
+
|
18
|
+
HEADER = <<-HEADER.freeze
|
19
|
+
#!/bin/sh
|
20
|
+
set -e
|
21
|
+
|
22
|
+
# Implementation note: 'tee' is used as a sudo-friendly 'cat' to populate a file with the contents provided below.
|
23
|
+
HEADER
|
24
|
+
|
25
|
+
def initialize options
|
26
|
+
@options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :options
|
30
|
+
|
31
|
+
def sudo
|
32
|
+
@sudo ||= options["sudo"] ? ->(x) { "sudo -n #{x}" } : ->(x) { x }
|
33
|
+
end
|
34
|
+
|
35
|
+
# Generate a piece of shell to write to a file
|
36
|
+
# @param path [String] absolute path to write to
|
37
|
+
# @param content [String] contents to write
|
38
|
+
# @option options [String, Fixnum] :mode mode to apply to the file
|
39
|
+
def write_file path, content, options = {}
|
40
|
+
[
|
41
|
+
((mode = options[:mode]) && set_mode(path, mode)),
|
42
|
+
[sudo["tee"], path, "> /dev/null << EOF"].join(" "),
|
43
|
+
content.strip,
|
44
|
+
"EOF\n"
|
45
|
+
].compact.join("\n")
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_mode path, mode
|
49
|
+
mode = mode.to_s(8) if mode.respond_to? :to_int
|
50
|
+
[
|
51
|
+
[sudo["touch"], path].join(" "),
|
52
|
+
[sudo["chmod"], mode, path].join(" ")
|
53
|
+
].join("\n")
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.generate configuration, options
|
57
|
+
new(options).generate configuration
|
58
|
+
end
|
59
|
+
|
60
|
+
def install_chef?
|
61
|
+
run_chef? && !options[:"chef-executable"]
|
62
|
+
end
|
63
|
+
|
64
|
+
def run_chef?
|
65
|
+
options.values_at(:ssh, :"conjur-run-list").any?
|
66
|
+
end
|
67
|
+
|
68
|
+
def chef_executable
|
69
|
+
options[:"chef-executable"] || "chef-solo"
|
70
|
+
end
|
71
|
+
|
72
|
+
def conjur_cookbook_url
|
73
|
+
options[:"conjur-cookbook-url"] || Script.latest_conjur_cookbook_release
|
74
|
+
end
|
75
|
+
|
76
|
+
def conjur_run_list
|
77
|
+
options[:"conjur-run-list"] || "conjur"
|
78
|
+
end
|
79
|
+
|
80
|
+
def chef_script
|
81
|
+
@chef_script ||= [
|
82
|
+
("curl -L https://www.opscode.com/chef/install.sh | " + sudo["bash"] \
|
83
|
+
if install_chef?),
|
84
|
+
(sudo["#{chef_executable} -r #{conjur_cookbook_url} " \
|
85
|
+
"-o #{conjur_run_list}"] if run_chef?)
|
86
|
+
].join "\n"
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.rc configuration
|
90
|
+
[
|
91
|
+
"account: #{configuration['account']}",
|
92
|
+
"appliance_url: #{configuration['appliance_url']}",
|
93
|
+
"cert_file: /etc/conjur-#{configuration['account']}.pem",
|
94
|
+
"netrc_path: /etc/conjur.identity",
|
95
|
+
"plugins: []"
|
96
|
+
].join "\n"
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.identity configuration
|
100
|
+
"""
|
101
|
+
machine #{configuration['appliance_url']}/authn
|
102
|
+
login host/#{configuration['id']}
|
103
|
+
password #{configuration['api_key']}
|
104
|
+
"""
|
105
|
+
end
|
106
|
+
|
107
|
+
def configure_conjur configuration
|
108
|
+
[
|
109
|
+
write_file("/etc/conjur.conf", Script.rc(configuration)),
|
110
|
+
write_file(
|
111
|
+
"/etc/conjur-#{configuration['account']}.pem",
|
112
|
+
configuration["certificate"]
|
113
|
+
),
|
114
|
+
write_file(
|
115
|
+
"/etc/conjur.identity",
|
116
|
+
Script.identity(configuration),
|
117
|
+
mode: 0600
|
118
|
+
)
|
119
|
+
].join "\n"
|
120
|
+
end
|
121
|
+
|
122
|
+
def generate configuration
|
123
|
+
fail "No 'id' field in host JSON" unless configuration["id"]
|
124
|
+
fail "No 'api_key' field in host JSON" unless configuration["api_key"]
|
125
|
+
|
126
|
+
[
|
127
|
+
HEADER,
|
128
|
+
configure_conjur(configuration),
|
129
|
+
chef_script
|
130
|
+
].join("\n")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
data/lib/conjur/version.rb
CHANGED
data/publish.sh
ADDED
@@ -17,7 +17,7 @@ describe Conjur::Command::Elevate do
|
|
17
17
|
|
18
18
|
expect(RestClient::Request).to receive(:execute).with({
|
19
19
|
method: :get,
|
20
|
-
url: "https://core.example.com/users/alice",
|
20
|
+
url: "https://core.example.com/api/users/alice",
|
21
21
|
username: "dknuth",
|
22
22
|
headers: {:authorization=>"Token token=\"eyJsb2dpbiI6ImRrbnV0aCJ9\"", x_conjur_privilege: "elevate"}
|
23
23
|
}).and_return(double(:response, body: "[]"))
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'conjur/command/host_factories'
|
3
|
+
|
4
|
+
describe Conjur::Command::HostFactories, :logged_in => true do
|
5
|
+
let (:group_memberships) { double(:group_memberships, :roleid => 'the-account:group:security_admin') }
|
6
|
+
let (:group) { double(:group, :exists? => true, :memberships => [group_memberships]) }
|
7
|
+
let (:layer_members) { double(:layer_members, :member => double(:member, :roleid => 'the-account:group:security_admin'), :admin_option => true ) }
|
8
|
+
let (:layer_role) { double(:layer_role, :members => [layer_members]) }
|
9
|
+
let (:layer) { double(:layer, :exists? => true, :role => layer_role) }
|
10
|
+
|
11
|
+
before do
|
12
|
+
allow(Conjur::Command.api).to receive(:role).with("the-account:group:the-group").and_return group
|
13
|
+
allow(Conjur::Command.api).to receive(:layer).with("layer1").and_return layer
|
14
|
+
end
|
15
|
+
|
16
|
+
describe_command 'hostfactory:create --as-group the-group --layer layer1 hf1 ' do
|
17
|
+
|
18
|
+
it 'calls api.create_host_factory and prints the results' do
|
19
|
+
expect_any_instance_of(Conjur::API).to receive(:create_host_factory).and_return '{}'
|
20
|
+
expect { invoke }.to write('{}')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'command-line errors' do
|
25
|
+
describe_command 'hostfactory:create hf1' do
|
26
|
+
it "fails without owner" do
|
27
|
+
expect {invoke}.to raise_error('Use --as-group or --as-role to indicate the host factory role')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
describe_command 'hostfactory:create --as-group the-group hf' do
|
31
|
+
it "fails without layer" do
|
32
|
+
expect {invoke}.to raise_error('Provide at least one layer')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
data/spec/command/hosts_spec.rb
CHANGED
@@ -1,30 +1,94 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Conjur::Command::Hosts, logged_in: true do
|
4
|
-
let(:collection_url) { "https://core.example.com/hosts" }
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
4
|
+
let(:collection_url) { "https://core.example.com/api/hosts" }
|
5
|
+
|
6
|
+
context "creating a host" do
|
7
|
+
let(:new_host) { double("new-host") }
|
8
|
+
|
9
|
+
describe_command "host:create" do
|
10
|
+
it "lets the server assign the id" do
|
11
|
+
expect(RestClient::Request).to receive(:execute).with({
|
12
|
+
method: :post,
|
13
|
+
url: collection_url,
|
14
|
+
headers: {},
|
15
|
+
payload: {}
|
16
|
+
}).and_return(post_response('assigned-id'))
|
17
|
+
|
18
|
+
expect { invoke }.to write({ id: 'assigned-id' }).to(:stdout)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
describe_command "host:create the-id" do
|
22
|
+
it "propagates the user-assigned id" do
|
23
|
+
expect(RestClient::Request).to receive(:execute).with({
|
24
|
+
method: :post,
|
25
|
+
url: collection_url,
|
26
|
+
headers: {},
|
27
|
+
payload: { id: 'the-id' }
|
28
|
+
}).and_return(post_response('the-id'))
|
29
|
+
|
30
|
+
expect { invoke }.to write({ id: 'the-id' }).to(:stdout)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
describe_command "host:create --cidr 192.168.1.1,127.0.0.0/32" do
|
34
|
+
it "Creates a host with specified CIDR" do
|
35
|
+
expect_any_instance_of(Conjur::API).to receive(:create_host).with(
|
36
|
+
{ cidr: ['192.168.1.1', '127.0.0.0/32'] }
|
37
|
+
).and_return new_host
|
38
|
+
invoke
|
39
|
+
end
|
40
|
+
end
|
41
|
+
describe_command "host:create --as-group security_admin --cidr 192.168.1.1,127.0.0.0/32" do
|
42
|
+
it "Creates a host with specified CIDR" do
|
43
|
+
expect(api).to receive(:group).with("security_admin").and_return(double(:group, roleid: "the-account:group:security_admin"))
|
44
|
+
expect(api).to receive(:role).with("the-account:group:security_admin").and_return(double(:group_role, exists?: true))
|
45
|
+
expect_any_instance_of(Conjur::API).to receive(:create_host).with(
|
46
|
+
{ ownerid: "the-account:group:security_admin", cidr: ['192.168.1.1', '127.0.0.0/32'] }
|
47
|
+
).and_return new_host
|
48
|
+
invoke
|
49
|
+
end
|
16
50
|
end
|
17
51
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
52
|
+
|
53
|
+
context "updating host attributes" do
|
54
|
+
describe_command "host update --cidr 127.0.0.0/32 the-user" do
|
55
|
+
it "updates the CIDR" do
|
56
|
+
stub_host = double()
|
57
|
+
expect_any_instance_of(Conjur::API).to receive(:host).with("the-user").and_return stub_host
|
58
|
+
expect(stub_host).to receive(:update).with(cidr: ['127.0.0.0/32']).and_return ""
|
59
|
+
expect { invoke }.to write "Host updated"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe_command "host update --cidr all the-user" do
|
64
|
+
it "resets the CIDR restrictions" do
|
65
|
+
stub_host = double()
|
66
|
+
expect_any_instance_of(Conjur::API).to receive(:host).with("the-user").and_return stub_host
|
67
|
+
expect(stub_host).to receive(:update).with(cidr: []).and_return ""
|
68
|
+
expect { invoke }.to write "Host updated"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'rotating api key' do
|
74
|
+
describe_command 'host rotate_api_key --host redis001' do
|
75
|
+
before do
|
76
|
+
expect(RestClient::Request).to receive(:execute).with({
|
77
|
+
method: :head,
|
78
|
+
url: 'https://core.example.com/api/hosts/redis001',
|
79
|
+
headers: {}
|
80
|
+
}).and_return true
|
81
|
+
expect(RestClient::Request).to receive(:execute).with({
|
82
|
+
method: :put,
|
83
|
+
url: 'https://authn.example.com/users/api_key?id=host%2Fredis001',
|
84
|
+
headers: {},
|
85
|
+
payload: ''
|
86
|
+
}).and_return double(:response, body: 'new api key')
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'puts with basic auth' do
|
90
|
+
invoke
|
91
|
+
end
|
28
92
|
end
|
29
93
|
end
|
30
94
|
end
|
data/spec/command/users_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Conjur::Command::Users, logged_in: true do
|
4
|
-
let(:create_user_url) { "https://core.example.com/users" }
|
4
|
+
let(:create_user_url) { "https://core.example.com/api/users" }
|
5
5
|
let(:update_password_url) { "https://authn.example.com/users/password" }
|
6
6
|
|
7
7
|
context "creating a user" do
|
@@ -31,16 +31,41 @@ describe Conjur::Command::Users, logged_in: true do
|
|
31
31
|
invoke
|
32
32
|
end
|
33
33
|
end
|
34
|
+
describe_command "#{cmd} --cidr 192.168.1.1,127.0.0.0/32 the-user" do
|
35
|
+
it "Creates a user with specified CIDR" do
|
36
|
+
expect_any_instance_of(Conjur::API).to receive(:create_user).with(
|
37
|
+
"the-user", { cidr: ['192.168.1.1', '127.0.0.0/32'] }
|
38
|
+
).and_return new_user
|
39
|
+
invoke
|
40
|
+
end
|
41
|
+
end
|
34
42
|
end
|
35
43
|
end
|
36
44
|
|
37
|
-
context "updating
|
45
|
+
context "updating user attributes" do
|
38
46
|
describe_command "user update --uidnumber 12345 the-user" do
|
39
47
|
it "updates the uidnumber" do
|
40
48
|
stub_user = double()
|
41
49
|
expect_any_instance_of(Conjur::API).to receive(:user).with("the-user").and_return stub_user
|
42
50
|
expect(stub_user).to receive(:update).with(uidnumber: 12345).and_return ""
|
43
|
-
expect { invoke }.to write "
|
51
|
+
expect { invoke }.to write "User updated"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
describe_command "user update --cidr 127.0.0.0/32 the-user" do
|
55
|
+
it "updates the CIDR" do
|
56
|
+
stub_user = double()
|
57
|
+
expect_any_instance_of(Conjur::API).to receive(:user).with("the-user").and_return stub_user
|
58
|
+
expect(stub_user).to receive(:update).with(cidr: ['127.0.0.0/32']).and_return ""
|
59
|
+
expect { invoke }.to write "User updated"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe_command "user update --cidr all the-user" do
|
64
|
+
it "resets the CIDR restrictions" do
|
65
|
+
stub_user = double()
|
66
|
+
expect_any_instance_of(Conjur::API).to receive(:user).with("the-user").and_return stub_user
|
67
|
+
expect(stub_user).to receive(:update).with(cidr: []).and_return ""
|
68
|
+
expect { invoke }.to write "User updated"
|
44
69
|
end
|
45
70
|
end
|
46
71
|
end
|
@@ -81,4 +106,27 @@ describe Conjur::Command::Users, logged_in: true do
|
|
81
106
|
end
|
82
107
|
end
|
83
108
|
end
|
109
|
+
|
110
|
+
context 'rotating api key' do
|
111
|
+
describe_command 'user rotate_api_key' do
|
112
|
+
before do
|
113
|
+
expect(RestClient::Request).to receive(:execute).with({
|
114
|
+
method: :put,
|
115
|
+
url: 'https://authn.example.com/users/api_key',
|
116
|
+
user: username,
|
117
|
+
password: api_key,
|
118
|
+
headers: {},
|
119
|
+
payload: ''
|
120
|
+
}).and_return double(:response, body: 'new api key')
|
121
|
+
expect(Conjur::Authn).to receive(:save_credentials).with({
|
122
|
+
username: username,
|
123
|
+
password: 'new api key'
|
124
|
+
})
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'puts with basic auth' do
|
128
|
+
invoke
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
84
132
|
end
|