cf-uaac 3.10.0 → 3.11.0

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 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.