Merge branch '2013.10' into 2014.09
authorPhilipp Schüle <p.schuele@metaways.de>
Thu, 9 Oct 2014 08:53:58 +0000 (10:53 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 9 Oct 2014 08:53:58 +0000 (10:53 +0200)
Conflicts:
tests/tine20/Tinebase/Acl/RolesTest.php
tine20/Crm/js/LeadGridPanel.js
tine20/Tinebase/Container.php
tine20/Tinebase/Controller.php

Change-Id: I4c40fed17e17b42fa85fe45d67d912887fbe229d

20 files changed:
1  2 
tests/tine20/ActiveSync/Controller/CalendarTests.php
tests/tine20/Admin/JsonTest.php
tests/tine20/Felamimail/Frontend/JsonTest.php
tests/tine20/Tinebase/Acl/RolesTest.php
tine20/ActiveSync/Controller/Abstract.php
tine20/ActiveSync/Controller/Calendar.php
tine20/Admin/Frontend/Json.php
tine20/Calendar/Controller/MSEventFacade.php
tine20/Crm/Model/LeadFilter.php
tine20/Crm/js/LeadGridPanel.js
tine20/Crm/js/Model.js
tine20/Tinebase/Acl/Roles.php
tine20/Tinebase/Backend/Sql/Abstract.php
tine20/Tinebase/Container.php
tine20/Tinebase/Controller.php
tine20/Tinebase/Convert/Json.php
tine20/Tinebase/Frontend/Http.php
tine20/Tinebase/Frontend/Json.php
tine20/Tinebase/Server/WebDAV.php
tine20/Voipmanager/Setup/setup.xml

Simple merge
@@@ -1668,22 -1655,8 +1668,22 @@@ class Felamimail_Frontend_JsonTest exte
      }
  
      /**
 +     * search preferences by application felamimail
 +     *
 +     */
 +    public function testSearchFelamimailPreferences()
 +    {
 +        // search prefs
 +        $result = $this->_frontend->searchPreferencesForApplication('Felamimail', '');
 +        
 +        // check results
 +        $this->assertTrue(isset($result['results']));
 +        $this->assertGreaterThan(0, $result['totalcount']);
 +    }
 +    
 +    /**
       * testGetRegistryData
-      * 
+      *
       * @see 0010251: do not send unused config data to client
       */
      public function testGetRegistryData()
