0011890: disallow external attendee status setting for external organizer
authorCornelius Weiß <c.weiss@metaways.de>
Mon, 30 May 2016 16:00:12 +0000 (18:00 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 16 Jun 2016 08:06:29 +0000 (10:06 +0200)
Change-Id: I47bc3235431650d786b6798b14b500b62d7addd4
Reviewed-on: http://gerrit.tine20.com/customers/3184
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Calendar/Convert/Event/VCalendar/GenericTest.php
tests/tine20/Calendar/Frontend/iMIPTest.php
tine20/Calendar/Controller/MSEventFacade.php
tine20/Calendar/Convert/Event/Json.php
tine20/Calendar/Export/Abstract.php
tine20/Calendar/Frontend/iMIP.php
tine20/Calendar/Model/Attender.php

index f8bd0fc..2f2c991 100644 (file)
@@ -525,9 +525,9 @@ class Calendar_Convert_Event_VCalendar_GenericTest extends PHPUnit_Framework_Tes
         $this->assertContains('TZNAME:CET',          $vevent, $vevent);
         
     }
-    
+
     /**
-     * 
+     *
      * @depends testConvertToTine20Model
      */
     public function testConvertRepeatingEventFromTine20Model()
index 5fc7007..a6d56c5 100644 (file)
@@ -319,7 +319,7 @@ class Calendar_Frontend_iMIPTest extends TestCase
         
         $this->_iMIPFrontend->prepareComponent($iMIP);
         $this->_eventIdsToDelete[] = $iMIP->event->getId();
-        
+
         // assert external organizer
         $this->assertEquals('l.kneschke@caldav.org', $iMIP->event->organizer->email, 'wrong organizer');
         $this->assertTrue(empty($iMIP->event->organizer->account_id), 'organizer must not have an account');
@@ -329,6 +329,13 @@ class Calendar_Frontend_iMIPTest extends TestCase
         $this->assertTrue(!! $ownAttendee, 'own attendee missing');
         $this->assertEquals(5, count($iMIP->event->attendee), 'all attendee must be keeped');
         $this->assertEquals(Calendar_Model_Attender::STATUS_ACCEPTED, $ownAttendee->status, 'must be ACCEPTED');
+
+        // assert no status authkey for external attendee
+        foreach($iMIP->event->attendee as $attendee) {
+            if (!$attendee->user_id->account_id) {
+                $this->assertFalse(!!$attendee->user_id->status_authkey, 'authkey should be skipped');
+            }
+        }
         
         // assert REPLY message to organizer only
         $smtpConfig = Tinebase_Config::getInstance()->get(Tinebase_Config::SMTP);
@@ -428,7 +435,7 @@ class Calendar_Frontend_iMIPTest extends TestCase
         $result = $this->_iMIPFrontendMock->process($iMIP, Calendar_Model_Attender::STATUS_TENTATIVE);
         
         $event = $this->_iMIPFrontend->getExistingEvent($iMIP, true);
-        
+
         $attender = Calendar_Model_Attender::getOwnAttender($event->attendee);
         $this->assertEquals(Calendar_Model_Attender::STATUS_TENTATIVE, $attender->status);
     }
