cf-uaac 3.10.0 → 3.11.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: bfd5454d263e6da7b3bfd4a4af5aadc6025a7960
4
- data.tar.gz: f6874a63ac34a6e68fd39d31a0deeb69fbaa6b91
3
+ metadata.gz: d82226a5579050e9e9fff98de302c291a96a7b05
4
+ data.tar.gz: f868e74326c0140a5586257d184a95c27362974f
5
5
  SHA512:
6
- metadata.gz: c0ebc2c42d29ccff07ae37d8905b26421954e404b5462ce1faa802fe66b6f4f7cc26e0f0d5c388b139983315ef5dc2114509b46750d3a06f6ae248278c3a89e4
7
- data.tar.gz: 5b077bab9d8f4f001e15b25ac3e030d7154eb41b3daf7470574c90cc9ea10961950ec4bf0c89727149ddb38a971b4165d0bda97fe0d71edf23e08d92379e31b1
6
+ metadata.gz: a57c42af2d72f2b817c9ebeee3c2f5697c419e777596508dced216b6f4d9d90b1c3e91992e49ed789f4f612c14d45f2f565e8f43b1474269b219fb2bcfa7cc68
7
+ data.tar.gz: 9cb180a3232a919f83d3e6bec490023b91062b9ec560cb789bfc6cce1cf982048952327390c7961dae14af4865f60514a349fb5ad26db4dc85a2d5f6122e64ff
File without changes
data/NOTICE ADDED
@@ -0,0 +1,11 @@
1
+ Copyright (c) 2015-Present CloudFoundry.org Foundation, Inc. All Rights Reserved.
2
+
3
+ This project contains software that is Copyright (c) 2012-2015 Pivotal Software, Inc.
4
+
5
+ This project is licensed to you under the Apache License, Version 2.0 (the "License").
6
+
7
+ You may not use this project except in compliance with the License.
8
+
9
+ This project may include a number of subcomponents with separate copyright notices
10
+ and license terms. Your use of these subcomponents is subject to the terms and
11
+ conditions of the subcomponent's license, as noted in the LICENSE file.
data/lib/uaa/cli/base.rb CHANGED
@@ -148,10 +148,10 @@ class Topic
148
148
  }.join(' ')
149
149
  end
150
150
 
151
- def say_cmd_helper(info, suffix = nil)
151
+ def say_cmd_helper(info, topic, suffix = nil)
152
152
  say_definition 2, info[:template], info[:desc]
153
153
  info[:options].each do |o|
154
- odef, desc = opt_help(o, @cli_class.option_defs[o])
154
+ odef, desc = opt_help(o, topic.option_defs[o] ? topic.option_defs[o]: @cli_class.option_defs[o])
155
155
  say_definition help_col_start, "", desc ? "#{odef}, #{desc}" : odef
156
156
  end
157
157
  @output.print suffix
@@ -162,7 +162,7 @@ class Topic
162
162
  @cli_class.topics.each do |tpc|
163
163
  tpc.commands.each do |k, v|
164
164
  if args[0..v[:parts].length - 1] == v[:parts]
165
- say_cmd_helper(v, "\n")
165
+ say_cmd_helper(v, tpc, "\n")
166
166
  return "help command"
167
167
  end
168
168
  end
@@ -177,7 +177,7 @@ class Topic
177
177
  @cli_class.topics.each do |tpc|
178
178
  next if topic && topic != tpc
179
179
  @output.print "\n#{tpc.topic}\n"
180
- tpc.commands.each { |k, v| say_cmd_helper v }
180
+ tpc.commands.each { |k, v| say_cmd_helper v, tpc }
181
181
  end
182
182
  if topic || !@cli_class.global_options
183
183
  @output.print("\n")
@@ -229,6 +229,7 @@ end
229
229
  class BaseCli
230
230
 
231
231
  class << self
232
+ attr_writer :input
232
233
  attr_reader :input, :output, :option_defs
233
234
  attr_accessor :overview, :topics, :global_options
234
235
  end
@@ -103,14 +103,42 @@ class CommonCli < Topic
103
103
  }
104
104
  end
105
105
 
