diff --git a/test/membership_validators/active_directory_test.rb b/test/membership_validators/active_directory_test.rb index b44d9b2..0caafe2 100644 --- a/test/membership_validators/active_directory_test.rb +++ b/test/membership_validators/active_directory_test.rb @@ -1,10 +1,11 @@ require_relative '../test_helper' -# NOTE: Since this strategy is targeted at ActiveDirectory and we don't have -# AD setup in CI, we stub out actual queries and test against what AD *would* -# respond with. +class GitHubLdapActiveDirectoryMembershipValidatorsStubbedTest < GitHub::Ldap::Test + # Only run when AD integration tests aren't run + def run(*) + self.class.test_env != "activedirectory" ? super : self + end -class GitHubLdapActiveDirectoryMembershipValidatorsTest < GitHub::Ldap::Test def setup @ldap = GitHub::Ldap.new(options.merge(search_domains: %w(dc=github,dc=com))) @domain = @ldap.domain("dc=github,dc=com") @@ -66,3 +67,60 @@ def test_does_not_validate_user_not_in_any_group end end end + +# See test/support/vm/activedirectory/README.md for details +class GitHubLdapActiveDirectoryMembershipValidatorsIntegrationTest < GitHub::Ldap::Test + # Only run this test suite if ActiveDirectory is configured + def run(*) + self.class.test_env == "activedirectory" ? super : self + end + + def setup + @ldap = GitHub::Ldap.new(options) + @domain = @ldap.domain(options[:search_domains]) + @entry = @domain.user?('user1') + @validator = GitHub::Ldap::MembershipValidators::ActiveDirectory + end + + def make_validator(groups) + groups = @domain.groups(groups) + @validator.new(@ldap, groups) + end + + def test_validates_user_in_group + validator = make_validator(%w(nested-group1)) + assert validator.perform(@entry) + end + + def test_validates_user_in_child_group + validator = make_validator(%w(n-depth-nested-group1)) + assert validator.perform(@entry) + end + + def test_validates_user_in_grandchild_group + validator = make_validator(%w(n-depth-nested-group2)) + assert validator.perform(@entry) + end + + def test_validates_user_in_great_grandchild_group + validator = make_validator(%w(n-depth-nested-group3)) + assert validator.perform(@entry) + end + + def test_does_not_validate_user_not_in_group + validator = make_validator(%w(ghe-admins)) + refute validator.perform(@entry) + end + + def test_does_not_validate_user_not_in_any_group + skip "update AD ldif to have a groupless user" + @entry = @domain.user?('groupless-user1') + validator = make_validator(%w(all-users)) + refute validator.perform(@entry) + end + + def test_validates_user_in_posix_group + validator = make_validator(%w(posix-group1)) + assert validator.perform(@entry) + end +end diff --git a/test/support/vm/activedirectory/.gitignore b/test/support/vm/activedirectory/.gitignore new file mode 100644 index 0000000..137e678 --- /dev/null +++ b/test/support/vm/activedirectory/.gitignore @@ -0,0 +1 @@ +env.sh diff --git a/test/support/vm/activedirectory/README.md b/test/support/vm/activedirectory/README.md new file mode 100644 index 0000000..36155bd --- /dev/null +++ b/test/support/vm/activedirectory/README.md @@ -0,0 +1,26 @@ +# Local ActiveDirectory Integration Testing + +Integration tests are not run for ActiveDirectory in continuous integration +because we cannot install a Windows VM on TravisCI. To test ActiveDirectory, +configure a local VM with AD running (this is left as an exercise for the +reader). + +To run integration tests against the local ActiveDirectory VM, from the project +root run: + +``` bash +# duplicate example env.sh for specific config +$ cp test/support/vm/activedirectory/env.sh{.example,} + +# edit env.sh and fill in with your VM's values, then +$ source test/support/vm/activedirectory/env.sh + +# run all tests against AD +$ time bundle exec rake + +# run a specific test file against AD +$ time bundle exec ruby test/membership_validators/active_directory_test.rb + +# reset environment to test other LDAP servers +$ source test/support/vm/activedirectory/reset-env.sh +``` diff --git a/test/support/vm/activedirectory/env.sh.example b/test/support/vm/activedirectory/env.sh.example new file mode 100644 index 0000000..3ca2c9b --- /dev/null +++ b/test/support/vm/activedirectory/env.sh.example @@ -0,0 +1,8 @@ +# Copy this to ad-env.sh, and fill in with your own values + +export TESTENV=activedirectory +export INTEGRATION_HOST=123.123.123.123 +export INTEGRATION_PORT=389 +export INTEGRATION_USER="CN=Administrator,CN=Users,DC=ad,DC=example,DC=com" +export INTEGRATION_PASSWORD='passworD1' +export INTEGRATION_SEARCH_DOMAINS='CN=Users,DC=example,DC=com' diff --git a/test/support/vm/activedirectory/reset-env.sh b/test/support/vm/activedirectory/reset-env.sh new file mode 100644 index 0000000..971423f --- /dev/null +++ b/test/support/vm/activedirectory/reset-env.sh @@ -0,0 +1,6 @@ +unset TESTENV +unset INTEGRATION_HOST +unset INTEGRATION_PORT +unset INTEGRATION_USER +unset INTEGRATION_PASSWORD +unset INTEGRATION_SEARCH_DOMAINS diff --git a/test/support/vm/openldap/README.md b/test/support/vm/openldap/README.md index 67a4ded..ced5a63 100644 --- a/test/support/vm/openldap/README.md +++ b/test/support/vm/openldap/README.md @@ -16,10 +16,10 @@ $ ip=$(vagrant ssh -- "ifconfig eth1 | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9] $ cd ../../../.. # run all tests against OpenLDAP -$ time TESTENV=openldap OPENLDAP_HOST=$ip bundle exec rake +$ time TESTENV=openldap INTEGRATION_HOST=$ip bundle exec rake # run a specific test file against OpenLDAP -$ time TESTENV=openldap OPENLDAP_HOST=$ip bundle exec ruby test/membership_validators/recursive_test.rb +$ time TESTENV=openldap INTEGRATION_HOST=$ip bundle exec ruby test/membership_validators/recursive_test.rb # run OpenLDAP tests by default $ export TESTENV=openldap diff --git a/test/test_helper.rb b/test/test_helper.rb index 7780371..5beca09 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -71,7 +71,7 @@ def options instrumentation_service: @service when "openldap" { - host: ENV.fetch("OPENLDAP_HOST", "localhost"), + host: ENV.fetch("INTEGRATION_HOST", "localhost"), port: 389, admin_user: 'uid=admin,dc=github,dc=com', admin_password: 'passworD1', @@ -79,6 +79,15 @@ def options uid: 'uid', instrumentation_service: @service } + when "activedirectory" + { + host: ENV.fetch("INTEGRATION_HOST"), + port: ENV.fetch("INTEGRATION_PORT", 389), + admin_user: ENV.fetch("INTEGRATION_USER"), + admin_password: ENV.fetch("INTEGRATION_PASSWORD"), + search_domains: ENV.fetch("INTEGRATION_SEARCH_DOMAINS"), + instrumentation_service: @service + } end end end