index 183cf0a..dc6475a 100644 (file)
@@ -763,7 +763,7 @@ class Calendar_Controller_MSEventFacade implements Tinebase_Controller_Record_In
             if (!array_key_exists($cacheId, self::$_attendeeEmailCache)) {
                 $this->_fillResolvedAttendeeCache($event);
                 
-                self::$_attendeeEmailCache[$cacheId] = !!$attender->getEmail();
+                self::$_attendeeEmailCache[$cacheId] = !!$attender->getEmail($event);
                 
                 // limit class cache to 100 entries
                 if (count(self::$_attendeeEmailCache) > 100) {
index 21bbecf..2fa3c55 100644 (file)
@@ -99,19 +99,11 @@ class Calendar_Convert_Event_Json extends Tinebase_Convert_Json
         if (Setup_Controller::getInstance()->isFilesystemAvailable()) {
             Tinebase_FileSystem_RecordAttachments::getInstance()->getMultipleAttachmentsOfRecords($_records);
         }
-        
+
         Calendar_Model_Attender::resolveAttendee($_records->attendee, TRUE, $_records);
         Calendar_Convert_Event_Json::resolveRrule($_records);
         Calendar_Controller_Event::getInstance()->getAlarms($_records);
         
-        self::resolveMultipleIdFields($_records, array(
-            'Addressbook_Model_Contact' => array(
-                'options' => array('ignoreAcl' => TRUE),
-                'fields'  => array('organizer'),
-            ),
-            'recursive' => array('attachments' => 'Tinebase_Model_Tree_Node')
-        ));
-        
         Calendar_Model_Rrule::mergeAndRemoveNonMatchingRecurrences($_records, $_filter);
         $_records->sortByPagination($_pagination);
         
index e01c5a3..6359b5b 100644 (file)
@@ -84,13 +84,12 @@ abstract class Calendar_Export_Abstract extends Tinebase_Export_Spreadsheet_Ods
     protected function _resolveRecords(Tinebase_Record_RecordSet $_records)
     {
         Calendar_Model_Attender::resolveAttendee($_records->attendee, false, $_records);
-        $organizers = Addressbook_Controller_Contact::getInstance()->getMultiple(array_unique($_records->organizer), TRUE);
 
         foreach($_records as $record) {
             $attendee = $record->attendee->getName();
             $record->attendee = implode('& ', $attendee);
 
-            $organizer = $organizers->getById($record->organizer);
+            $organizer = $record->resolveOrganizer();
             if ($organizer) {
                 $record->organizer = $organizer->n_fileas;
             }
index 1a3e7eb..d820e17 100644 (file)
@@ -331,7 +331,7 @@ class Calendar_Frontend_iMIP
             )));
 
             $event = $events->filter(Tinebase_Model_Grants::GRANT_READ, TRUE)->getFirstRecord();
-            Calendar_Model_Attender::resolveAttendee($event['attendee']);
+            Calendar_Model_Attender::resolveAttendee($event['attendee'], true, $event);
 
             $_iMIP->existing_event = $event;
         }
index 5150391..c462f98 100644 (file)
@@ -126,9 +126,9 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
      * 
      * @return string
      */