106
+ def scim_get_user_object(scim, type, name, origin, attrs = nil)
107
+ origin_filter = origin ? " and origin eq \"#{origin}\"" : ''
108
+ query = { attributes: attrs, filter: "#{scim.name_attr(type)} eq \"#{name}\"#{origin_filter}"}
109
+ info = scim.all_pages(type, query)
110
+ raise BadResponse unless info.is_a?(Array)
111
+ raise NotFound if info.length == 0
112
+ if info.length >= 2
113
+ info.each_with_index do |i, idx|
114
+ puts "#{idx+1}: #{i['username']} from #{i['origin']}"
115
+ end
116
+
117
+ choice = @highline.ask("Select user: ").to_i
118
+ if choice > info.length || choice <= 0
119
+ raise ArgumentError 'bad input, klugscheisser'
120
+ end
121
+ info = info[choice - 1]
122
+ else
123
+ info = info[0]
124
+ end
125
+
126
+ # when getting whole object, handle case of UAA < 1.3 which did not return meta attr from query
127
+ attrs || !info["id"] || info["meta"] ? info : scim.get(type, info["id"])
128
+ end
129
+
106
130
  def scim_get_object(scim, type, name, attrs = nil)
107
131
  query = { attributes: attrs, filter: "#{scim.name_attr(type)} eq \"#{name}\""}
132
+ scim_get_helper(attrs, query, scim, type)
133
+ end
134
+
135
+ def scim_get_helper(attrs, query, scim, type)
108
136
  info = scim.all_pages(type, query)
109
137
  raise BadResponse unless info.is_a?(Array) && info.length < 2
110
138
  raise NotFound if info.length == 0
111
139
  info = info[0]
112
140
  # when getting whole object, handle case of UAA < 1.3 which did not return meta attr from query
113
- attrs || !info["id"] || info["meta"]? info : scim.get(type, info["id"])
141
+ attrs || !info["id"] || info["meta"] ? info : scim.get(type, info["id"])
114
142
  end
115
143
  end
116
144
 
data/lib/uaa/cli/user.rb CHANGED
@@ -23,7 +23,8 @@ class UserCli < CommonCli
23
23
  define_option :familyName, '--family_name <name>'
24
24
  define_option :emails, '--emails <addresses>'
25
25
  define_option :phoneNumbers, '--phones <phone_numbers>'
26
- USER_INFO_OPTS = [:givenName, :familyName, :emails, :phoneNumbers]
26
+ define_option :origin, '--origin <identity provider origin, defaults to UAA>'
27
+ USER_INFO_OPTS = [:givenName, :familyName, :emails, :phoneNumbers, :origin]
27
28
 
28
29
  def user_opts(info = {})
29
30
  [:emails, :phoneNumbers].each do |o|
@@ -32,6 +33,7 @@ class UserCli < CommonCli
32
33
  end
33
34
  n = [:givenName, :familyName].each_with_object({}) { |o, n| n[o] = opts[o] if opts[o] }
34
35
  info[:name] = n unless n.empty?
36
+ info[:origin] = opts[:origin] if opts[:origin]
35
37
  info
36
38
  end
37
39
 
@@ -42,8 +44,8 @@ class UserCli < CommonCli
42
44
  scim_common_list(:user, filter)
43
45
  end
44
46
 
45
- desc 'user get [name]', 'Get specific user account', :attrs do |name|
46
- pp scim_request { |sr| scim_get_object(sr, :user, username(name), opts[:attrs]) }
47
+ desc 'user get [name]', 'Get specific user account', :origin, :attrs do |name|
48
+ pp scim_request { |sr| scim_get_user_object(sr, :user, username(name), opts[:origin], opts[:attrs]) }
47
49
  end
48
50
 
49
51
  desc 'user add [name]', 'Add a user account', *USER_INFO_OPTS, :password do |name|
@@ -59,16 +61,17 @@ class UserCli < CommonCli
59
61
  *USER_INFO_OPTS, :del_attrs do |name|
60
62
  return say 'no user updates specified' if (updates = user_opts).empty?
61
63
  pp scim_request { |ua|
62
- info = ua.get(:user, ua.id(:user, username(name)))
64
+ info = scim_get_user_object(ua, :user, username(name), opts[:origin])
63
65
  opts[:del_attrs].each { |a| info.delete(a.to_s) } if opts[:del_attrs]
64
66
  ua.put(:user, info.merge(updates))
65
67
  'user account successfully updated'
66
68
  }
67
69
  end
68
70
 
69
- desc 'user delete [name]', 'Delete user account' do |name|
71
+ desc 'user delete [name]', 'Delete user account', :origin do |name|
70
72
  pp scim_request { |ua|
71
- ua.delete(:user, ua.id(:user, username(name)))
73
+ user = scim_get_user_object(ua, :user, username(name), opts[:origin])
74
+ ua.delete(:user, user['id'])
72
75
  'user account successfully deleted'
73
76
  }
