Merge branch 'master' into use_global_catalog_for_auth
This commit is contained in:
Коммит
3a58f8323b
|
@ -1,12 +1,18 @@
|
|||
language: ruby
|
||||
rvm:
|
||||
- 1.9.3
|
||||
- 2.0.0
|
||||
- 2.1.0
|
||||
|
||||
env:
|
||||
- TESTENV=openldap
|
||||
- TESTENV=apacheds
|
||||
|
||||
# https://docs.travis-ci.com/user/hosts/
|
||||
addons:
|
||||
hosts:
|
||||
- ad1.ghe.dev
|
||||
- ad2.ghe.dev
|
||||
|
||||
install:
|
||||
- if [ "$TESTENV" = "openldap" ]; then ./script/install-openldap; fi
|
||||
- bundle install
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
# CHANGELOG
|
||||
|
||||
# v1.10.0
|
||||
|
||||
* Bump net-ldap to 0.15.0 [#92](https://github.com/github/github-ldap/pull/92)
|
||||
|
||||
# v1.9.0
|
||||
|
||||
* Update net-ldap dependency to `~> 0.11.0` [#84](https://github.com/github/github-ldap/pull/84)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "github-ldap"
|
||||
spec.version = "1.9.0"
|
||||
spec.version = "1.10.0"
|
||||
spec.authors = ["David Calavera", "Matt Todd"]
|
||||
spec.email = ["david.calavera@gmail.com", "chiology@gmail.com"]
|
||||
spec.description = %q{LDAP authentication for humans}
|
||||
|
@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|||
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
||||
spec.require_paths = ["lib"]
|
||||
|
||||
spec.add_dependency 'net-ldap', '~> 0.11.0'
|
||||
spec.add_dependency 'net-ldap', '~> 0.15.0'
|
||||
|
||||
spec.add_development_dependency "bundler", "~> 1.3"
|
||||
spec.add_development_dependency 'ladle'
|
||||
|
|
|
@ -12,6 +12,9 @@ require 'github/ldap/member_search'
|
|||
require 'github/ldap/membership_validators'
|
||||
require 'github/ldap/user_search/default'
|
||||
require 'github/ldap/user_search/active_directory'
|
||||
require 'github/ldap/connection_cache'
|
||||
require 'github/ldap/referral_chaser'
|
||||
require 'github/ldap/url'
|
||||
|
||||
module GitHub
|
||||
class Ldap
|
||||
|
@ -40,13 +43,17 @@ module GitHub
|
|||
#
|
||||
# Returns the return value of the block.
|
||||
def_delegator :@connection, :open
|
||||
def_delegator :@connection, :host
|
||||
|
||||
attr_reader :uid, :search_domains, :virtual_attributes,
|
||||
:membership_validator,
|
||||
:member_search_strategy,
|
||||
:instrumentation_service,
|
||||
:user_search_strategy,
|
||||
:connection
|
||||
:connection,
|
||||
:admin_user,
|
||||
:admin_password,
|
||||
:port
|
||||
|
||||
# Build a new GitHub::Ldap instance
|
||||
#
|
||||
|
@ -76,6 +83,7 @@ module GitHub
|
|||
# Keep a reference to these as default auth for a Global Catalog if needed
|
||||
@admin_user = options[:admin_user]
|
||||
@admin_password = options[:admin_password]
|
||||
@port = options[:port]
|
||||
|
||||
@connection = Net::LDAP.new({
|
||||
host: options[:host],
|
||||
|
@ -106,7 +114,7 @@ module GitHub
|
|||
# configure both the membership validator and the member search strategies
|
||||
configure_search_strategy(options[:search_strategy])
|
||||
|
||||
# configure both the membership validator and the member search strategies
|
||||
# configure the strategy used by Domain#user? to look up a user entry for login
|
||||
configure_user_search_strategy(options[:user_search_strategy])
|
||||
|
||||
# enables instrumenting queries
|
||||
|
@ -340,9 +348,6 @@ module GitHub
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
# Internal: Detect whether the LDAP host is an ActiveDirectory server.
|
||||
#
|
||||
# See: http://msdn.microsoft.com/en-us/library/cc223359.aspx.
|
||||
|
@ -351,7 +356,6 @@ module GitHub
|
|||
def active_directory_capability?
|
||||
capabilities[:supportedcapabilities].include?(ACTIVE_DIRECTORY_V51_OID)
|
||||
end
|
||||
|
||||
attr_reader :admin_user, :admin_password
|
||||
private :active_directory_capability?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
module GitHub
|
||||
class Ldap
|
||||
|
||||
# A simple cache of GitHub::Ldap objects to prevent creating multiple
|
||||
# instances of connections that point to the same URI/host.
|
||||
class ConnectionCache
|
||||
|
||||
# Public - Create or return cached instance of GitHub::Ldap created with options,
|
||||
# where the cache key is the value of options[:host].
|
||||
#
|
||||
# options - Initialization attributes suitable for creating a new connection with
|
||||
# GitHub::Ldap.new(options)
|
||||
#
|
||||
# Returns true or false.
|
||||
def self.get_connection(options={})
|
||||
@cache ||= self.new
|
||||
@cache.get_connection(options)
|
||||
end
|
||||
|
||||
def get_connection(options)
|
||||
@connections ||= {}
|
||||
@connections[options[:host]] ||= GitHub::Ldap.new(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -24,15 +24,23 @@ module GitHub
|
|||
# Sets the entry to the base and scopes the search to the base,
|
||||
# according to the source documentation, found here:
|
||||
# http://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx
|
||||
matched = ldap.search \
|
||||
#
|
||||
# Use ReferralChaser to chase any potential referrals for an entry that may be owned by a different
|
||||
# domain controller.
|
||||
matched = referral_chaser.search \
|
||||
filter: membership_in_chain_filter(entry),
|
||||
base: entry.dn,
|
||||
scope: Net::LDAP::SearchScope_BaseObject,
|
||||
return_referrals: true,
|
||||
attributes: ATTRS
|
||||
|
||||
# membership validated if entry was matched and returned as a result
|
||||
# Active Directory DNs are case-insensitive
|
||||
matched.map { |m| m.dn.downcase }.include?(entry.dn.downcase)
|
||||
Array(matched).map { |m| m.dn.downcase }.include?(entry.dn.downcase)
|
||||
end
|
||||
|
||||
def referral_chaser
|
||||
@referral_chaser ||= GitHub::Ldap::ReferralChaser.new(@ldap)
|
||||
end
|
||||
|
||||
# Internal: Constructs a membership filter using the "in chain"
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
module GitHub
|
||||
class Ldap
|
||||
|
||||
# This class adds referral chasing capability to a GitHub::Ldap connection.
|
||||
#
|
||||
# See: https://technet.microsoft.com/en-us/library/cc978014.aspx
|
||||
# http://www.umich.edu/~dirsvcs/ldap/doc/other/ldap-ref.html
|
||||
#
|
||||
class ReferralChaser
|
||||
|
||||
# Public - Creates a ReferralChaser that decorates an instance of GitHub::Ldap
|
||||
# with additional functionality to the #search method, allowing it to chase
|
||||
# any referral entries and aggregate the results into a single response.
|
||||
#
|
||||
# connection - The instance of GitHub::Ldap to use for searching. Will use
|
||||
# the connection's authentication, (admin_user and admin_password) as credentials
|
||||
# for connecting to referred domain controllers.
|
||||
def initialize(connection)
|
||||
@connection = connection
|
||||
@admin_user = connection.admin_user
|
||||
@admin_password = connection.admin_password
|
||||
@port = connection.port
|
||||
end
|
||||
|
||||
# Public - Search the domain controller represented by this instance's connection.
|
||||
# If a referral is returned, search only one of the domain controllers indicated
|
||||
# by the referral entries, per RFC 4511 (https://tools.ietf.org/html/rfc4511):
|
||||
#
|
||||
# "If the client wishes to progress the operation, it contacts one of
|
||||
# the supported services found in the referral. If multiple URIs are
|
||||
# present, the client assumes that any supported URI may be used to
|
||||
# progress the operation."
|
||||
#
|
||||
# options - is a hash with the same options that Net::LDAP::Connection#search supports.
|
||||
# Referral searches will use the given options, but will replace options[:base]
|
||||
# with the referral URL's base search dn.
|
||||
#
|
||||
# Does not take a block argument as GitHub::Ldap and Net::LDAP::Connection#search do.
|
||||
#
|
||||
# Will not recursively follow any subsequent referrals.
|
||||
#
|
||||
# Returns an Array of Net::LDAP::Entry.
|
||||
def search(options)
|
||||
search_results = []
|
||||
referral_entries = []
|
||||
|
||||
search_results = connection.search(options) do |entry|
|
||||
if entry && entry[:search_referrals]
|
||||
referral_entries << entry
|
||||
end
|
||||
end
|
||||
|
||||
unless referral_entries.empty?
|
||||
entry = referral_entries.first
|
||||
referral_string = entry[:search_referrals].first
|
||||
if GitHub::Ldap::URL.valid?(referral_string)
|
||||
referral = Referral.new(referral_string, admin_user, admin_password, port)
|
||||
search_results = referral.search(options)
|
||||
end
|
||||
end
|
||||
|
||||
Array(search_results)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :connection, :admin_user, :admin_password, :port
|
||||
|
||||
# Represents a referral entry from an LDAP search result. Constructs a corresponding
|
||||
# GitHub::Ldap object from the paramaters on the referral_url and provides a #search
|
||||
# method to continue the search on the referred domain.
|
||||
class Referral
|
||||
def initialize(referral_url, admin_user, admin_password, port=nil)
|
||||
url = GitHub::Ldap::URL.new(referral_url)
|
||||
@search_base = url.dn
|
||||
|
||||
connection_options = {
|
||||
host: url.host,
|
||||
port: port || url.port,
|
||||
scope: url.scope,
|
||||
admin_user: admin_user,
|
||||
admin_password: admin_password
|
||||
}
|
||||
|
||||
@connection = GitHub::Ldap::ConnectionCache.get_connection(connection_options)
|
||||
end
|
||||
|
||||
# Search the referred domain controller with options, merging in the referred search
|
||||
# base DN onto options[:base].
|
||||
def search(options)
|
||||
connection.search(options.merge(base: search_base))
|
||||
end
|
||||
|
||||
attr_reader :search_base, :connection
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,87 @@
|
|||
module GitHub
|
||||
class Ldap
|
||||
|
||||
# This class represents an LDAP URL
|
||||
#
|
||||
# See: https://tools.ietf.org/html/rfc4516#section-2
|
||||
# https://docs.oracle.com/cd/E19957-01/817-6707/urls.html
|
||||
#
|
||||
class URL
|
||||
extend Forwardable
|
||||
SCOPES = {
|
||||
"base" => Net::LDAP::SearchScope_BaseObject,
|
||||
"one" => Net::LDAP::SearchScope_SingleLevel,
|
||||
"sub" => Net::LDAP::SearchScope_WholeSubtree
|
||||
}
|
||||
SCOPES.default = Net::LDAP::SearchScope_BaseObject
|
||||
|
||||
attr_reader :dn, :attributes, :scope, :filter
|
||||
|
||||
def_delegators :@uri, :port, :host, :scheme
|
||||
|
||||
# Public - Creates a new GitHub::Ldap::URL object with :port, :host and :scheme
|
||||
# delegated to a URI object parsed from url_string, and then parses the
|
||||
# query params according to the LDAP specification.
|
||||
#
|
||||
# url_string - An LDAP URL string.
|
||||
# returns - a GitHub::Ldap::URL with the following attributes:
|
||||
# host - Name or IP of the LDAP server.
|
||||
# port - The given port, defaults to 389.
|
||||
# dn - The base search DN.
|
||||
# attributes - The comma-delimited list of attributes to be returned.
|
||||
# scope - The scope of the search.
|
||||
# filter - Search filter to apply to entries within the specified scope of the search.
|
||||
#
|
||||
# Supported LDAP URL strings look like this, where sections in brackets are optional:
|
||||
#
|
||||
# ldap[s]://[hostport][/[dn[?[attributes][?[scope][?[filter]]]]]]
|
||||
#
|
||||
# where:
|
||||
#
|
||||
# hostport is a host name with an optional ":portnumber"
|
||||
# dn is the base DN to be used for an LDAP search operation
|
||||
# attributes is a comma separated list of attributes to be retrieved
|
||||
# scope is one of these three strings: base one sub (default=base)
|
||||
# filter is LDAP search filter as used in a call to ldap_search
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# ldap://dc4.ghe.local:456/CN=Maggie,DC=dc4,DC=ghe,DC=local?cn,mail?base?(cn=Charlie)
|
||||
#
|
||||
def initialize(url_string)
|
||||
if !self.class.valid?(url_string)
|
||||
raise InvalidLdapURLException.new("Invalid LDAP URL: #{url_string}")
|
||||
end
|
||||
@uri = URI(url_string)
|
||||
@dn = URI.unescape(@uri.path.sub(/^\//, ""))
|
||||
if @uri.query
|
||||
@attributes, @scope, @filter = @uri.query.split("?")
|
||||
end
|
||||
end
|
||||
|
||||
def self.valid?(url_string)
|
||||
url_string =~ URI::regexp && ["ldap", "ldaps"].include?(URI(url_string).scheme)
|
||||
end
|
||||
|
||||
# Maps the returned scope value from the URL to one of Net::LDAP::Scopes
|
||||
#
|
||||
# The URL scope value can be one of:
|
||||
# "base" - retrieves information only about the DN (base_dn) specified.
|
||||
# "one" - retrieves information about entries one level below the DN (base_dn) specified. The base entry is not included in this scope.
|
||||
# "sub" - retrieves information about entries at all levels below the DN (base_dn) specified. The base entry is included in this scope.
|
||||
#
|
||||
# Which will map to one of the following Net::LDAP::Scopes:
|
||||
# SearchScope_BaseObject = 0
|
||||
# SearchScope_SingleLevel = 1
|
||||
# SearchScope_WholeSubtree = 2
|
||||
#
|
||||
# If no scope or an invalid scope is given, defaults to SearchScope_BaseObject
|
||||
def net_ldap_scope
|
||||
Net::LDAP::SearchScopes[SCOPES[scope]]
|
||||
end
|
||||
|
||||
class InvalidLdapURLException < Exception; end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -37,7 +37,7 @@ module GitHub
|
|||
auth = netldap.instance_variable_get(:@auth)
|
||||
|
||||
new({
|
||||
host: ldap.instance_variable_get(:@host),
|
||||
host: ldap.host,
|
||||
instrumentation_service: ldap.instrumentation_service,
|
||||
port: encryption ? LDAPS_GC_PORT : STANDARD_GC_PORT,
|
||||
auth: auth,
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
require_relative 'test_helper'
|
||||
|
||||
class GitHubLdapConnectionCacheTestCases < GitHub::Ldap::Test
|
||||
|
||||
def test_returns_cached_connection
|
||||
conn1 = GitHub::Ldap::ConnectionCache.get_connection(options.merge(:host => "ad1.ghe.dev"))
|
||||
conn2 = GitHub::Ldap::ConnectionCache.get_connection(options.merge(:host => "ad1.ghe.dev"))
|
||||
assert_equal conn1.object_id, conn2.object_id
|
||||
end
|
||||
|
||||
def test_creates_new_connections_per_host
|
||||
conn1 = GitHub::Ldap::ConnectionCache.get_connection(options.merge(:host => "ad1.ghe.dev"))
|
||||
conn2 = GitHub::Ldap::ConnectionCache.get_connection(options.merge(:host => "ad2.ghe.dev"))
|
||||
conn3 = GitHub::Ldap::ConnectionCache.get_connection(options.merge(:host => "ad2.ghe.dev"))
|
||||
refute_equal conn1.object_id, conn2.object_id
|
||||
assert_equal conn2.object_id, conn3.object_id
|
||||
end
|
||||
end
|
|
@ -1,5 +1,4 @@
|
|||
require_relative 'test_helper'
|
||||
require 'mocha/mini_test'
|
||||
|
||||
module GitHubLdapDomainTestCases
|
||||
def setup
|
||||
|
@ -143,8 +142,8 @@ module GitHubLdapDomainTestCases
|
|||
end
|
||||
|
||||
def test_user_search_returns_first_entry
|
||||
entry = Object.new
|
||||
search_strategy = Object.new
|
||||
entry = mock("Net::Ldap::Entry")
|
||||
search_strategy = mock("GitHub::Ldap::UserSearch::Default")
|
||||
search_strategy.stubs(:perform).returns([entry])
|
||||
@ldap.expects(:user_search_strategy).returns(search_strategy)
|
||||
user = @domain.user?('user1', :attributes => [:cn])
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
require_relative 'test_helper'
|
||||
require 'mocha/mini_test'
|
||||
|
||||
module GitHubLdapTestCases
|
||||
def setup
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
require_relative 'test_helper'
|
||||
|
||||
class GitHubLdapReferralChaserTestCases < GitHub::Ldap::Test
|
||||
|
||||
def setup
|
||||
@ldap = GitHub::Ldap.new(options)
|
||||
@chaser = GitHub::Ldap::ReferralChaser.new(@ldap)
|
||||
end
|
||||
|
||||
def test_creates_referral_with_connection_credentials
|
||||
@ldap.expects(:search).yields({ search_referrals: ["ldap://dc1.ghe.local/"]}).returns([])
|
||||
|
||||
referral = mock("GitHub::Ldap::ReferralChaser::Referral")
|
||||
referral.stubs(:search).returns([])
|
||||
|
||||
GitHub::Ldap::ReferralChaser::Referral.expects(:new)
|
||||
.with("ldap://dc1.ghe.local/", "uid=admin,dc=github,dc=com", "passworD1", options[:port])
|
||||
.returns(referral)
|
||||
|
||||
@chaser.search({})
|
||||
end
|
||||
|
||||
def test_creates_referral_with_default_port
|
||||
@ldap.expects(:search).yields({
|
||||
search_referrals: ["ldap://dc1.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local"]
|
||||
}).returns([])
|
||||
|
||||
stub_referral_connection = mock("GitHub::Ldap")
|
||||
stub_referral_connection.stubs(:search).returns([])
|
||||
GitHub::Ldap::ConnectionCache.expects(:get_connection).with(has_entry(port: options[:port])).returns(stub_referral_connection)
|
||||
chaser = GitHub::Ldap::ReferralChaser.new(@ldap)
|
||||
chaser.search({})
|
||||
end
|
||||
|
||||
def test_creates_referral_for_first_referral_string
|
||||
@ldap.expects(:search).multiple_yields([
|
||||
{ search_referrals:
|
||||
["ldap://dc1.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local",
|
||||
"ldap://dc2.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local"]
|
||||
}
|
||||
],[
|
||||
{ search_referrals:
|
||||
["ldap://dc3.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local",
|
||||
"ldap://dc4.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local"]
|
||||
}
|
||||
]).returns([])
|
||||
|
||||
referral = mock("GitHub::Ldap::ReferralChaser::Referral")
|
||||
referral.stubs(:search).returns([])
|
||||
|
||||
GitHub::Ldap::ReferralChaser::Referral.expects(:new)
|
||||
.with(
|
||||
"ldap://dc1.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local",
|
||||
"uid=admin,dc=github,dc=com",
|
||||
"passworD1",
|
||||
options[:port])
|
||||
.returns(referral)
|
||||
|
||||
@chaser.search({})
|
||||
end
|
||||
|
||||
def test_returns_referral_search_results
|
||||
@ldap.expects(:search).multiple_yields([
|
||||
{ search_referrals:
|
||||
["ldap://dc1.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local",
|
||||
"ldap://dc2.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local"]
|
||||
}
|
||||
],[
|
||||
{ search_referrals:
|
||||
["ldap://dc3.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local",
|
||||
"ldap://dc4.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local"]
|
||||
}
|
||||
]).returns([])
|
||||
|
||||
referral = mock("GitHub::Ldap::ReferralChaser::Referral")
|
||||
referral.expects(:search).returns(["result", "result"])
|
||||
|
||||
GitHub::Ldap::ReferralChaser::Referral.expects(:new).returns(referral)
|
||||
|
||||
results = @chaser.search({})
|
||||
assert_equal(["result", "result"], results)
|
||||
end
|
||||
|
||||
def test_handle_blank_url_string_in_referral
|
||||
@ldap.expects(:search).yields({ search_referrals: [""] })
|
||||
|
||||
results = @chaser.search({})
|
||||
assert_equal([], results)
|
||||
end
|
||||
|
||||
def test_returns_referral_search_results
|
||||
@ldap.expects(:search).yields({ foo: ["not a referral"] })
|
||||
|
||||
GitHub::Ldap::ReferralChaser::Referral.expects(:new).never
|
||||
results = @chaser.search({})
|
||||
end
|
||||
|
||||
def test_referral_should_use_host_from_referral_string
|
||||
GitHub::Ldap::ConnectionCache.expects(:get_connection).with(has_entry(host: "dc4.ghe.local"))
|
||||
GitHub::Ldap::ReferralChaser::Referral.new("ldap://dc4.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local", "", "")
|
||||
end
|
||||
end
|
|
@ -13,6 +13,8 @@ require 'github/ldap/server'
|
|||
require 'minitest/mock'
|
||||
require 'minitest/autorun'
|
||||
|
||||
require 'mocha/mini_test'
|
||||
|
||||
if ENV.fetch('TESTENV', "apacheds") == "apacheds"
|
||||
# Make sure we clean up running test server
|
||||
# NOTE: We need to do this manually since its internal `at_exit` hook
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
require_relative 'test_helper'
|
||||
|
||||
class GitHubLdapURLTestCases < GitHub::Ldap::Test
|
||||
|
||||
def setup
|
||||
@url = GitHub::Ldap::URL.new("ldap://dc4.ghe.local:123/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local?cn,mail,telephoneNumber?base?(cn=Charlie)")
|
||||
end
|
||||
|
||||
def test_host
|
||||
assert_equal "dc4.ghe.local", @url.host
|
||||
end
|
||||
|
||||
def test_port
|
||||
assert_equal 123, @url.port
|
||||
end
|
||||
|
||||
def test_scheme
|
||||
assert_equal "ldap", @url.scheme
|
||||
end
|
||||
|
||||
def test_default_port
|
||||
url = GitHub::Ldap::URL.new("ldap://dc4.ghe.local/CN=Maggie%20Mae,CN=Users,DC=dc4,DC=ghe,DC=local?attributes?scope?filter")
|
||||
assert_equal 389, url.port
|
||||
end
|
||||
|
||||
def test_simple_url
|
||||
url = GitHub::Ldap::URL.new("ldap://dc4.ghe.local")
|
||||
assert_equal 389, url.port
|
||||
assert_equal "dc4.ghe.local", url.host
|
||||
assert_equal "ldap", url.scheme
|
||||
assert_equal "", url.dn
|
||||
assert_equal nil, url.attributes
|
||||
assert_equal nil, url.filter
|
||||
assert_equal nil, url.scope
|
||||
end
|
||||
|
||||
def test_invalid_scheme
|
||||
ex = assert_raises(GitHub::Ldap::URL::InvalidLdapURLException) do
|
||||
GitHub::Ldap::URL.new("http://dc4.ghe.local")
|
||||
end
|
||||
assert_equal("Invalid LDAP URL: http://dc4.ghe.local", ex.message)
|
||||
end
|
||||
|
||||
def test_invalid_url
|
||||
ex = assert_raises(GitHub::Ldap::URL::InvalidLdapURLException) do
|
||||
GitHub::Ldap::URL.new("not a url")
|
||||
end
|
||||
assert_equal("Invalid LDAP URL: not a url", ex.message)
|
||||
end
|
||||
|
||||
def test_parse_dn
|
||||
assert_equal "CN=Maggie Mae,CN=Users,DC=dc4,DC=ghe,DC=local", @url.dn
|
||||
end
|
||||
|
||||
def test_parse_attributes
|
||||
assert_equal "cn,mail,telephoneNumber", @url.attributes
|
||||
end
|
||||
|
||||
def test_parse_filter
|
||||
assert_equal "(cn=Charlie)", @url.filter
|
||||
end
|
||||
|
||||
def test_parse_scope
|
||||
assert_equal "base", @url.scope
|
||||
end
|
||||
|
||||
def test_default_scope
|
||||
url = GitHub::Ldap::URL.new("ldap://dc4.ghe.local/base_dn?cn=joe??filter")
|
||||
assert_equal "", url.scope
|
||||
end
|
||||
|
||||
def test_net_ldap_scopes
|
||||
sub_scope_url = GitHub::Ldap::URL.new("ldap://ghe.local/base_dn?cn=joe?sub?filter")
|
||||
one_scope_url = GitHub::Ldap::URL.new("ldap://ghe.local/base_dn?cn=joe?one?filter")
|
||||
base_scope_url = GitHub::Ldap::URL.new("ldap://ghe.local/base_dn?cn=joe?base?filter")
|
||||
default_scope_url = GitHub::Ldap::URL.new("ldap://dc4.ghe.local/base_dn?cn=joe??filter")
|
||||
invalid_scope_url = GitHub::Ldap::URL.new("ldap://dc4.ghe.local/base_dn?cn=joe?invalid?filter")
|
||||
|
||||
assert_equal Net::LDAP::SearchScope_BaseObject, base_scope_url.net_ldap_scope
|
||||
assert_equal Net::LDAP::SearchScope_SingleLevel, one_scope_url.net_ldap_scope
|
||||
assert_equal Net::LDAP::SearchScope_WholeSubtree, sub_scope_url.net_ldap_scope
|
||||
assert_equal Net::LDAP::SearchScope_BaseObject, default_scope_url.net_ldap_scope
|
||||
assert_equal Net::LDAP::SearchScope_BaseObject, invalid_scope_url.net_ldap_scope
|
||||
end
|
||||
end
|
|
@ -1,46 +1,52 @@
|
|||
require_relative '../test_helper'
|
||||
require 'mocha/mini_test'
|
||||
|
||||
class GitHubLdapActiveDirectoryUserSearchTests < GitHub::Ldap::Test
|
||||
|
||||
def setup
|
||||
@ldap = GitHub::Ldap.new(options)
|
||||
@ad_user_search = GitHub::Ldap::UserSearch::ActiveDirectory.new(@ldap)
|
||||
end
|
||||
|
||||
def test_global_catalog_returns_empty_array_for_no_results
|
||||
ldap = GitHub::Ldap.new(options.merge(host: 'ghe.dev'))
|
||||
ad_user_search = GitHub::Ldap::UserSearch::ActiveDirectory.new(ldap)
|
||||
|
||||
mock_global_catalog_connection = mock("GitHub::Ldap::UserSearch::GlobalCatalog")
|
||||
mock_global_catalog_connection.expects(:search).returns(nil)
|
||||
@ad_user_search.expects(:global_catalog_connection).returns(mock_global_catalog_connection)
|
||||
results = @ad_user_search.perform("login", "CN=Joe", "uid", {})
|
||||
ad_user_search.expects(:global_catalog_connection).returns(mock_global_catalog_connection)
|
||||
results = ad_user_search.perform("login", "CN=Joe", "uid", {})
|
||||
assert_equal [], results
|
||||
end
|
||||
|
||||
def test_global_catalog_returns_array_of_results
|
||||
ldap = GitHub::Ldap.new(options.merge(host: 'ghe.dev'))
|
||||
ad_user_search = GitHub::Ldap::UserSearch::ActiveDirectory.new(ldap)
|
||||
|
||||
mock_global_catalog_connection = mock("GitHub::Ldap::UserSearch::GlobalCatalog")
|
||||
stub_entry = mock("Net::LDAP::Entry")
|
||||
|
||||
mock_global_catalog_connection.expects(:search).returns(stub_entry)
|
||||
@ad_user_search.expects(:global_catalog_connection).returns(mock_global_catalog_connection)
|
||||
results = @ad_user_search.perform("login", "CN=Joe", "uid", {})
|
||||
ad_user_search.expects(:global_catalog_connection).returns(mock_global_catalog_connection)
|
||||
|
||||
results = ad_user_search.perform("login", "CN=Joe", "uid", {})
|
||||
assert_equal [stub_entry], results
|
||||
end
|
||||
|
||||
def test_searches_with_empty_base_dn
|
||||
ldap = GitHub::Ldap.new(options.merge(host: 'ghe.dev'))
|
||||
ad_user_search = GitHub::Ldap::UserSearch::ActiveDirectory.new(ldap)
|
||||
|
||||
mock_global_catalog_connection = mock("GitHub::Ldap::UserSearch::GlobalCatalog")
|
||||
mock_global_catalog_connection.expects(:search).with(has_entry(:base => ""))
|
||||
@ad_user_search.expects(:global_catalog_connection).returns(mock_global_catalog_connection)
|
||||
@ad_user_search.perform("login", "CN=Joe", "uid", {})
|
||||
ad_user_search.expects(:global_catalog_connection).returns(mock_global_catalog_connection)
|
||||
ad_user_search.perform("login", "CN=Joe", "uid", {})
|
||||
end
|
||||
|
||||
def test_global_catalog_default_settings
|
||||
global_catalog = @ad_user_search.global_catalog_connection
|
||||
ldap = GitHub::Ldap.new(options.merge(host: 'ghe.dev'))
|
||||
global_catalog = GitHub::Ldap::UserSearch::GlobalCatalog.connection(ldap)
|
||||
instrumentation_service = global_catalog.instance_variable_get(:@instrumentation_service)
|
||||
|
||||
auth = global_catalog.instance_variable_get(:@auth)
|
||||
assert_equal :simple, auth[:method]
|
||||
assert_equal "uid=admin,dc=github,dc=com", auth[:username]
|
||||
assert_equal "passworD1", auth[:password]
|
||||
assert_equal "127.0.0.1", global_catalog.host
|
||||
assert_equal "ghe.dev", global_catalog.host
|
||||
assert_equal 3268, global_catalog.port
|
||||
assert_equal "MockInstrumentationService", instrumentation_service.class.name
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
require_relative '../test_helper'
|
||||
require 'mocha/mini_test'
|
||||
|
||||
class GitHubLdapActiveDirectoryUserSearchTests < GitHub::Ldap::Test
|
||||
def setup
|
||||
|
|
Загрузка…
Ссылка в новой задаче