Class: GitHub::Ldap

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/github/ldap.rb,
lib/github/ldap/group.rb,
lib/github/ldap/domain.rb,
lib/github/ldap/filter.rb,
lib/github/ldap/server.rb,
lib/github/ldap/posix_group.rb,
lib/github/ldap/virtual_group.rb,
lib/github/ldap/virtual_attributes.rb

Defined Under Namespace

Modules: Filter Classes: Domain, Group, PosixGroup, VirtualAttributes, VirtualGroup

Constant Summary collapse

DEFAULT_FIXTURES_PATH =

Preconfigured user fixtures. If you want to use them for your own tests.

File.expand_path('fixtures.ldif', File.dirname(__FILE__))
DEFAULT_SERVER_OPTIONS =
{
  user_fixtures:  DEFAULT_FIXTURES_PATH,
  user_domain:    'dc=github,dc=com',
  admin_user:     'uid=admin,dc=github,dc=com',
  admin_password: 'secret',
  quiet:          true,
  port:           3897
}

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Ldap

Returns a new instance of Ldap.



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/github/ldap.rb', line 28

def initialize(options = {})
  @uid = options[:uid] || "sAMAccountName"

  @connection = Net::LDAP.new({host: options[:host], port: options[:port]})

  if options[:admin_user] && options[:admin_password]
    @connection.authenticate(options[:admin_user], options[:admin_password])
  end

  if encryption = check_encryption(options[:encryption])
    @connection.encryption(encryption)
  end

  configure_virtual_attributes(options[:virtual_attributes])

  # enable fallback recursive group search unless option is false
  @recursive_group_search_fallback = (options[:recursive_group_search_fallback] != false)

  # enable posixGroup support unless option is false
  @posix_support = (options[:posix_support] != false)

  # search_domains is a connection of bases to perform searches
  # when a base is not explicitly provided.
  @search_domains = Array(options[:search_domains])
end

Class Attribute Details

.ldap_serverObject (readonly)

ldap_server: is the instance of the testing ldap server,

you should never interact with it,
but it's used to grecefully stop it after your tests finalize.


26
27
28
# File 'lib/github/ldap/server.rb', line 26

def ldap_server
  @ldap_server
end

.server_optionsObject (readonly)

server_options: is the options used to start the server,

useful to know in development.


21
22
23
# File 'lib/github/ldap/server.rb', line 21

def server_options
  @server_options
end

Instance Attribute Details

#search_domainsObject (readonly)

Returns the value of attribute search_domains.



26
27
28
# File 'lib/github/ldap.rb', line 26

def search_domains
  @search_domains
end

#uidObject (readonly)

Returns the value of attribute uid.



26
27
28
# File 'lib/github/ldap.rb', line 26

def uid
  @uid
end

#virtual_attributesObject (readonly)

Returns the value of attribute virtual_attributes.



26
27
28
# File 'lib/github/ldap.rb', line 26

def virtual_attributes
  @virtual_attributes
end

Class Method Details

.server_tmpObject

Determine the temporal directory where the ldap server lives. If there is no temporal directory in the environment we create one in the base path.

Returns the path to the temporal directory.



55
56
57
58
59
60
61
62
63
64
# File 'lib/github/ldap/server.rb', line 55

def self.server_tmp
  tmp = ENV['TMPDIR'] || ENV['TEMPDIR']

  if tmp.nil?
    tmp = 'tmp'
    Dir.mkdir(tmp) unless File.directory?('tmp')
  end

  tmp
end

.start_server(options = {}) ⇒ Object

Start a testing server. If there is already a server initialized it doesn’t do anything.

options: is a hash with the custom options for the server.



33
34
35
36
37
38
39
40
41
42
43
# File 'lib/github/ldap/server.rb', line 33

def self.start_server(options = {})
  @server_options = DEFAULT_SERVER_OPTIONS.merge(options)

  @server_options[:allow_anonymous] ||= false
  @server_options[:ldif]              = @server_options[:user_fixtures]
  @server_options[:domain]            = @server_options[:user_domain]
  @server_options[:tmpdir]          ||= server_tmp

  @ldap_server = Ladle::Server.new(@server_options)
  @ldap_server.start
end

.stop_serverObject

Stop the testing server. If there is no server started this method doesn’t do anything.



47
48
49
# File 'lib/github/ldap/server.rb', line 47

def self.stop_server
  ldap_server && ldap_server.stop
end

Instance Method Details

#check_encryption(encryption) ⇒ Object

Internal - Determine whether to use encryption or not.

encryption: is the encryption method, either ‘ssl’, ‘tls’, ‘simple_tls’ or ‘start_tls’.

Returns the real encryption type.



147
148
149
150
151
152
153
154
155
156
# File 'lib/github/ldap.rb', line 147

def check_encryption(encryption)
  return unless encryption

  case encryption.downcase.to_sym
  when :ssl, :simple_tls
    :simple_tls
  when :tls, :start_tls
    :start_tls
  end
end

#configure_virtual_attributes(attributes) ⇒ Object

Internal - Configure virtual attributes for this server. If the option is ‘true`, we’ll use the default virual attributes. If it’s a Hash we’ll map the attributes in the hash.

attributes: is the option set when Ldap is initialized.

Returns a VirtualAttributes.



165
166
167
168
169
170
171
172
173
# File 'lib/github/ldap.rb', line 165

def configure_virtual_attributes(attributes)
  @virtual_attributes = if attributes == true
    VirtualAttributes.new(true)
  elsif attributes.is_a?(Hash)
    VirtualAttributes.new(true, attributes)
  else
    VirtualAttributes.new(false)
  end
end

#domain(base_name) ⇒ Object

Public - Creates a new domain object to perform operations

base_name: is the dn of the base root.

Returns a new Domain object.



90
91
92
# File 'lib/github/ldap.rb', line 90

def domain(base_name)
  Domain.new(self, base_name, @uid)
end

#group(base_name) ⇒ Object

Public - Creates a new group object to perform operations

base_name: is the dn of the base root.

Returns a new Group object. Returns nil if the dn is not in the server.



100
101
102
103
104
105
# File 'lib/github/ldap.rb', line 100

def group(base_name)
  entry = domain(base_name).bind
  return unless entry

  load_group(entry)
end

#load_group(group_entry) ⇒ Object

Public - Create a new group object based on a Net::LDAP::Entry.

group_entry: is a Net::LDAP::Entry.

Returns a Group, PosixGroup or VirtualGroup object.



112
113
114
115
116
117
118
119
120
# File 'lib/github/ldap.rb', line 112

def load_group(group_entry)
  if @virtual_attributes.enabled?
    VirtualGroup.new(self, group_entry)
  elsif posix_support_enabled? && PosixGroup.valid?(group_entry)
    PosixGroup.new(self, group_entry)
  else
    Group.new(self, group_entry)
  end
end

#posix_support_enabled?Boolean

Public - Whether membership checks should include posixGroup filter conditions on ‘memberUid`. Configurable since some LDAP servers don’t handle unsupported attribute queries gracefully.

Enable by passing :posix_support => true.

Returns true, false, or nil (assumed false).

Returns:

  • (Boolean)


71
72
73
# File 'lib/github/ldap.rb', line 71

def posix_support_enabled?
  @posix_support
end

#recursive_group_search_fallback?Boolean

Public - Whether membership checks should recurse into nested groups when virtual attributes aren’t enabled. The fallback search has poor performance characteristics in some cases, in which case this should be disabled by passing :recursive_group_search_fallback => false.

Returns true or false.

Returns:

  • (Boolean)


60
61
62
# File 'lib/github/ldap.rb', line 60

def recursive_group_search_fallback?
  @recursive_group_search_fallback
end

#search(options, &block) ⇒ Object

Public - Search entries in the ldap server.

options: is a hash with the same options that Net::LDAP::Connection#search supports. block: is an optional block to pass to the search.

Returns an Array of Net::LDAP::Entry.



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/github/ldap.rb', line 128

def search(options, &block)
  result = if options[:base]
    @connection.search(options, &block)
  else
    search_domains.each_with_object([]) do |base, result|
      rs = @connection.search(options.merge(:base => base), &block)
      result.concat Array(rs) unless rs == false
    end
  end

  return [] if result == false
  Array(result)
end

#test_connectionObject

Public - Utility method to check if the connection with the server can be stablished. It tries to bind with the ldap auth default configuration.

Returns an OpenStruct with ‘code` and `message`. If `code` is 0, the operation succeeded and there is no message.



80
81
82
83
# File 'lib/github/ldap.rb', line 80

def test_connection
  @connection.bind
  last_operation_result
end