183 lines
4.4 KiB
Ruby
183 lines
4.4 KiB
Ruby
# SPDX-License-Identifier: Apache-2.0
|
|
# Copyright (C) 2021 OKTET Labs Ltd. All rights reserved.
|
|
|
|
#
|
|
# Class LdapRecord for Diary Management Application.
|
|
#
|
|
|
|
require_relative 'ldap_cache'
|
|
require 'net/smtp'
|
|
|
|
class LdapRecord
|
|
@@connection = nil
|
|
@@cache = {}
|
|
attr_reader :id
|
|
|
|
def LdapRecord.setup(args)
|
|
raise "Invalid parameters" unless args.is_a? Hash
|
|
raise "LDAP server is not specified" unless args[:host]
|
|
@@ldap = LDAP::Conn.new(args[:host], args[:port] || LDAP::LDAP_PORT)
|
|
if args[:ver] == 3
|
|
@@ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
|
|
end
|
|
if args[:binddn] != ""
|
|
@@ldap.bind(args[:binddn], args[:bindpw])
|
|
end
|
|
#@@ldap.bind # Bind is optional for LDAPv3
|
|
|
|
raise "LDAP tree root is not specified" unless args[:root]
|
|
raise "LDAP key attribute is not specified" unless args[:key]
|
|
@@connection = LDAP::Cache.new(@@ldap, args[:root],
|
|
LDAP::LDAP_SCOPE_SUBTREE, args[:key])
|
|
end
|
|
|
|
def initialize(id)
|
|
raise "LDAP connection is not established" if not @@connection
|
|
@id = id
|
|
@@cache[id] = self
|
|
@attributes = @@connection[id]
|
|
end
|
|
|
|
def LdapRecord.find(id)
|
|
# entry = @@cache[id] || (exists?(id) ? new(id) : nil)
|
|
# entry = nil if (entry && !entry.valid?)
|
|
# entry
|
|
return @@cache[id] if valid?(@@cache[id])
|
|
exists?(id) ? new(id) : nil
|
|
end
|
|
|
|
def LdapRecord.valid?(entry)
|
|
entry != nil
|
|
end
|
|
|
|
def LdapRecord.find_or_create(id)
|
|
@@cache[id] || new(id)
|
|
end
|
|
|
|
def LdapRecord.exists?(id)
|
|
@@connection[id] != nil
|
|
end
|
|
|
|
def LdapRecord.find_by_filter(filter)
|
|
@@connection.list(filter, "uid").collect { |x| find(x[0]) }.find_all { |x| x }
|
|
end
|
|
|
|
def method_missing(method, *args)
|
|
@attributes ? @attributes[method.to_s] : nil
|
|
end
|
|
end
|
|
|
|
class Person < LdapRecord
|
|
MAX_LENGTH = 30
|
|
|
|
attr_reader :organization
|
|
def initialize(id)
|
|
super(id)
|
|
@organization = Organization.find_by_name(self.o)
|
|
end
|
|
|
|
def Person.exists?(id)
|
|
super(id) && @@connection[id]["objectClass"] == "inetOrgPerson"
|
|
end
|
|
|
|
def Person.valid?(entry)
|
|
super(entry) && entry.objectClass == "inetOrgPerson"
|
|
end
|
|
|
|
def Person.set_local(o_name, ou_name)
|
|
@@local_o = o_name
|
|
@@local_ou = ou_name
|
|
end
|
|
|
|
def to_s
|
|
self.cn || @id
|
|
end
|
|
|
|
def to_html
|
|
if not self.cn
|
|
e(:span, :style => "color:red"){ @id }
|
|
elsif self.mail
|
|
e(:a, :href => "mailto:" + self.mail){ self.cn }
|
|
else
|
|
e(:span){ self.cn }
|
|
end
|
|
end
|
|
|
|
def local?
|
|
self.o == @@local_o
|
|
end
|
|
|
|
def employee?
|
|
local? and self.ou == @@local_ou
|
|
end
|
|
|
|
def customer?
|
|
self.o != nil and not local?
|
|
end
|
|
|
|
def Person.find_by_org(org_name)
|
|
find_by_filter("(&(o=#{org_name})(objectClass=inetOrgPerson))")
|
|
end
|
|
|
|
def <=>(rhs)
|
|
if self.cn
|
|
rhs.cn ? self.cn <=> rhs.cn : -1
|
|
else
|
|
rhs.cn ? 1 : @id <=> rhs.id
|
|
end
|
|
end
|
|
end
|
|
|
|
class Organization < LdapRecord
|
|
def to_s
|
|
self.o || @id
|
|
end
|
|
|
|
def to_html
|
|
if not self.o
|
|
e(:span, :style => "color:red"){ @id }
|
|
else
|
|
e(:span){ self.o }
|
|
end
|
|
end
|
|
|
|
def Organization.exists?(id)
|
|
super(id) && @@connection[id]["objectClass"] == "organization"
|
|
end
|
|
|
|
def Organization.valid?(entry)
|
|
super(entry) && entry.objectClass == "organization"
|
|
end
|
|
|
|
def Organization.all
|
|
find_by_filter("(objectClass=organization)")
|
|
end
|
|
|
|
def Organization.find_by_name(name)
|
|
return nil unless name.is_a? String
|
|
res = find_by_filter("(&(o=#{name})(objectClass=organization))")
|
|
res ? res[0] : nil
|
|
end
|
|
|
|
def <=>(rhs)
|
|
if self.o
|
|
rhs.o ? self.o <=> rhs.o : -1
|
|
else
|
|
rhs.o ? 1 : @id <=> rhs.id
|
|
end
|
|
end
|
|
end
|
|
|
|
class Notifier
|
|
def notify(who, message)
|
|
raise "No such person \"#{who.to_s}\"" if not who.is_a? Person
|
|
msg = "From: Diary Management Application <#{DiaryEnv::SMTP_FROM}>\n" +
|
|
"To: #{who.cn} <#{who.mail}>\n" +
|
|
"Subject: Diary Management\n" +
|
|
"\n" + message
|
|
Net::SMTP.start(DiaryEnv::SMTP_HOST) do |smtp|
|
|
smtp.send_message msg, DiaryEnv::SMTP_FROM, who.mail.untaint
|
|
end
|
|
end
|
|
end
|