9 commits - lib/api lib/Auth lib/Auth.php lib/client lib/ext lib/kolab_api_service.php lib/kolab_client_task.php lib/Log.php public_html/js

Jeroen van Meeuwen vanmeeuwen at kolabsys.com
Mon Sep 3 13:34:04 CEST 2012


 lib/Auth.php                              |   50 ---------
 lib/Auth/LDAP.php                         |  163 ++++++++++++++++++++----------
 lib/Log.php                               |    8 -
 lib/api/kolab_api_service_form_value.php  |   42 ++++---
 lib/api/kolab_api_service_group.php       |    2 
 lib/api/kolab_api_service_resource.php    |    2 
 lib/api/kolab_api_service_resources.php   |    2 
 lib/api/kolab_api_service_role.php        |   15 +-
 lib/api/kolab_api_service_user.php        |    2 
 lib/client/kolab_client_task_domain.php   |    7 -
 lib/client/kolab_client_task_group.php    |    7 -
 lib/client/kolab_client_task_resource.php |    7 -
 lib/client/kolab_client_task_role.php     |    6 -
 lib/client/kolab_client_task_user.php     |    7 -
 lib/ext/Net/LDAP3.php                     |   28 ++---
 lib/kolab_api_service.php                 |   32 +++--
 lib/kolab_client_task.php                 |    1 
 public_html/js/kolab_admin.js             |   14 ++
 18 files changed, 219 insertions(+), 176 deletions(-)

New commits:
commit ad4fe9295c591d0f8da16169983194377959f668
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Mon Sep 3 12:25:37 2012 +0100

    Allow parse_input_attributes to use/abuse a level of variable substitution