Simple merge
@@@ -738,19 -638,31 +740,35 @@@ class Calendar_Controller_MSEventFacad
       */
      protected function _filterAttendeeWithoutEmail($event)
      {
 +        if (! $event->attendee instanceof Tinebase_Record_RecordSet) {
 +            return;
 +        }
 +
          $this->_fillResolvedAttendeeCache($event);
          
-         $filteredAttendee = new Tinebase_Record_RecordSet('Calendar_Model_Attender');
-         foreach ($event->attendee->getEmail() as $idx => $email) {
-             if ($email) {
-                 $filteredAttendee->addRecord($event->attendee[$idx]);
+         foreach ($event->attendee as $attender) {
+             $cacheId = $attender['user_type'] . $attender['user_id'];
+             
+             // value is in array and true
+             if (isset(self::$_attendeeEmailCache[$cacheId])) {
+                 continue;
+             }
+             
+             // add value to cache if not existing already
+             if (!array_key_exists($cacheId, self::$_attendeeEmailCache)) {
+                 self::$_attendeeEmailCache[$cacheId] = !!$attender->getEmail();
+                 
+                 // limit class cache to 100 entries
+                 if (count(self::$_attendeeEmailCache) > 100) {
+                     array_shift(self::$_attendeeEmailCache);
+                 }
+             }
+             
+             // remove entry if value is not true => attender has no email address
+             if (!self::$_attendeeEmailCache[$cacheId]) {
+                 $event->attendee->removeRecord($attender);
              }
          }
-         $event->attendee = $filteredAttendee;
      }
  
      /**
Simple merge
@@@ -143,13 -121,10 +143,14 @@@ Tine.Crm.LeadGridPanel = Ext.extend(Tin
                  {header: this.app.i18n._('Partner'), id: 'lead_partner', dataIndex: 'relations', width: 175, sortable: false, renderer: this.partnerRenderer},
                  {header: this.app.i18n._('Customer'), id: 'lead_customer', dataIndex: 'relations', width: 175, sortable: false, renderer: this.customerRenderer},
                  {header: this.app.i18n._('Leadstate'), id: 'leadstate_id', dataIndex: 'leadstate_id', sortable: false, width: 100, renderer: Tine.Crm.LeadState.Renderer},
 -                {header: this.app.i18n._('Probability'), id: 'probability', dataIndex: 'probability', width: 50, renderer: Ext.util.Format.percentage },
+                 {header: this.app.i18n._('Leadsource'), id: 'leadsource_id', dataIndex: 'leadsource_id', sortable: false, width: 100, renderer: Tine.Crm.LeadSource.Renderer},
 +                {header: this.app.i18n._('Probability'), id: 'probability', dataIndex: 'probability', width: 50, renderer: Ext.ux.PercentRenderer },
                  {header: this.app.i18n._('Turnover'), id: 'turnover', dataIndex: 'turnover', width: 100, renderer: Ext.util.Format.euMoney },
 -                {header: this.app.i18n._('Probable Turnover'), id: 'probableTurnover', dataIndex: 'probableTurnover', width: 100, renderer: Ext.util.Format.euMoney, sortable: false }
 +
 +                {header: this.app.i18n._('Estimated end'), id: 'end_scheduled', dataIndex: 'end_scheduled', width: 100, renderer: Tine.Tinebase.common.dateRenderer, sortable: true },
 +                {header: this.app.i18n._('Probable Turnover'), id: 'probableTurnover', dataIndex: 'probableTurnover', width: 100, renderer: Ext.util.Format.euMoney, sortable: false },
 +                {header: this.app.i18n._('Resubmission Date'), id: 'resubmission_date', dataIndex: 'resubmission_date', width: 100, renderer: Tine.Tinebase.common.dateRenderer, sortable: true }
 +                
              ].concat(this.getModlogColumns().concat(this.getCustomfieldColumns()))
          });
      },
Simple merge
Simple merge
@@@ -759,18 -748,10 +759,10 @@@ class Tinebase_Container extends Tineba
       * @param   bool                                $_ignoreACL
       * @return  Tinebase_Record_RecordSet set of Tinebase_Model_User
       */
 -    public function getOtherUsers($_accountId, $_application, $_grant, $_ignoreACL = FALSE)
 +    public function getOtherUsers($_accountId, $recordClass, $_grant, $_ignoreACL = FALSE)
      {
-         // legacy handling
-         $meta = $this->_resolveRecordClassArgument($recordClass);
-         
-         $containersData = $this->_getOtherUsersContainerData($_accountId, $meta['appName'], $_grant, $_ignoreACL);
 -        $userIds = $this->_getOtherAccountIds($_accountId, $_application, $_grant, $_ignoreACL);
++        $userIds = $this->_getOtherAccountIds($_accountId, $meta['appName'], $_grant, $_ignoreACL);
          
-         $userIds = array();
-         foreach($containersData as $containerData) {
-             $userIds[] = $containerData['account_id'];
-         }
          $users = Tinebase_User::getInstance()->getMultiple($userIds);
          $users->sort('accountDisplayName');
          
@@@ -63,66 -66,129 +66,129 @@@ class Tinebase_Controller extends Tineb
      /**
       * create new user session
       *
-      * @param   string $_loginname
-      * @param   string $_password
-      * @param   string $_ipAddress
-      * @param   string $_clientIdString
-      * @param   string $securitycode the security code(captcha)
+      * @param   string                           $loginName
+      * @param   string                           $password
+      * @param   Zend_Controller_Request_Abstract $request
+      * @param   string                           $clientIdString
+      * @param   string                           $securitycode   the security code(captcha)
       * @return  bool
       */
-     public function login($_loginname, $_password, $_ipAddress, $_clientIdString = NULL, $securitycode = NULL)
+     public function login($loginName, $password, Zend_Controller_Request_Abstract $request, $clientIdString = NULL, $securitycode = NULL)
      {
-         $authResult = Tinebase_Auth::getInstance()->authenticate($_loginname, $_password);
-         $authResultCode = $authResult->getCode();
+         $authResult         = Tinebase_Auth::getInstance()->authenticate($loginName, $password);
+         $authResultCode     = $authResult->getCode();
          $authResultIdentity = $authResult->getIdentity();
          
-         Tinebase_Core::set(Tinebase_Core::SESSIONID, Zend_Session::isStarted() ? session_id() : Tinebase_Record_Abstract::generateUID());
+         $remoteAddr = $request->getClientIp();
+         $userAgent  = $request->getHeader('USER_AGENT');
          
          $accessLog = new Tinebase_Model_AccessLog(array(
-             'sessionid'     => Tinebase_Core::get(Tinebase_Core::SESSIONID),
-             'ip'            => $_ipAddress,
-             'li'            => Tinebase_DateTime::now()->get(Tinebase_Record_Abstract::ISO8601LONG),
+             'ip'            => $remoteAddr,
+             'li'            => Tinebase_DateTime::now(),
              'result'        => $authResultCode,
-             'clienttype'    => $_clientIdString,
+             'clienttype'    => $clientIdString,
+             'login_name'    => $loginName ? $loginName : $authResultIdentity
          ), TRUE);
          
-         $user = NULL;
-         if ($accessLog->result == Tinebase_Auth::SUCCESS) {
-             $user = $this->_getLoginUser($authResultIdentity, $accessLog);
-             if ($user !== NULL) {
-                 $this->_checkUserStatus($user, $accessLog);
-             }
+         // authentication failed
+         if ($accessLog->result !== Tinebase_Auth::SUCCESS) {
+             $this->_loginFailed($authResult, $accessLog);
+             
+             return false;
          }
          
-         if ($accessLog->result === Tinebase_Auth::SUCCESS && $user !== NULL && $user->accountStatus === Tinebase_User::STATUS_ENABLED) {
-             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(
-                 __METHOD__ . '::' . __LINE__ . " Login with username $_loginname from $_ipAddress succeeded.");
+         // try to retrieve user from accounts backend
+         $user = $this->_getLoginUser($authResultIdentity, $accessLog);
+         
+         if ($accessLog->result !== Tinebase_Auth::SUCCESS || !$user) {
+             $this->_loginFailed($authResult, $accessLog);
              
-             $this->_initUserAfterLogin($user, $accessLog, $_password);
+             return false;
+         }
+         
+         // check if user is expired or blocked
+         $this->_checkUserStatus($user, $accessLog);
+         
+         if ($accessLog->result !== Tinebase_Auth::SUCCESS) {
+             $this->_loginFailed($authResult, $accessLog);
              
-             $result = true;
+             return false;
+         }
+         
+         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(
+             __METHOD__ . '::' . __LINE__ . " Login with username $loginName from $remoteAddr succeeded.");
+         
+         if (in_array($clientIdString, array(Tinebase_Server_WebDAV::REQUEST_TYPE, ActiveSync_Server_Http::REQUEST_TYPE))) {
+             $previousAccessLog = Tinebase_AccessLog::getInstance()->search(
+                 new Tinebase_Model_AccessLogFilter(array(
+                     array(
+                         'field'    => 'ip',
+                         'operator' => 'equals',
+                         'value'    => $remoteAddr
+                     ),
+                     array(
+                         'field'    => 'account_id',
+                         'operator' => 'equals',
+                         'value'    => $user->getId()
+                     ),
+                     array(
+                         'field'    => 'result',
+                         'operator' => 'equals',
+                         'value'    => Tinebase_Auth::SUCCESS
+                     ),
+                     array(
+                         'field'    => 'clienttype',
+                         'operator' => 'equals',
+                         'value'    => $clientIdString
+                     ),
+                     array(
+                         'field'    => 'sessionid',
+                         'operator' => 'equals',
+                         'value'    => sha1(
+                             $accessLog->ip .
+                             $accessLog->clienttype .
+                             $user->getId() .
+                             $userAgent
+                         )
+                     ),
+                     array(
+                         'field'    => 'lo',
+                         'operator' => 'after',
+                         'value'    => Tinebase_DateTime::now()->subHour(2)
+                     ),
+                 )),
+                 new Tinebase_Model_Pagination(array(
+                     'sort'  => 'li',
+                     'dir'   => 'DESC',
+                     'limit' => 1
+                 ))
+             )->getFirstRecord();
              
+             if ($previousAccessLog) {
+                 $accessLog = $previousAccessLog;
+                 Tinebase_Core::set(Tinebase_Core::SESSIONID, $accessLog->sessionid);
+             } else {
+                 Tinebase_Core::set(Tinebase_Core::SESSIONID, sha1(
+                     $accessLog->ip .
+                     $accessLog->clienttype .
+                     $user->getId() .
+                     $userAgent
+                 ));
+             }
          } else {
-             if ($user !== NULL && $user->accountStatus === Tinebase_User::STATUS_DISABLED) {
-                 // TODO send this for blocked/expired, too? allow to configure this?
-                 Tinebase_User::getInstance()->sendDeactivationNotification($user);
+             Tinebase_Core::set(Tinebase_Core::SESSIONID, Zend_Session::isStarted() ? session_id() : Tinebase_Record_Abstract::generateUID());
+         }
+         
 -        $this->_initUser($user, $accessLog, $password);
++        $this->_initUserAfterLogin($user, $accessLog, $password);
+         
+         if (!$accessLog->getId()) {
+             $user->setLoginTime($accessLog->ip);
+                 if ($this->_writeAccessLog) {
+                 $accessLog = Tinebase_AccessLog::getInstance()->create($accessLog);
              }
-             
-             if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) Tinebase_Core::getLogger()->warn(
-                 __METHOD__ . '::' . __LINE__ . " Login with username $_loginname from $_ipAddress failed ($authResultCode)!");
-             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(
-                 __METHOD__ . '::' . __LINE__ . ' Failure messages: ' . print_r($authResult->getMessages(), TRUE));
-             $this->_loginFailed($_loginname ? $_loginname : $authResultIdentity, $accessLog);
-             
-             $result = false;
-         } 
-         if (Tinebase_Core::get('serverclassname') !== 'ActiveSync_Server_Http' || !(ActiveSync_Config::getInstance()->get(ActiveSync_Config::DISABLE_ACCESS_LOG))) {
-             Tinebase_AccessLog::getInstance()->create($accessLog);
          }
  
-         return $result;
+         return true;
      }
      
      /**
      }
      
      /**
- <<<<<<< HEAD
 -     * init user session
 +     * init user after login (credential cache, access log, session, ...)
- =======
-      * init user session
- >>>>>>> parent of ea7f897... 00100118: Refactoring of login methods
       * 
       * @param Tinebase_Model_FullUser $_user
       * @param Tinebase_Model_AccessLog $_accessLog
-      * @param string $_password
+      * @param string $password
       */
 -    protected function _initUser(Tinebase_Model_FullUser $_user, Tinebase_Model_AccessLog $_accessLog, $password)
 +    protected function _initUserAfterLogin(Tinebase_Model_FullUser $_user, Tinebase_Model_AccessLog $_accessLog, $_password)
      {
 -        $this->_initUserSession($_user);
 +        if ($_accessLog->result !== Tinebase_Auth::SUCCESS || $_user->accountStatus !== Tinebase_User::STATUS_ENABLED) {
 +            return false;
 +        }
          
 -        Tinebase_Core::set(Tinebase_Core::USER, $_user);
 +        $this->initUser($_user);
          
 -        $credentialCache = Tinebase_Auth_CredentialCache::getInstance()->cacheCredentials($_user->accountLoginName, $password);
 +        $credentialCache = Tinebase_Auth_CredentialCache::getInstance()->cacheCredentials($_user->accountLoginName, $_password);
          Tinebase_Core::set(Tinebase_Core::USERCREDENTIALCACHE, $credentialCache);
          
-         $_user->setLoginTime($_accessLog->ip);
 +        $_accessLog->sessionid = Tinebase_Core::get(Tinebase_Core::SESSIONID);
 +        $_accessLog->login_name = $_user->accountLoginName;
 +        $_accessLog->account_id = $_user->getId();
 +    }
 +    
 +    /**
- <<<<<<< HEAD
 +     * initialize user (session, locale, tz)
- =======
-      * init session after successful login
- >>>>>>> parent of ea7f897... 00100118: Refactoring of login methods
 +     * 
 +     * @param Tinebase_Model_FullUser $_user
 +     * @param boolean $fixCookieHeader
 +     */
 +    public function initUser(Tinebase_Model_FullUser $_user, $fixCookieHeader = true)
 +    {
 +        $this->_initUserSession($_user, $fixCookieHeader);
 +        
 +        Tinebase_Core::set(Tinebase_Core::USER, $_user);
 +        
          // need to set locale again and because locale might not be set correctly during loginFromPost
          // use 'auto' setting because it is fetched from cookie or preference then
          Tinebase_Core::setupUserLocale('auto');
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge