cf-uaac 1.3.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.
@@ -0,0 +1,104 @@
1
+ #--
2
+ # Cloud Foundry 2012.02.03 Beta
3
+ # Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the Apache License, Version 2.0 (the "License").
6
+ # You may not use this product except in compliance with the License.
7
+ #
8
+ # This product includes a number of subcomponents with
9
+ # separate copyright notices and license terms. Your use of these
10
+ # subcomponents is subject to the terms and conditions of the
11
+ # subcomponent's license, as noted in the LICENSE file.
12
+ #++
13
+
14
+ require 'spec_helper'
15
+ require 'cli'
16
+
17
+ module CF::UAA
18
+
19
+ describe ClientCli do
20
+
21
+ include SpecHelper
22
+
23
+ before :all do
24
+ #Util.default_logger(:trace)
25
+ Cli.configure("", nil, StringIO.new, true)
26
+ setup_target(authorities: "scim.read", grant_types: "client_credentials")
27
+ @test_user, @test_pwd = "sam_#{Time.now.to_i}", "correcthorsebatterystaple"
28
+ end
29
+
30
+ after :all do cleanup_target end
31
+
32
+ it "registers a new client" do
33
+ @test_client.should be # actually registered in the before :all block
34
+ end
35
+
36
+ it "gets a client registration" do
37
+ Cli.run("client get #{@test_client}").should be
38
+ Cli.output.string.should include @test_client
39
+ end
40
+
41
+ it "lists client registrations" do
42
+ Cli.run("clients").should be
43
+ Cli.output.string.should include @admin_client, @test_client
44
+ end
45
+
46
+ context "as test client" do
47
+
48
+ before :all do
49
+ Cli.run("token client get #{@test_client} -s #{@test_secret}").should be
50
+ end
51
+
52
+ it "logs in as test client" do
53
+ Cli.run("context").should be # login was in before :all block
54
+ Cli.output.string.should include "access_token", @test_client
55
+ end
56
+
57
+ it "fails to create a user account as test client" do
58
+ Cli.run("user add #{@test_user} -p #{@test_pwd}").should be_nil
59
+ Cli.output.string.should include "insufficient_scope"
60
+ end
61
+
62
+ context "as updated client" do
63
+
64
+ before :all do
65
+ # update the test client as the admin client
66
+ Cli.run("token client get #{@test_client} -s #{@test_secret}").should be
67
+ Cli.run("context #{@admin_client}").should be
68
+ Cli.run("client update #{@test_client} --authorities scim.write,scim.read").should be
69
+ Cli.run("client get #{@test_client}").should be
70
+ Cli.output.string.should include "scim.read", "scim.write"
71
+ end
72
+
73
+ it "fails to create a user account with old token" do
74
+ Cli.run("context #{@test_client}").should be
75
+ Cli.run("user add #{@test_user} -p #{@test_pwd}").should be_nil
76
+ Cli.output.string.should include "insufficient_scope"
77
+ end
78
+
79
+ it "creates a user account with a new token" do
80
+ Cli.run("context #{@test_client}").should be
81
+ Cli.run("token client get #{@test_client} -s #{@test_secret}").should be
82
+ Cli.run("token decode")
83
+ Cli.run("user add #{@test_user.capitalize} -p #{@test_pwd} --email #{@test_user}@example.com --family_name #{@test_user.capitalize} --given_name joe").should be
84
+ Cli.output.string.should_not include "insufficient_scope"
85
+ Cli.run("user get #{@test_user}").should be
86
+ Cli.output.string.should include @test_user.capitalize
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ context "as admin client" do
93
+ it "deletes a client registration" do
94
+ client = @test_client.dup
95
+ @test_client.replace("")
96
+ Cli.run("context #{@admin_client}").should be
97
+ Cli.run("client delete #{client}").should be
98
+ Cli.output.string.should include "deleted"
99
+ end
100
+ end
101
+
102
+ end
103
+
104
+ end
@@ -0,0 +1,89 @@
1
+ #--
2
+ # Cloud Foundry 2012.02.03 Beta
3
+ # Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the Apache License, Version 2.0 (the "License").
6
+ # You may not use this product except in compliance with the License.
7
+ #
8
+ # This product includes a number of subcomponents with
9
+ # separate copyright notices and license terms. Your use of these
10
+ # subcomponents is subject to the terms and conditions of the
11
+ # subcomponent's license, as noted in the LICENSE file.
12
+ #++
13
+
14
+ require 'spec_helper'
15
+ require 'stringio'
16
+ require 'cli'
17
+
18
+ module CF::UAA
19
+
20
+ describe CommonCli do
21
+
22
+ include SpecHelper
23
+
24
+ before :each do
25
+ Util.default_logger(:trace)
26
+ Cli.configure("", nil, StringIO.new, true)
27
+ end
28
+
29
+ ["-v", "version", "--version"].each do |opt|
30
+ it "displays a version with #{opt}" do
31
+ Cli.run(opt).should be
32
+ Cli.output.string.should include CLI_VERSION
33
+ end
34
+ end
35
+
36
+ ["help", "-h"].each do |opt|
37
+ it "displays general help with #{opt}" do
38
+ Cli.run(opt).should be
39
+ ["UAA Command Line Interface", "System Information", "Tokens", "User Accounts"].each do |s|
40
+ Cli.output.string.should include s
41
+ end
42
+ end
43
+ end
44
+
45
+ it "gets commands in bash completion format" do
46
+ Cli.run("help commands").should be
47
+ [/--no-version/, /--version/, /^#{File.basename($0)}/, /help/].each do |s|
48
+ Cli.output.string.should match(s)
49
+ end
50
+ end
51
+
52
+ ["help targets", "targets -h", "-h targets"].each do |opt|
53
+ it "displays command specific help like: #{opt}" do
54
+ Cli.run(opt).should be
55
+ Cli.output.string.should include("Display all targets")
56
+ end
57
+ end
58
+
59
+ it "sets a target in the config file" do
60
+ Cli.run("target example.com --force").should be
61
+ Config.yaml.should include "https://example.com"
62
+ end
63
+
64
+ it "strips trailing / from target" do
65
+ Cli.run("target example.com/uaa/ --force")
66
+ Config.yaml.should include "https://example.com/uaa"
67
+ Config.yaml.should_not include "https://example.com/uaa/"
68
+ end
69
+
70
+ it "sets multiple targets to be forced qualified in config and targets output" do
71
+ Cli.run("target example.com --force")
72
+ Cli.run("target example2.com --force")
73
+ Cli.run("targets").should be
74
+ Config.yaml.should include "https://example.com", "https://example2.com"
75
+ Cli.output.string.should include "https://example.com", "https://example2.com"
76
+ end
77
+
78
+ it "gets it's configuration from alternate source when specified" do
79
+ Cli.run("target --force foo.bar --config").should be
80
+ Config.yaml.should include "foo\.bar"
81
+ Cli.run "target --force baz.com --config"
82
+ Config.yaml.should include "baz\.com"
83
+ Config.yaml.should_not include "foo\.bar"
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
@@ -0,0 +1,93 @@
1
+ #--
2
+ # Cloud Foundry 2012.02.03 Beta
3
+ # Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the Apache License, Version 2.0 (the "License").
6
+ # You may not use this product except in compliance with the License.
7
+ #
8
+ # This product includes a number of subcomponents with
9
+ # separate copyright notices and license terms. Your use of these
10
+ # subcomponents is subject to the terms and conditions of the
11
+ # subcomponent's license, as noted in the LICENSE file.
12
+ #++
13
+
14
+ require 'spec_helper'
15
+ require 'cli'
16
+
17
+ module CF::UAA
18
+
19
+ describe GroupCli do
20
+
21
+ include SpecHelper
22
+
23
+ before :all do
24
+ #Util.default_logger(:trace)
25
+ Cli.configure("", nil, StringIO.new, true)
26
+ setup_target(authorities: "clients.read,scim.read,scim.write")
27
+ Cli.run("token client get #{@test_client} -s #{@test_secret}").should be
28
+ @test_user, @test_pwd = "sam_#{Time.now.to_i}", "correcthorsebatterystaple"
29
+ @test_group = "JaNiToRs_#{Time.now.to_i}"
30
+ end
31
+
32
+ after :all do cleanup_target end
33
+ before :each do Cli.output.string = "" end
34
+
35
+ it "creates many users and a group as the test client" do
36
+ Cli.run "context #{@test_client}"
37
+ Cli.run("user add #{@test_user.upcase} -p #{@test_pwd} " +
38
+ "--email joey@example.com --family_name JONES --given_name JOE").should be
39
+ 29.times { |i| Cli.run("user add #{@test_user.capitalize}-#{i} -p #{@test_pwd} " +
40
+ "--email #{@test_user}+#{i}@example.com " +
41
+ "--family_name #{@test_user.capitalize} --given_name joe").should be }
42
+ Cli.run("group add #{@test_group}").should be
43
+ Cli.run("groups -a displayName").should be
44
+ Cli.output.string.should include @test_group
45
+ end
46
+
47
+ it "gets attributes with case-insensitive attribute names" do
48
+ Cli.run("groups -a displayname").should be
49
+ Cli.output.string.should include @test_group
50
+ end
51
+
52
+ it "lists all users" do
53
+ Cli.run("users -a UsernamE").should be
54
+ 29.times { |i| Cli.output.string.should =~ /#{@test_user.capitalize}-#{i}/i }
55
+ end
56
+
57
+ it "preserves case in names" do
58
+ Cli.run("users -a username").should be
59
+ 29.times { |i| Cli.output.string.should =~ /#{@test_user.capitalize}-#{i}/ }
60
+ end
61
+
62
+ it "lists a page of users" do
63
+ Cli.run("users -a userName --count 13 --start 5").should be
64
+ Cli.output.string.should match /itemsPerPage: 13/i
65
+ Cli.output.string.should match /startIndex: 5/i
66
+ end
67
+
68
+ it "adds users to the group" do
69
+ cmd = "member add #{@test_group}"
70
+ 29.times { |i| cmd << " #{@test_user.capitalize}-#{i}" }
71
+ Cli.run(cmd).should be
72
+ Cli.output.string.should include "success"
73
+ end
74
+
75
+ it "adds one user to the group" do
76
+ Cli.run("member add #{@test_group} #{@test_user}").should be
77
+ Cli.output.string.should include "success"
78
+ end
79
+
80
+ it "deletes all members from a group" do
81
+ pending "waiting on bug fix in uaa, [40594865]" if ENV["UAA_CLIENT_TARGET"]
82
+ cmd = "member delete #{@test_group} #{@test_user.capitalize}"
83
+ 29.times { |i| cmd << " #{@test_user.capitalize}-#{i}" }
84
+ Cli.run(cmd).should be
85
+ Cli.output.string.should include "success"
86
+ # and they should really be gone
87
+ Cli.run("group get #{@test_group}")
88
+ Cli.output.string.should_not match /members/i
89
+ end
90
+
91
+ end
92
+
93
+ end
data/spec/http_spec.rb ADDED
@@ -0,0 +1,165 @@
1
+ #--
2
+ # Cloud Foundry 2012.02.03 Beta
3
+ # Copyright (c) [2009-2012] VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the Apache License, Version 2.0 (the "License").
6
+ # You may not use this product except in compliance with the License.
7
+ #
8
+ # This product includes a number of subcomponents with
9
+ # separate copyright notices and license terms. Your use of these
10
+ # subcomponents is subject to the terms and conditions of the
11
+ # subcomponent's license, as noted in the LICENSE file.
12
+ #++
13
+
14
+ require 'spec_helper'
15
+ require 'fiber'
16
+ require 'net/http'
17
+ require 'em-http'
18
+ require 'uaa/http'
19
+ require 'cli/version'
20
+ require 'stub/server'
21
+
22
+ module CF::UAA
23
+
24
+ class StubHttp < Stub::Base
25
+ route(:get, '/') { reply_in_kind "welcome to stub http, version #{CLI_VERSION}" }
26
+ route( :get, '/bad') { reply.headers[:location] = ":;+)(\/"; reply_in_kind(3, "bad http status code") }
27
+ end
28
+
29
+ class HttpClient
30
+ include Http
31
+ end
32
+
33
+ describe Http do
34
+
35
+ include SpecHelper
36
+
37
+ before :all do
38
+ @stub_http = Stub::Server.new(StubHttp, Util.default_logger(:info)).run_on_thread
39
+ end
40
+
41
+ after :all do @stub_http.stop if @stub_http end
42
+
43
+ it "gets something from stub server on a fiber" do
44
+ frequest(true) {
45
+ f = Fiber.current
46
+ http = EM::HttpRequest.new("#{@stub_http.url}/").get
47
+ http.errback { f.resume "error" }
48
+ http.callback {
49
+ http.response_header.http_status.should == 200
50
+ f.resume http.response
51
+ }
52
+ Fiber.yield
53
+ }.should match /welcome to stub http/
54
+ end
55
+
56
+ it "uses persistent connections from stubserver" do
57
+ frequest(true) {
58
+ f = Fiber.current
59
+ conn = EM::HttpRequest.new("#{@stub_http.url}/")
60
+ req1 = conn.get keepalive: true
61
+ req1.errback { f.resume "error1" }
62
+ req1.callback {
63
+ req2 = conn.get
64
+ req2.errback { f.resume req2.error }
65
+ req2.callback { f.resume req2.response }
66
+ }
67
+ Fiber.yield
68
+ }.should match /welcome to stub http/
69
+ end
70
+
71
+ it "gets something from stub server on a thread" do
72
+ @async = false
73
+ resp = Net::HTTP.get(URI("#{@stub_http.url}/"))
74
+ resp.should match /welcome to stub http/
75
+ end
76
+
77
+ shared_examples_for "http client" do
78
+
79
+ # the following is intended to test that a failed dns lookup will fail the
80
+ # same way on the buggy em-http-request 1.0.0.beta3 client as it does on
81
+ # the rest-client. However, some networks (such as the one I am on now)
82
+ # configure the dhcp client with a dns server that will resolve
83
+ # every name as a valid address, e.g. bad.example.bad returns an address
84
+ # to a service signup screen. I have tried stubbing the code in various
85
+ # ways:
86
+ # EventMachine.stub(:connect) { raise EventMachine::ConnectionError, "fake error for bad dns lookup" }
87
+ # EventMachine.unstub(:connect)
88
+ # Socket.stub(:gethostbyname) { raise SocketError, "getaddrinfo: Name or service not known" }
89
+ # Socket.unstub(:gethostbyname)
90
+ # This has had varied success but seems rather brittle. Currently I have opted
91
+ # to just make the domain name invalid with tildes, but this may not test
92
+ # the desired code paths
93
+ it "fails cleanly for a failed dns lookup" do
94
+ result = frequest(@on_fiber) { @client.http_get("http://bad~host~name/") }
95
+ result.should be_an_instance_of BadTarget
96
+ end
97
+
98
+ it "fails cleanly for a get operation, no connection to address" do
99
+ result = frequest(@on_fiber) { @client.http_get("http://127.0.0.1:30000/") }
100
+ result.should be_an_instance_of BadTarget
101
+ end
102
+
103
+ it "fails cleanly for a get operation with bad response" do
104
+ frequest(@on_fiber) { @client.http_get(@stub_http.url, "/bad") }.should be_an_instance_of HTTPException
105
+ end
106
+
107
+ it "works for a get operation to a valid address" do
108
+ status, body, headers = frequest(@on_fiber) { @client.http_get(@stub_http.url, "/") }
109
+ status.should == 200
110
+ body.should match /welcome to stub http/
111
+ end
112
+
113
+ it "should send debug information to a custom logger" do
114
+ class CustomLogger
115
+ attr_reader :log
116
+ def initialize; @log = "" end
117
+ def debug(str = nil) ; @log << (str ? str : yield) end
118
+ end
119
+ @client.logger = clog = CustomLogger.new
120
+ clog.log.should be_empty
121
+ frequest(@on_fiber) { @client.http_get(@stub_http.url, "/") }
122
+ clog.log.should_not be_empty
123
+ end
124
+ end
125
+
126
+ context "on a fiber" do
127
+ before :all do
128
+ @on_fiber = true
129
+ @client = HttpClient.new
130
+ @client.set_request_handler do |url, method, body, headers|
131
+ f = Fiber.current
132
+ connection = EventMachine::HttpRequest.new(url, connect_timeout: 2, inactivity_timeout: 2)
133
+ client = connection.setup_request(method, head: headers, body: body)
134
+
135
+ # This check is for proper error handling with em-http-request 1.0.0.beta.3
136
+ if defined?(EventMachine::FailedConnection) && connection.is_a?(EventMachine::FailedConnection)
137
+ raise BadTarget, "HTTP connection setup error: #{client.error}"
138
+ end
139
+
140
+ client.callback { f.resume [client.response_header.http_status, client.response, client.response_header] }
141
+ client.errback { f.resume [:error, client.error] }
142
+ result = Fiber.yield
143
+ if result[0] == :error
144
+ raise BadTarget, "connection failed" unless result[1] && result[1] != ""
145
+ raise BadTarget, "connection refused" if result[1].to_s =~ /ECONNREFUSED/
146
+ raise BadTarget, "unable to resolve address" if /unable.*server.*address/.match result[1]
147
+ raise HTTPException, result[1]
148
+ end
149
+ [result[0], result[1], Util.hash_keys!(result[2], :todash)]
150
+ end
151
+ end
152
+ it_should_behave_like "http client"
153
+ end
154
+
155
+ context "on a thread" do
156
+ before :all do
157
+ @on_fiber = false
158
+ @client = HttpClient.new
159
+ end
160
+ it_should_behave_like "http client"
161
+ end
162
+
163
+ end
164
+
165
+ end