lib/api lib/kolab_api_service.php

Aleksander Machniak machniak at kolabsys.com
Fri Oct 25 13:06:12 CEST 2013


 lib/api/kolab_api_service_form_value.php |   86 ++++++++++++++++---------------
 lib/kolab_api_service.php                |   20 +++++++
 2 files changed, 67 insertions(+), 39 deletions(-)

New commits:
commit bc02bf23dfa00062ca94a9fe285496a11e010967
Author: Aleksander Machniak <alec at alec.pl>
Date:   Fri Oct 25 13:04:07 2013 +0200

    Add support for validate='extended' in 'alias' field, which if set
    will check for availability of provided email addresses.
    Added in-memory cache for entrydn-to-nsuniqueid resolving.
    Code improvements

diff --git a/lib/api/kolab_api_service_form_value.php b/lib/api/kolab_api_service_form_value.php
index d96a9b1..acffcd3 100644
--- a/lib/api/kolab_api_service_form_value.php
+++ b/lib/api/kolab_api_service_form_value.php
@@ -28,9 +28,10 @@
  */
 class kolab_api_service_form_value extends kolab_api_service
 {
-    const VALIDATE_DEFAULT = 'default';
-    const VALIDATE_BASIC   = 'basic';
-    const VALIDATE_NONE    = 'none';
+    const VALIDATE_DEFAULT  = 'default';
+    const VALIDATE_BASIC    = 'basic';
+    const VALIDATE_EXTENDED = 'extended';
+    const VALIDATE_NONE     = 'none';
 
 
     /**
@@ -421,15 +422,14 @@ class kolab_api_service_form_value extends kolab_api_service
                 }
             }
 
-            $auth        = Auth::get_instance($_SESSION['user']->get_domain());
-            $unique_attr = $this->unique_attribute();
-            $cn          = $postdata['cn'];
+            $auth = Auth::get_instance($_SESSION['user']->get_domain());
+            $cn   = $postdata['cn'];
 
             $x = 2;
             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_entry_attribute($resource_found_dn, $unique_attr);
+                    $resource_found_dn          = key($resource_found);
+                    $resource_found_unique_attr = $this->unique_attribute_value($resource_found_dn);
                     //console("resource with mail $mail found", $resource_found_unique_attr);
                     if ($resource_found_unique_attr == $postdata['id']) {
                         //console("that's us.");
@@ -609,13 +609,12 @@ class kolab_api_service_form_value extends kolab_api_service
             $mail_domain = $_SESSION['user']->get_domain();
             $mail        = $mail_local . '@' . $mail_domain;
             $auth        = Auth::get_instance($_SESSION['user']->get_domain());
-            $unique_attr = $this->unique_attribute();
 
             $x = 2;
             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_entry_attribute($resource_found_dn, $unique_attr);
+                    $resource_found_dn          = key($resource_found);
+                    $resource_found_unique_attr = $this->unique_attribute_value($resource_found_dn);
                     //console("resource with mail $mail found", $resource_found_unique_attr);
                     if ($resource_found_unique_attr == $postdata['id']) {
                         //console("that's us.");
@@ -724,30 +723,9 @@ class kolab_api_service_form_value extends kolab_api_service
             }
 
             $auth = Auth::get_instance();
-            $conf = Conf::get_instance();
-
-            // Find the authentication mechanism in order to be able to fall back from a
-            // '[$domain]' section setting for the mail attributes list, to an '[$auth_mech]'
-            // section setting
-            $auth_mech = $conf->get($_SESSION['user']->get_domain(), 'auth_mechanism');
-            if (empty($auth_mech)) {
-                $auth_mech = $conf->get('kolab', 'auth_mechanism');
-            }
-            if (empty($auth_mech)) {
-                $auth_mech = 'ldap';
-            }
-
-            $mail_attrs = $conf->get_list($_SESSION['user']->get_domain(), 'mail_attributes');
-            if (empty($mail_attrs)) {
-                $mail_attrs = $conf->get_list($auth_mech, 'mail_attributes');
-            }
-            if (empty($mail_attrs)) {
-                $mail_attrs = array('mail', 'alias');
-            }
 
             $_secondary_mail_addresses = kolab_recipient_policy::secondary_mail($postdata);
             $secondary_mail_addresses  = array();
-            $unique_attr               = $this->unique_attribute();
 
             foreach ($_secondary_mail_addresses as $num => $alias) {
                 list($_local, $_domain) = explode("@", $alias);
@@ -759,7 +737,7 @@ class kolab_api_service_form_value extends kolab_api_service
 
                     if (!empty($postdata['id'])) {
                         $user_found_dn          = key($user_found);
-                        $user_found_unique_attr = $auth->get_entry_attribute($user_found_dn, $unique_attr);
+                        $user_found_unique_attr = $this->unique_attribute_value($user_found_dn);
 
                         if ($user_found_unique_attr == $postdata['id']) {
                             Log::trace(__FUNCTION__ . ": Entry with address " . $local . "@" . $_domain . " is actually us.");
@@ -803,20 +781,18 @@ class kolab_api_service_form_value extends kolab_api_service
             }
 
             $userdata = kolab_recipient_policy::normalize_userdata($postdata);
+            $uid      = kolab_recipient_policy::uid($userdata);
 
-            $uid = kolab_recipient_policy::uid($userdata);
             Log::debug("uid from recipient policy: " . var_export($uid, TRUE));
 
             $orig_uid = $uid;
-
-            $auth        = Auth::get_instance($_SESSION['user']->get_domain());
-            $unique_attr = $this->unique_attribute();
+            $auth     = Auth::get_instance($_SESSION['user']->get_domain());
 
             $x = 2;
             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_entry_attribute($user_found_dn, $unique_attr);
+                    $user_found_dn          = key($user_found);
+                    $user_found_unique_attr = $this->unique_attribute_value($user_found_dn);
                     //console("user with uid $uid found", $user_found_unique_attr);
                     if ($user_found_unique_attr == $postdata['id']) {
                         //console("that's us.");
@@ -1087,6 +1063,33 @@ class kolab_api_service_form_value extends kolab_api_service
         return $options;
     }
 
+    /**
+     * Checks if specified list of email addresses is already
+     * in use by another user
+     */
+    private function _email_addresses_in_use($addresses, $postdata)
+    {
+        $auth = Auth::get_instance();
+
+        foreach ($addresses as $addr) {
+            if ($users = $auth->find_recipient($addr)) {
+                Log::trace(__FUNCTION__ . ": An entry with address $addr was found.");
+
+                if (!empty($postdata['id']) && count($users) == 1) {
+                    $user_found_dn          = key($users);
+                    $user_found_unique_attr = $this->unique_attribute_value($user_found_dn);
+
+                    if ($user_found_unique_attr == $postdata['id']) {
+                        Log::trace(__FUNCTION__ . ": Entry with address $addr is actually us.");
+                        continue;
+                    }
+                }
+
+                throw new Exception("Email address '$addr' is already in use", 694);
+            }
+        }
+    }
+
     private function validate_alias($value, $postdata = null, $validation_type = null)
     {
         $conf = Conf::get_instance();
@@ -1113,6 +1116,11 @@ class kolab_api_service_form_value extends kolab_api_service
             }
         }
 
+        // Check if addresses are not already in use
+        if ($validation_type == self::VALIDATE_EXTENDED) {
+            $this->_email_addresses_in_use($value, $postdata);
+        }
+
         return 'OK';
     }
 
diff --git a/lib/kolab_api_service.php b/lib/kolab_api_service.php
index fa5bd8e..c8f2680 100644
--- a/lib/kolab_api_service.php
+++ b/lib/kolab_api_service.php
@@ -560,4 +560,24 @@ abstract class kolab_api_service
 
         return $unique_attr;
     }
+
+    /**
+     * Returns unique attribute for specified entry DN
+     *
+     * @return string Unique attribute value
+     */
+    protected function unique_attribute_value($dn)
+    {
+        // this method can be called internally quite often
+        // let's cache results in memory
+        if (!empty($this->cache['unique_attributes'][$dn])) {
+            return $this->cache['unique_attributes'][$dn];
+        }
+
+        $unique_attr = $this->unique_attribute();
+        $auth        = Auth::get_instance();
+        $result      = $auth->get_entry_attribute($dn, $unique_attr);
+
+        return $this->cache['unique_attributes'][$dn] = $result;
+    }
 }




More information about the commits mailing list