Add LDAP service and seed task
This commit is contained in:
parent
93d56f79d5
commit
c3b9ff8b4a
@ -50,6 +50,13 @@ back-end:
|
|||||||
|
|
||||||
docker-compose exec ldap dsconf localhost backend create --suffix="dc=kosmos,dc=org" --be-name="dev"
|
docker-compose exec ldap dsconf localhost backend create --suffix="dc=kosmos,dc=org" --be-name="dev"
|
||||||
|
|
||||||
|
Now you can seed the back-end with data using this Rails task:
|
||||||
|
|
||||||
|
bundle exec rails ldap:seed
|
||||||
|
|
||||||
|
The seeds task will first delete any existing entries in the directory tree
|
||||||
|
("dc=kosmos,dc=org"), and then create our example/development entries.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
* [Ruby on Rails](https://guides.rubyonrails.org/)
|
* [Ruby on Rails](https://guides.rubyonrails.org/)
|
||||||
|
111
app/services/ldap_service.rb
Normal file
111
app/services/ldap_service.rb
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
class LdapService < ApplicationService
|
||||||
|
def initialize
|
||||||
|
@suffix = ENV["LDAP_SUFFIX"] || "dc=kosmos,dc=org"
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_entry(dn, attrs, interactive=false)
|
||||||
|
puts "Adding entry: #{dn}" if interactive
|
||||||
|
res = ldap_client.add dn: dn, attributes: attrs
|
||||||
|
puts res.inspect if interactive && !res
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_entry(dn, interactive=false)
|
||||||
|
puts "Deleting entry: #{dn}" if interactive
|
||||||
|
res = ldap_client.delete dn: dn
|
||||||
|
puts res.inspect if interactive && !res
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_all_entries
|
||||||
|
if Rails.env.production?
|
||||||
|
raise "Mass deletion of entries not allowed in production"
|
||||||
|
end
|
||||||
|
|
||||||
|
filter = Net::LDAP::Filter.eq("objectClass", "*")
|
||||||
|
entries = ldap_client.search(base: @suffix, filter: filter, attributes: %w{dn})
|
||||||
|
entries.sort_by!{ |e| e.dn.length }.reverse!
|
||||||
|
|
||||||
|
entries.each do |e|
|
||||||
|
delete_entry e.dn, true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_users(args={})
|
||||||
|
if args[:ou]
|
||||||
|
treebase = "ou=#{args[:ou]},cn=users,#{@suffix}"
|
||||||
|
else
|
||||||
|
treebase = ldap_config["base"]
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes = %w{dn cn uid mail admin}
|
||||||
|
filter = Net::LDAP::Filter.eq("uid", "*")
|
||||||
|
|
||||||
|
entries = ldap_client.search(base: treebase, filter: filter, attributes: attributes)
|
||||||
|
entries.sort_by! { |e| e.cn[0] }
|
||||||
|
|
||||||
|
entries = entries.collect do |e|
|
||||||
|
{
|
||||||
|
uid: e.uid.first,
|
||||||
|
mail: e.try(:mail) ? e.mail.first : nil,
|
||||||
|
admin: e.try(:admin) ? 'admin' : nil
|
||||||
|
# password: e.userpassword.first
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_organizations
|
||||||
|
attributes = %w{dn ou description}
|
||||||
|
filter = Net::LDAP::Filter.eq("objectClass", "organizationalUnit")
|
||||||
|
# filter = Net::LDAP::Filter.eq("objectClass", "*")
|
||||||
|
treebase = "cn=users,#{@suffix}"
|
||||||
|
|
||||||
|
entries = ldap_client.search(base: treebase, filter: filter, attributes: attributes)
|
||||||
|
|
||||||
|
entries.sort_by! { |e| e.ou[0] }
|
||||||
|
|
||||||
|
entries = entries.collect do |e|
|
||||||
|
{
|
||||||
|
dn: e.dn,
|
||||||
|
ou: e.ou.first,
|
||||||
|
description: e.try(:description) ? e.description.first : nil,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_organization(ou, description, interactive=false)
|
||||||
|
dn = "ou=#{ou},cn=users,#{@suffix}"
|
||||||
|
|
||||||
|
aci = <<-EOS
|
||||||
|
(target="ldap:///cn=*,ou=#{ou},cn=users,#{@suffix}")(targetattr="cn || sn || uid || mail || userPassword || nsRole || objectClass") (version 3.0; acl "service-#{ou.gsub(".", "-")}-read-search"; allow (read,search) userdn="ldap:///uid=service,ou=#{ou},cn=applications,#{@suffix}";)
|
||||||
|
EOS
|
||||||
|
|
||||||
|
attrs = {
|
||||||
|
objectClass: ["top", "organizationalUnit"],
|
||||||
|
description: description,
|
||||||
|
ou: ou,
|
||||||
|
aci: aci
|
||||||
|
}
|
||||||
|
|
||||||
|
add_entry dn, attrs, interactive
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def ldap_client
|
||||||
|
ldap_client ||= Net::LDAP.new host: ldap_config['host'],
|
||||||
|
port: ldap_config['port'],
|
||||||
|
# TODO has to be :simple_tls if TLS is enabled
|
||||||
|
# encryption: ldap_config['ssl'],
|
||||||
|
auth: {
|
||||||
|
method: :simple,
|
||||||
|
username: ldap_config['admin_user'],
|
||||||
|
password: ldap_config['admin_password']
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def ldap_config
|
||||||
|
ldap_config ||= YAML.load(ERB.new(File.read("#{Rails.root}/config/ldap.yml")).result)[Rails.env]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
24
lib/tasks/ldap.rake
Normal file
24
lib/tasks/ldap.rake
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
namespace :ldap do
|
||||||
|
desc "Set up base entries for LDAP directory"
|
||||||
|
task seed: :environment do |t, args|
|
||||||
|
ldap = LdapService.new
|
||||||
|
|
||||||
|
ldap.delete_all_entries
|
||||||
|
|
||||||
|
ldap.add_entry "dc=kosmos,dc=org", {
|
||||||
|
dc: "kosmos", objectClass: ["top", "domain"]
|
||||||
|
}, true
|
||||||
|
ldap.add_entry "cn=users,dc=kosmos,dc=org", {
|
||||||
|
cn: "users", objectClass: ["top", "organizationalRole"]
|
||||||
|
}, true
|
||||||
|
|
||||||
|
ldap.add_organization "kosmos.org", "Kosmos", true
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "List user domains/organizations"
|
||||||
|
task list_organizations: :environment do |t, args|
|
||||||
|
ldap = LdapService.new
|
||||||
|
orgs = ldap.fetch_organizations
|
||||||
|
puts orgs.inspect
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user