Class: GitHub::Ldap::MembershipValidators::ActiveDirectory

Inherits:
Base
  • Object
show all
Defined in:
lib/github/ldap/membership_validators/active_directory.rb

Overview

Validates membership using the ActiveDirectory “in chain” matching rule.

The 1.2.840.113556.1.4.1941 matching rule (LDAP_MATCHING_RULE_IN_CHAIN) “walks the chain of ancestry in objects all the way to the root until it finds a match”. Source: msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx

This means we have an efficient method of searching membership even in nested groups, performed on the server side.

Instance Attribute Summary

Attributes inherited from Base

#groups, #ldap

Instance Method Summary collapse

Methods inherited from Base

#initialize

Constructor Details

This class inherits a constructor from GitHub::Ldap::MembershipValidators::Base

Instance Method Details

#group_dnsObject

Internal: the group DNs to check against.

Returns an Array of String DNs.



50
51
52
# File 'lib/github/ldap/membership_validators/active_directory.rb', line 50

def group_dns
  @group_dns ||= groups.map(&:dn)
end

#membership_in_chain_filter(entry) ⇒ Object

Internal: Constructs a membership filter using the “in chain” extended matching rule afforded by ActiveDirectory.

Returns a Net::LDAP::Filter object.



41
42
43
44
45
# File 'lib/github/ldap/membership_validators/active_directory.rb', line 41

def membership_in_chain_filter(entry)
  group_dns.map do |dn|
    Net::LDAP::Filter.ex("memberOf:#{OID}", dn)
  end.reduce(:|)
end

#perform(entry) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/github/ldap/membership_validators/active_directory.rb', line 17

def perform(entry)
  # short circuit validation if there are no groups to check against
  return true if groups.empty?

  # search for the entry on the condition that the entry is a member
  # of one of the groups or their subgroups.
  #
  # 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 \
    filter: membership_in_chain_filter(entry),
    base:   entry.dn,
    scope:  Net::LDAP::SearchScope_BaseObject,
    attributes: ATTRS

  # membership validated if entry was matched and returned as a result
  matched.map(&:dn).include?(entry.dn)
end