74
77
  end
@@ -14,6 +14,6 @@
14
14
  # Cloud Foundry namespace
15
15
  module CF
16
16
  module UAA
17
- CLI_VERSION = '3.10.0'
17
+ CLI_VERSION = '3.11.0'
18
18
  end
19
19
  end
data/lib/uaa/stub/scim.rb CHANGED
@@ -60,7 +60,7 @@ class StubScim
60
60
  LEGAL_ATTRS = {
61
61
  user: [*COMMON_ATTRS, :displayname, :username, :nickname,
62
62
  :profileurl, :title, :usertype, :preferredlanguage, :locale,
63
- :timezone, :active, :password, :emails, :phonenumbers, :ims, :photos,
63
+ :timezone, :active, :password, :emails, :phonenumbers, :origin, :ims, :photos,
64
64
  :entitlements, :roles, :x509certificates, :name, :addresses,
65
65
  :authorizations, :groups].to_set,
66
66
  client: [*COMMON_ATTRS, :client_id, :name, :client_secret, :authorities,
@@ -199,12 +199,16 @@ class StubScim
199
199
  end
200
200
 
201
201
  def name(id, rtype = nil) (t = ref_by_id(id, rtype))? t[NAME_ATTR[t[:rtype]]]: nil end
202
- def id(name, rtype) (t = ref_by_name(name, rtype))? t[:id] : nil end
202
+ def id(name, rtype)
203
+ name = append_origin_to_username(name, rtype, nil)
204
+ (t = ref_by_name(name, rtype))? t[:id] : nil
205
+ end
203
206
 
204
207
  def add(rtype, stuff)
205
208
  unless stuff.is_a?(Hash) && (name = stuff[NAME_ATTR[rtype].to_s])
206
209
  raise SchemaViolation, "new #{rtype} has no name #{NAME_ATTR[rtype]}"
207
210
  end
211
+ name = append_origin_to_username(name, rtype, stuff['origin'])
208
212
  raise AlreadyExists if @things_by_name.key?(name = rtype.to_s + name.downcase)
209
213
  enforce_schema(rtype, stuff)
210
214
  thing = input(stuff).merge!(rtype: rtype, id: (id = SecureRandom.uuid),
@@ -225,9 +229,10 @@ class StubScim
225
229
  if newname = new_thing[NAME_ATTR[rtype]]
226
230
  oldname = rtype.to_s + thing[NAME_ATTR[rtype]].downcase
227
231
  unless (newname = rtype.to_s + newname.downcase) == oldname
228
- raise AlreadyExists if @things_by_name.key?(newname)
232
+ name = append_origin_to_username(newname, rtype, stuff['origin'])
233
+ raise AlreadyExists if @things_by_name.key?(name)
229
234
  @things_by_name.delete(oldname)
230
- @things_by_name[newname] = thing
235
+ @things_by_name[name] = thing
231
236
  end
232
237
  end
233
238
  if new_thing[:members] || thing[:members]
@@ -293,8 +298,10 @@ class StubScim
293
298
  return unless thing = ref_by_id(id, rtype)
294
299
  rtype = thing[:rtype]
295
300
  delete_user_groups(id, thing[:members])
301
+ origin = @things_by_id[id][:origin]
296
302
  @things_by_id.delete(id)
297
- thing = @things_by_name.delete(rtype.to_s + thing[NAME_ATTR[rtype]].downcase)
303
+ name = append_origin_to_username(rtype.to_s + thing[NAME_ATTR[rtype]].downcase, rtype, origin)
304
+ thing = @things_by_name.delete(name)
298
305
  delete_references(id)
299
306
  remove_attrs(output(thing))
300
307
  end
@@ -309,10 +316,19 @@ class StubScim
309
316
  end
310
317
 
311
318
  def get_by_name(name, rtype, *attrs)
319
+ name = append_origin_to_username(name, rtype, nil)
312
320
  return unless thing = ref_by_name(name, rtype)
313
321
  output(thing, attrs)
314
322
  end
315
323
 
324
+ def append_origin_to_username(name, rtype, origin)
325
+ if rtype == :user
326
+ origin = origin || 'uaa'
327
+ name = "#{name}_#{origin}"
328
+ end
329
+ name
330
+ end
331
+
316
332
  def find(rtype, opts = {})
317
333
  filter, total, start = ScimFilter.new(opts[:filter]), 0, (opts[:start] || 0)
318
334
  count, attrs, acl, acl_id = opts[:count], opts[:attrs], opts[:acl], opts[:acl_id]
data/spec/common_spec.rb CHANGED
@@ -42,6 +42,16 @@ describe CommonCli do
42
42
  end
43
43
  end
44
44
 
45
+ it "displays user help with -h has --origin option" do
46
+ Cli.run("user -h")
47
+ Cli.output.string.should include("--origin <identity provider origin, defaults to UAA>")
48
+ end
49
+
50
+ it "displays group help with -h has --origin option" do
51
+ Cli.run("group -h")
52
+ Cli.output.string.should include("--origin <origin>, map uaa scope to external group for this origin. Defaults to ldap.")
53
+ end
54
+
45
55
  it "gets commands in bash completion format" do
46
56
  Cli.run("help commands").should be
47
57
  [/--no-version/, /--version/, /^#{File.basename($0)}/, /help/].each do |s|
data/spec/info_spec.rb CHANGED
@@ -39,7 +39,7 @@ describe InfoCli do
39
39
 
40
40
  it "gets server info" do
41
41
  Cli.run("info").should be
42
- Cli.output.string.should match /\d.\d.\d/
42
+ Cli.output.string.should match /\d.\d+.\d+/
43
43
  Cli.output.string.should include "prompts", "commit_id"
44
44
  end
45
45
 
data/spec/user_spec.rb CHANGED
@@ -29,7 +29,7 @@ describe UserCli do
29
29
  @test_pwd = 'TesTpwd$%^'
30
30
  @test_user = "tEst_UseR_#{Time.now.to_i}"
31
31
  Cli.run("user add #{@test_user} -p #{@test_pwd} " +
32
- '--emails sam@example.com,joNES@sample.com --given_name SamueL ' +
32
+ '--emails sam@example.com --given_name SamueL ' +
33
33
  '--phones 801-555-1212 --family_name jonES').should be
34
34
  end
35
35
 
@@ -42,6 +42,97 @@ describe UserCli do
42
42
  Cli.output.string.should include 'success'
43
43
  end
44
44
 
45
+ it 'does not set a origin (defaults to uaa through api)' do
46
+ Cli.run("user get #{@test_user.upcase}").should_not include 'origin'
47
+ end
48
+
49
+ it 'sets an origin when specified' do
50
+ user_with_origin = "#{@test_user}_with_origin"
51
+ create_user_by_origin( user_with_origin, 'ldap')
52
+ Cli.run("user delete #{user_with_origin}")
53
+ end
54
+
55
+ it 'updates origin when specified' do
56
+ user_with_origin = "#{@test_user}_with_origin"
57
+ create_user_by_origin( user_with_origin, 'ldap')
58
+ create_user_by_origin( user_with_origin, 'saml')
59
+
60
+ Cli.run("user update #{user_with_origin} --origin saml --given_name snoopy")
61
+
62
+ returned_user = Cli.run("user get #{user_with_origin.upcase} --origin saml")
63
+ returned_user['origin'].should match 'saml'
64
+ returned_user['name']['givenname'].should match 'snoopy'
65
+ Cli.run("user delete #{user_with_origin} --origin saml")
66
+ Cli.run("user delete #{user_with_origin} --origin ldap")
67
+ end
68
+
69
+ it 'gets user when origin specified' do
70
+ user_with_diff_origin = "same_username_with_two_origins"
71
+ create_user_by_origin( user_with_diff_origin, 'ldap')
72
+ create_user_by_origin( user_with_diff_origin, 'saml')
73
+
74
+ returned_user = Cli.run("user get #{user_with_diff_origin.upcase} --origin ldap")
75
+ returned_user['origin'].should match 'ldap'
76
+ Cli.run("user delete #{user_with_diff_origin} --origin ldap")
77
+ Cli.run("user delete #{user_with_diff_origin} --origin saml")
78
+ end
79
+
80
+ it 'gets user when origin not specified' do
81
+ Cli.input = StringIO.new("1") # selecting first origin through stdin
82
+ user_with_diff_origin = "same_username_with_two_origins"
83
+ create_user_by_origin( user_with_diff_origin, 'ldap')
84
+ create_user_by_origin( user_with_diff_origin, 'saml')
85
+
86
+ Cli.run("user get #{user_with_diff_origin.upcase}")
87
+
88
+ expect(Cli.output.string).to match 'Select user:'
89
+ expect(Cli.output.string).to match 'ldap'
90
+ Cli.run("user delete #{user_with_diff_origin} --origin ldap")
91
+ Cli.run("user delete #{user_with_diff_origin} --origin saml")
92
+ end
93
+
94
+ it 'deletes user when origin not specified' do
95
+ Cli.input = StringIO.new("2") # selecting first origin through stdin
96
+ user_with_diff_origin = "same_username_with_two_origins"
97
+ create_user_by_origin( user_with_diff_origin, 'ldap')
98
+ create_user_by_origin( user_with_diff_origin, 'saml')
99
+
100
+ Cli.run("user delete #{user_with_diff_origin.upcase}")
101
+
102
+ expect(Cli.output.string).to match 'Select user:'
103
+ expect(Cli.output.string).to match 'successfully deleted'
104
+ Cli.run("user get #{user_with_diff_origin.upcase} --origin saml")
105
+ expect(Cli.output.string).to match 'NotFound'
106
+ Cli.run("user delete #{user_with_diff_origin} --origin ldap")
107
+ end
108
+
109
+ it 'updates user when origin not specified' do
110
+ Cli.input = StringIO.new("2") # selecting first origin through stdin
111
+ user_with_diff_origin = "same_username_with_two_origins"
112
+ create_user_by_origin( user_with_diff_origin, 'ldap')
113
+ create_user_by_origin( user_with_diff_origin, 'saml')
114
+
115
+ Cli.run("user update #{user_with_diff_origin.upcase} --given_name rumpelstiltskin")
116
+
117
+ expect(Cli.output.string).to match 'Select user:'
118
+ expect(Cli.output.string).to match 'successfully updated'
119
+ Cli.run("user get #{user_with_diff_origin.upcase} --origin saml")
120
+ expect(Cli.output.string).to match 'rumpelstiltskin'
121
+
122
+ Cli.run("user delete #{user_with_diff_origin} --origin saml")
123
+ Cli.run("user delete #{user_with_diff_origin} --origin ldap")
124
+ end
125
+
126
+ it 'deletes user when origin specified' do
127
+ user_with_diff_origin = "same_username_with_two_origins"
128
+ create_user_by_origin( user_with_diff_origin, 'ldap')
129
+ create_user_by_origin( user_with_diff_origin, 'saml')
130
+
131
+ Cli.run("user delete #{user_with_diff_origin.upcase} --origin ldap")
132
+ Cli.output.string.should include 'successfully deleted'
133
+ Cli.run("user delete #{user_with_diff_origin} --origin saml")
134
+ end
135
+
45
136
  it "fails to change a user's password with the wrong old pwd" do
46
137
  Cli.run('password change -p newpwd --old_password not-the-password').should be_nil
47
138
  end
@@ -84,6 +175,15 @@ describe UserCli do
84
175
  Cli.output.string.should include 'active: true'
85
176
  end
86
177
 
178
+ def create_user_by_origin(user_name, origin)
179
+ Cli.run("user add #{user_name} -p #{@test_pwd} " +
180
+ '--emails sam@example.com,joNES@sample.com --given_name SamueL ' +
181
+ "--phones 801-555-1212 --family_name jonES --origin #{origin}").should be
182
+ user_name = Cli.run("user get #{user_name.upcase} --origin #{origin}")
183
+ user_name['origin'].should match origin
184
+ user_name
185
+ end
186
+
87
187
  describe 'get list of users' do
88
188
  before :all do
89
189
  i = 1
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cf-uaac
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.10.0
4
+ version: 3.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Syer
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2017-03-24 00:00:00.000000000 Z
15
+ date: 2017-05-08 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: cf-uaa-lib
@@ -286,8 +286,8 @@ files:
286
286
  - ".travis.yml"
287
287
  - ".yardopts"
288
288
  - Gemfile
289
- - LICENSE.TXT
290
- - NOTICE.TXT
289
+ - LICENSE
290
+ - NOTICE
291
291
  - README.md
292
292
  - Rakefile
293
293
  - bin/completion-helper
data/NOTICE.TXT DELETED
@@ -1,10 +0,0 @@
1
- Cloud Foundry
2
- Copyright (c) [2009-2014] Pivotal Software, Inc. All Rights Reserved.
3
-
4
- This product is licensed to you under the Apache License, Version 2.0 (the "License").
5
- You may not use this product except in compliance with the License.
6
-
7
- This product includes a number of subcomponents with
8
- separate copyright notices and license terms. Your use of these
9
- subcomponents is subject to the terms and conditions of the
10
- subcomponent's license, as noted in the LICENSE file.