allows to configure hooks for synced user data
authorPhilipp Schüle <p.schuele@metaways.de>
Thu, 31 Jul 2014 14:24:43 +0000 (16:24 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 31 Jul 2014 20:57:51 +0000 (22:57 +0200)
* this is called after user is fetched from sync backend
* use Tinebase_Config::SYNC_USER_HOOK_CLASS to configure a class
with a 'syncHook' function

Change-Id: I854ebbdd9f3ad84316ebdf2c006839031898429b
Reviewed-on: http://gerrit.tine20.com/customers/919
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tine20/Tinebase/Config.php
tine20/Tinebase/User.php
tine20/Tinebase/User/Ldap.php

index c26447a..97aedde 100644 (file)
@@ -138,6 +138,13 @@ class Tinebase_Config extends Tinebase_Config_Abstract
     const LDAP_DISABLE_TLSREQCERT = 'ldapDisableTlsReqCert';
     
     /**
+     * configure hook class for user sync
+     *
+     * @var string
+     */
+    const SYNC_USER_HOOK_CLASS = 'syncUserHookClass';
+    
+    /**
      * Config key for session ip validation -> if this is set to FALSE no Zend_Session_Validator_IpAddress is registered
      * 
      * @var string
@@ -450,6 +457,16 @@ class Tinebase_Config extends Tinebase_Config_Abstract
             'setBySetupModule'      => true,
             'default'               => false
         ),
+        self::SYNC_USER_HOOK_CLASS => array(
+                                   //_('Configure hook class for user sync')
+            'label'                 => 'Configure hook class for user sync',
+                                   //_('Allows to change data after fetching user from sync backend')
+            'description'           => 'Allows to change data after fetching user from sync backend',
+            'type'                  => 'string',
+            'clientRegistryInclude' => false,
+            'setByAdminModule'      => false,
+            'setBySetupModule'      => true,
+        ),
         self::SESSIONIPVALIDATION => array(
                                    //_('IP Session Validator')
             'label'                 => 'IP Session Validator',
index 01727a6..8e84771 100644 (file)
@@ -438,37 +438,16 @@ class Tinebase_User
             }
         }
         
-        $groupBackend = Tinebase_Group::getInstance();
-        
         $user = $userBackend->getUserByPropertyFromSyncBackend('accountLoginName', $username, 'Tinebase_Model_FullUser');
-        $user->accountPrimaryGroup = $groupBackend->resolveGIdNumberToUUId($user->accountPrimaryGroup);
+        $user->accountPrimaryGroup = Tinebase_Group::getInstance()->resolveGIdNumberToUUId($user->accountPrimaryGroup);
         
-        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($user->toArray(), TRUE));
+        $userProperties = method_exists($userBackend, 'getLastUserProperties') ? $userBackend->getLastUserProperties() : array();
+        self::_syncUserHook($user, $userProperties);
         
-        // make sure primary group exists
-        try {
-            $group = $groupBackend->getGroupById($user->accountPrimaryGroup);
-        } catch (Tinebase_Exception_Record_NotDefined $tern) {
-            if ($groupBackend->isDisabledBackend()) {
-                // groups are sql only
-                $group = $groupBackend->getDefaultGroup();
-                $user->accountPrimaryGroup = $group->getId();
-            } else {
-                try {
-                    $group = $groupBackend->getGroupByIdFromSyncBackend($user->accountPrimaryGroup);
-                } catch (Tinebase_Exception_Record_NotDefined $ternd) {
-                    throw new Tinebase_Exception('Primary group ' . $user->accountPrimaryGroup . ' not found in sync backend.');
-                }
-                try {
-                    $sqlGgroup = $groupBackend->getGroupByName($group->name);
-                    throw new Tinebase_Exception('Group already exists but it has a different ID: ' . $group->name);
-                    
-                } catch (Tinebase_Exception_Record_NotDefined $tern) {
-                    if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Adding group " . $group->name);
-                    $group = $groupBackend->addGroupInSqlBackend($group);
-                }
-            }
-        }
+        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' 
+            . print_r($user->toArray(), TRUE));
+        
+        $group = self::getPrimaryGroupForUser($user);
         
         try {
             $currentUser = $userBackend->getUserByProperty('accountId', $user, 'Tinebase_Model_FullUser');
@@ -491,19 +470,26 @@ class Tinebase_User
         } catch (Tinebase_Exception_NotFound $ten) {
             try {
                 $invalidUser = $userBackend->getUserByPropertyFromSqlBackend('accountLoginName', $username, 'Tinebase_Model_FullUser');
-                if (Tinebase_Core::isLogLevel(Zend_Log::CRIT)) Tinebase_Core::getLogger()->crit(__METHOD__ . '::' . __LINE__ . " remove invalid user: " . $username);
+                if (Tinebase_Core::isLogLevel(Zend_Log::CRIT)) Tinebase_Core::getLogger()->crit(__METHOD__ . '::' . __LINE__ 
+                    . " Remove invalid user: " . $username);
                 $userBackend->deleteUserInSqlBackend($invalidUser);
             } catch (Tinebase_Exception_NotFound $ten) {
                 // do nothing
             }
-        
-            self::syncContact($user);
+            
+            if ($user->visibility !== Tinebase_Model_FullUser::VISIBILITY_HIDDEN) {
+                self::syncContact($user);
+            }
             $syncedUser = $userBackend->addUserInSqlBackend($user);
             $userBackend->addPluginUser($syncedUser, $user);
         }
         
         // import contactdata(phone, address, fax, birthday. photo)
-        if (isset($options['syncContactData']) && $options['syncContactData'] && Tinebase_Application::getInstance()->isInstalled('Addressbook') === true) {
+        if (isset($options['syncContactData']) 
+                && $options['syncContactData'] 
+                && Tinebase_Application::getInstance()->isInstalled('Addressbook') === true
+                && $syncedUser->visibility !== Tinebase_Model_FullUser::VISIBILITY_HIDDEN
+        ) {
             $addressbook = Addressbook_Backend_Factory::factory(Addressbook_Backend_Factory::SQL);
             
             try {
@@ -523,6 +509,65 @@ class Tinebase_User
     }
     
     /**
+     * get primary group for user and make sure that group exists
+     * 
+     * @param Tinebase_Model_FullUser $user
+     * @throws Tinebase_Exception
+     * @return Tinebase_Model_Group
+     */
+    public static function getPrimaryGroupForUser($user)
+    {
+        $groupBackend = Tinebase_Group::getInstance();
+        
+        try {
+            $group = $groupBackend->getGroupById($user->accountPrimaryGroup);
+        } catch (Tinebase_Exception_Record_NotDefined $tern) {
+            if ($groupBackend->isDisabledBackend()) {
+                // groups are sql only
+                $group = $groupBackend->getDefaultGroup();
+                $user->accountPrimaryGroup = $group->getId();
+            } else {
+                try {
+                    $group = $groupBackend->getGroupByIdFromSyncBackend($user->accountPrimaryGroup);
+                } catch (Tinebase_Exception_Record_NotDefined $ternd) {
+                    throw new Tinebase_Exception('Primary group ' . $user->accountPrimaryGroup . ' not found in sync backend.');
+                }
+                try {
+                    $sqlGgroup = $groupBackend->getGroupByName($group->name);
+                    throw new Tinebase_Exception('Group already exists but it has a different ID: ' . $group->name);
+        
+                } catch (Tinebase_Exception_Record_NotDefined $tern) {
+                    if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+                        . " Adding group " . $group->name);
+                    $group = $groupBackend->addGroupInSqlBackend($group);
+                }
+            }
+        }
+        
+        return $group;
+    }
+    
+    /**
+     * call configured hooks for adjusting synced user data
+     * 
+     * @param Tinebase_Model_FullUser $user
+     * @param array $userProperties
+     */
+    protected static function _syncUserHook(Tinebase_Model_FullUser $user, $userProperties)
+    {
+        $hookClass = Tinebase_Config::getInstance()->get(Tinebase_Config::SYNC_USER_HOOK_CLASS);
+        if ($hookClass) {
+            $hook = new $hookClass();
+            if (method_exists($hook, 'syncUser')) {
+                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__
+                    . ' Calling ' . $hookClass . '::syncUser() ...');
+                
+                call_user_func_array(array($hook, 'syncUser'), array($user, $userProperties));
+            }
+        }
+    }
+    
+    /**
      * create contact in addressbook
      * 
      * @param Tinebase_Model_FullUser $user
index 34c11a2..b86cef4 100644 (file)
@@ -103,7 +103,12 @@ class Tinebase_User_Ldap extends Tinebase_User_Sql implements Tinebase_User_Inte
 
     protected $_ldapPlugins = array();
     
-    protected $_isReadOnlyBackend     = false;
+    protected $_isReadOnlyBackend = false;
+    
+    /**
+     * used to save the last user properties from ldap backend
+     */
+    protected $_lastLdapProperties = array();
     
     /**
      * the constructor
@@ -794,6 +799,8 @@ class Tinebase_User_Ldap extends Tinebase_User_Sql implements Tinebase_User_Inte
     {
         $errors = false;
         
+        $this->_lastLdapProperties = $_userData;
+        
         foreach ($_userData as $key => $value) {
             if (is_int($key)) {
                 continue;
@@ -851,6 +858,16 @@ class Tinebase_User_Ldap extends Tinebase_User_Sql implements Tinebase_User_Inte
     }
     
     /**
+     * returns properties of last user fetched from sync backend
+     * 
+     * @return array
+     */
+    public function getLastUserProperties()
+    {
+        return $this->_lastLdapProperties;
+    }
+    
+    /**
      * helper function to be overwriten in subclasses
      * 
      * @param  string  $accountId