summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
authorthomascube <thomas@roundcube.net>2011-01-29 11:31:23 +0000
committerthomascube <thomas@roundcube.net>2011-01-29 11:31:23 +0000
commit6039aae3878aa5880415290cbc41af4bac4fdcb5 (patch)
treeaf67fca02fb859cb6863127d97c0a71680f69bb6 /program
parentcf2da2f9aacd1b13ad9019f44a3f1edd824cd015 (diff)
Add groups support for LDAP address books, contributed by Andreas Dick
Diffstat (limited to 'program')
-rw-r--r--program/include/rcmail.php2
-rw-r--r--program/include/rcube_ldap.php269
-rw-r--r--program/steps/addressbook/save.inc2
3 files changed, 270 insertions, 3 deletions
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 7f76ba4c3..ab2c16172 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -394,7 +394,7 @@ class rcmail
$list[$id] = array(
'id' => $id,
'name' => $prop['name'],
- 'groups' => false,
+ 'groups' => is_array($prop['groups']),
'readonly' => !$prop['writable'],
'autocomplete' => in_array('sql', $autocomplete)
);
diff --git a/program/include/rcube_ldap.php b/program/include/rcube_ldap.php
index 7ea22ebac..4fe74e310 100644
--- a/program/include/rcube_ldap.php
+++ b/program/include/rcube_ldap.php
@@ -4,7 +4,7 @@
| program/include/rcube_ldap.php |
| |
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2006-2010, The Roundcube Dev Team |
+ | Copyright (C) 2006-2011, The Roundcube Dev Team |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
@@ -12,6 +12,7 @@
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+ | Andreas Dick <andudi (at) gmx (dot) ch> |
+-----------------------------------------------------------------------+
$Id$
@@ -40,11 +41,16 @@ class rcube_ldap extends rcube_addressbook
/** public properties */
public $primary_key = 'ID';
public $readonly = true;
+ public $groups = false;
public $list_page = 1;
public $page_size = 10;
+ public $group_id = 0;
public $ready = false;
public $coltypes = array();
+ private $group_cache = array();
+ private $group_members = array();
+
/**
* Object constructor
@@ -58,6 +64,10 @@ class rcube_ldap extends rcube_addressbook
{
$this->prop = $p;
+ // check if groups are configured
+ if (is_array($p['groups']))
+ $this->groups = true;
+
// fieldmap property is given
if (is_array($p['fieldmap'])) {
foreach ($p['fieldmap'] as $rf => $lf)
@@ -347,6 +357,21 @@ class rcube_ldap extends rcube_addressbook
$this->result->add($this->_ldap2result($entries[$i]));
}
+ // temp hack for filtering group members
+ if ($this->group_id)
+ {
+ $result = new rcube_result_set();
+ while ($record = $this->result->iterate())
+ {
+ if ($this->group_members[$record['ID']])
+ {
+ $result->add($record);
+ $result->count++;
+ }
+ }
+ $this->result = $result;
+ }
+
return $this->result;
}
@@ -799,5 +824,247 @@ class rcube_ldap extends rcube_addressbook
return strtr($str, $replace);
}
+
+ /**
+ * Setter for the current group
+ * (empty, has to be re-implemented by extending class)
+ */
+ function set_group($group_id)
+ {
+ if ($group_id)
+ {
+ if (! $this->group_cache) $this->list_groups();
+ $cache = $this->group_cache[$group_id]['members'];
+
+ $members = array();
+ for ($i=1; $i<$cache["count"]; $i++)
+ {
+ $member_dn = base64_encode($cache[$i]);
+ $members[$member_dn] = 1;
+ }
+ $this->group_members = $members;
+ $this->group_id = $group_id;
+ }
+ else $this->group_id = 0;
+ }
+
+ /**
+ * List all active contact groups of this source
+ *
+ * @param string Optional search string to match group name
+ * @return array Indexed list of contact groups, each a hash array
+ */
+ function list_groups($search = null)
+ {
+ if (!$this->prop['groups'])
+ return array();
+
+ $base_dn = $this->prop['groups']['base_dn'];
+ $filter = $this->prop['groups']['filter'];
+
+ $res = ldap_search($this->conn, $base_dn, $filter, array('cn','member'));
+ if ($res === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
+ $this->set_error(self::ERROR_SAVING, 'errorsaving');
+ return array();
+ }
+ $ldap_data = ldap_get_entries($this->conn, $res);
+
+ $groups = array();
+ $group_sortnames = array();
+ for ($i=0; $i<$ldap_data["count"]; $i++)
+ {
+ $group_name = $ldap_data[$i]['cn'][0];
+ $group_id = base64_encode($group_name);
+ $groups[$group_id]['ID'] = $group_id;
+ $groups[$group_id]['name'] = $group_name;
+ $groups[$group_id]['members'] = $ldap_data[$i]['member'];
+ $group_sortnames[] = strtolower($group_name);
+ }
+ array_multisort($group_sortnames, SORT_ASC, SORT_STRING, $groups);
+
+ $this->group_cache = $groups;
+ return $groups;
+ }
+
+ /**
+ * Create a contact group with the given name
+ *
+ * @param string The group name
+ * @return mixed False on error, array with record props in success
+ */
+ function create_group($group_name)
+ {
+ if (!$this->group_cache)
+ $this->list_groups();
+
+ $base_dn = $this->prop['groups']['base_dn'];
+ $new_dn = "cn=$group_name,$base_dn";
+ $new_gid = base64_encode($group_name);
+
+ $new_entry = array(
+ 'objectClass' => array('top', 'groupOfNames'),
+ 'cn' => $group_name,
+ 'member' => '',
+ );
+
+ $res = ldap_add($this->conn, $new_dn, $new_entry);
+ if ($res === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
+ $this->set_error(self::ERROR_SAVING, 'errorsaving');
+ return false;
+ }
+ return array('id' => $new_gid, 'name' => $group_name);
+ }
+
+ /**
+ * Delete the given group and all linked group members
+ *
+ * @param string Group identifier
+ * @return boolean True on success, false if no data was changed
+ */
+ function delete_group($group_id)
+ {
+ if (!$this->group_cache)
+ $this->list_groups();
+
+ $base_dn = $this->prop['groups']['base_dn'];
+ $group_name = $this->group_cache[$group_id]['name'];
+
+ $del_dn = "cn=$group_name,$base_dn";
+ $res = ldap_delete($this->conn, $del_dn);
+ if ($res === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
+ $this->set_error(self::ERROR_SAVING, 'errorsaving');
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Rename a specific contact group
+ *
+ * @param string Group identifier
+ * @param string New name to set for this group
+ * @return boolean New name on success, false if no data was changed
+ */
+ function rename_group($group_id, $new_name)
+ {
+ if (!$this->group_cache)
+ $this->list_groups();
+
+ $base_dn = $this->prop['groups']['base_dn'];
+ $group_name = $this->group_cache[$group_id]['name'];
+ $old_dn = "cn=$group_name,$base_dn";
+ $new_rdn = "cn=$new_name";
+
+ $res = ldap_rename($this->conn, $old_dn, $new_rdn, NULL, TRUE);
+ if ($res === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
+ $this->set_error(self::ERROR_SAVING, 'errorsaving');
+ return false;
+ }
+ return $new_name;
+ }
+
+ /**
+ * Add the given contact records the a certain group
+ *
+ * @param string Group identifier
+ * @param array List of contact identifiers to be added
+ * @return int Number of contacts added
+ */
+ function add_to_group($group_id, $contact_ids)
+ {
+ if (!$this->group_cache)
+ $this->list_groups();
+
+ $base_dn = $this->prop['groups']['base_dn'];
+ $group_name = $this->group_cache[$group_id]['name'];
+ $group_dn = "cn=$group_name,$base_dn";
+
+ $new_attrs = array();
+ foreach (explode(",", $contact_ids) as $id)
+ $new_attrs['member'][] = base64_decode($id);
+
+ $res = ldap_mod_add($this->conn, $group_dn, $new_attrs);
+ if ($res === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
+ $this->set_error(self::ERROR_SAVING, 'errorsaving');
+ return 0;
+ }
+ return count($new_attrs['member']);
+ }
+
+ /**
+ * Remove the given contact records from a certain group
+ *
+ * @param string Group identifier
+ * @param array List of contact identifiers to be removed
+ * @return int Number of deleted group members
+ */
+ function remove_from_group($group_id, $contact_ids)
+ {
+ if (!$this->group_cache)
+ $this->list_groups();
+
+ $base_dn = $this->prop['groups']['base_dn'];
+ $group_name = $this->group_cache[$group_id]['name'];
+ $group_dn = "cn=$group_name,$base_dn";
+
+ $del_attrs = array();
+ foreach (explode(",", $contact_ids) as $id)
+ $del_attrs['member'][] = base64_decode($id);
+
+ $res = ldap_mod_del($this->conn, $group_dn, $del_attrs);
+ if ($res === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
+ $this->set_error(self::ERROR_SAVING, 'errorsaving');
+ return 0;
+ }
+ return count($del_attrs['member']);
+ }
+
+ /**
+ * Get group assignments of a specific contact record
+ *
+ * @param mixed Record identifier
+ *
+ * @return array List of assigned groups as ID=>Name pairs
+ * @since 0.5-beta
+ */
+ function get_record_groups($contact_id)
+ {
+ if (!$this->prop['groups'])
+ return array();
+
+ $base_dn = $this->prop['groups']['base_dn'];
+ $contact_dn = base64_decode($contact_id);
+ $filter = "(member=$contact_dn)";
+
+ $res = ldap_search($this->conn, $base_dn, $filter, array('cn'));
+ if ($res === false)
+ {
+ $this->_debug("S: ".ldap_error($this->conn));
+ $this->set_error(self::ERROR_SAVING, 'errorsaving');
+ return array();
+ }
+ $ldap_data = ldap_get_entries($this->conn, $res);
+
+ $groups = array();
+ for ($i=0; $i<$ldap_data["count"]; $i++)
+ {
+ $group_name = $ldap_data[$i]['cn'][0];
+ $group_id = base64_encode($group_name);
+ $groups[$group_id] = $group_id;
+ }
+ return $groups;
+ }
}
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 5d8b53159..4eb24fe82 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -242,7 +242,7 @@ else {
if ($insert_id) {
// add new contact to the specified group
- if ($CONTACTS->group_id) {
+ if ($CONTACTS->groups && $CONTACTS->group_id) {
$plugin = $RCMAIL->plugins->exec_hook('group_addmembers', array('group_id' => $CONTACTS->group_id, 'ids' => $insert_id, 'source' => $source));
if (!$plugin['abort']) {