diff options
author | Patrick J Cherry <patrick@bytemark.co.uk> | 2012-04-21 13:37:12 +0100 |
---|---|---|
committer | Patrick J Cherry <patrick@bytemark.co.uk> | 2012-04-21 13:37:12 +0100 |
commit | 84b1abf30fe79032209cb0fcd0bfa9d6aaf37721 (patch) | |
tree | 403433b040d2b51b5d40c56b10a530e7fcf2aef4 /test | |
parent | 392a87cfa181a762bf4b3244aa3c6d065ef15253 (diff) |
Overhaul of authentication.
* Added new configuration options:
** bytemark_calendar_url
** bytemark_auth_url
** remote_https_verify_mode
** remote_http_timeout
** failed_login_delay
* Added authentication tests
* Removed remote auth tests in from the web interface tests.
* If no bytemark_auth_url is set, then no remote auth takes place.
* SSL peer cert validation now takes place by default.
* Removed old logic tests
* Tidied the way tests take place a little.
Diffstat (limited to 'test')
-rw-r--r-- | test/alert_and_notification_logic.rb | 391 | ||||
-rw-r--r-- | test/tc_mauve_authentication.rb | 168 | ||||
-rw-r--r-- | test/tc_mauve_web_interface.rb | 18 | ||||
-rw-r--r-- | test/test_mauve.rb | 21 | ||||
-rw-r--r-- | test/th_mauve.rb | 4 |
5 files changed, 179 insertions, 423 deletions
diff --git a/test/alert_and_notification_logic.rb b/test/alert_and_notification_logic.rb deleted file mode 100644 index 19b2478..0000000 --- a/test/alert_and_notification_logic.rb +++ /dev/null @@ -1,391 +0,0 @@ -# Mauve server tests - alerts and notification logic. Define the basic workings -# so that we know what should happen when we send sequences of alerts at -# different times. -# -# These aren't really unit tests, just narrative specifications as to what -# should happen under what stimuli. I suspect I will break these down into -# smaller units if things break under otherwise difficult conditions. -# - -$: << __FILE__.split("/")[0..-2].join("/") -require 'test/unit' -require 'mauve_test_helper' -require 'mauve_time' - -class AlertAndNotificationLogic < Test::Unit::TestCase - include MauveTestHelper - - def configuration_template - <<-TEMPLATE - # This is the head of all the configuration files. Filenames are relative - # to the cwd, which is assumed to be a fleeting test directory. - - server { - ip "127.0.0.1" - port #{@port_alerts ||= 44444} - log_file ENV['TEST_LOG'] ? STDOUT : "#{dir}/log" - log_level 0 - database "sqlite3:///#{dir}/mauve_test.db" - transmission_id_expire_time 600 - - # doesn't restart nicely at the moment - #web_interface { - # port #{@port_web ||= 44444} - #} - } - - # - # All notifications are sent to files which we can open up and check during - # our tests. Network delivery is not tested in this script. - # - - notification_method("xmpp") { - deliver_to_queue AlertAndNotificationLogic::Notifications - deliver_to_file "#{dir}/xmpp.txt" - disable_normal_delivery! - - jid "mauveserv@chat.bytemark.co.uk" - password "foo" - } - - notification_method("email") { - deliver_to_queue AlertAndNotificationLogic::Notifications - deliver_to_file "#{dir}/email.txt" - disable_normal_delivery! - - # add in SMTP server, username, password etc. - # default to sending through localhost - from "matthew@bytemark.co.uk" - server "bytemail.bytemark.co.uk" - subject_prefix "[Bytemark alerts] " - - } - - notification_method("sms") { - provider "AQL" - deliver_to_queue AlertAndNotificationLogic::Notifications - deliver_to_file "#{dir}/sms.txt" - disable_normal_delivery! - - username "x" - password "x" - from "01904890890" - max_messages_per_alert 3 - } - - # a person common to all our tests - - person("joe_bloggs") { - urgent { sms("12345") } - normal { email("12345@joe_bloggs.email") } - low { xmpp("12345@joe_bloggs.xmpp") } - } - - person("jimmy_junior") { - urgent { sms("66666") } - normal { email("jimmy@junior.email") } - low { email("jimmy@junior.email") } - } - - alert_group { - includes { source == "rare-and-important" } - acknowledgement_time 60.minutes - level URGENT - - notify("joe_bloggs") { every 10.minutes } - } - - alert_group { - includes { source == "noisy-and-annoying" || alert_id == "whine" } - acknowledgement_time 24.hours - level LOW - - notify("jimmy_junior") { every 2.hours } - notify("joe_bloggs") { - every 30.minutes - during { - unacknowledged 6.hours - } - } - } - - alert_group { - includes { source == "can-wait-until-monday" } - level NORMAL - - notify("jimmy_junior") { - every 30.minutes - during { days_in_week(1..5) && hours_in_day(9..5) } - } - notify("joe_bloggs") { - every 2.hours - during { days_in_week(1..5) && hours_in_day(9..5) } - } - } - - # catch-all - alert_group { - acknowledgement_time 1.minute - level NORMAL - - notify("joe_bloggs") { every 1.hour } - } - TEMPLATE - end - - def setup - start_server(configuration_template) - end - - def teardown - stop_server - # no tests should leave notifications on the stack - assert_no_notification - end - - # Raise one alert, check representation in database, and that alert is - # received as expected. - # - def test_basic_fields_are_recognised - mauvesend("-o my_source -i alert1 -s \"alert1 summary\" -d \"alert1 detail\" -u \"alert1 subject\"") - - assert_not_nil(alert = Alert.first) - assert_equal("my_source", alert.source) - assert_equal("alert1", alert.alert_id) - assert_equal("alert1 summary", alert.summary) - assert_equal("alert1 detail", alert.detail) - assert_equal("alert1 subject", alert.subject) - assert(alert.raised?) - assert(!alert.cleared?) - assert(!alert.acknowledged?) - - with_next_notification do |destination, this_alert, other_alerts| - assert_equal("12345@joe_bloggs.email", destination) - assert_equal(Alert.first, this_alert) - assert_equal([Alert.first], other_alerts) - end - - end - - # Check that a simple automatic raise, acknowledge & auto-clear request - # work properly. - # - def test_auto_raise_and_clear - # Raise the alert, wait for it to be processed - mauvesend("-o my_source -i alert1 -s \"alert1 summary\" -d \"alert1 detail\" -u \"alert1 subject\" -r +5m -c +10m") - - # Check internal state - # - assert(!Alert.first.raised?, "Auto-raising alert raised early") - assert(!Alert.first.cleared?, "Auto-clearing alert cleared early") - assert(!Alert.first.acknowledged?, "Alert acknowledged when I didn't expect it") - - # We asked for it to be raised in 5 minutes, so no alert yet... - # - assert_no_notification - - # Push forward to when the alert should be raised, check it has been - # - Time.advance(5.minutes) - assert(Alert.first.raised?, "#{Alert.first.inspect} should be raised by now") - assert(!Alert.first.cleared?, "#{Alert.first.inspect} should not be cleared") - - # Check that we have a notification - # - with_next_notification do |destination, this_alert, other_alerts| - assert_equal("12345@joe_bloggs.email", destination) - assert_equal(Alert.first, this_alert) - assert_equal('raised', this_alert.update_type) - end - - # Simulate manual acknowledgement - # - Alert.first.acknowledge!(Configuration.current.people["joe_bloggs"]) - Timers.restart_and_then_wait_until_idle - assert(Alert.first.acknowledged?, "Acknowledgement didn't work") - - # Check that the acknowledgement has caused a notification - # - with_next_notification do |destination, this_alert, other_alerts| - assert_equal("12345@joe_bloggs.email", destination) - assert_equal(Alert.first, this_alert) - assert_equal('acknowledged', this_alert.update_type, this_alert.inspect) - end - assert(Alert.first.acknowledged?) - assert(Alert.first.raised?) - assert(!Alert.first.cleared?) - - # Now with the config set to un-acknowledge alerts after only 1 minute, - # try winding time on and check that this happens. - # - Time.advance(2.minutes) - with_next_notification do |destination, this_alert, other_alerts| - assert_equal("12345@joe_bloggs.email", destination) - assert_equal(Alert.first, this_alert) - assert_equal('raised', this_alert.update_type, this_alert.inspect) - end - - # Check that auto-clearing works four minutes later - # - Time.advance(5.minutes) - assert(Alert.first.cleared?) - assert(!Alert.first.raised?) - - # Finally check for a notification that auto-clearing has happened - # - with_next_notification do |destination, this_alert, other_alerts| - assert_equal("12345@joe_bloggs.email", destination) - assert_equal(Alert.first, this_alert) - assert_equal('cleared', this_alert.update_type, this_alert.inspect) - end - - # And see that no further reminders are sent a while later - Time.advance(1.day) - assert_no_notification - end - - def test_one_alert_changes_from_outside - # Raise our test alert, wait for it to be processed - mauvesend("-o my_source -i alert1 -s \"alert1 summary\" -d \"alert1 detail\" -u \"alert1 subject\"") - - # Check internal representation, external notification - # - assert(Alert.first.raised?) - assert(!Alert.first.cleared?) - with_next_notification do |destination, this_alert, other_alerts| - assert_equal('raised', this_alert.update_type, this_alert.inspect) - end - - # Check we get reminders every hour, and no more - # - 12.times do - Time.advance(1.hour) - with_next_notification do |destination, this_alert, other_alerts| - assert_equal('raised', this_alert.update_type, this_alert.inspect) - end - assert_no_notification - end - - # Clear the alert, wait for it to be processed - mauvesend("-o my_source -i alert1 -c now") - assert(!Alert.first.raised?) - assert(Alert.first.cleared?) - with_next_notification do |destination, this_alert, other_alerts| - assert_equal('cleared', this_alert.update_type, this_alert.inspect) - end - - # Check we can raise the same alert again - Time.advance(1.minute) - mauvesend("-o my_source -i alert1 -s \"alert1 summary\" -d \"alert1 detail\" -u \"alert1 subject\" -r now") - assert(Alert.first.raised?, Alert.first.inspect) - assert(!Alert.first.cleared?, Alert.first.inspect) - with_next_notification do |destination, this_alert, other_alerts| - assert_equal('raised', this_alert.update_type, this_alert.inspect) - end - end - - def test_alert_groups - # check that this alert is reminded more often than normal - mauvesend("-o rare-and-important -i alert1 -s \"rare and important alert\"") - assert(Alert.first.raised?) - assert(!Alert.first.cleared?) - - 10.times do - with_next_notification do |destination, this_alert, other_alerts| - assert_equal('raised', this_alert.update_type, this_alert.inspect) - assert_equal('12345', destination) - Time.advance(10.minutes) - end - end - discard_next_notification - end - - def test_future_raising - mauvesend("-i heartbeat -c now -r +10m -s \"raise in the future\"") - assert(!Alert.first.raised?) - assert(Alert.first.cleared?) - assert_no_notification - - # Check the future alert goes off - # - Time.advance(10.minutes) - assert(Alert.first.raised?) - assert(!Alert.first.cleared?) - with_next_notification do |destination, this_alert, other_alerts| - assert_equal('raised', this_alert.update_type, this_alert.inspect) - end - - # Check that a repeat of the "heartbeat" update clears it, and we get - # a notification. - # - mauvesend("-i heartbeat -c now -r +10m -s \"raise in the future\"") - assert(!Alert.first.raised?) - assert(Alert.first.cleared?) - with_next_notification do |destination, this_alert, other_alerts| - assert_equal('cleared', this_alert.update_type, this_alert.inspect) - end - - # Check that a re-send of the same clear alert doesn't send another - # notification - # - Time.advance(1.minute) - mauvesend("-i heartbeat -c now -r +10m -s \"raise in the future\"") - assert(!Alert.first.raised?) - assert(Alert.first.cleared?) - assert_no_notification - - # Check that a skewed resend doesn't confuse it - # - mauvesend("-i heartbeat -c +1m -r +11m -s \"raise in the future\"") - assert(!Alert.first.raised?) - assert(Alert.first.cleared?) - Time.advance(1.minute) - assert(!Alert.first.raised?) - assert(Alert.first.cleared?) - assert_no_notification - end - - # Make sure that using the "replace all flag" works as expected. - # - def test_replace_flag - mauvesend("-p") - #mauvesend("-p") - assert_no_notification - - mauvesend("-i test1 -s\"\test1\"") - assert(Alert.first.raised?) - with_next_notification do |destination, this_alert, other_alerts| - assert_equal('raised', this_alert.update_type, this_alert.inspect) - end - assert_no_notification - - mauvesend("-p") - #mauvesend("-p") - with_next_notification do |destination, this_alert, other_alerts| - assert_equal('cleared', this_alert.update_type, this_alert.inspect) - end - assert_no_notification - end - - def test_earliest_date - alert = Alert.create!( - :alert_id => "test_id", - :source => "test1", - :subject => "test subject", - :summary => "test summary", - :raised_at => nil, - :will_raise_at => Time.now + 60, - :will_clear_at => Time.now + 120, - :update_type => "cleared", - :updated_at => Time.now - ) - assert(alert) - - assert(AlertEarliestDate.first.alert == alert) - end - -end - - - - diff --git a/test/tc_mauve_authentication.rb b/test/tc_mauve_authentication.rb new file mode 100644 index 0000000..d0f2d4f --- /dev/null +++ b/test/tc_mauve_authentication.rb @@ -0,0 +1,168 @@ +$:.unshift "../lib" + + +require 'th_mauve' +require 'th_mauve_resolv' + +require 'mauve/server' +require 'mauve/authentication' +require 'mauve/configuration' +require 'mauve/configuration_builder' +require 'mauve/configuration_builders' + +class TcMauveAuthentication < Mauve::UnitTest + include Mauve + + + def setup + super + setup_database + end + + def teardown + teardown_database + super + end + + def test_default_auth_always_fails + config=<<EOF +server { + failed_login_delay 0 +} +EOF + + Configuration.current = ConfigurationBuilder.parse(config) + Server.instance.setup + assert_equal(false, Authentication.authenticate("test","password")) + # + # No warning + # + assert_nil(logger_shift) + + end + + def test_local_auth + config=<<EOF +server { + failed_login_delay 0 +} + +person ("test") { + password "#{Digest::SHA1.new.hexdigest("password")}" + all { true } +} +EOF + + Configuration.current = ConfigurationBuilder.parse(config) + Server.instance.setup + assert(!Authentication.authenticate("test","badpassword")) + # + # Should warn that a bad password has been used. + # + assert_match(/AuthLocal for test failed/, logger_shift) + assert(Authentication.authenticate("test","password")) + # + # No warnings + # + assert_nil(logger_shift) + end + + + def test_local_auth + config=<<EOF +server { + failed_login_delay 0 +} + +person ("nopass") { } + +person ("test") { + password "#{Digest::SHA1.new.hexdigest("password")}" +} +EOF + + Configuration.current = ConfigurationBuilder.parse(config) + Server.instance.setup + assert(!Authentication.authenticate("nopass","badpassword")) + logger_shift + assert(!Authentication.authenticate("test","badpassword")) + logger_shift + assert(Authentication.authenticate("test","password")) + end + + def test_bytemark_auth + # + # BytemarkAuth test users are: + # test1: ummVRu7qF + # test2: POKvBqLT7 + # + config=<<EOF +server { + failed_login_delay 0 + bytemark_auth_url "https://auth.bytemark.co.uk/" +} + +person ("test1") { } + +person ("test2") { + password "#{Digest::SHA1.new.hexdigest("password")}" +} + +person ("test3") { + password "#{Digest::SHA1.new.hexdigest("password")}" +} +EOF + + Configuration.current = ConfigurationBuilder.parse(config) + Server.instance.setup + + # + # Test to make sure auth can fail + # + assert(!Authentication.authenticate("test1","password")) + # + # Should issue a warning for just bytemark auth failing, and no more. + # + assert_match(/AuthBytemark for test1 failed/, logger_shift) + assert_nil(logger_shift) + + assert(Authentication.authenticate("test1","ummVRu7qF")) + # + # Shouldn't issue any warnings. + # + assert_nil(logger_shift) + + # + # Test to make sure that in the event of failure we fall back to local + # auth, which should also fail in this case. + # + assert(!Authentication.authenticate("test2","badpassword")) + assert_match(/AuthBytemark for test2 failed/, logger_shift) + assert_match(/AuthLocal for test2 failed/, logger_shift) + + # + # Test to make sure that in the event of failure we fall back to local + # auth, which should pass in this case. + # + assert(Authentication.authenticate("test2","password")) + # + # Should issue a warning for just bytemark auth failing, and no more. + # + assert_match(/AuthBytemark for test2 failed/, logger_shift) + assert_nil(logger_shift) + + # + # Finally test to make sure local-only still works + # + assert(Authentication.authenticate("test3","password")) + # + # Should issue a warning for just bytemark auth failing, and no more. + # + assert_match(/AuthBytemark for test3 failed/, logger_shift) + assert_nil(logger_shift) + + end + + + +end diff --git a/test/tc_mauve_web_interface.rb b/test/tc_mauve_web_interface.rb index 69828e9..54c9697 100644 --- a/test/tc_mauve_web_interface.rb +++ b/test/tc_mauve_web_interface.rb @@ -53,12 +53,6 @@ class WebInterfaceTest < Mauve::UnitTest super setup_database - # - # BytemarkAuth test users are: - # - # test1: ummVRu7qF - # test2: POKvBqLT7 - # config =<<EOF server { hostname "localhost" @@ -70,13 +64,8 @@ server { } } -person ("test0") { - password "#{Digest::SHA1.new.hexdigest("password")}" - all { true } -} - person ("test1") { - password "#{Digest::SHA1.new.hexdigest("ummVRu7qF")}" + password "#{Digest::SHA1.new.hexdigest("goodpassword")}" all { true } } @@ -156,9 +145,10 @@ EOF # logger_pop ; logger_pop - post '/login', :username => 'test1', :password => 'ummVRu7qF' + post '/login', :username => 'test1', :password => 'goodpassword' follow_redirect! while last_response.redirect? assert last_response.body.include?('Mauve: ') + assert last_response.ok? get '/logout' follow_redirect! while last_response.redirect? @@ -166,7 +156,7 @@ EOF end def test_alerts_show_subject - post '/login', :username => 'test1', :password => 'ummVRu7qF' + post '/login', :username => 'test1', :password => 'goodpassword' follow_redirect! while last_response.redirect? assert last_response.body.include?('Mauve: ') diff --git a/test/test_mauve.rb b/test/test_mauve.rb index ce83c6c..a0531d7 100644 --- a/test/test_mauve.rb +++ b/test/test_mauve.rb @@ -8,24 +8,9 @@ require 'pp' require 'test/unit' require 'th_mauve' -%w( -tc_mauve_alert_changed.rb -tc_mauve_alert_group.rb -tc_mauve_alert.rb -tc_mauve_configuration_builder.rb -tc_mauve_configuration_builders_alert_group.rb -tc_mauve_configuration_builders_logger.rb -tc_mauve_configuration_builders_notification_method.rb -tc_mauve_configuration_builders_person.rb -tc_mauve_configuration_builders_server.rb -tc_mauve_history.rb -tc_mauve_notification.rb -tc_mauve_people_list.rb -tc_mauve_person.rb -tc_mauve_source_list.rb -tc_mauve_time.rb -tc_mauve_web_interface.rb -).each do |s| +%w(. test).each do |dir| +Dir.glob(File.join(dir,"tc_*.rb")).each do |s| require s end +end diff --git a/test/th_mauve.rb b/test/th_mauve.rb index 2b97e64..ce29e11 100644 --- a/test/th_mauve.rb +++ b/test/th_mauve.rb @@ -77,6 +77,10 @@ module Mauve def logger_pop @outputter.pop end + + def logger_shift + @outputter.shift + end def teardown_logger logger = Log4r::Logger['Mauve'] |