0009918: shared (only free/busy) calendar is showing history
authorPhilipp Schüle <p.schuele@metaways.de>
Tue, 13 May 2014 15:09:16 +0000 (17:09 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Wed, 14 May 2014 15:21:09 +0000 (17:21 +0200)
* adds acl check for record notes are searched for
* adds a test that asserts removal of notes in free/busy cleanup
* json note search now always requires model and record id (adopted
tests)
* adds note model name when using addMultipleModificationSystemNotes

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

Change-Id: Ieb59a66c8fc0c03b7c1a281dbfbbff38514875fc
Reviewed-on: http://gerrit.tine20.com/customers/634
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Addressbook/JsonTest.php
tests/tine20/Calendar/JsonTests.php
tests/tine20/Tinebase/Frontend/JsonTest.php
tine20/Tinebase/Controller/Record/Abstract.php
tine20/Tinebase/Frontend/Json.php
tine20/Tinebase/Notes.php

index 18e1f9a..199d7bc 100644 (file)
@@ -437,8 +437,16 @@ class Addressbook_JsonTest extends PHPUnit_Framework_TestCase
     {
         $tinebaseJson = new Tinebase_Frontend_Json();
         $history = $tinebaseJson->searchNotes(array(array(
-            'field' => 'record_id', 'operator' => 'equals', 'value' => $_recordId
-        )), array('sort' => array('note_type_id', 'creation_time')));
+            'field' => 'record_id',
+            'operator' => 'equals',
+            'value' => $_recordId
+        ), array(
+            'field' => "record_model",
+            'operator' => "equals",
+            'value' => 'Addressbook_Model_Contact'
+        )), array(
+            'sort' => array('note_type_id', 'creation_time')
+        ));
         $this->assertEquals($_changedNoteNumber, $history['totalcount'], print_r($history, TRUE));
         $changedNote = $history['results'][$_changedNoteNumber - 1];
         foreach ((array) $_expectedText as $text) {
index dc4b3c9..cdbce17 100644 (file)
@@ -9,11 +9,6 @@
  */
 
 /**
- * Test helper
- */
-require_once dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'TestHelper.php';
-
-/**
  * Test class for Json Frontend
  * 
  * @package     Calendar
@@ -713,6 +708,8 @@ class Calendar_JsonTests extends Calendar_TestCase
     
     /**
      * testFreeBusyCleanup
+     * 
+     * @return array event data
      */
     public function testFreeBusyCleanup()
     {
@@ -762,6 +759,33 @@ class Calendar_JsonTests extends Calendar_TestCase
         $this->assertFalse((isset($eventData['attendee']) || array_key_exists('attendee', $eventData)), 'attendee not empty');
         $this->assertFalse((isset($eventData['organizer']) || array_key_exists('organizer', $eventData)), 'organizer not empty');
         $this->assertFalse((isset($eventData['alarms']) || array_key_exists('alarms', $eventData)), 'alarms not empty');
+        
+        return $eventData;
+    }
+
+    /**
+     * testFreeBusyCleanupOfNotes
+     * 
+     * @see 0009918: shared (only free/busy) calendar is showing event details within the history tab.
+     */
+    public function testFreeBusyCleanupOfNotes()
+    {
+        $eventData = $this->testFreeBusyCleanup();
+        
+        $tinebaseJson = new Tinebase_Frontend_Json();
+        $filter = array(array(
+            'field' => "record_model",
+            'operator' => "equals",
+            'value' => "Calendar_Model_Event"
+        ), array(
+            'field' => 'record_id',
+            'operator' => 'equals',
+            'value' => $eventData['id']
+        ));
+        $notes = $tinebaseJson->searchNotes($filter, array());
+        
+        $this->assertEquals(0, $notes['totalcount'], 'should not find any notes of record');
+        $this->assertEquals(0, count($notes['results']), 'should not find any notes of record');
     }
     
     /**
index 564efa0..533ff17 100644 (file)
@@ -6,19 +6,14 @@
  * @subpackage  Json
  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
  * @author      Philipp Schüle <p.schuele@metaways.de>
- * @copyright   Copyright (c) 2007-2013 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2007-2014 Metaways Infosystems GmbH (http://www.metaways.de)
  *
  */
 
 /**
- * Test helper
- */
-require_once dirname(dirname(dirname(__FILE__))) . DIRECTORY_SEPARATOR . 'TestHelper.php';
-
-/**
  * Test class for Tinebase_Group
  */
-class Tinebase_Frontend_JsonTest extends PHPUnit_Framework_TestCase
+class Tinebase_Frontend_JsonTest extends TestCase
 {
     /**
      * unit under test (UIT)
@@ -46,7 +41,7 @@ class Tinebase_Frontend_JsonTest extends PHPUnit_Framework_TestCase
      */
     public function setUp()
     {
-        Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb());
+        parent::setUp();
         
         $this->_instance = new Tinebase_Frontend_Json();
         
@@ -71,7 +66,6 @@ class Tinebase_Frontend_JsonTest extends PHPUnit_Framework_TestCase
             'note'              => 'phpunit test note',
             'record_model'      => $this->_objects['record']['model'],
             'record_backend'    => $this->_objects['record']['backend'],
-            'record_id'         => $this->_objects['record']['id']
         ));
     }
     
