conjur-cli 5.5.0 → 5.6.3
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/.rubocop.yml +2 -2
- data/CHANGELOG.md +22 -0
- data/Dockerfile +1 -1
- data/Gemfile +2 -7
- data/Jenkinsfile +98 -0
- data/LICENSE.md +195 -0
- data/README.md +19 -1
- data/acceptance-features/support/hooks.rb +1 -2
- data/acceptance-features/support/world.rb +8 -2
- data/build-deb.sh +3 -1
- data/ci/secrets/publish.yml +2 -2
- data/{conjur.gemspec → conjur-cli.gemspec} +3 -2
- data/lib/conjur/command.rb +82 -22
- data/lib/conjur/command/groups.rb +1 -1
- data/lib/conjur/command/resources.rb +7 -4
- data/lib/conjur/command/roles.rb +31 -9
- data/lib/conjur/version.rb +2 -2
- data/publish-rubygem.sh +11 -0
- data/spec/command/resources_spec.rb +92 -10
- data/spec/command/roles_spec.rb +133 -1
- data/{jenkins.sh → test.sh} +0 -0
- metadata +73 -58
- data/LICENSE +0 -22
data/build-deb.sh
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
export DEBUG=true
|
4
4
|
export GLI_DEBUG=true
|
5
5
|
|
6
|
-
|
6
|
+
if [[ "$(id -un)" == "jenkins" ]]; then
|
7
|
+
docker run -i --rm -v $PWD:/src -w /src alpine/git clean -fxd
|
8
|
+
fi
|
7
9
|
|
8
10
|
docker build -t conjur-cli-fpm -f Dockerfile.fpm .
|
9
11
|
docker build -t conjur-cli-validate-packaging -f Dockerfile.validate-packaging .
|
data/ci/secrets/publish.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
ART_USERNAME: !var artifactory/users/jenkins/username
|
2
|
-
ART_PASSWORD: !var artifactory/users/jenkins/password
|
1
|
+
ART_USERNAME: !var ci/artifactory/users/jenkins/username
|
2
|
+
ART_PASSWORD: !var ci/artifactory/users/jenkins/password
|
@@ -15,8 +15,8 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.require_paths = ["lib"]
|
16
16
|
gem.version = Conjur::VERSION
|
17
17
|
|
18
|
-
gem.add_dependency 'activesupport', '
|
19
|
-
gem.add_dependency 'conjur-api', '
|
18
|
+
gem.add_dependency 'activesupport', '~> 4.2'
|
19
|
+
gem.add_dependency 'conjur-api', '~> 4.30'
|
20
20
|
gem.add_dependency 'gli', '>=2.8.0'
|
21
21
|
gem.add_dependency 'highline', '~> 1.7'
|
22
22
|
gem.add_dependency 'netrc', '~> 0.10'
|
@@ -24,6 +24,7 @@ Gem::Specification.new do |gem|
|
|
24
24
|
gem.add_dependency 'deep_merge', '~> 1.0'
|
25
25
|
gem.add_dependency 'xdg', '~> 2.2'
|
26
26
|
gem.add_dependency 'table_print', '~> 1.5'
|
27
|
+
gem.add_dependency 'semantic', '>= 1.4.1'
|
27
28
|
|
28
29
|
gem.add_runtime_dependency 'cas_rest_client', '~> 1.3'
|
29
30
|
|
data/lib/conjur/command.rb
CHANGED
@@ -142,35 +142,60 @@ module Conjur
|
|
142
142
|
end
|
143
143
|
end.join("\n")
|
144
144
|
end
|
145
|
-
|
146
|
-
def
|
145
|
+
|
146
|
+
def command_option_kind c
|
147
|
+
c.desc "Filter by kind"
|
148
|
+
c.flag [:k, :kind]
|
149
|
+
end
|
150
|
+
|
151
|
+
def command_option_as_role c
|
147
152
|
return if c.flags.member?(:role) # avoid duplicate flags
|
148
153
|
c.desc "Role to act as. By default, the current logged-in role is used."
|
149
154
|
c.arg_name 'ROLE'
|
150
155
|
c.flag [:role]
|
151
|
-
|
156
|
+
end
|
157
|
+
|
158
|
+
def command_options_for_search c
|
152
159
|
c.desc "Full-text search on resource id and annotation values"
|
153
160
|
c.flag [:s, :search]
|
154
161
|
|
155
|
-
c.desc "Maximum number of records to return"
|
156
|
-
c.flag [:l, :limit]
|
157
|
-
|
158
162
|
c.desc "Offset to start from"
|
159
163
|
c.flag [:o, :offset]
|
160
164
|
|
165
|
+
c.desc "Maximum number of records to return"
|
166
|
+
c.flag [:l, :limit]
|
167
|
+
|
168
|
+
c.desc "Show the number of results, rather than printing them"
|
169
|
+
c.switch [:count]
|
170
|
+
end
|
171
|
+
|
172
|
+
def command_options_for_list(c)
|
173
|
+
command_option_as_role c
|
174
|
+
command_options_for_search c
|
175
|
+
|
161
176
|
c.desc "Show only ids"
|
162
177
|
c.switch [:i, :ids]
|
163
|
-
|
178
|
+
|
164
179
|
c.desc "Show annotations in 'raw' format"
|
165
180
|
c.switch [:r, :"raw-annotations"]
|
166
181
|
end
|
182
|
+
|
183
|
+
def process_command_options_for_search options
|
184
|
+
opts = options.slice(:search, :count, :limit, :offset, :kind)
|
185
|
+
opts[:acting_as] = options[:role] if options[:role]
|
186
|
+
opts[:search] = opts[:search].gsub('-',' ') if opts[:search]
|
187
|
+
if opts[:kind] && opts[:kind].index(',')
|
188
|
+
opts[:kind] = opts[:kind].split(',')
|
189
|
+
end
|
190
|
+
opts
|
191
|
+
end
|
167
192
|
|
168
193
|
def command_impl_for_list(global_options, options, args)
|
169
|
-
opts =
|
170
|
-
opts[:acting_as] = options[:role] if options[:role]
|
171
|
-
opts[:search]=opts[:search].gsub('-',' ') if opts[:search]
|
194
|
+
opts = process_command_options_for_search(options)
|
172
195
|
resources = api.resources(opts)
|
173
|
-
if
|
196
|
+
if resources.is_a?(Numeric)
|
197
|
+
puts resources
|
198
|
+
elsif options[:ids]
|
174
199
|
puts JSON.pretty_generate(resources.map(&:resourceid))
|
175
200
|
else
|
176
201
|
resources = resources.map &:attributes
|
@@ -297,23 +322,58 @@ an alternative destination role.)
|
|
297
322
|
obj.resource.give_to destination_role
|
298
323
|
end
|
299
324
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
325
|
+
# Displays members, which may be either:
|
326
|
+
#
|
327
|
+
# * A numeric count
|
328
|
+
# * A list of role ids
|
329
|
+
# * A list of RoleGrant
|
330
|
+
#
|
331
|
+
# +options+ may include:
|
332
|
+
#
|
333
|
+
# * **V** Show full RoleGrant info
|
334
|
+
# * **system** show system (internal) roles
|
335
|
+
#
|
336
|
+
# @return [Numeric, Hash] Convert the input to a number or Hash.
|
337
|
+
def display_members(members, member_field, options)
|
338
|
+
# Get this case out of the way
|
339
|
+
return display(members) if members.is_a?(Numeric)
|
340
|
+
|
341
|
+
result, roleid_function = if members.blank?
|
342
|
+
[ [], nil ]
|
343
|
+
elsif members.first.is_a?(Conjur::RoleGrant)
|
344
|
+
if options[:V]
|
345
|
+
items = members.collect do |member|
|
346
|
+
{
|
347
|
+
member: member.member.roleid,
|
348
|
+
grantor: member.grantor.roleid,
|
349
|
+
admin_option: member.admin_option
|
350
|
+
}.tap do |obj|
|
351
|
+
obj[:role] = member.role.roleid if member.role
|
352
|
+
end
|
353
|
+
end
|
354
|
+
[
|
355
|
+
items, lambda {|member| member[member_field] }
|
356
|
+
]
|
357
|
+
else
|
358
|
+
[ members.map{|m| m.send(member_field) }.map(&:roleid), lambda{|r| r} ]
|
359
|
+
end
|
309
360
|
else
|
310
|
-
members.map(&:
|
361
|
+
[ members.map(&:roleid), lambda{|r| r} ]
|
311
362
|
end
|
363
|
+
|
364
|
+
unless options[:system]
|
365
|
+
result.reject! do |member|
|
366
|
+
roleid_function.call(member) =~ /^.+?:@/
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
312
370
|
display result
|
313
371
|
end
|
314
372
|
|
315
373
|
def display(obj, options = {})
|
316
|
-
str = if obj.
|
374
|
+
str = if obj.is_a?(Numeric)
|
375
|
+
obj.to_s
|
376
|
+
elsif obj.respond_to?(:attributes)
|
317
377
|
JSON.pretty_generate obj.attributes
|
318
378
|
elsif obj.respond_to?(:id)
|
319
379
|
obj.id
|
@@ -145,7 +145,7 @@ class Conjur::Command::Groups < Conjur::Command
|
|
145
145
|
c.switch [:V,:verbose]
|
146
146
|
c.action do |global_options,options,args|
|
147
147
|
group = require_arg(args, 'GROUP')
|
148
|
-
display_members api.group(group).role.members, options
|
148
|
+
display_members api.group(group).role.members, :member, options
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
@@ -137,10 +137,15 @@ class Conjur::Command::Resources < Conjur::Command
|
|
137
137
|
resource.desc "List roles with a specified permission on the resource"
|
138
138
|
resource.arg_name "RESOURCE PERMISSION"
|
139
139
|
resource.command :permitted_roles do |c|
|
140
|
+
command_option_kind c
|
141
|
+
command_options_for_search c
|
142
|
+
|
140
143
|
c.action do |global_options,options,args|
|
141
144
|
id = full_resource_id( require_arg(args, "RESOURCE") )
|
142
145
|
permission = require_arg(args, "PERMISSION")
|
143
|
-
|
146
|
+
|
147
|
+
opts = process_command_options_for_search(options)
|
148
|
+
display api.resource(id).permitted_roles(permission, opts)
|
144
149
|
end
|
145
150
|
end
|
146
151
|
|
@@ -191,9 +196,7 @@ class Conjur::Command::Resources < Conjur::Command
|
|
191
196
|
|
192
197
|
resource.desc "List all resources"
|
193
198
|
resource.command :list do |c|
|
194
|
-
c
|
195
|
-
c.flag [:k, :kind]
|
196
|
-
|
199
|
+
command_option_kind c
|
197
200
|
command_options_for_list c
|
198
201
|
|
199
202
|
c.action do |global_options, options, args|
|
data/lib/conjur/command/roles.rb
CHANGED
@@ -74,21 +74,32 @@ class Conjur::Command::Roles < Conjur::Command
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
role.desc "Lists role memberships. The role membership list is recursively expanded."
|
77
|
+
role.desc "Lists role memberships. The role membership list is recursively expanded by default."
|
78
78
|
role.arg_name "ROLE"
|
79
79
|
|
80
80
|
role.command :memberships do |c|
|
81
|
+
c.desc "Verbose output. Only meaningful with --no-recursive."
|
82
|
+
c.switch [:V,:verbose]
|
83
|
+
|
84
|
+
c.desc "Whether to recursively expand role memberships"
|
85
|
+
c.default_value true
|
86
|
+
c.switch [:r, :recursive]
|
87
|
+
|
81
88
|
c.desc "Whether to show system (internal) roles"
|
82
|
-
c.switch [:
|
89
|
+
c.switch [:system]
|
90
|
+
|
91
|
+
command_option_kind c
|
92
|
+
command_options_for_search c
|
83
93
|
|
84
94
|
c.action do |global_options,options,args|
|
85
95
|
roleid = args.shift
|
96
|
+
assert_empty(args)
|
86
97
|
role = roleid.nil? && api.current_role || api.role(roleid)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
98
|
+
|
99
|
+
opts = process_command_options_for_search(options)
|
100
|
+
opts[:recursive] = false unless options[:recursive]
|
101
|
+
memberships = role.all(opts)
|
102
|
+
display_members memberships, :role, options
|
92
103
|
end
|
93
104
|
end
|
94
105
|
|
@@ -98,9 +109,20 @@ class Conjur::Command::Roles < Conjur::Command
|
|
98
109
|
c.desc "Verbose output"
|
99
110
|
c.switch [:V,:verbose]
|
100
111
|
|
112
|
+
c.desc "Whether to show system (internal) roles"
|
113
|
+
c.switch [:system]
|
114
|
+
|
115
|
+
command_option_kind c
|
116
|
+
command_options_for_search c
|
117
|
+
|
101
118
|
c.action do |global_options,options,args|
|
102
|
-
|
103
|
-
|
119
|
+
roleid = args.shift
|
120
|
+
assert_empty(args)
|
121
|
+
role = roleid.nil? && api.current_role || api.role(roleid)
|
122
|
+
opts = process_command_options_for_search(options)
|
123
|
+
|
124
|
+
members = role.members(opts)
|
125
|
+
display_members members, :member, options
|
104
126
|
end
|
105
127
|
end
|
106
128
|
|
data/lib/conjur/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (C) 2014-
|
2
|
+
# Copyright (C) 2014-2017 Conjur Inc.
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
5
5
|
# this software and associated documentation files (the "Software"), to deal in
|
@@ -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 = '5.
|
22
|
+
VERSION = '5.6.3'.freeze
|
23
23
|
::Version=VERSION
|
24
24
|
end
|
data/publish-rubygem.sh
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/bin/bash -e
|
2
|
+
|
3
|
+
docker run -i --rm -v $PWD:/src -w /src alpine/git clean -fxd
|
4
|
+
|
5
|
+
docker pull registry.tld/conjurinc/publish-rubygem
|
6
|
+
|
7
|
+
summon --yaml "RUBYGEMS_API_KEY: !var rubygems/api-key" \
|
8
|
+
docker run --rm --env-file @SUMMONENVFILE -v "$(pwd)":/opt/src \
|
9
|
+
registry.tld/conjurinc/publish-rubygem conjur-cli
|
10
|
+
|
11
|
+
docker run -i --rm -v $PWD:/src -w /src alpine/git clean -fxd
|
@@ -7,6 +7,7 @@ describe Conjur::Command::Resources, logged_in: true do
|
|
7
7
|
let (:resource_attributes) { { "some" => "attribute"} }
|
8
8
|
|
9
9
|
before :each do
|
10
|
+
allow(api).to receive(:resource).and_call_original
|
10
11
|
allow(api).to receive(:resource).with(full_resource_id).and_return(resource_instance)
|
11
12
|
end
|
12
13
|
|
@@ -135,18 +136,99 @@ describe Conjur::Command::Resources, logged_in: true do
|
|
135
136
|
it { expect { invoke }.to write "Ownership granted" }
|
136
137
|
end
|
137
138
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
context "list" do
|
140
|
+
def make_resource(kind, identifier, attributes)
|
141
|
+
authz_host = "http://conjur/authz"
|
142
|
+
credentials = {}
|
143
|
+
id = "the-account:#{kind}:#{identifier}"
|
144
|
+
api.resource(id).tap do |resource|
|
145
|
+
resource.attributes = attributes.merge(resourceid: id)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
let(:resources) {
|
149
|
+
[
|
150
|
+
make_resource("food", "bacon", {}),
|
151
|
+
make_resource("food", "eggs", {})
|
152
|
+
]
|
142
153
|
}
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
154
|
+
let(:resource_ids) {
|
155
|
+
[
|
156
|
+
"the-account:food:bacon",
|
157
|
+
"the-account:food:eggs"
|
158
|
+
]
|
159
|
+
}
|
160
|
+
describe_command "resource:list" do
|
161
|
+
it "displays JSONised list of resources" do
|
162
|
+
expect(api).to receive(:resources).with({}).and_return(resources)
|
163
|
+
expect(JSON.parse( expect { invoke }.to write )).to eq([
|
164
|
+
{"resourceid"=>"the-account:food:bacon", "annotations"=>{}},
|
165
|
+
{"resourceid"=>"the-account:food:eggs", "annotations"=>{}}
|
166
|
+
])
|
167
|
+
end
|
168
|
+
end
|
169
|
+
describe_command "resource:list -i -k jobs" do
|
170
|
+
it "searches by resource kind" do
|
171
|
+
expect(api).to receive(:resources).with({kind: 'jobs'}).and_return(resources)
|
172
|
+
expect(JSON.parse( expect { invoke }.to write )).to eq(resource_ids)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
describe_command "resource:list -i" do
|
176
|
+
it "displays resource ids" do
|
177
|
+
expect(api).to receive(:resources).with({}).and_return(resources)
|
178
|
+
expect(JSON.parse( expect { invoke }.to write )).to eq(resource_ids)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
{ search: "hamster", offset: 10, limit: 10 }.each do |k,v|
|
182
|
+
describe_command "resource:list -i --#{k} #{v}" do
|
183
|
+
it "displays the items" do
|
184
|
+
expect(api).to receive(:resources).with({k => v.to_s}).and_return(resources)
|
185
|
+
expect(JSON.parse( expect { invoke }.to write )).to eq(resource_ids)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "permitted roles" do
|
192
|
+
let(:roles_list) { %W[klaatu barada nikto] }
|
193
|
+
describe_command "resource:permitted_roles #{KIND}:#{ID} #{PRIVILEGE}" do
|
194
|
+
before(:each) {
|
195
|
+
allow(resource_instance).to receive(:permitted_roles).and_return(roles_list)
|
196
|
+
}
|
197
|
+
it_behaves_like "it obtains resource by id"
|
198
|
+
it "calls resource.permitted_roles(#{PRIVILEGE}" do
|
199
|
+
expect(resource_instance).to receive(:permitted_roles).with(PRIVILEGE, {})
|
200
|
+
invoke_silently
|
201
|
+
end
|
202
|
+
it "displays JSONised list of roles" do
|
203
|
+
expect(JSON.parse( expect { invoke }.to write )).to eq(roles_list)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe_command "resource:permitted_roles --count #{KIND}:#{ID} #{PRIVILEGE}" do
|
208
|
+
before {
|
209
|
+
expect(resource_instance).to receive(:permitted_roles).with(PRIVILEGE, count: true).
|
210
|
+
and_return(12)
|
211
|
+
}
|
212
|
+
it_behaves_like "it obtains resource by id"
|
213
|
+
it "calls resource.permitted_roles(#{PRIVILEGE}" do
|
214
|
+
invoke_silently
|
215
|
+
end
|
216
|
+
it "displays role count" do
|
217
|
+
expect(JSON.parse( expect { invoke }.to write )).to eq(12)
|
218
|
+
end
|
147
219
|
end
|
148
|
-
|
149
|
-
|
220
|
+
|
221
|
+
|
222
|
+
describe_command "resource:permitted_roles -s frontend #{KIND}:#{ID} #{PRIVILEGE}" do
|
223
|
+
let(:roles_list) { %W[klaatu barada nikto] }
|
224
|
+
before {
|
225
|
+
expect(resource_instance).to receive(:permitted_roles).with(PRIVILEGE, search: "frontend").
|
226
|
+
and_return(roles_list)
|
227
|
+
}
|
228
|
+
it_behaves_like "it obtains resource by id"
|
229
|
+
it "displays JSONised list of roles" do
|
230
|
+
expect(JSON.parse( expect { invoke }.to write )).to eq(roles_list)
|
231
|
+
end
|
150
232
|
end
|
151
233
|
end
|
152
234
|
|
data/spec/command/roles_spec.rb
CHANGED
@@ -46,13 +46,92 @@ describe Conjur::Command::Roles, logged_in: true do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
describe "role:members" do
|
50
|
+
let(:all_roles) { %w(foo:user:joerandom foo:something:cool foo:something:else foo:group:admins) }
|
51
|
+
let(:all_role_grants) {
|
52
|
+
all_roles.map do |r|
|
53
|
+
Conjur::RoleGrant.new(api.role("foo:user:joerandom"), api.role(r), api.role("foo:user:admin"), false)
|
54
|
+
end
|
55
|
+
}
|
56
|
+
let(:role) do
|
57
|
+
double "the role", members: all_role_grants
|
58
|
+
end
|
59
|
+
|
60
|
+
before do
|
61
|
+
allow(api).to receive(:role).and_call_original
|
62
|
+
allow(api).to receive(:role).with(rolename).and_return role
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when logged in as a user" do
|
66
|
+
let(:username) { "joerandom" }
|
67
|
+
let(:rolename) { "user:joerandom" }
|
68
|
+
|
69
|
+
describe_command "role:members" do
|
70
|
+
it "lists all roles" do
|
71
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe_command "role:members -V" do
|
76
|
+
it "lists all roles verbosely" do
|
77
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_role_grants.map(&:to_h).map(&:stringify_keys))
|
78
|
+
end
|
79
|
+
describe "without RoleGrant.role field" do
|
80
|
+
it "lists the roles verbosely" do
|
81
|
+
all_role_grants.each do |rg|
|
82
|
+
rg.instance_variable_set "@role", nil
|
83
|
+
end
|
84
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_role_grants.map(&:to_h).map(&:stringify_keys))
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe_command "role:members --count" do
|
90
|
+
it "counts the roles" do
|
91
|
+
expect(role).to receive(:members).with({count: true}).and_return(all_roles.size)
|
92
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles.size)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe_command "role:members -k hamster -s frontend -o 10 -l 10" do
|
97
|
+
it "lists selected roles" do
|
98
|
+
expect(role).to receive(:members).with({kind: 'hamster', search: 'frontend', offset: "10", limit: "10"}).and_return(all_role_grants)
|
99
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe_command "role:members -k hamster,giraffe" do
|
104
|
+
it "lists selected roles" do
|
105
|
+
expect(role).to receive(:members).with({kind: %w(hamster giraffe)}).and_return(all_role_grants)
|
106
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe_command "role:members -k hamster -k giraffe" do
|
111
|
+
it "applies only the last 'kind' filter" do
|
112
|
+
expect(role).to receive(:members).with({kind: 'giraffe'}).and_return(all_role_grants)
|
113
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe_command "role:members foo:bar" do
|
118
|
+
let(:rolename) { 'foo:bar' }
|
119
|
+
it "lists all roles of foo:bar" do
|
120
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
49
126
|
describe "role:memberships" do
|
50
127
|
let(:all_roles) { %w(foo:user:joerandom foo:something:cool foo:something:else foo:group:admins) }
|
128
|
+
let(:all_role_objects) { all_roles.map{|r| double r, roleid: r } }
|
51
129
|
let(:role) do
|
52
|
-
double "the role", all:
|
130
|
+
double "the role", all: all_role_objects
|
53
131
|
end
|
54
132
|
|
55
133
|
before do
|
134
|
+
allow(api).to receive(:role).and_call_original
|
56
135
|
allow(api).to receive(:role).with(rolename).and_return role
|
57
136
|
end
|
58
137
|
|
@@ -65,6 +144,59 @@ describe Conjur::Command::Roles, logged_in: true do
|
|
65
144
|
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles)
|
66
145
|
end
|
67
146
|
end
|
147
|
+
|
148
|
+
describe_command "when empty" do
|
149
|
+
let(:all_roles) { [] }
|
150
|
+
describe_command "role:memberships" do
|
151
|
+
it "prints an empty array" do
|
152
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq([])
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe_command "role:memberships" do
|
158
|
+
it "hides system roles" do
|
159
|
+
expect(role).to receive(:all).with({}).and_return([
|
160
|
+
double(:role, roleid: "the-account:@:hamster")
|
161
|
+
])
|
162
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq([])
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
describe_command "role:memberships --count" do
|
167
|
+
it "counts the roles" do
|
168
|
+
expect(role).to receive(:all).with({count: true}).and_return(all_roles.size)
|
169
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles.size)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "with full role grant info" do
|
174
|
+
let(:all_role_grants) {
|
175
|
+
all_roles.map do |r|
|
176
|
+
Conjur::RoleGrant.new(api.role(r), api.role("foo:user:joerandom"), api.role("foo:user:admin"), false)
|
177
|
+
end
|
178
|
+
}
|
179
|
+
before {
|
180
|
+
expect(role).to receive(:all).with({recursive: false}).and_return(all_role_grants)
|
181
|
+
}
|
182
|
+
describe_command "role:memberships --no-recursive" do
|
183
|
+
it "lists the roles" do
|
184
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
describe_command "role:memberships -V --no-recursive" do
|
188
|
+
it "shows all the roles" do
|
189
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_role_grants.map(&:to_h).map(&:stringify_keys))
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
describe_command "role:memberships -k hamster -s frontend -o 10 -l 10" do
|
195
|
+
it "lists selected roles" do
|
196
|
+
expect(role).to receive(:all).with({kind: 'hamster', search: 'frontend', offset: "10", limit: "10"}).and_return(all_role_objects)
|
197
|
+
expect(JSON::parse(expect { invoke }.to write)).to eq(all_roles)
|
198
|
+
end
|
199
|
+
end
|
68
200
|
|
69
201
|
describe_command "role:memberships foo:bar" do
|
70
202
|
let(:rolename) { 'foo:bar' }
|