cf-uaac 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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