@@ -80,7 +74,7 @@ class Tinebase_Frontend_JsonTest extends PHPUnit_Framework_TestCase
      */
     public function tearDown()
     {
-        Tinebase_TransactionManager::getInstance()->rollBack();
+        parent::tearDown();
         
         // reset tz in core
         Tinebase_Core::set(Tinebase_Core::USERTIMEZONE, Tinebase_Core::getPreference()->getValue(Tinebase_Preference::TIMEZONE));
@@ -88,16 +82,26 @@ class Tinebase_Frontend_JsonTest extends PHPUnit_Framework_TestCase
     
     /**
      * try to add a note type
-     *
      */
     public function testSearchNotes()
     {
-        Tinebase_Notes::getInstance()->addNote($this->_objects['note']);
+        $contact = Addressbook_Controller_Contact::getInstance()->create(new Addressbook_Model_Contact(array('n_family' => 'Schulz')));
+        $note = $this->_objects['note'];
+        $note->record_id = $contact->getId();
+        Tinebase_Notes::getInstance()->addNote($note);
 
         $filter = array(array(
             'field' => 'query',
             'operator' => 'contains',
             'value' => 'phpunit'
+        ), array(
+            'field' => "record_model",
+            'operator' => "equals",
+            'value' => $this->_objects['record']['model']
+        ), array(
+            'field' => 'record_id',
+            'operator' => 'equals',
+            'value' => $contact->getId()
         ));
         $paging = array();
         
@@ -116,7 +120,7 @@ class Tinebase_Frontend_JsonTest extends PHPUnit_Framework_TestCase
         Tinebase_Notes::getInstance()->deleteNotesOfRecord(
             $this->_objects['record']['model'], 
             $this->_objects['record']['backend'], 
-            $this->_objects['record']['id']
+            $contact->getId()
         );
     }
     
index 726afb8..c71a91d 100644 (file)
@@ -996,7 +996,7 @@ abstract class Tinebase_Controller_Record_Abstract
                 . ' Writing modlog for ' . count($ids) . ' records ...');
             
             $currentMods = Tinebase_Timemachine_ModificationLog::getInstance()->writeModLogMultiple($ids, $_oldData, $_newData, $this->_modelName, $this->_getBackendType(), $updateMetaData);
-            Tinebase_Notes::getInstance()->addMultipleModificationSystemNotes($currentMods, $currentAccountId);
+            Tinebase_Notes::getInstance()->addMultipleModificationSystemNotes($currentMods, $currentAccountId, $this->_modelName);
         }
     }
     
index 775e57c..d00b36e 100644 (file)
@@ -368,13 +368,13 @@ class Tinebase_Frontend_Json extends Tinebase_Frontend_Json_Abstract
     {
         $filter = new Tinebase_Model_NoteFilter($filter);
         $paging = new Tinebase_Model_Pagination($paging);
-
-        $records = Tinebase_Notes::getInstance()->searchNotes($filter, $paging);
+        
+        $records = Tinebase_Notes::getInstance()->searchNotes($filter, $paging, /* ignoreACL = */ false);
         $result = $this->_multipleRecordsToJson($records);
 
         return array(
             'results'       => $result,
-            'totalcount'    => Tinebase_Notes::getInstance()->searchNotesCount($filter)
+            'totalcount'    => Tinebase_Notes::getInstance()->searchNotesCount($filter, /* ignoreACL = */ false)
         );
     }
 
index 65487ff..ecabd50 100644 (file)
@@ -150,20 +150,23 @@ class Tinebase_Notes implements Tinebase_Backend_Sql_Interface
      *
      * @param Tinebase_Model_NoteFilter $_filter
      * @param Tinebase_Model_Pagination $_pagination
