0011810: credential cache decode fails sometimes
authorPhilipp Schüle <p.schuele@metaways.de>
Wed, 13 Apr 2016 13:27:52 +0000 (15:27 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Wed, 27 Apr 2016 11:49:28 +0000 (13:49 +0200)
* fixes problem by lazy loading user credential cache
 in FMailControllerAccount
* fixes json decode for empty credential caches
* throw exception if empty cache is found
* moves json decode helper to Tinebase_Helper

https://forge.tine20.org/view.php?id=11810

Change-Id: Id9264da16cec78a2408e0fee77ac22db906ed24a
Reviewed-on: https://gerrit.tine20.org/tine20/3336
Tested-by: jenkins user
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Felamimail/Controller/AccountTest.php
tine20/Felamimail/Controller/Account.php
tine20/Tinebase/Auth/CredentialCache.php
tine20/Tinebase/Frontend/Json/Abstract.php
tine20/Tinebase/Helper.php

index 0b7cd6d..cee0787 100644 (file)
@@ -233,4 +233,38 @@ class Felamimail_Controller_AccountTest extends PHPUnit_Framework_TestCase
         
         $this->assertEquals('', $account->signature, 'did not save empty signature');
     }
+
+    /**
+     * @see 0011810: credential cache decode fails sometimes
+     */
+    public function testSaveAccountAndCredentialCache()
+    {
+        $account = new Felamimail_Model_Account(array(
+            'from' => 'Admin Account, Tine 2.0',
+            'port' => '143',
+            'smtp_port' => '25',
+            'smtp_ssl' => 'none',
+            'sieve_port' => '2000',
+            'sieve_ssl' => 'none',
+            'signature' => 'Sent with love from the Tine 2.0 email client ...<br>Please visit <a href="http://www.tine20.com">http://www.tine20.com</a>',
+            'sent_folder' => 'Sent',
+            'trash_folder' => 'Trash',
+            'name' => 'test',
+            'user' => 'abcde@tine20.org',
+            'host' => 'mail.abc.de',
+            'email' => 'abcde@tine20.org',
+            'password' => 'abcde',
+            'organization' => '',
+            'ssl' => 'none',
+            'display_format' => 'html',
+            'signature_position' => 'below',
+            'smtp_auth' => 'login',
+        ));
+
+        $savedAccount = $this->_controller->create($account);
+
+        $savedAccount->resolveCredentials();
+        $this->assertEquals('abcde@tine20.org', $savedAccount->user);
+        $this->assertEquals('abcde', $savedAccount->password);
+    }
 }
index 4677af4..b840d7e 100644 (file)
@@ -891,9 +891,9 @@ class Felamimail_Controller_Account extends Tinebase_Controller_Record_Abstract
             } 
             Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $message);
         }
-        
-        if (Tinebase_Core::isRegistered(Tinebase_Core::USERCREDENTIALCACHE)) {
-            $userCredentialCache = Tinebase_Core::getUserCredentialCache();
+
+        $userCredentialCache = Tinebase_Core::getUserCredentialCache();
+        if ($userCredentialCache !== null) {
             Tinebase_Auth_CredentialCache::getInstance()->getCachedCredentials($userCredentialCache);
         } else {
             Tinebase_Core::getLogger()->crit(__METHOD__ . '::' . __LINE__ 
index 8d283b2..78739b5 100644 (file)
@@ -252,7 +252,7 @@ class Tinebase_Auth_CredentialCache extends Tinebase_Backend_Sql_Abstract implem
     }
     
     /**
-     * decryptes username and password
+     * decrypts username and password
      *
      * @param  Tinebase_Model_CredentialCache $_cache
      * @return void
@@ -267,14 +267,19 @@ class Tinebase_Auth_CredentialCache extends Tinebase_Backend_Sql_Abstract implem
         
         $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
         mcrypt_generic_init($td, $_cache->key, substr($_cache->getId(), 0, 16));
-        
-        $cacheData = Zend_Json::decode(trim(mdecrypt_generic($td, $encryptedData)));
-        
-        $_cache->username = $cacheData['username'];
-        $_cache->password = $cacheData['password'];
-        
+
+        $jsonEncodedData = trim(mdecrypt_generic($td, $encryptedData));
+        $cacheData = Tinebase_Helper::jsonDecode($jsonEncodedData);
+
         mcrypt_generic_deinit($td);
         mcrypt_module_close($td);
+
+        if (! isset($cacheData['username']) && ! isset($cacheData['password'])) {
+            throw new Tinebase_Exception_NotFound('could not find valid credential cache');
+        }
+
+        $_cache->username = $cacheData['username'];
+        $_cache->password = $cacheData['password'];
     }
     
     /**
index da7d57f..a5e07b1 100644 (file)
@@ -437,7 +437,7 @@ abstract class Tinebase_Frontend_Json_Abstract extends Tinebase_Frontend_Abstrac
     /**
      * returns function parameter as object, decode Json if needed
      *
-     * Prepare function input to be an object. Input maybe already an array or (empty) text.
+     * Prepare function input to be an array. Input maybe already an array or (empty) text.
      * Starting PHP 7 Zend_Json::decode can't handle empty strings.
      *
      * @param  mixed $_dataAsArrayOrJson
@@ -445,15 +445,7 @@ abstract class Tinebase_Frontend_Json_Abstract extends Tinebase_Frontend_Abstrac
      */
     protected function _prepareParameter($_dataAsArrayOrJson)
     {
-        if (is_array($_dataAsArrayOrJson)) {
-            return $_dataAsArrayOrJson;
-        }
-        else if (trim($_dataAsArrayOrJson) == '') {
-            return Zend_Json::decode("{}");
-        }
-        else {
-            return Zend_Json::decode($_dataAsArrayOrJson);
-        }
+        return Tinebase_Helper::jsonDecode($_dataAsArrayOrJson);
     }
 
     /**
index 582821f..08bf30b 100644 (file)
@@ -328,4 +328,25 @@ class Tinebase_Helper
         
         return $exists;
     }
+
+    /**
+     * decode json string or
+     *
+     * Prepare function input to be an array. Input maybe already an array or (empty) text.
+     * Starting PHP 7 Zend_Json::decode can't handle empty strings.
+     *
+     * @param $jsonOrArray
+     * @return mixed
+     * @throws Zend_Json_Exception
+     */
+    public static function jsonDecode($jsonOrArray)
+    {
+        if (is_array($jsonOrArray)) {
+            return $jsonOrArray;
+        } else if (trim($jsonOrArray) == '') {
+            return Zend_Json::decode("{}");
+        } else {
+            return Zend_Json::decode($jsonOrArray);
+        }
+    }
 }