# -*- coding: utf-8 -*- # Copyright (c) 2007 Juan Manuel Gimeno Illa # License: # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # # A full copy of the GPL can be found in /usr/share/common-licenses/GPL on most # Debian systems. import deskbar import deskbar.Handler import deskbar.Match import gtk import ldap from gettext import gettext as _ GCONF_LDAP_HOST = deskbar.GCONF_DIR+"/ldap/path" GCONF_LDAP_PORT = deskbar.GCONF_DIR+"/ldap/port" GCONF_LDAP_BASE = deskbar.GCONF_DIR+"/ldap/base" GCONF_LDAP_WHO = deskbar.GCONF_DIR+"/ldap/who" GCONF_LDAP_CRED = deskbar.GCONF_DIR+"/ldap/cred" def _check_requirements(): if not deskbar.GCONF_CLIENT.get_string(GCONF_LDAP_HOST) or \ not deskbar.GCONF_CLIENT.get_string(GCONF_LDAP_PORT) or \ not deskbar.GCONF_CLIENT.get_string(GCONF_LDAP_BASE): return (deskbar.Handler.HANDLER_HAS_REQUIREMENTS, _("You must configure the LDAP server"), _on_config_server) else: return (deskbar.Handler.HANDLER_IS_CONFIGURABLE, _("You can configure the LDAP server"), _on_config_server) def _add_labeled_entry_at_row(table, row, name, text): label = gtk.Label(name) entry = gtk.Entry() entry.set_text(text) table.attach(label, 0, 1, row, row+1) table.attach(entry, 1, 2, row, row+1) return entry def _on_config_server(parent): dialog = gtk.Dialog( _("LDAP Configuration"), parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) host, base, port, who, cred = _get_ldap_gconf() table = gtk.Table(rows=5, columns=2) host_entry = _add_labeled_entry_at_row(table, 0, _("Host"), host) port_entry = _add_labeled_entry_at_row(table, 1, _("Port"), port) base_entry = _add_labeled_entry_at_row(table, 2, _("Base"), base) who_entry = _add_labeled_entry_at_row(table, 3, _("Who"), who) cred_entry = _add_labeled_entry_at_row(table, 4, _("Cred"), cred) table.show_all() dialog.vbox.add(table) response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_ACCEPT: _update_gconf_from_entry(GCONF_LDAP_HOST, host_entry) _update_gconf_from_entry(GCONF_LDAP_PORT, port_entry) _update_gconf_from_entry(GCONF_LDAP_BASE, base_entry) _update_gconf_from_entry(GCONF_LDAP_WHO, who_entry) _update_gconf_from_entry(GCONF_LDAP_CRED, cred_entry) def _update_gconf_from_entry(key, entry): if entry.get_text() != "": deskbar.GCONF_CLIENT.set_string(key, entry.get_text()) def _get_ldap_gconf(): host = deskbar.GCONF_CLIENT.get_string(GCONF_LDAP_HOST) or "" base = deskbar.GCONF_CLIENT.get_string(GCONF_LDAP_BASE) or "" port = deskbar.GCONF_CLIENT.get_string(GCONF_LDAP_PORT) or "" who = deskbar.GCONF_CLIENT.get_string(GCONF_LDAP_WHO) or "" cred = deskbar.GCONF_CLIENT.get_string(GCONF_LDAP_CRED) or "" return host, base, port, who, cred class LDAPHandler(deskbar.Handler.Handler): def __init__ (self): deskbar.Handler.Handler.__init__ (self, "nobody.png") host, base, port, who, cred = _get_ldap_gconf() self.ld = LDAPServer(host, port, who, cred, base) def query(self, text): return [LDAPMatch(self, text)] class LDAPMatch(deskbar.Match.Match): "This class represents and LDAP entry" def __init__(self, backend, fragment, **kwargs): deskbar.Match.Match.__init__(self, backend, **kwargs) self.backend = backend self.fragment = fragment def get_verb(self): return _("Search in LDAP for %s") % self.fragment def get_category(self): return "ldap" def action(self, text=None): try: entries = self.backend.ld.find_by_name_fragment(text) if entries: dlg = make_results_dialog(entries, text) dlg.show_all() #win.run() #win.destroy() else: dlg = gtk.MessageDialog( type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_CLOSE, message_format=_("No matches in LDAP")) dlg.run() dlg.destroy() except ldap.LDAPError: dlg = gtk.MessageDialog( type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_CLOSE, message_format=_("Unable to connect to LDAP server")) dlg.run() dlg.destroy() def make_results_dialog(entries, text): dialog = gtk.Dialog( title=_("LDAP entries matching %s") % text) dialog.set_position(gtk.WIN_POS_CENTER) dialog.set_size_request(600,400) close_btn = dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) close_btn.connect("clicked", lambda widget, data: dialog.destroy(), None) close_btn.grab_focus() scrolled_window = gtk.ScrolledWindow() scrolled_window.set_policy( hscrollbar_policy=gtk.POLICY_AUTOMATIC, vscrollbar_policy=gtk.POLICY_ALWAYS) dialog.vbox.pack_start(scrolled_window) listview = make_listview(entries) scrolled_window.add_with_viewport(listview) return dialog def make_listview(entries): model = gtk.ListStore(str, str, str) model.set_sort_column_id(0, gtk.SORT_ASCENDING) listview = gtk.TreeView(model) cell = gtk.CellRendererText() listview.append_column(gtk.TreeViewColumn(_("Name"), cell, text=0)) listview.append_column(gtk.TreeViewColumn(_("Mail"), cell, text=1)) listview.append_column(gtk.TreeViewColumn(_("Phone"), cell, text=2)) for entry in entries: model.append([entry.name, entry.mail, entry.phone]) listview.set_model(model) return listview class LDAPEntry(object): "This class represents and LDAP entry" def __init__(self, attrs): self.name = attrs["cn"] self.mail = attrs.get("mail") or _("Unknown") self.phone = attrs.get("telephoneNumber") or _("Unknown") class LDAPServer(object): "This class represents the LDAP server" def __init__(self, host, port=389, who="", cred="", base=""): self.host = host self.port = port self.who = who self.cred = cred self.base = base def find_by_name_fragment(self, frag): attributes = ["cn", "mail", "telephoneNumber"] pattern = "(|(cn=*%(frag)s*)(sn=*%(frag)s*)(givenName=*%(frag)s*))" \ % {"frag" : frag} self.ldap = ldap.initialize("ldap://%s:%s" % (self.host, self.port)) self.ldap.simple_bind_s(self.who, self.cred) result = self.ldap.search_s( self.base, ldap.SCOPE_SUBTREE, pattern, attributes) entries = [] for _, entry_attrs in result: entry = dict.fromkeys(attributes, "") for key in entry_attrs: entry[key] = entry_attrs[key][0] entries.append(LDAPEntry(entry)) return entries HANDLERS = { "LDAPHandler" : { "name" : _("LDAP Server"), "description" : _("Searches into LDAP servers by name fragment"), "requirements" : _check_requirements, "categories" : { "ldap" : { "name" : _("LDAP Entries"), } }, } }