+     * @param boolean $ignoreACL
      * @return Tinebase_Record_RecordSet subtype Tinebase_Model_Note
      */
-    public function searchNotes(Tinebase_Model_NoteFilter $_filter, Tinebase_Model_Pagination $_pagination = NULL)
+    public function searchNotes(Tinebase_Model_NoteFilter $_filter, Tinebase_Model_Pagination $_pagination = NULL, $ignoreACL = true)
     {
         $select = $this->_db->select()
             ->from(array('notes' => SQL_TABLE_PREFIX . 'notes'));
         
+        if (! $ignoreACL) {
+            $this->_checkFilterACL($_filter);
+        }
+        
         Tinebase_Backend_Sql_Filter_FilterGroup::appendFilters($select, $_filter, $this);
         if ($_pagination !== NULL) {
             $_pagination->appendPaginationSql($select);
         }
         
-        //if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $select->__toString());
-        
         $rows = $this->_db->fetchAssoc($select);
         $result = new Tinebase_Record_RecordSet('Tinebase_Model_Note', $rows, true);
 
@@ -171,18 +174,53 @@ class Tinebase_Notes implements Tinebase_Backend_Sql_Interface
     }
     
     /**
+     * checks acl of filter
+     * 
+     * @param Tinebase_Model_NoteFilter $noteFilter
+     * @throws Tinebase_Exception_AccessDenied
+     */
+    protected function _checkFilterACL(Tinebase_Model_NoteFilter $noteFilter)
+    {
+        $recordModelFilter = $noteFilter->getFilter('record_model');
+        if (empty($recordModelFilter)) {
+            throw new Tinebase_Exception_AccessDenied('record model filter required');
+        }
+        
+        $recordIdFilter = $noteFilter->getFilter('record_id');
+        if (empty($recordIdFilter) || $recordIdFilter->getOperator() !== 'equals') {
+            throw new Tinebase_Exception_AccessDenied('record id filter required or wrong operator');
+        }
+        
+        $recordModel = $recordModelFilter->getValue();
+        if (! is_string($recordModel)) {
+            throw new Tinebase_Exception_AccessDenied('no explicit record model set in filter');
+        }
+        
+        try {
+            $record = Tinebase_Core::getApplicationInstance($recordModel)->get($recordIdFilter->getValue());
+        } catch (Tinebase_Exception_AccessDenied $tead) {
+            Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Do not fetch record notes because user has no read grant for container');
+            $recordIdFilter->setValue('');
+        }
+    }
+    
+    /**
      * count notes
      *
      * @param Tinebase_Model_NoteFilter $_filter
+     * @param boolean $ignoreACL
      * @return int notes count
      */
-    public function searchNotesCount(Tinebase_Model_NoteFilter $_filter)
+    public function searchNotesCount(Tinebase_Model_NoteFilter $_filter, $ignoreACL = true)
     {
         $select = $this->_db->select()
             ->from(array('notes' => SQL_TABLE_PREFIX . 'notes'), array('count' => 'COUNT(' . $this->_db->quoteIdentifier('id') . ')'));
         
+        if (! $ignoreACL) {
+            $this->_checkFilterACL($_filter);
+        }
+        
         Tinebase_Backend_Sql_Filter_FilterGroup::appendFilters($select, $_filter, $this);
-        //$_filter->appendFilterSql($select);
         
         $result = $this->_db->fetchOne($select);
         return $result;
@@ -443,13 +481,14 @@ class Tinebase_Notes implements Tinebase_Backend_Sql_Interface
      * 
      * @param Tinebase_Record_RecordSet $_mods
      * @param string $_userId
+     * @param string $modelName
      */
-    public function addMultipleModificationSystemNotes($_mods, $_userId)
+    public function addMultipleModificationSystemNotes($_mods, $_userId, $modelName = null)
     {
         $_mods->addIndices(array('record_id'));
         foreach ($_mods->record_id as $recordId) {
             $modsOfRecord = $_mods->filter('record_id', $recordId);
-            $this->addSystemNote($recordId, $_userId, Tinebase_Model_Note::SYSTEM_NOTE_NAME_CHANGED, $modsOfRecord);
+            $this->addSystemNote($recordId, $_userId, Tinebase_Model_Note::SYSTEM_NOTE_NAME_CHANGED, $modsOfRecord, 'Sql', $modelName);
         }
     }