Module: AdGear::Infrastructure::GroupManager::LDAP

Includes:
Config, Logging, Utils
Included in:
App
Defined in:
lib/ldap.rb

Overview

The global ldap instance. Uses the net-ldap.

Since:

  • 0.1.0

Constant Summary collapse

Binder =

Since:

  • 0.1.0

Net::LDAP.new host: GLOBAL_CONFIG[:ldap_host],
port: 636,
encryption: {
  method: :simple_tls,
  tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS
},
auth: {
  method: :simple,
  username: GLOBAL_CONFIG[:user_dn],
  password: GLOBAL_CONFIG[:password]
}

Constants included from Logging

AdGear::Infrastructure::GroupManager::Logging::Log

Constants included from Config

Config::GLOBAL_CONFIG

Class Method Summary collapse

Methods included from Utils

compare_attributes, create_ops_list, diff_op_exist?, duplicate?, find_ou, sort_member, stringify_all_keys, symbolify_all_keys

Methods included from Logging

fatal

Methods included from Config

list_users

Class Method Details

.delete_item(dn) ⇒ Object

Deletes an item. Kerplow!

Since:

  • 0.1.0



102
103
104
105
106
# File 'lib/ldap.rb', line 102

def delete_item(dn)
  Binder.delete(dn: dn)
  result = Binder.get_operation_result
  Log.debug(msg: 'Trying to delete item', result: result, dn: dn)
end

.extract_cn(dn) ⇒ Object

Extracts the CN out of a full DN.

Since:

  • 0.1.0



189
190
191
# File 'lib/ldap.rb', line 189

def extract_cn(dn)
  dn.split(',').select { |p| p.match(/^CN=/) }.first.gsub('CN=', '')
end

.get_item(cn, location) ⇒ Object

Fetches a given item by CN.

Since:

  • 0.1.0



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

def get_item(cn, location)
  treebase = GLOBAL_CONFIG[:treebase]

  filter_string = ["distinguishedName=CN=#{cn}"]
  filter_string << location if location
  filter_string << treebase
  filter_string = filter_string.join(', ')

  filter = Net::LDAP::Filter.construct("(#{filter_string})")

  hash = {}
  Log.debug("Filter: #{filter}")

  Binder.search(base: treebase, filter: filter) do |entry|
    entry.each { |var| hash[var.to_s.delete('@')] = entry.public_send(var) }
    Log.debug(msg: 'Found this!', data: hash)
  end
  hash
end

.list_all_groupsObject

Lists all groups groups in the remote instance.

Since:

  • 0.1.0



178
179
180
181
182
183
184
185
# File 'lib/ldap.rb', line 178

def list_all_groups
  groups = {}
  groups.merge!(list_org_groups)
  groups.merge!(list_func_groups)
  groups.merge!(list_perm_groups)
  groups.merge!(list_locations)
  groups
end

.list_func_groupsObject

Lists all functional groups in the remote instance.

Since:

  • 1.0.0



160
161
162
# File 'lib/ldap.rb', line 160

def list_func_groups
  list_groups(list_organizational_units.select { |g| g.match?(/^OU=Functional/) }.first)
end

.list_groups(treebase) ⇒ Object

Lists all groups in the remote instance.

Since:

  • 0.1.0



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/ldap.rb', line 124

def list_groups(treebase)
  filter = Net::LDAP::Filter.construct('(objectClass=group)')

  result = {}

  Log.debug(msg: 'base and filter', base: treebase, filter: filter.to_s)

  Binder.search(base: treebase, filter: filter) do |entry|
    Log.trace('Dumping binder entry', entry)

    obj = {}

    entry.each do |k, v|
      next unless [:member].include?(k)
      Log.trace('dumping key, values', k: k, v: v)
      obj[k] = v.map { |p| extract_cn(p) }.sort
    end

    obj[:description] = entry.description if entry.respond_to?(:description)

    result[extract_cn(entry.dn)] = obj unless entry.dn.nil?
  end

  Binder.get_operation_result
  Log.error("No results for #{treebase}") if result.empty?
  result
end

.list_locationsObject

Lists all location groups in the remote instance.

Since:

  • 0.1.0



172
173
174
# File 'lib/ldap.rb', line 172

def list_locations
  list_groups(list_organizational_units.select { |g| g.match?(/^OU=Location/) }.first)
end

.list_org_groupsObject

Lists all organizational groups in the remote instance.

Since:

  • 0.1.0



154
155
156
# File 'lib/ldap.rb', line 154

def list_org_groups
  list_groups(list_organizational_units.select { |g| g.match?(/^OU=Organizational/) }.first)
end

.list_organizational_unitsObject

Lists organizational units in the remote instance.

Since:

  • 0.1.0



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

def list_organizational_units
  treebase = GLOBAL_CONFIG[:treebase]

  result = []

  filter = Net::LDAP::Filter.construct('(objectCategory=organizationalUnit)')
  Binder.search(base: treebase, filter: filter) do |entry|
    result.push(entry.dn) if entry.dn.match?(/OU=Keycloak Groups/)
  end
  result.empty? ? raise('No valid OUs found') : result
end

.list_perm_groupsObject

Lists all permissions groups in the remote instance.

Since:

  • 0.1.0



166
167
168
# File 'lib/ldap.rb', line 166

def list_perm_groups
  list_groups(list_organizational_units.select { |g| g.match?(/^OU=Permission/) }.first)
end

.set_item(action, dn, attrib = nil, val = nil) ⇒ Object

Modifies or creates an item. This is shoddily written and modify and create should be split.

Since:

  • 0.1.0



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ldap.rb', line 71

def set_item(action, dn, attrib = nil, val = nil)
  if action == :modify
    if attrib == :member && !val.nil?
      val.map! do |m|
        [
          "cn=#{m}",
          AdGear::Infrastructure::GroupManager::Utils.find_ou(m),
          GLOBAL_CONFIG[:treebase]
        ].join(', ')
      end
      Binder.replace_attribute(dn, attrib, val)
    elsif val.nil?
      Binder.replace_attribute(dn, attrib, [])
    else
      Binder.replace_attribute(dn, attrib, val)
    end
    Log.debug(msg: 'Trying to set attribute', result: Binder.get_operation_result, dn: dn, key: attrib, value: val)
  elsif action == :create
    base_attributes = {
      samaccountname: dn.split(',').first.gsub(/cn=/i, ''),
      objectclass: %w[top group]
    }

    Binder.add(dn: dn, attributes: base_attributes)
    result = Binder.get_operation_result
    Log.debug(msg: 'Trying to add item', result: result, dn: dn)
  end
end

.user_exists?(dn) ⇒ Boolean

Verifies that a given user exists.

Returns:

  • (Boolean)

Since:

  • 0.1.0



53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ldap.rb', line 53

def user_exists?(dn)
  Log.debug("Verifying if user #{dn} exists")
  treebase = GLOBAL_CONFIG[:treebase]

  filter_string = ["distinguishedName=CN=#{dn}"]
  filter_string << 'OU=Keycloak Users'
  filter_string << treebase

  filter = Net::LDAP::Filter.construct("(#{filter_string.join(', ')})")
  result = Binder.search(base: treebase, filter: filter)
  Log.trace("Dumping query inspect", data: result.inspect)
  Log.trace("Dumping operation result", data: Binder.get_operation_result)
  result.kind_of?(Array) && result.any?
end