-    public function getEmail()
+    public function getEmail($event=null)
     {
-        $resolvedUser = $this->getResolvedUser();
+        $resolvedUser = $this->getResolvedUser($event);
         if (! $resolvedUser instanceof Tinebase_Record_Abstract) {
             return '';
         }
@@ -183,11 +183,11 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
      * 
      * @return Tinebase_Record_Abstract
      */
-    public function getResolvedUser()
+    public function getResolvedUser($event=null)
     {
         $clone = clone $this;
         $resolvable = new Tinebase_Record_RecordSet('Calendar_Model_Attender', array($clone));
-        self::resolveAttendee($resolvable);
+        self::resolveAttendee($resolvable, true, $event);
         
         if ($this->user_type === self::USERTYPE_RESOURCE) {
             $resource = $clone->user_id;
@@ -879,11 +879,15 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
         }
         
         $eventAttendee = $eventAttendees instanceof Tinebase_Record_RecordSet ? array($eventAttendees) : $eventAttendees;
-        $events = $_events instanceof Tinebase_Record_Abstract ? array($_events) : $_events;
-        
+
+
+        $events = !$_events ? array() : $_events;
+        $events = $_events instanceof Tinebase_Record_Abstract ? array($events) : $events;
+        $events = is_array($events) ? new Tinebase_Record_RecordSet('Calendar_Model_Event', $events) : $events;
+
         // set containing all attendee
         $allAttendee = new Tinebase_Record_RecordSet('Calendar_Model_Attender');
-        $typeMap = array();
+        $typeMap = array(self::USERTYPE_USER => array(), self::USERTYPE_GROUPMEMBER => array());
         
         // build type map 
         foreach ($eventAttendee as $attendee) {
@@ -912,15 +916,26 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
                 Tinebase_Container::getInstance()->getGrantsOfRecords($allAttendee, Tinebase_Core::getUser(), 'displaycontainer_id');
             }
         }
-        
+
+        $organizerIds = array();
+        foreach($events as $event) {
+            $organizerId = $event->organizer;
+            if (! $organizerId instanceof Addressbook_Model_Contact) {
+                $organizerIds[] = $organizerId;
+            }
+        }
+
+        $contactIds = array_merge($typeMap[self::USERTYPE_USER], $typeMap[self::USERTYPE_GROUPMEMBER], $organizerIds);
+        $resolveCf = Addressbook_Controller_Contact::getInstance()->resolveCustomfields(FALSE);
+        $contacts = Addressbook_Controller_Contact::getInstance()->getMultiple(array_unique($contactIds));
+        Addressbook_Controller_Contact::getInstance()->resolveCustomfields($resolveCf);
+
         // get all user_id entries
         foreach ($typeMap as $type => $ids) {
             switch ($type) {
                 case self::USERTYPE_USER:
                 case self::USERTYPE_GROUPMEMBER:
-                    $resolveCf = Addressbook_Controller_Contact::getInstance()->resolveCustomfields(FALSE);
-                    $typeMap[$type] = Addressbook_Controller_Contact::getInstance()->getMultiple(array_unique($ids), TRUE);
-                    Addressbook_Controller_Contact::getInstance()->resolveCustomfields($resolveCf);
+                    $typeMap[$type] = $contacts;
                     break;
                 case self::USERTYPE_GROUP:
                 case Calendar_Model_AttenderFilter::USERTYPE_MEMBEROF:
@@ -938,6 +953,12 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
         }
         
         // sort entries in
+        foreach($events as $event) {
+            if ($event->organizer && ! $event->organizer instanceof Addressbook_Model_Contact) {
+                $event->organizer = $contacts->getById($event->organizer);
+            }
+        }
+
         foreach ($eventAttendee as $attendee) {
             foreach ($attendee as $attender) {
                 if ($attender->user_id instanceof Tinebase_Record_Abstract) {
@@ -974,19 +995,24 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
         
         
         foreach ($eventAttendee as $idx => $attendee) {
-            $event = is_array($events) && (isset($events[$idx]) || array_key_exists($idx, $events)) ? $events[$idx] : NULL;
-            
             foreach ($attendee as $attender) {
+                $event = $events->getById($attender->cal_event_id);
+
                 // keep authkey if user has editGrant to displaycontainer
-                if (isset($attender['displaycontainer_id']) && !is_scalar($attender['displaycontainer_id']) && (isset($attender['displaycontainer_id']['account_grants'][Tinebase_Model_Grants::GRANT_EDIT]) || array_key_exists(Tinebase_Model_Grants::GRANT_EDIT, $attender['displaycontainer_id']['account_grants'])) &&  $attender['displaycontainer_id']['account_grants'][Tinebase_Model_Grants::GRANT_EDIT]) {
+                if (isset($attender['displaycontainer_id'])
+                    && !is_scalar($attender['displaycontainer_id'])
+                    && isset($attender['displaycontainer_id']['account_grants'][Tinebase_Model_Grants::GRANT_EDIT])
+                    && $attender['displaycontainer_id']['account_grants'][Tinebase_Model_Grants::GRANT_EDIT]
+                ) {
                     continue;
                 }
-                
+
                 // keep authkey if attender is a contact (no account) and user has editGrant for event
                 if ($attender->user_type == self::USERTYPE_USER
                     && $attender->user_id instanceof Tinebase_Record_Abstract
                     && (!$attender->user_id->has('account_id') || !$attender->user_id->account_id)
                     && (!$event || $event->{Tinebase_Model_Grants::GRANT_EDIT})
+                    && (!$event || !$event->hasExternalOrganizer())
                 ) {
                     continue;
                 }