From b81db203b1cc2963b465c744ec81bf0a7b776556 Mon Sep 17 00:00:00 2001 From: Bodaniel Jeanes Date: Wed, 13 Oct 2010 17:11:57 -0700 Subject: [PATCH] WIP: Authentication support. --- features/authentication.feature | 15 ++++++++++ features/fixtures/authentication.config.xml | 30 +++++++++++++++++++ .../fixtures/no-authentication.config.xml | 28 +++++++++++++++++ features/fixtures/user.config.xml | 23 ++++++++++++++ features/step_definitions/hudson_steps.rb | 30 +++++++++++++++++-- features/support/hooks.rb | 19 ++++++++++++ hudson.gemspec | 4 +-- lib/hudson/cli.rb | 12 ++++++++ 8 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 features/authentication.feature create mode 100644 features/fixtures/authentication.config.xml create mode 100644 features/fixtures/no-authentication.config.xml create mode 100644 features/fixtures/user.config.xml diff --git a/features/authentication.feature b/features/authentication.feature new file mode 100644 index 0000000..f613b50 --- /dev/null +++ b/features/authentication.feature @@ -0,0 +1,15 @@ +@authentication +Feature: Authentication + In order to allow me to protect my source code and build status from outsiders + As a developer + I want to control a Hudson instance that requires authentication + + Background: + Given I have a Hudson server running + And the Hudson server has no current jobs + And managing the Hudson server requires authenticating + + Scenario: Not authenticated + When I run local executable "hudson" with arguments "list --host localhost --port 3010" + Then I should see "Authentication required. Please use --username and --password options" + diff --git a/features/fixtures/authentication.config.xml b/features/fixtures/authentication.config.xml new file mode 100644 index 0000000..f1db1cf --- /dev/null +++ b/features/fixtures/authentication.config.xml @@ -0,0 +1,30 @@ + + + 1.379 + 2 + NORMAL + true + + + false + + + + + 5 + 0 + + + + All + false + false + + + All + 0 + + + + + \ No newline at end of file diff --git a/features/fixtures/no-authentication.config.xml b/features/fixtures/no-authentication.config.xml new file mode 100644 index 0000000..9bb1d13 --- /dev/null +++ b/features/fixtures/no-authentication.config.xml @@ -0,0 +1,28 @@ + + + 1.379 + 2 + NORMAL + false + + + + + + 5 + 0 + + + + All + false + false + + + All + 0 + + + + + \ No newline at end of file diff --git a/features/fixtures/user.config.xml b/features/fixtures/user.config.xml new file mode 100644 index 0000000..f87c09c --- /dev/null +++ b/features/fixtures/user.config.xml @@ -0,0 +1,23 @@ + + + Foo Bar + + + All + + + + All + false + false + + + + + YfWKuO:65b9e18f77c17a84f78db759fc8018211416d71d3958e2c93ee6354ae3d5ed09 + + + foo@example.com + + + \ No newline at end of file diff --git a/features/step_definitions/hudson_steps.rb b/features/step_definitions/hudson_steps.rb index c73391c..eb514d9 100644 --- a/features/step_definitions/hudson_steps.rb +++ b/features/step_definitions/hudson_steps.rb @@ -42,13 +42,39 @@ job_url = "#{base_url}/computer/#{CGI::escape(name).gsub('+', '%20')}" res = Net::HTTP.start("localhost", port) { |http| http.post("#{job_url}/doDelete/api/json", {}) } end - hudson_info = Yajl::Parser.new.parse(open("http://#{@hudson_host}:#{@hudson_port}/api/json")) - hudson_info['jobs'].should == [] + hudson_info = Yajl::Parser.new.parse(open("http://#{base_url}/computes/api/json")) + hudson_info['computer'].should have(1).item else puts "WARNING: Run 'I have a Hudson server running' step first." end end +Given /^managing the Hudson server requires authenticating$/ do + if port = @hudson_port + require "fileutils" + + @hudson_home = "/tmp/test_hudson" + @user_dir = "#{@hudson_home}/admin" + fixtures = File.join(File.dirname(__FILE__), "..", "fixtures") + + FileUtils.mkdir_p(@user_dir) + FileUtils.cp(File.join(fixtures, "user.config.xml"), File.join(@user_dir, "config.xml")) + FileUtils.cp(File.join(fixtures, "authentication.config.xml"), File.join(@hudson_home, "config.xml")) + + Net::HTTP.start("localhost", port) do |http| + req = Net::HTTP::Post.new("/reload/api/json") + http.request(req) + end + + Net::HTTP.start("localhost", port) do |http| + sleep 1 while http.get("/").body =~ /Please wait while Hudson is getting ready to work/ + end + else + puts "WARNING: Run 'I have a Hudson server running' step first." + end +end + + Given /^there is nothing listening on port (\d+)$/ do |port| lambda { TCPSocket.open("localhost", port) {} diff --git a/features/support/hooks.rb b/features/support/hooks.rb index 684fe72..dfa30b0 100644 --- a/features/support/hooks.rb +++ b/features/support/hooks.rb @@ -2,6 +2,25 @@ Before do @hudson_cleanup = [] + + require "fileutils" + + FileUtils.cp( + File.join(File.join(File.dirname(__FILE__), "..", "fixtures"), "no-authentication.config.xml"), + File.join("/tmp/test_hudson", "config.xml") + ) + + port = @hudson_port || 3010 + + Net::HTTP.start("localhost", port) do |http| + req = Net::HTTP::Post.new("/reload/api/json") + req.basic_auth "admin", "password" + p http.request(req) + end + + Net::HTTP.start("localhost", port) do |http| + sleep 1 while http.get("/").body =~ /Please wait while Hudson is getting ready to work/ + end end After do diff --git a/hudson.gemspec b/hudson.gemspec index acecf21..b4b26f4 100644 --- a/hudson.gemspec +++ b/hudson.gemspec @@ -6,12 +6,12 @@ Gem::Specification.new do |s| s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version= s.authors = ["Charles Lowell", "Dr Nic Williams"] - s.date = %q{2010-10-11} + s.date = %q{2010-10-13} s.default_executable = %q{hudson} s.description = %q{A suite of utilities for bringing continous integration to your projects (not the other way around) with hudson CI} s.email = ["cowboyd@thefrontside.net", "drnicwilliams@gmail.com"] s.executables = ["hudson"] - s.files = ["bin", "bin/hudson", "features", "features/create_jobs.feature", "features/development.feature", "features/fixtures", "features/fixtures/projects", "features/fixtures/projects/ruby", "features/fixtures/projects/ruby/Rakefile", "features/listing_jobs.feature", "features/managing_remote_servers.feature", "features/server.feature", "features/step_definitions", "features/step_definitions/common_steps.rb", "features/step_definitions/fixture_project_steps.rb", "features/step_definitions/hudson_steps.rb", "features/step_definitions/scm_steps.rb", "features/support", "features/support/common.rb", "features/support/env.rb", "features/support/hooks.rb", "features/support/matchers.rb", "Gemfile", "Gemfile.lock", "hudson.gemspec", "lib", "lib/hudson", "lib/hudson/api.rb", "lib/hudson/cli", "lib/hudson/cli/formatting.rb", "lib/hudson/cli.rb", "lib/hudson/config.rb", "lib/hudson/hudson-cli.jar", "lib/hudson/hudson.war", "lib/hudson/job_config_builder.rb", "lib/hudson/plugins", "lib/hudson/plugins/git.hpi", "lib/hudson/plugins/github.hpi", "lib/hudson/plugins/greenballs.hpi", "lib/hudson/plugins/rake.hpi", "lib/hudson/plugins/ruby.hpi", "lib/hudson/project_scm.rb", "lib/hudson/remote.rb", "lib/hudson.rb", "Rakefile", "README.md", "spec", "spec/fixtures", "spec/fixtures/ec2_global.config.xml", "spec/fixtures/rails.multi.config.xml", "spec/fixtures/rails.single.config.xml", "spec/fixtures/rubygem.config.xml", "spec/fixtures/therubyracer.config.xml", "spec/job_config_builder_spec.rb", "spec/spec_helper.rb"] + s.files = ["bin", "bin/hudson", "features", "features/adding_slave_nodes.feature", "features/authentication.feature", "features/create_jobs.feature", "features/development.feature", "features/fixtures", "features/fixtures/authentication.config.xml", "features/fixtures/no-authentication.config.xml", "features/fixtures/projects", "features/fixtures/projects/ruby", "features/fixtures/projects/ruby/Rakefile", "features/fixtures/user.config.xml", "features/listing_jobs.feature", "features/managing_remote_servers.feature", "features/server.feature", "features/step_definitions", "features/step_definitions/common_steps.rb", "features/step_definitions/fixture_project_steps.rb", "features/step_definitions/hudson_steps.rb", "features/step_definitions/scm_steps.rb", "features/support", "features/support/common.rb", "features/support/env.rb", "features/support/hooks.rb", "features/support/matchers.rb", "Gemfile", "Gemfile.lock", "hudson.gemspec", "lib", "lib/hudson", "lib/hudson/api.rb", "lib/hudson/cli", "lib/hudson/cli/formatting.rb", "lib/hudson/cli.rb", "lib/hudson/config.rb", "lib/hudson/hudson-cli.jar", "lib/hudson/hudson.war", "lib/hudson/job_config_builder.rb", "lib/hudson/plugins", "lib/hudson/plugins/git.hpi", "lib/hudson/plugins/github.hpi", "lib/hudson/plugins/greenballs.hpi", "lib/hudson/plugins/rake.hpi", "lib/hudson/plugins/ruby.hpi", "lib/hudson/project_scm.rb", "lib/hudson/remote.rb", "lib/hudson.rb", "Rakefile", "README.md", "spec", "spec/fixtures", "spec/fixtures/ec2_global.config.xml", "spec/fixtures/rails.multi.config.xml", "spec/fixtures/rails.single.config.xml", "spec/fixtures/rubygem.config.xml", "spec/fixtures/therubyracer.config.xml", "spec/job_config_builder_spec.rb", "spec/spec_helper.rb"] s.homepage = %q{http://github.com/cowboyd/hudson.rb} s.require_paths = ["lib"] s.rubyforge_project = %q{hudson} diff --git a/lib/hudson/cli.rb b/lib/hudson/cli.rb index 84026a1..f8a7cac 100644 --- a/lib/hudson/cli.rb +++ b/lib/hudson/cli.rb @@ -75,6 +75,10 @@ def create(project_path = ".") def list select_hudson_server(options) if summary = Hudson::Api.summary + if summary["useSecurity"] == true && !authenticating? + raise_authentication_error + end + unless summary["jobs"].blank? shell.say "#{@uri} -" summary["jobs"].each do |job| @@ -155,6 +159,14 @@ def self.help(shell, *) private + def raise_authentication_error + error "#{@uri} - Authentication required. Please use --username and --password options" + end + + def authenticating? + false + end + def select_hudson_server(options) unless @uri = Hudson::Api.setup_base_url(options) error "Either use --host or add remote servers."