Skip to content

Commit 05cb39c

Browse files
committed
Add member search Detect strategy
1 parent a2ea06f commit 05cb39c

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

lib/github/ldap/member_search.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
require 'github/ldap/member_search/detect'
12
require 'github/ldap/member_search/classic'
23
require 'github/ldap/member_search/recursive'
34

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
module GitHub
2+
class Ldap
3+
module MemberSearch
4+
# Detects the LDAP host's capabilities and determines the appropriate
5+
# member search strategy at runtime.
6+
#
7+
# Currently detects for ActiveDirectory in-chain membership validation.
8+
#
9+
# An explicit strategy can also be defined via
10+
# `GitHub::Ldap#member_search_strategy=`.
11+
#
12+
# See also `GitHub::Ldap#configure_member_search_strategy`.
13+
class Detect
14+
# Defines `active_directory_capability?` and necessary helpers.
15+
include GitHub::Ldap::Capabilities
16+
17+
# Internal: The GitHub::Ldap object to search domains with.
18+
attr_reader :ldap
19+
20+
# Internal: The Hash of options to pass through to the strategy.
21+
attr_reader :options
22+
23+
# Public: Instantiate a meta strategy to detect the right strategy
24+
# to use for the search, and call that strategy, at runtime.
25+
#
26+
# - ldap: GitHub::Ldap object
27+
# - options: Hash of options (passed through)
28+
def initialize(ldap, options = {})
29+
@ldap = ldap
30+
@options = options
31+
end
32+
33+
# Public: Performs search for group members via the appropriate search
34+
# strategy detected/configured.
35+
#
36+
# Returns Array of Net::LDAP::Entry objects.
37+
def perform(entry)
38+
strategy.perform(entry)
39+
end
40+
41+
# Internal: Returns the member search strategy object.
42+
def strategy
43+
@strategy ||= begin
44+
strategy = detect_strategy
45+
strategy.new(ldap, options)
46+
end
47+
end
48+
49+
# Internal: Find the most appropriate search strategy, either by
50+
# configuration or by detecting the host's capabilities.
51+
#
52+
# Returns the strategy class.
53+
def detect_strategy
54+
case
55+
when GitHub::Ldap::MemberSearch::STRATEGIES.key?(strategy_config)
56+
GitHub::Ldap::MemberSearch::STRATEGIES[strategy_config]
57+
when active_directory_capability?
58+
GitHub::Ldap::MemberSearch::STRATEGIES[:active_directory]
59+
else
60+
GitHub::Ldap::MemberSearch::STRATEGIES[:recursive]
61+
end
62+
end
63+
64+
# Internal: Returns the configured member search strategy Symbol.
65+
def strategy_config
66+
ldap.member_search_strategy
67+
end
68+
end
69+
end
70+
end
71+
end

test/member_search/detect_test.rb

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
require_relative '../test_helper'
2+
3+
# NOTE: Since this strategy is targeted at detecting ActiveDirectory
4+
# capabilities, and we don't have AD setup in CI, we stub out actual queries
5+
# and test against what AD *would* respond with.
6+
7+
class GitHubLdapDetectMemberSearchTest < GitHub::Ldap::Test
8+
include GitHub::Ldap::Capabilities
9+
10+
def setup
11+
@ldap = GitHub::Ldap.new(options.merge(search_domains: %w(dc=github,dc=com)))
12+
@domain = @ldap.domain("dc=github,dc=com")
13+
@entry = @domain.user?('user1')
14+
@strategy = GitHub::Ldap::MemberSearch::Detect.new(@ldap)
15+
end
16+
17+
def test_defers_to_configured_strategy
18+
@ldap.configure_member_search_strategy(:classic)
19+
20+
assert_kind_of GitHub::Ldap::MemberSearch::Classic, @strategy.strategy
21+
end
22+
23+
def test_detects_active_directory
24+
caps = Net::LDAP::Entry.new
25+
caps[:supportedcapabilities] = [ACTIVE_DIRECTORY_V61_R2_OID]
26+
27+
@ldap.stub :capabilities, caps do
28+
assert_kind_of GitHub::Ldap::MemberSearch::ActiveDirectory,
29+
@strategy.strategy
30+
end
31+
end
32+
33+
def test_falls_back_to_recursive
34+
caps = Net::LDAP::Entry.new
35+
caps[:supportedcapabilities] = []
36+
37+
@ldap.stub :capabilities, caps do
38+
assert_kind_of GitHub::Ldap::MemberSearch::Recursive,
39+
@strategy.strategy
40+
end
41+
end
42+
end

0 commit comments

Comments
 (0)