diff --git a/lib/kolab_api_service.php b/lib/kolab_api_service.php
index 3d70ef0..ad5c051 100644
--- a/lib/kolab_api_service.php
+++ b/lib/kolab_api_service.php
@@ -28,9 +28,10 @@
  */
 abstract class kolab_api_service
 {
+    protected $cache = array();
+    protected $conf;
     protected $controller;
     protected $db;
-    protected $cache = array();
 
     /**
      * Class constructor.
@@ -39,9 +40,10 @@ abstract class kolab_api_service
      */
     public function __construct($ctrl)
     {
-        $this->db         = SQL::get_instance();
+        $this->conf       = Conf::get_instance();
         $this->controller = $ctrl;
-    }
+        $this->db         = SQL::get_instance();
+   }
 
     /**
      * Advertise this service's capabilities
@@ -239,8 +241,8 @@ abstract class kolab_api_service
     {
         $type_attrs   = $this->object_type_attributes($object_name, $attribs['type_id']);
 
-        //console("parse_input_attributes", $type_attrs);
-        //console("called with \$attribs", $attribs);
+        Log::trace("kolab_api_service::parse_input_attributes for $object_name: " . var_export($type_attrs, TRUE));
+        Log::trace("called with \$attribs: " . var_export($attribs, TRUE));
 
         $form_service = $this->controller->get_service('form_value');
 
@@ -251,14 +253,14 @@ abstract class kolab_api_service
 
         if (isset($type_attrs['form_fields'])) {
             foreach ($type_attrs['form_fields'] as $key => $value) {
-                //console("Running parse input attributes for key $key");
+                Log::trace("Running parse input attributes for key $key");
 
                 if (empty($attribs[$key]) && empty($value['optional'])) {
-                    //console("\$attribs['" . $key . "'] is empty, and the field is not optional");
+                    Log::error("\$attribs['" . $key . "'] is empty, and the field is not optional");
                     throw new Exception("Missing input value for $key", 345);
                 }
                 else {
-                    //console("Either \$attribs['" . $key . "'] is empty or the field is optional");
+                    Log::trace("Either \$attribs['" . $key . "'] is empty or the field is optional");
                     $result[$key] = $attribs[$key];
                 }
             }
@@ -281,15 +283,23 @@ abstract class kolab_api_service
 
         if (isset($type_attrs['fields'])) {
             foreach ($type_attrs['fields'] as $key => $value) {
+                if (!is_array($value)) {
+                    $value2 = $this->conf->expand($value);
+                    if ($value !== $value2) {
+                        Log::trace("Made value " . var_export($value, TRUE) . " in to: " . var_export($value2, TRUE));
+                        $value = $value2;
+                    }
+                }
+
                 if (empty($attribs[$key])) {
-                    $result[$key] = $type_attrs['fields'][$key];
+                    $result[$key] = $type_attrs['fields'][$key] = $value;
                 } else {
-                    $result[$key] = $attribs[$key];
+                    $result[$key] = $attribs[$key] = $value;
                 }
             }
         }
 
-        //console("parse_input_attributes result", $result);
+        Log::trace("parse_input_attributes result", $result);
 
         return $result;
     }


commit 100522862f21bcf6a67eaf057cb8a6945522af4e
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Mon Sep 3 12:24:12 2012 +0100

    Teach functions get_entry_attribute() and get_entry_attributes() to treat a Net_LDAP3_Result like it deserves

diff --git a/lib/ext/Net/LDAP3.php b/lib/ext/Net/LDAP3.php
index 2ea7833..f917dec 100644
--- a/lib/ext/Net/LDAP3.php
+++ b/lib/ext/Net/LDAP3.php
@@ -675,27 +675,22 @@ class Net_LDAP3
 
     public function get_entry_attribute($subject_dn, $attribute)
     {
-        $this->config_set('return_attributes', $attributes);
-        $result = $this->search($subject_dn, '(objectclass=*)', 'base');
-        $dn     = key($result);
-        $attr   = key($result[$dn]);
+        $this->config_set('return_attributes', $attribute);
+        $entries = $this->search($subject_dn, '(objectclass=*)', 'base')->entries(TRUE);
+        $entry_dn = key($entries);
+        $entry = $entries[$entry_dn];
 
-        return $result[$dn][$attr];
+        return $entry[$attribute];
     }
 
     public function get_entry_attributes($subject_dn, $attributes)
     {
         $this->config_set('return_attributes', $attributes);
-        $entries = $this->search($subject_dn, '(objectclass=*)', 'base');
-        $entry = $entries->entries(TRUE);
-        $result = $entry[0];
-
-        if (!empty($result)) {
-            $result = array_pop($result);
-            return $result;
-        }
+        $entries = $this->search($subject_dn, '(objectclass=*)', 'base')->entries(TRUE);
+        $entry_dn = key($entries);
+        $entry = $entries[$entry_dn];
 
-        return FALSE;
+        return $entry;
     }
 
     /*
@@ -1899,11 +1894,16 @@ class Net_LDAP3
 
     private function supported_controls()
     {
+        if (!empty($this->supported_controls)) {
+            return $this->supported_controls;
+        }
+
         $this->_info("Obtaining supported controls");
         $this->return_attributes = Array("supportedcontrol");
         $result = $this->search("", "(objectclass=*)", 'base');
         $result = $result->entries(TRUE);
         $this->_info("Obtained " . count($result['']['supportedcontrol']) . " supported controls");
+        $this->supported_controls = $result['']['supportedcontrol'];
         return $result['']['supportedcontrol'];
     }
 


commit c7c715d78cdb4e9467bfb67ac100b47d9b5a3cd0
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Mon Sep 3 12:23:32 2012 +0100

    Actually do not set the watermark

diff --git a/lib/client/kolab_client_task_domain.php b/lib/client/kolab_client_task_domain.php
index 14c5034..97d5624 100644
--- a/lib/client/kolab_client_task_domain.php
+++ b/lib/client/kolab_client_task_domain.php
@@ -170,8 +170,6 @@ class kolab_client_task_domain extends kolab_client_task
         $this->output->set_env('search_request', $search_request ? base64_encode(serialize($search_request)) : null);
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
-
-        $this->watermark('taskcontent');
         $this->output->set_object('domainlist', $table);
     }
 
diff --git a/lib/client/kolab_client_task_group.php b/lib/client/kolab_client_task_group.php
index ef7b76c..a4b7c24 100644
--- a/lib/client/kolab_client_task_group.php
+++ b/lib/client/kolab_client_task_group.php
@@ -162,8 +162,6 @@ class kolab_client_task_group extends kolab_client_task
         $this->output->set_env('search_request', $search_request ? base64_encode(serialize($search_request)) : null);
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
-
-        $this->watermark('taskcontent');
         $this->output->set_object('grouplist', $table);
     }
 
diff --git a/lib/client/kolab_client_task_resource.php b/lib/client/kolab_client_task_resource.php
index 1535fe8..2d8f099 100644
--- a/lib/client/kolab_client_task_resource.php
+++ b/lib/client/kolab_client_task_resource.php
@@ -164,8 +164,6 @@ class kolab_client_task_resource extends kolab_client_task
         $this->output->set_env('search_request', $search_request ? base64_encode(serialize($search_request)) : null);
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
-
-        $this->watermark('taskcontent');
         $this->output->set_object('resourcelist', $table);
     }
 
diff --git a/lib/client/kolab_client_task_role.php b/lib/client/kolab_client_task_role.php
index c13b845..e460a95 100644
--- a/lib/client/kolab_client_task_role.php
+++ b/lib/client/kolab_client_task_role.php
@@ -163,8 +163,6 @@ class kolab_client_task_role extends kolab_client_task
         $this->output->set_env('search_request', $search_request ? base64_encode(serialize($search_request)) : null);
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
-
-        $this->watermark('taskcontent');
         $this->output->set_object('rolelist', $table);
     }
 
diff --git a/lib/client/kolab_client_task_user.php b/lib/client/kolab_client_task_user.php
index 8102e8c..09bbca3 100644
--- a/lib/client/kolab_client_task_user.php
+++ b/lib/client/kolab_client_task_user.php
@@ -162,8 +162,6 @@ class kolab_client_task_user extends kolab_client_task
         $this->output->set_env('search_request', $search_request ? base64_encode(serialize($search_request)) : null);
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
-
-        $this->watermark('taskcontent');
         $this->output->set_object('userlist', $table);
     }
 


commit a61cd894caba26fb96a53c79243d1888fecf7cd0
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Mon Sep 3 12:23:15 2012 +0100

    Whitespace

diff --git a/lib/Log.php b/lib/Log.php
index 88d62c2..2705912 100644
--- a/lib/Log.php
+++ b/lib/Log.php
@@ -45,7 +45,7 @@ class Log
     static function trace($message, $args = array())
     {
         if (self::mode() >= self::TRACE) {
-            self::log_message(self::TRACE, $message, $args);    
+            self::log_message(self::TRACE, $message, $args);
         }
     }
 
@@ -58,7 +58,7 @@ class Log
     static function debug($message, $args = array())
     {
         if (self::mode() >= self::DEBUG) {
-            self::log_message(self::DEBUG, $message, $args);    
+            self::log_message(self::DEBUG, $message, $args);
         }
     }
 
@@ -87,7 +87,7 @@ class Log
             self::log_message(self::WARNING, $message, $args);
         }
     }
-    
+
     /**
      * Logs error message
      *
@@ -227,7 +227,7 @@ class Log
         case 'WARNING':
             self::$mode = self::WARNING;
             break;
-        
+
         case self::ERROR:
         default:
             self::$mode = self::ERROR;


commit a0731f496c3570c23bec53d5c514c20c23b0aee9
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Mon Sep 3 12:20:50 2012 +0100

    Set the root_dn for our LDAP instance to the correct value.
    Use a shortcut function _subject_base_dn() to determine what the base_dn is for different object types.
    Add a function to use LDAP to get from a domain name space to a domain root dn.

diff --git a/lib/Auth/LDAP.php b/lib/Auth/LDAP.php
index bd9b7ce..b351593 100644
--- a/lib/Auth/LDAP.php
+++ b/lib/Auth/LDAP.php
@@ -51,8 +51,6 @@ class LDAP extends Net_LDAP3 {
         $this->config_set("service_bind_dn", $this->conf->get("service_bind_dn"));
         $this->config_set("service_bind_pw", $this->conf->get("service_bind_pw"));
 
-        $this->config_set("root_dn", $this->conf->get("base_dn"));
-
         // See if we are to connect to any domain explicitly defined.
         if (empty($domain)) {
             // If not, attempt to get the domain from the session.
@@ -89,6 +87,15 @@ class LDAP extends Net_LDAP3 {
         $this->config_set("port", $this->_ldap_port);
 
         parent::connect();
+
+        // Attempt to get the root dn from the configuration file.
+        $root_dn = $this->conf->get($this->domain, "base_dn");
+        if (empty($root_dn)) {
+            // Fall back to a root dn from LDAP, or the standard root dn
+            $root_dn = $this->domain_root_dn($this->domain);
+        }
+
+        $this->config_set("root_dn", $root_dn);
     }
 
     /**********************************************************
@@ -206,32 +213,29 @@ class LDAP extends Net_LDAP3 {
      * configuration.
      */
     public function effective_rights($subject) {
+        // Ensure we are bound with the user's credentials
         $this->bind($_SESSION['user']->user_bind_dn, $_SESSION['user']->user_bind_pw);
 
+        Log::trace("Auth::LDAP::effective_rights(\$subject = '" . $subject . "')");
+
         switch ($subject) {
             case "domain":
-                $result = parent::effective_rights($this->conf->get("ldap", "domain_base_dn"));
-                return $result;
+                return parent::effective_rights($this->conf->get("ldap", "domain_base_dn"));
                 break;
             case "group":
-                $result = parent::effective_rights($this->conf->get("ldap", "group_base_dn"));
-                return $result;
+                return parent::effective_rights($this->_subject_base_dn("group"));
                 break;
             case "resource":
-                $result = parent::effective_rights($this->conf->get("ldap", "resource_base_dn"));
-                return $result;
+                return parent::effective_rights($this->_subject_base_dn("resource"));
                 break;
             case "role":
-                $result = parent::effective_rights($this->conf->get("ldap", "base_dn"));
-                return $result;
+                return parent::effective_rights($this->_subject_base_dn("role"));
                 break;
             case "user":
-                $result = parent::effective_rights($this->conf->get("ldap", "user_base_dn"));
-                return $result;
+                return parent::effective_rights($this->_subject_base_dn("user"));
                 break;
             default:
-                $result = parent::effective_rights($subject);
-                return $result;
+                return parent::effective_rights($subject);
                 break;
         }
 
@@ -412,11 +416,7 @@ class LDAP extends Net_LDAP3 {
 
         $this->config_set('return_attributes', $attributes);
 
-        $base_dn = $this->conf->get('group_base_dn');
-        if (empty($base_dn)) {
-            $base_dn = $this->conf->get('base_dn');
-        }
-
+        $base_dn = $this->_subject_base_dn("group");
         $filter = $this->conf->get('group_filter');
 
         $result = $this->search_entries($base_dn, $filter, 'sub', NULL, $search);
@@ -464,11 +464,7 @@ class LDAP extends Net_LDAP3 {
 
         $this->config_set("return_attributes", $attributes);
 
-        $base_dn = $this->conf->get('resource_base_dn');
-        if (!$base_dn) {
-            $base_dn = "ou=Resources," . $this->conf->get('base_dn');
-        }
-
+        $base_dn = $this->_subject_base_dn("resource");
         $filter  = $this->conf->get('resource_filter');
 
         if (!$filter) {
@@ -501,7 +497,8 @@ class LDAP extends Net_LDAP3 {
             }
         }
 
-        $base_dn = $this->conf->get('base_dn');
+        $base_dn = $this->_subject_base_dn("role");
+
         // TODO: From config
         $filter  = "(&(objectclass=ldapsubentry)(objectclass=nsroledefinition))";
 
@@ -566,11 +563,7 @@ class LDAP extends Net_LDAP3 {
 
         $this->config_set("return_attributes", $attributes);
 
-        $base_dn = $this->conf->get('user_base_dn');
-        if (empty($base_dn)) {
-            $base_dn = $this->conf->get('base_dn');
-        }
-
+        $base_dn = $this->_subject_base_dn("user");
         $filter = $this->conf->get('user_filter');
 
         Log::trace("Auth::LDAP::list_users() searching entries in $base_dn with $filter, 'sub', NULL, " . var_export($search, TRUE));
@@ -675,11 +668,9 @@ class LDAP extends Net_LDAP3 {
             $type_str = $_key['key'];
         }
 
-        // Check if the user_type has a specific base DN specified.
-        $base_dn = $this->conf->get($this->domain, $type_str . "base_dn");
-        if (empty($base_dn)) {
-            $base_dn = $this->conf->get('ldap', "base_dn");
-        }
+        $this->bind($_SESSION['user']->user_bind_dn, $_SESSION['user']->user_bind_pw);
+
+        $base_dn = $this->subject_base_dn('role');
 
         // TODO: The rdn is configurable as well.
         // Use [$type_str . "_"]user_rdn_attr
@@ -693,13 +684,12 @@ class LDAP extends Net_LDAP3 {
         $unique_attr = $this->unique_attribute();
         $attributes[$unique_attr] = $role;
 
-        console("\$this->domain: " . $this->domain);
         // Now that values have been re-generated where necessary, compare
         // the new role attributes to the original role attributes.
         $_role = $this->entry_find_by_attribute(array($unique_attr => $attributes[$unique_attr], 'objectclass' => 'ldapsubentry'));
 
         if (!$_role) {
-            console("Could not find role");
+            Log::error("Could not find role identified with $role.");
             return false;
         }
 
@@ -711,7 +701,7 @@ class LDAP extends Net_LDAP3 {
     }
 
     public function role_find_by_attribute($attribute) {
-        console("Finding role by attribute", $attribute);
+        Log::trace("Finding role by attribute: " . var_export($attribute, TRUE));
 
         $attribute['objectclass'] = 'ldapsubentry';
         $result = $this->entry_find_by_attribute($attribute);
@@ -745,7 +735,7 @@ class LDAP extends Net_LDAP3 {
             $this->bind($_SESSION['user']->user_bind_dn, $_SESSION['user']->user_bind_pw);
         }
 
-        Log::trace("Relaying search to parent:" . var_export($base_dn, TRUE));
+        Log::trace("Relaying search to parent:" . var_export(func_get_args(), TRUE));
         return parent::search($base_dn, $filter, $scope, $sort, $search);
     }
 
@@ -902,24 +892,29 @@ class LDAP extends Net_LDAP3 {
         }
     }
 
-    private function groups_list($attributes = array(), $search = array()) {
-        $base_dn = $this->conf->get('group_base_dn');
+    private function _subject_base_dn($subject) {
+        // Attempt to get a configured base_dn
+        $base_dn = $this->conf->get($this->domain, "base_dn");
 
-        if (!$base_dn)
-            $base_dn = $this->conf->get('base_dn');
+        if (empty($base_dn)) {
+            $base_dn = $this->domain_root_dn($this->domain);
+        }
 
-        $filter  = $this->conf->get('group_filter');
+        Log::trace(__FILE__ . "::" . __FUNCTION__ . " using base_dn $base_dn");
 
-        if (empty($attributes) || !is_array($attributes)) {
-            $attributes = array('*');
+        if (empty($subject)) {
+            return $base_dn;
+        } else {
+            $subject_base_dn = $this->conf->get_raw($this->domain, $subject . "_base_dn");
+            if (empty($subject_base_dn)) {
+                $subject_base_dn = $this->conf->get_raw("ldap", $subject . "_base_dn");
+            }
+            $base_dn = $this->conf->expand($subject_base_dn, array("base_dn" => $base_dn));
         }
 
-        if ($s_filter = $this->search_filter($search)) {
-            // join search filter with objectClass filter
-            $filter = '(&' . $filter . $s_filter . ')';
-        }
+        Log::trace("subject_base_dn for subject $subject results in $base_dn");
 
-        return $this->_search($base_dn, $filter, $attributes);
+        return $base_dn;
     }
 
     private function legacy_rights($subject) {
@@ -1295,6 +1290,70 @@ class LDAP extends Net_LDAP3 {
     }
 
     /**
+     * Translate a domain name into it's corresponding root dn.
+     */
+    private function domain_root_dn($domain)
+    {
+        if (!empty($this->domain_root_dn)) {
+            return $this->domain_root_dn;
+        }
+
+        if (!$this->connect()) {
+            Log::trace("Could not connect");
+            return false;
+        }
+
+        $bind_dn = $this->config_get("service_bind_dn", $this->conf->get("service_bind_dn"));
+        $bind_pw = $this->config_get("service_bind_pw", $this->conf->get("service_bind_pw"));
+
+        if (!$this->bind($bind_dn, $bind_pw)) {
+            Log::trace("Could not connect");
+            return false;
+        }
+
+        Log::trace("Auth::LDAP::domain_root_dn(\$domain = $domain) called");
+        if (empty($domain)) {
+            return false;
+        }
+
+        $domain_base_dn        = $this->conf->get('ldap', 'domain_base_dn');
+        $domain_filter         = $this->conf->get('ldap', 'domain_filter');
+        $domain_name_attribute = $this->conf->get('ldap', 'domain_name_attribute');
+
+        if (empty($domain_name_attribute)) {
+            $domain_name_attribute = 'associateddomain';
+        }
+
+        $domain_filter         = "(&" . $domain_filter . "(" . $domain_name_attribute . "=" . $domain . "))";
+
+        $result = $this->_search($domain_base_dn, $domain_filter);
+
+        $entries = $result->entries(TRUE);
+        $entry_dn = key($entries);
+        $entry_attrs = $entries[$entry_dn];
+
+        if (is_array($entry_attrs)) {
+            if (in_array('inetdomainbasedn', $entry_attrs) && !empty($entry_attrs['inetdomainbasedn'])) {
+                $this->domain_root_dn = $entry_attrs['inetdomainbasedn'];
+            }
+            else {
+                if (is_array($entry_attrs[$domain_name_attribute])) {
+                    $this->domain_root_dn = $this->_standard_root_dn($entry_attrs[$domain_name_attribute][0]);
+                }
+                else {
+                    $this->domain_root_dn = $this->_standard_root_dn($entry_attrs[$domain_name_attribute]);
+                }
+            }
+        }
+        else {
+            $this->domain_root_dn = $this->_standard_root_dn($domain);
+        }
+
+        return $this->domain_root_dn;
+
+    }
+
+    /**
      * Probe the root dn with the user credentials.
      *
      * When a list of domains is retrieved, this does not mean the user


commit 6d515f55b9dc0da0ba3d81fa98996603df41e748
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Mon Sep 3 12:18:52 2012 +0100

    Make non-required attributes that do not validate not block submission - drop the attribute value instead
    Use correct Auth() function calls (get_attribute() -> get_entry_attribute())
    Increase helpful trace statements.
    List rights on correct subject if no existing object is being edited.

diff --git a/lib/api/kolab_api_service_form_value.php b/lib/api/kolab_api_service_form_value.php
index 49e8994..d5eaf87 100644
--- a/lib/api/kolab_api_service_form_value.php
+++ b/lib/api/kolab_api_service_form_value.php
@@ -62,6 +62,7 @@ class kolab_api_service_form_value extends kolab_api_service
         $attribs    = $this->object_type_attributes($postdata['object_type'], $postdata['type_id']);
 
         $attributes = (array) $postdata['attributes'];
+
         $result     = array();
 
         foreach ($attributes as $attr_name) {
@@ -72,18 +73,22 @@ class kolab_api_service_form_value extends kolab_api_service
             $method_name = 'generate_' . strtolower($attr_name) . '_' . strtolower($postdata['object_type']);
 
             if (!method_exists($this, $method_name)) {
-                //console("Method $method_name doesn't exist");
+                Log::trace("Method $method_name doesn't exist");
 
                 $method_name = 'generate_' . strtolower($attr_name);
 
                 if (!method_exists($this, $method_name)) {
+                    Log::trace("Method $method_name doesn't exist either");
                     continue;
                 }
             }
 
+            Log::trace("Executing method $method_name");
             $result[$attr_name] = $this->{$method_name}($postdata, $attribs);
         }
 
+        Log::trace("Returning result: " . var_export($result, TRUE));
+
         return $result;
     }
 
@@ -206,7 +211,15 @@ class kolab_api_service_form_value extends kolab_api_service
                 }
             }
 
-            $result[$attr_name] = $this->{$method_name}($attr_value);
+            if (array_key_exists($attr_name, $attribs['form_fields']) && !empty($attribs['form_fields'][$attr_name]['optional']) && !$attribs['form_fields'][$attr_name]['optional']) {
+                $result[$attr_name] = $this->{$method_name}($attr_value);
+            } else {
+                try {
+                    $result[$attr_name] = $this->{$method_name}($attr_value);
+                } catch (Exception $e) {
+                    Log::debug("Attribute $attr_name did not validate, but it is not a required attribute. Not saving. (Error was: $e)");
+                }
+            }
         }
 
         return $result;
@@ -258,7 +271,7 @@ class kolab_api_service_form_value extends kolab_api_service
             while (($resource_found = $auth->resource_find_by_attribute(array('cn' => $cn)))) {
                 if (!empty($postdata['id'])) {
                     $resource_found_dn = key($resource_found);
-                    $resource_found_unique_attr = $auth->get_attribute($resource_found_dn, $unique_attr);
+                    $resource_found_unique_attr = $auth->get_entry_attribute($resource_found_dn, $unique_attr);
                     //console("resource with mail $mail found", $resource_found_unique_attr);
                     if ($resource_found_unique_attr == $postdata['id']) {
                         //console("that's us.");
@@ -432,7 +445,7 @@ class kolab_api_service_form_value extends kolab_api_service
             while (($resource_found = $auth->resource_find_by_attribute(array('mail' => $mail)))) {
                 if (!empty($postdata['id'])) {
                     $resource_found_dn = key($resource_found);
-                    $resource_found_unique_attr = $auth->get_attribute($resource_found_dn, $unique_attr);
+                    $resource_found_unique_attr = $auth->get_entry_attribute($resource_found_dn, $unique_attr);
                     //console("resource with mail $mail found", $resource_found_unique_attr);
                     if ($resource_found_unique_attr == $postdata['id']) {
                         //console("that's us.");
@@ -590,7 +603,7 @@ class kolab_api_service_form_value extends kolab_api_service
             while (($user_found = $auth->user_find_by_attribute(array('uid' => $uid)))) {
                 if (!empty($postdata['id'])) {
                     $user_found_dn = key($user_found);
-                    $user_found_unique_attr = $auth->get_attribute($user_found_dn, $unique_attr);
+                    $user_found_unique_attr = $auth->get_entry_attribute($user_found_dn, $unique_attr);
                     //console("user with uid $uid found", $user_found_unique_attr);
                     if ($user_found_unique_attr == $postdata['id']) {
                         //console("that's us.");
@@ -737,7 +750,6 @@ class kolab_api_service_form_value extends kolab_api_service
 
     private function list_options_uniquemember($postdata, $attribs = array())
     {
-        Log::trace("form_value.list_options for uniquemember attribute", $postdata, $attribs);
         $result = $this->_list_options_members($postdata, $attribs);
         return $result;
     }
@@ -768,18 +780,13 @@ class kolab_api_service_form_value extends kolab_api_service
         }
 
         if (!empty($postdata['id'])) {
-            Log::trace("form_value.select_options_ou is going to search in base dn: " . var_export($base_dn, TRUE));
             $subjects = $auth->search($base_dn, '(' . $unique_attr . '=' . $postdata['id'] . ')')->entries(TRUE);
-            Log::trace("form_value.select_options_ou subjects: " . var_export($subjects, TRUE));
-            $subject = key($subjects);
-            Log::trace("form_value.select_options_ou subject: " . var_export($subject, TRUE));
-            $subject_dn_components = ldap_explode_dn($subject, 0);
-            Log::trace("form_value.select_options_ou subject dn components: " . var_export($subject_dn_components, TRUE));
+            $subject = array_shift($subjects);
+            $subject_dn = key($subject);
+            $subject_dn_components = ldap_explode_dn($subject_dn, 0);
             unset($subject_dn_components['count']);
             array_shift($subject_dn_components);
-            Log::trace("form_value.select_options_ou subject dn components: " . var_export($subject_dn_components, TRUE));
             $default = strtolower(implode(',', $subject_dn_components));
-            Log::trace("form_value.select_options_ou is using default $default");
         } else {
             $default = $base_dn;
         }
@@ -924,7 +931,6 @@ class kolab_api_service_form_value extends kolab_api_service
     {
         // return specified records only, by exact DN attributes
         if (!empty($postdata['list'])) {
-            Log::trace("\$postdata['list'] not empty");
             $data['search'] = array(
                     'params' => array(
                             'entrydn' => array(
@@ -1140,6 +1146,12 @@ class kolab_api_service_form_value extends kolab_api_service
             $valid = true;
         }
 
+        if ($valid) {
+            Log::trace("Found email address to be in one of my domains.");
+        } else {
+            Log::trace("Found email address to NOT be in one of my domains.");
+        }
+
         return $valid;
     }
 
diff --git a/lib/api/kolab_api_service_group.php b/lib/api/kolab_api_service_group.php
index fb458b1..c41dd3c 100644
--- a/lib/api/kolab_api_service_group.php
+++ b/lib/api/kolab_api_service_group.php
@@ -135,7 +135,7 @@ class kolab_api_service_group extends kolab_api_service
     public function group_effective_rights($getdata, $postdata)
     {
         $auth = Auth::get_instance();
-        $effective_rights = $auth->list_rights($getdata['group']);
+        $effective_rights = $auth->list_rights(empty($getdata['group']) ? 'group' : $getdata['group']);
         return $effective_rights;
     }
 
diff --git a/lib/api/kolab_api_service_resource.php b/lib/api/kolab_api_service_resource.php
index 9cd3304..48b3a88 100644
--- a/lib/api/kolab_api_service_resource.php
+++ b/lib/api/kolab_api_service_resource.php
@@ -150,7 +150,7 @@ class kolab_api_service_resource extends kolab_api_service
     public function resource_effective_rights($getdata, $postdata)
     {
         $auth = Auth::get_instance();
-        $effective_rights = $auth->list_rights($getdata['resource']);
+        $effective_rights = $auth->list_rights(empty($getdata['resource']) ? 'resource' : $getdata['resource']);
         return $effective_rights;
     }
 
diff --git a/lib/api/kolab_api_service_resources.php b/lib/api/kolab_api_service_resources.php
index f35e22c..f7b00dc 100644
--- a/lib/api/kolab_api_service_resources.php
+++ b/lib/api/kolab_api_service_resources.php
@@ -52,7 +52,7 @@ class kolab_api_service_resources extends kolab_api_service
     }
 
     /**
-     * Users listing (with searching).
+     * Resources listing (with searching).
      *
      * @param array $get   GET parameters
      * @param array $post  POST parameters
diff --git a/lib/api/kolab_api_service_role.php b/lib/api/kolab_api_service_role.php
index 1e6ac3c..1158f03 100644
--- a/lib/api/kolab_api_service_role.php
+++ b/lib/api/kolab_api_service_role.php
@@ -137,14 +137,17 @@ class kolab_api_service_role extends kolab_api_service
         $auth = Auth::get_instance();
         $conf = Conf::get_instance();
 
-        $unique_attr = $conf->get('unique_attribute');
-        if (empty($unique_attr)) {
-            $unique_attr = 'nsuniqueid';
+        // Roles are special in that they are ldapsubentries.
+        if (!empty($getdata['role'])) {
+            $unique_attr = $conf->get('unique_attribute');
+            if (empty($unique_attr)) {
+                $unique_attr = 'nsuniqueid';
+            }
+
+            $role_dn = $auth->role_find_by_attribute(Array($unique_attr => $getdata['role']));
         }
 
-        $role_dn = $auth->role_find_by_attribute(Array($unique_attr => $getdata['role']));
-
-        $effective_rights = $auth->list_rights($role_dn);
+        $effective_rights = $auth->list_rights(empty($role_dn) ? 'role' : $role_dn);
 
         return $effective_rights;
     }
diff --git a/lib/api/kolab_api_service_user.php b/lib/api/kolab_api_service_user.php
index c0fbee5..37c83af 100644
--- a/lib/api/kolab_api_service_user.php
+++ b/lib/api/kolab_api_service_user.php
@@ -149,7 +149,7 @@ class kolab_api_service_user extends kolab_api_service
     public function user_effective_rights($getdata, $postdata)
     {
         $auth = Auth::get_instance();
-        $effective_rights = $auth->list_rights($getdata['user']);
+        $effective_rights = $auth->list_rights(empty($getdata['user']) ? 'user' : $getdata['user']);
         return $effective_rights;
     }
 


commit 4c3e0eda4e2d108335353a49332a0ba9b9573cab
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sun Sep 2 19:06:42 2012 +0100

    Limit Auth to using the configured primary_domain or the domain to log in to only

diff --git a/lib/Auth.php b/lib/Auth.php
index 91c7bba..20da7b6 100644
--- a/lib/Auth.php
+++ b/lib/Auth.php
@@ -38,22 +38,19 @@ class Auth {
      */
     static function get_instance($domain = NULL)
     {
+        Log::trace("Auth::get_instance(\$domain = " . var_export($domain, TRUE) . ")");
+
         $conf = Conf::get_instance();
 
         if (empty($domain)) {
             if (!empty($_SESSION['user'])) {
                 $domain = $_SESSION['user']->get_domain();
-                Log::trace(__CLASS__ . "::" . __FUNCTION__ . ": using domain $domain from session");
             } else {
                 $domain = $conf->get('primary_domain');
-                Log::trace(__CLASS__ . "::" . __FUNCTION__ . ": using default domain $domain");
             }
-        } else {
-            Log::trace(__CLASS__ . "::" . __FUNCTION__ . ": using domain $domain");
         }
 
         if (!isset(self::$instance[$domain])) {
-            Log::trace(__CLASS__ . "::" . __FUNCTION__ . ": Creating new instance for $domain");
             self::$instance[$domain] = new Auth($domain);
         }
 
@@ -111,48 +108,11 @@ class Auth {
      */
     public function authenticate($username, $password)
     {
-        Log::info("Authentication request for $username");
-
-        if (strpos($username, '@')) {
-            // Case-sensitivity does not matter for strstr() on '@', which
-            // has no case.
-            $user_domain = substr(strstr($username, '@'), 1);
-            Log::trace("Auth::authenticate(): User domain: " . $user_domain);
-
-            if (isset($this->_auth[$user_domain])) {
-                // We know this domain
-                $domain = $user_domain;
-            }
-            else {
-                // Attempt to find the primary domain name space for the
-                // domain used in the authentication request.
-                //
-                // This will enable john at example.org to login using 'alias'
-                // domains as well, such as 'john at example.ch'.
-                Log::trace("Attempting to find the primary domain name space for the user domain $user_domain");
-                $associated_domain = $this->primary_for_valid_domain($user_domain);
-
-                if ($associated_domain) {
-                    $domain = $user_domain;
-                }
-                else {
-                    // It seems we do not know about this domain.
-                    $domain = FALSE;
-                }
-            }
-        }
-        else {
-            $domain = $this->conf->get('primary_domain');
-        }
+        Log::info("Authentication request for $username against " . $this->domain);
 
         // TODO: Debug logging for the use of a current or the creation of
         // a new authentication class instance.
-        if ($this->domain == $domain) {
-            $result = $this->_auth[$domain]->authenticate($username, $password);
-        }
-        else {
-            $result = Auth::get_instance($domain)->authenticate($username, $password);
-        }
+        $result = $this->_auth[$this->domain]->authenticate($username, $password);
 
         return $result;
     }
@@ -317,7 +277,7 @@ class Auth {
 
     public function list_rights($subject)
     {
-        return $this->auth_instance($this->domain)->effective_rights($subject);
+        return $this->auth_instance()->effective_rights($subject);
     }
 
     public function list_users($domain = NULL, $attributes = array(), $search = array(), $params = array())


commit f66659f20d214022ed40faaf9689fdd005b28bf4
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sun Sep 2 00:43:48 2012 +0100

    Resolve #984:
    
     - Fix post add/edit/delete UI update by setting back the watermark after the action has been executed.
     - List the contents of the directory information tree before considering adding a form for users logged in that can add entries

diff --git a/lib/client/kolab_client_task_domain.php b/lib/client/kolab_client_task_domain.php
index 60d84ef..14c5034 100644
--- a/lib/client/kolab_client_task_domain.php
+++ b/lib/client/kolab_client_task_domain.php
@@ -38,15 +38,13 @@ class kolab_client_task_domain extends kolab_client_task
         $this->output->set_object('content', 'domain', true);
         $this->output->set_object('task_navigation', $this->menu());
 
+        $this->action_list();
+
         // display form to add domain if logged-in user has right to do so
         $caps = $this->get_capability('actions');
         if($caps['domain.add']['type'] == 'w') {
             $this->action_add();
-        } else {
-            $this->watermark('taskcontent');
         }
-
-        $this->action_list();
     }
 
     /**
@@ -173,6 +171,7 @@ class kolab_client_task_domain extends kolab_client_task
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
 
+        $this->watermark('taskcontent');
         $this->output->set_object('domainlist', $table);
     }
 
diff --git a/lib/client/kolab_client_task_group.php b/lib/client/kolab_client_task_group.php
index b31ac86..ef7b76c 100644
--- a/lib/client/kolab_client_task_group.php
+++ b/lib/client/kolab_client_task_group.php
@@ -38,15 +38,13 @@ class kolab_client_task_group extends kolab_client_task
         $this->output->set_object('content', 'group', true);
         $this->output->set_object('task_navigation', $this->menu());
 
+        $this->action_list();
+
         // display form to add group if logged-in user has right to do so
         $caps = $this->get_capability('actions');
         if($caps['group.add']['type'] == 'w') {
             $this->action_add();
-        } else {
-            $this->watermark('taskcontent');
         }
-
-        $this->action_list();
     }
 
     /**
@@ -165,6 +163,7 @@ class kolab_client_task_group extends kolab_client_task
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
 
+        $this->watermark('taskcontent');
         $this->output->set_object('grouplist', $table);
     }
 
diff --git a/lib/client/kolab_client_task_resource.php b/lib/client/kolab_client_task_resource.php
index 42d6554..1535fe8 100644
--- a/lib/client/kolab_client_task_resource.php
+++ b/lib/client/kolab_client_task_resource.php
@@ -38,15 +38,13 @@ class kolab_client_task_resource extends kolab_client_task
         $this->output->set_object('content', 'resource', true);
         $this->output->set_object('task_navigation', $this->menu());
 
+        $this->action_list();
+
         // display form to add resource if logged-in user has right to do so
         $caps = $this->get_capability('actions');
         if($caps['resource.add']['type'] == 'w') {
             $this->action_add();
-        } else {
-            $this->watermark('taskcontent');
         }
-
-        $this->action_list();
     }
 
     /**
@@ -167,6 +165,7 @@ class kolab_client_task_resource extends kolab_client_task
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
 
+        $this->watermark('taskcontent');
         $this->output->set_object('resourcelist', $table);
     }
 
diff --git a/lib/client/kolab_client_task_role.php b/lib/client/kolab_client_task_role.php
index eadaa59..c13b845 100644
--- a/lib/client/kolab_client_task_role.php
+++ b/lib/client/kolab_client_task_role.php
@@ -38,15 +38,14 @@ class kolab_client_task_role extends kolab_client_task
         $this->output->set_object('content', 'role', true);
         $this->output->set_object('task_navigation', $this->menu());
 
+        $this->action_list();
+
         // display form to add role if logged-in user has right to do so
         $caps = $this->get_capability('actions');
         if($caps['role.add']['type'] == 'w') {
             $this->action_add();
-        } else {
-            $this->watermark('taskcontent');
         }
 
-        $this->action_list();
     }
 
     /**
@@ -165,6 +164,7 @@ class kolab_client_task_role extends kolab_client_task
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
 
+        $this->watermark('taskcontent');
         $this->output->set_object('rolelist', $table);
     }
 
diff --git a/lib/client/kolab_client_task_user.php b/lib/client/kolab_client_task_user.php
index 5a198e0..8102e8c 100644
--- a/lib/client/kolab_client_task_user.php
+++ b/lib/client/kolab_client_task_user.php
@@ -38,15 +38,13 @@ class kolab_client_task_user extends kolab_client_task
         $this->output->set_object('content', 'user', true);
         $this->output->set_object('task_navigation', $this->menu());
 
+        $this->action_list();
+
         // display form to add user if logged-in user has right to do so
         $caps = $this->get_capability('actions');
         if($caps['user.add']['type'] == 'w') {
             $this->action_add();
-        } else {
-            $this->watermark('taskcontent');
         }
-
-        $this->action_list();
     }
 
     /**
@@ -165,6 +163,7 @@ class kolab_client_task_user extends kolab_client_task
         $this->output->set_env('list_page', $page);
         $this->output->set_env('list_count', $count);
 
+        $this->watermark('taskcontent');
         $this->output->set_object('userlist', $table);
     }
 
diff --git a/lib/kolab_client_task.php b/lib/kolab_client_task.php
index ba799e3..250332a 100644
--- a/lib/kolab_client_task.php
+++ b/lib/kolab_client_task.php
@@ -48,7 +48,6 @@ class kolab_client_task
 
     protected static $translation = array();
 
-
     /**
      * Class constructor.
      */
diff --git a/public_html/js/kolab_admin.js b/public_html/js/kolab_admin.js
index bb6ddc3..be08f8a 100644
--- a/public_html/js/kolab_admin.js
+++ b/public_html/js/kolab_admin.js
@@ -1089,6 +1089,7 @@ function kolab_admin()
 
     this.display_message('domain.add.success');
     this.command('domain.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.domain_edit_response = function(response)
@@ -1098,6 +1099,7 @@ function kolab_admin()
 
     this.display_message('domain.edit.success');
     this.command('domain.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.user_info = function(id)
@@ -1135,6 +1137,7 @@ function kolab_admin()
 
     this.display_message('user.delete.success');
     this.command('user.list', {page: page});
+    this.set_watermark('taskcontent');
   };
 
   this.user_save = function(reload, section)
@@ -1174,6 +1177,7 @@ function kolab_admin()
 
     this.display_message('user.add.success');
     this.command('user.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.user_edit_response = function(response)
@@ -1183,6 +1187,7 @@ function kolab_admin()
 
     this.display_message('user.edit.success');
     this.command('user.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.group_info = function(id)
@@ -1220,6 +1225,7 @@ function kolab_admin()
 
     this.display_message('group.delete.success');
     this.command('group.list', {page: page});
+    this.set_watermark('taskcontent');
   };
 
   this.group_save = function(reload, section)
@@ -1251,6 +1257,7 @@ function kolab_admin()
 
     this.display_message('group.add.success');
     this.command('group.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.group_edit_response = function(response)
@@ -1260,6 +1267,7 @@ function kolab_admin()
 
     this.display_message('group.edit.success');
     this.command('group.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.resource_info = function(id)
@@ -1297,6 +1305,7 @@ function kolab_admin()
 
     this.display_message('resource.delete.success');
     this.command('resource.list', {page: page});
+    this.set_watermark('taskcontent');
   };
 
   this.resource_save = function(reload, section)
@@ -1328,6 +1337,7 @@ function kolab_admin()
 
     this.display_message('resource.add.success');
     this.command('resource.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.resource_edit_response = function(response)
@@ -1337,6 +1347,7 @@ function kolab_admin()
 
     this.display_message('resource.edit.success');
     this.command('resource.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.role_info = function(id)
@@ -1374,6 +1385,7 @@ function kolab_admin()
 
     this.display_message('role.delete.success');
     this.command('role.list', {page: page});
+    this.set_watermark('taskcontent');
   };
 
   this.role_save = function(reload, section)
@@ -1405,6 +1417,7 @@ function kolab_admin()
 
     this.display_message('role.add.success');
     this.command('role.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.role_edit_response = function(response)
@@ -1414,6 +1427,7 @@ function kolab_admin()
 
     this.display_message('role.edit.success');
     this.command('role.list', {page: this.env.list_page});
+    this.set_watermark('taskcontent');
   };
 
   this.generate_password = function(fieldname)


commit 7d5258a69c6c95016bc01b1d35d7cd7f6ea4ba3c
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Sat Sep 1 16:59:36 2012 +0100

    Read the resource dn rather than search for its attributes (#982)

diff --git a/lib/Auth/LDAP.php b/lib/Auth/LDAP.php
index 53b8a30..bd9b7ce 100644
--- a/lib/Auth/LDAP.php
+++ b/lib/Auth/LDAP.php
@@ -652,7 +652,7 @@ class LDAP extends Net_LDAP3 {
             return false;
         }
 
-        return $this->_search($resource_dn, '(objectclass=*)', $attributes);
+        return $this->_read($resource_dn, $attributes);
     }
 
     public function resource_members_list($resource, $recurse = true) {





More information about the commits mailing list