/**
  * test testGetProperties method
  */
 public function testGetProperties()
 {
     $body = '<?xml version="1.0" encoding="utf-8"?>
              <propfind xmlns="DAV:">
                 <prop>
                     <default-alarm-vevent-date xmlns="urn:ietf:params:xml:ns:caldav"/>
                     <default-alarm-vevent-datetime xmlns="urn:ietf:params:xml:ns:caldav"/>
                     <default-alarm-vtodo-date xmlns="urn:ietf:params:xml:ns:caldav"/>
                     <default-alarm-vtodo-datetime xmlns="urn:ietf:params:xml:ns:caldav"/>
                 </prop>
              </propfind>';
     $request = new Sabre\HTTP\Request(array('REQUEST_METHOD' => 'PROPFIND', 'REQUEST_URI' => '/calendars/' . Tinebase_Core::getUser()->contact_id, 'HTTP_DEPTH' => '0'));
     $request->setBody($body);
     $this->server->httpRequest = $request;
     $this->server->exec();
     //var_dump($this->response->body);
     $this->assertEquals('HTTP/1.1 207 Multi-Status', $this->response->status);
     $responseDoc = new DOMDocument();
     $responseDoc->loadXML($this->response->body);
     //$responseDoc->formatOutput = true; echo $responseDoc->saveXML();
     $xpath = new DomXPath($responseDoc);
     $xpath->registerNamespace('cal', 'urn:ietf:params:xml:ns:caldav');
     $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vevent-datetime');
     $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
     $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vevent-date');
     $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
     $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vtodo-datetime');
     $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
     $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vtodo-date');
     $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
 }
 public function testExpandProperty()
 {
     $list = Tinebase_Group::getInstance()->getGroupById(Tinebase_Core::getUser()->accountPrimaryGroup);
     $body = '<?xml version="1.0" encoding="UTF-8"?>
             <A:expand-property xmlns:A="DAV:">
               <A:property name="expanded-group-member-set" namespace="http://calendarserver.org/ns/">
                 <A:property name="last-name" namespace="http://calendarserver.org/ns/"/>
                 <A:property name="principal-URL" namespace="DAV:"/>
                 <A:property name="calendar-user-type" namespace="urn:ietf:params:xml:ns:caldav"/>
                 <A:property name="calendar-user-address-set" namespace="urn:ietf:params:xml:ns:caldav"/>
                 <A:property name="first-name" namespace="http://calendarserver.org/ns/"/>
                 <A:property name="record-type" namespace="http://calendarserver.org/ns/"/>
                 <A:property name="displayname" namespace="DAV:"/>
               </A:property>
             </A:expand-property>';
     $request = new Sabre\HTTP\Request(array('REQUEST_METHOD' => 'REPORT', 'REQUEST_URI' => '/principals/groups/' . $list->list_id . '/'));
     $request->setBody($body);
     $this->server->httpRequest = $request;
     $this->server->exec();
     $responseDoc = new DOMDocument();
     $responseDoc->loadXML($this->response->body);
     #$responseDoc->formatOutput = true; echo $responseDoc->saveXML();
     $xpath = new DomXPath($responseDoc);
     $xpath->registerNamespace('cal', 'urn:ietf:params:xml:ns:caldav');
     $xpath->registerNamespace('cs', 'http://calendarserver.org/ns/');
     $nodes = $xpath->query('///cs:expanded-group-member-set/d:response/d:href[text()="/principals/groups/' . $list->list_id . '/"]');
     $this->assertEquals(1, $nodes->length, 'group itself (not shown by client) is missing');
     $nodes = $xpath->query('///cs:expanded-group-member-set/d:response/d:href[text()="/principals/intelligroups/' . $list->list_id . '/"]');
     $this->assertEquals(1, $nodes->length, 'intelligroup (to keep group itself) is missing');
     $nodes = $xpath->query('///cs:expanded-group-member-set/d:response/d:href[text()="/principals/users/' . Tinebase_Core::getUser()->contact_id . '/"]');
     $this->assertEquals(1, $nodes->length, 'user is missing');
 }
 /**
  * (non-PHPdoc)
  * @see Sabre\DAV\Collection::getChild()
  */
 public function getChild($_name)
 {
     $eventId = $_name instanceof Tinebase_Record_Interface ? $_name->getId() : $this->_getIdFromName($_name);
     // check if child exists in calendarQuery cache
     if ($this->_calendarQueryCache && isset($this->_calendarQueryCache[$eventId])) {
         $child = $this->_calendarQueryCache[$eventId];
         // remove entries from cache / they will not be used anymore
         unset($this->_calendarQueryCache[$eventId]);
         if (empty($this->_calendarQueryCache)) {
             $this->_calendarQueryCache = null;
         }
         return $child;
     }
     $modelName = $this->_application->name . '_Model_' . $this->_model;
     if ($_name instanceof $modelName) {
         $object = $_name;
     } else {
         $filterClass = $this->_application->name . '_Model_' . $this->_model . 'Filter';
         $filter = new $filterClass(array(array('field' => 'container_id', 'operator' => 'equals', 'value' => $this->_container->getId()), array('condition' => 'OR', 'filters' => array(array('field' => 'id', 'operator' => 'equals', 'value' => $eventId), array('field' => 'uid', 'operator' => 'equals', 'value' => $eventId)))));
         $object = $this->_getController()->search($filter, null, false, false, 'sync')->getFirstRecord();
         if ($object == null) {
             throw new Sabre\DAV\Exception\NotFound('Object not found');
         }
     }
     $httpRequest = new Sabre\HTTP\Request();
     // lie about existence of event of request is a PUT request from an ATTENDEE for an already existing event
     // to prevent ugly (and not helpful) error messages on the client
     if (isset($_SERVER['REQUEST_METHOD']) && $httpRequest->getMethod() == 'PUT' && $httpRequest->getHeader('If-None-Match') === '*') {
         if ($object->organizer != Tinebase_Core::getUser()->contact_id && Calendar_Model_Attender::getOwnAttender($object->attendee) !== null) {
             throw new Sabre\DAV\Exception\NotFound('Object not found');
         }
     }
     $objectClass = $this->_application->name . '_Frontend_WebDAV_' . $this->_model;
     return new $objectClass($this->_container, $object);
 }
 /**
  * test testGetProperties method
  */
 public function testGetProperties()
 {
     $body = '<?xml version="1.0" encoding="utf-8"?>
              <propfind xmlns="DAV:">
                 <prop>
                     <getlastmodified xmlns="DAV:"/>
                     <getcontentlength xmlns="DAV:"/>
                     <resourcetype xmlns="DAV:"/>
                     <getetag xmlns="DAV:"/>
                     <id xmlns="http://owncloud.org/ns"/>
                 </prop>
              </propfind>';
     $request = new Sabre\HTTP\Request(array('REQUEST_METHOD' => 'PROPFIND', 'REQUEST_URI' => '/remote.php/webdav/' . Tinebase_Core::getUser()->accountDisplayName, 'HTTP_DEPTH' => '0'));
     $request->setBody($body);
     $this->server->httpRequest = $request;
     $this->server->exec();
     //var_dump($this->response->body);
     $this->assertEquals('HTTP/1.1 207 Multi-Status', $this->response->status);
     $responseDoc = new DOMDocument();
     $responseDoc->loadXML($this->response->body);
     //$responseDoc->formatOutput = true; echo $responseDoc->saveXML();
     $xpath = new DomXPath($responseDoc);
     $xpath->registerNamespace('owncloud', 'http://owncloud.org/ns');
     $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/owncloud:id');
     $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
 }
Beispiel #5
0
 function testDefaultInputStream()
 {
     $h = fopen('php://memory', 'r+');
     fwrite($h, 'testing');
     rewind($h);
     $previousValue = Request::$defaultInputStream;
     Request::$defaultInputStream = $h;
     $this->assertEquals('testing', $this->request->getBody(true), 'We didn\'t get our testbody back');
     Request::$defaultInputStream = $previousValue;
 }
Beispiel #6
0
    /**
     * Returns the HTTP Prefer header information.
     *
     * The prefer header is defined in:
     * http://tools.ietf.org/html/draft-snell-http-prefer-14
     *
     * This method will return an array with options.
     *
     * Currently, the following options may be returned:
     *  [
     *      'return-asynch'         => true,
     *      'return-minimal'        => true,
     *      'return-representation' => true,
     *      'wait'                  => 30,
     *      'strict'                => true,
     *      'lenient'               => true,
     *  ]
     *
     * This method also supports the Brief header, and will also return
     * 'return-minimal' if the brief header was set to 't'.
     *
     * For the boolean options, false will be returned if the headers are not
     * specified. For the integer options it will be 'null'.
     *
     * @return array
     */
    function getHTTPPrefer() {

        $result = [
            // can be true or false
            'respond-async' => false,
            // Could be set to 'representation' or 'minimal'.
            'return'        => null,
            // Used as a timeout, is usually a number.
            'wait'          => null,
            // can be 'strict' or 'lenient'.
            'handling'      => false,
        ];

        if ($prefer = $this->httpRequest->getHeader('Prefer')) {

            $result = array_merge(
                $result,
                \Sabre\HTTP\parsePrefer($prefer)
            );

        } elseif ($this->httpRequest->getHeader('Brief') == 't') {
            $result['return'] = 'minimal';
        }

        return $result;

    }
Beispiel #7
0
 /**
  * Returns the HTTP Prefer header information.
  *
  * The prefer header is defined in:
  * http://tools.ietf.org/html/draft-snell-http-prefer-14
  *
  * This method will return an array with options.
  *
  * Currently, the following options may be returned:
  *  [
  *      'return-asynch'         => true,
  *      'return-minimal'        => true,
  *      'return-representation' => true,
  *      'wait'                  => 30,
  *      'strict'                => true,
  *      'lenient'               => true,
  *  ]
  *
  * This method also supports the Brief header, and will also return
  * 'return-minimal' if the brief header was set to 't'.
  *
  * For the boolean options, false will be returned if the headers are not
  * specified. For the integer options it will be 'null'.
  *
  * @return array
  */
 function getHTTPPrefer()
 {
     $result = ['return-asynch' => false, 'return-minimal' => false, 'return-representation' => false, 'wait' => null, 'strict' => false, 'lenient' => false];
     if ($prefer = $this->httpRequest->getHeader('Prefer')) {
         $parameters = array_map('trim', explode(',', $prefer));
         foreach ($parameters as $parameter) {
             // Right now our regex only supports the tokens actually
             // specified in the draft. We may need to expand this if new
             // tokens get registered.
             if (!preg_match('/^(?P<token>[a-z0-9-]+)(?:=(?P<value>[0-9]+))?$/', $parameter, $matches)) {
                 continue;
             }
             switch ($matches['token']) {
                 case 'return-asynch':
                 case 'return-minimal':
                 case 'return-representation':
                 case 'strict':
                 case 'lenient':
                     $result[$matches['token']] = true;
                     break;
                 case 'wait':
                     $result[$matches['token']] = $matches['value'];
                     break;
             }
         }
     } elseif ($this->httpRequest->getHeader('Brief') == 't') {
         $result['return-minimal'] = true;
     }
     return $result;
 }
Beispiel #8
0
 /**
  * Returns the HTTP Prefer header information.
  *
  * The prefer header is defined in:
  * http://tools.ietf.org/html/draft-snell-http-prefer-14
  *
  * This method will return an array with options.
  *
  * Currently, the following options may be returned:
  *  [
  *      'return-asynch'         => true,
  *      'return-minimal'        => true,
  *      'return-representation' => true,
  *      'wait'                  => 30,
  *      'strict'                => true,
  *      'lenient'               => true,
  *  ]
  *
  * This method also supports the Brief header, and will also return
  * 'return-minimal' if the brief header was set to 't'.
  *
  * For the boolean options, false will be returned if the headers are not
  * specified. For the integer options it will be 'null'.
  *
  * @return array
  */
 function getHTTPPrefer()
 {
     $result = ['respond-async' => false, 'return' => null, 'wait' => null, 'handling' => false];
     if ($prefer = $this->httpRequest->getHeader('Prefer')) {
         $result = array_merge($result, \Sabre\HTTP\parsePrefer($prefer));
     } elseif ($this->httpRequest->getHeader('Brief') == 't') {
         $result['return'] = 'minimal';
     }
     return $result;
 }
 /**
  * test testGetProperties method
  */
 public function testGetProperties()
 {
     $body = '<?xml version="1.0" encoding="utf-8"?>
              <A:calendarserver-principal-search xmlns:A="http://calendarserver.org/ns/" context="attendee">
                 <A:search-token>Administrators</A:search-token>
                 <A:limit>
                     <A:nresults>50</A:nresults>
                 </A:limit>
                 <B:prop xmlns:B="DAV:">
                     <C:calendar-user-address-set xmlns:C="urn:ietf:params:xml:ns:caldav"/>
                     <C:calendar-user-type xmlns:C="urn:ietf:params:xml:ns:caldav"/>
                     <A:record-type/>
                     <A:first-name/>
                     <A:last-name/>
                 </B:prop>
             </A:calendarserver-principal-search>';
     $request = new Sabre\HTTP\Request(array('REQUEST_METHOD' => 'REPORT', 'REQUEST_URI' => '/principals'));
     $request->setBody($body);
     $this->server->httpRequest = $request;
     $this->server->exec();
     //var_dump($this->response->body);
     $this->assertEquals('HTTP/1.1 207 Multi-Status', $this->response->status);
     $responseDoc = new DOMDocument();
     $responseDoc->loadXML($this->response->body);
     #$responseDoc->formatOutput = true; echo $responseDoc->saveXML();
     $xpath = new DomXPath($responseDoc);
     $xpath->registerNamespace('cal', 'urn:ietf:params:xml:ns:caldav');
     $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:calendar-user-address-set');
     $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
     $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:calendar-user-type');
     $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     $this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
     #$nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vtodo-datetime');
     #$this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     #$this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
     #$nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:default-alarm-vtodo-date');
     #$this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     #$this->assertNotEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
 }
 /**
  *
  */
 public function process()
 {
     $this->emit('process:before', [['request' => $this->httpRequest]]);
     // set Content Security Policy and CORS headers
     $this->httpResponse->addHeader('Content-Security-Policy', "default-src *");
     $this->httpResponse->addHeader('X-Content-Security-Policy', "default-src *");
     if ($this->httpRequest->hasHeader('Origin')) {
         // TODO: allow to configure allowed origins
         $this->httpResponse->addHeader('Access-Control-Allow-Origin', "*");
     }
     // FIXME: respond to OPTIONS requests directly and without validation
     if ($this->httpRequest->getMethod() == 'OPTIONS') {
         $this->httpResponse->addHeader('Access-Control-Request-Method', 'GET, POST, OPTIONS');
         $this->httpResponse->addHeader('Access-Control-Allow-Headers', $this->httpRequest->getHeader('Access-Control-Request-Headers'));
         $this->httpResponse->setStatus(204);
         $this->sapi->sendResponse($this->httpResponse);
         return;
     }
     // extract route from request (jmap, auth|.well-known/jmap, upload)
     if ($route = $this->getRouteMatch($this->httpRequest->getPath())) {
         try {
             call_user_func($this->routes[$route], $this->httpRequest, $this->httpResponse);
         } catch (\RuntimeException $e) {
             if ($e instanceof Exception\ProcessorException) {
                 $this->httpResponse->setStatus($e->getStatusCode());
             } else {
                 $this->httpResponse->setStatus(500);
             }
             $this->logger->err(strval($e));
             $this->emit('process:error', [['request' => $this->httpRequest, 'exception' => $e]]);
         }
     } else {
         // TODO: throw invalid route error
         $this->httpResponse->setStatus(404);
     }
     $this->emit('process:after', [['response' => $this->httpResponse]]);
     $this->sapi->sendResponse($this->httpResponse);
 }
 /**
  * test sync-collection request
  */
 public function testSyncCollection()
 {
     $body = '<?xml version="1.0" encoding="UTF-8"?>
             <A:sync-collection xmlns:A="DAV:">
                 <A:sync-token>http://tine20.net/ns/sync/0</A:sync-token>
                 <A:sync-level>1</A:sync-level>
                 <A:prop>
                     <A:getetag/>
                     <A:getcontenttype/>
                 </A:prop>
             </A:sync-collection>';
     $request = new Sabre\HTTP\Request(array('REQUEST_METHOD' => 'REPORT', 'REQUEST_URI' => '/calendars/' . Tinebase_Core::getUser()->contact_id . '/' . $this->objects['initialContainer']->id, 'HTTP_DEPTH' => '1'));
     $request->setBody($body);
     $this->server->httpRequest = $request;
     $this->server->exec();
     $this->assertEquals('HTTP/1.1 207 Multi-Status', $this->response->status);
     $this->assertContains('<d:sync-token>http://tine20.net/ns/sync/5</d:sync-token></d:multistatus>', $this->response->body);
     //check that we only got 2 responses, so no reoccuring events!
     $this->assertEquals(2, preg_match_all('/<d:response>/', $this->response->body, $m));
 }
 /**
  * login from HTTP post 
  * 
  * redirects the tine main screen if authentication is successful
  * otherwise redirects back to login url 
  */
 public function loginFromPost($username, $password)
 {
     Tinebase_Core::startCoreSession();
     if (!empty($username)) {
         // try to login user
         $success = Tinebase_Controller::getInstance()->login($username, $password, Tinebase_Core::get(Tinebase_Core::REQUEST), self::REQUEST_TYPE) === TRUE;
     } else {
         $success = FALSE;
     }
     if ($success === TRUE) {
         $this->_setJsonKeyCookie();
         $ccAdapter = Tinebase_Auth_CredentialCache::getInstance()->getCacheAdapter();
         if (Tinebase_Core::isRegistered(Tinebase_Core::USERCREDENTIALCACHE)) {
             $ccAdapter->setCache(Tinebase_Core::getUserCredentialCache());
         } else {
             Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Something went wrong with the CredentialCache / no CC registered.');
             $success = FALSE;
             $ccAdapter->resetCache();
         }
     }
     $request = new Sabre\HTTP\Request();
     $redirectUrl = str_replace('index.php', '', $request->getAbsoluteUri());
     // authentication failed
     if ($success !== TRUE) {
         $_SESSION = array();
         Tinebase_Session::destroyAndRemoveCookie();
         // redirect back to loginurl if needed
         $redirectUrl = Tinebase_Config::getInstance()->get(Tinebase_Config::REDIRECTURL, $redirectUrl);
     }
     // load the client with GET
     header('Location: ' . $redirectUrl);
 }
 /**
  * returns protocol + hostname
  * 
  * @return string
  */
 public static function getHostname()
 {
     $hostname = self::get('HOSTNAME');
     if (!$hostname) {
         $request = new Sabre\HTTP\Request();
         $hostname = strlen($request->getUri()) > 1 ? str_replace($request->getUri(), '', $request->getAbsoluteUri()) : $request->getAbsoluteUri();
         self::set('HOSTNAME', $hostname);
     }
     return $hostname;
 }
 /**
  * test testGetProperties method
  */
 public function testGetPropertiesSharedUserPrincipal()
 {
     $body = '<?xml version="1.0" encoding="UTF-8"?>
         <A:propfind xmlns:A="DAV:">
           <A:prop>
             <B:calendar-home-set xmlns:B="urn:ietf:params:xml:ns:caldav"/>
             <B:calendar-user-address-set xmlns:B="urn:ietf:params:xml:ns:caldav"/>
             <A:current-user-principal/>
             <A:displayname/>
             <C:dropbox-home-URL xmlns:C="http://calendarserver.org/ns/"/>
             <C:email-address-set xmlns:C="http://calendarserver.org/ns/"/>
             <C:notification-URL xmlns:C="http://calendarserver.org/ns/"/>
             <A:principal-collection-set/>
             <A:principal-URL/>
             <A:resource-id/>
             <B:schedule-inbox-URL xmlns:B="urn:ietf:params:xml:ns:caldav"/>
             <B:schedule-outbox-URL xmlns:B="urn:ietf:params:xml:ns:caldav"/>
             <A:supported-report-set/>
           </A:prop>
         </A:propfind>';
     $request = new Sabre\HTTP\Request(array('REQUEST_METHOD' => 'PROPFIND', 'REQUEST_URI' => '/' . Tinebase_WebDav_PrincipalBackend::PREFIX_USERS . '/' . Tinebase_WebDav_PrincipalBackend::SHARED, 'HTTP_BRIEF' => 't', 'HTTP_DEPTH' => '0'));
     $request->setBody($body);
     $this->server->httpRequest = $request;
     $this->server->exec();
     //var_dump($this->response->body);
     $this->assertEquals('HTTP/1.1 207 Multi-Status', $this->response->status);
     $responseDoc = new DOMDocument();
     $responseDoc->loadXML($this->response->body);
     //$responseDoc->formatOutput = true; echo $responseDoc->saveXML();
     $xpath = new DomXPath($responseDoc);
     $xpath->registerNamespace('cal', 'urn:ietf:params:xml:ns:caldav');
     $xpath->registerNamespace('cs', 'http://calendarserver.org/ns/');
     $xpath->registerNamespace('d', 'DAV');
     $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/cal:calendar-home-set');
     $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     #$this->assertEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
     $nodes = $xpath->query('//d:multistatus/d:response/d:propstat/d:prop/d:principal-URL');
     $this->assertEquals(1, $nodes->length, $responseDoc->saveXML());
     #$this->assertEmpty($nodes->item(0)->nodeValue, $responseDoc->saveXML());
 }
Beispiel #15
0
 /**
  * This method checks the main HTTP preconditions.
  *
  * Currently these are:
  *   * If-Match
  *   * If-None-Match
  *   * If-Modified-Since
  *   * If-Unmodified-Since
  *
  * The method will return true if all preconditions are met
  * The method will return false, or throw an exception if preconditions
  * failed. If false is returned the operation should be aborted, and
  * the appropriate HTTP response headers are already set.
  *
  * Normally this method will throw 412 Precondition Failed for failures
  * related to If-None-Match, If-Match and If-Unmodified Since. It will
  * set the status to 304 Not Modified for If-Modified_since.
  *
  * If the $handleAsGET argument is set to true, it will also return 304
  * Not Modified for failure of the If-None-Match precondition. This is the
  * desired behaviour for HTTP GET and HTTP HEAD requests.
  *
  * @param bool $handleAsGET
  * @return bool
  */
 public function checkPreconditions($handleAsGET = false)
 {
     $uri = $this->getRequestUri();
     $node = null;
     $lastMod = null;
     $etag = null;
     if ($ifMatch = $this->httpRequest->getHeader('If-Match')) {
         // If-Match contains an entity tag. Only if the entity-tag
         // matches we are allowed to make the request succeed.
         // If the entity-tag is '*' we are only allowed to make the
         // request succeed if a resource exists at that url.
         try {
             $node = $this->tree->getNodeForPath($uri);
         } catch (Exception\NotFound $e) {
             throw new Exception\PreconditionFailed('An If-Match header was specified and the resource did not exist', 'If-Match');
         }
         // Only need to check entity tags if they are not *
         if ($ifMatch !== '*') {
             // There can be multiple etags
             $ifMatch = explode(',', $ifMatch);
             $haveMatch = false;
             foreach ($ifMatch as $ifMatchItem) {
                 // Stripping any extra spaces
                 $ifMatchItem = trim($ifMatchItem, ' ');
                 $etag = $node->getETag();
                 if ($etag === $ifMatchItem) {
                     $haveMatch = true;
                 } else {
                     // Evolution has a bug where it sometimes prepends the "
                     // with a \. This is our workaround.
                     if (str_replace('\\"', '"', $ifMatchItem) === $etag) {
                         $haveMatch = true;
                     }
                 }
             }
             if (!$haveMatch) {
                 throw new Exception\PreconditionFailed('An If-Match header was specified, but none of the specified the ETags matched.', 'If-Match');
             }
         }
     }
     if ($ifNoneMatch = $this->httpRequest->getHeader('If-None-Match')) {
         // The If-None-Match header contains an etag.
         // Only if the ETag does not match the current ETag, the request will succeed
         // The header can also contain *, in which case the request
         // will only succeed if the entity does not exist at all.
         $nodeExists = true;
         if (!$node) {
             try {
                 $node = $this->tree->getNodeForPath($uri);
             } catch (Exception\NotFound $e) {
                 $nodeExists = false;
             }
         }
         if ($nodeExists) {
             $haveMatch = false;
             if ($ifNoneMatch === '*') {
                 $haveMatch = true;
             } else {
                 // There might be multiple etags
                 $ifNoneMatch = explode(',', $ifNoneMatch);
                 $etag = $node->getETag();
                 foreach ($ifNoneMatch as $ifNoneMatchItem) {
                     // Stripping any extra spaces
                     $ifNoneMatchItem = trim($ifNoneMatchItem, ' ');
                     if ($etag === $ifNoneMatchItem) {
                         $haveMatch = true;
                     }
                 }
             }
             if ($haveMatch) {
                 if ($handleAsGET) {
                     $this->httpResponse->sendStatus(304);
                     return false;
                 } else {
                     throw new Exception\PreconditionFailed('An If-None-Match header was specified, but the ETag matched (or * was specified).', 'If-None-Match');
                 }
             }
         }
     }
     if (!$ifNoneMatch && ($ifModifiedSince = $this->httpRequest->getHeader('If-Modified-Since'))) {
         // The If-Modified-Since header contains a date. We
         // will only return the entity if it has been changed since
         // that date. If it hasn't been changed, we return a 304
         // header
         // Note that this header only has to be checked if there was no If-None-Match header
         // as per the HTTP spec.
         $date = HTTP\Util::parseHTTPDate($ifModifiedSince);
         if ($date) {
             if (is_null($node)) {
                 $node = $this->tree->getNodeForPath($uri);
             }
             $lastMod = $node->getLastModified();
             if ($lastMod) {
                 $lastMod = new \DateTime('@' . $lastMod);
                 if ($lastMod <= $date) {
                     $this->httpResponse->sendStatus(304);
                     $this->httpResponse->setHeader('Last-Modified', HTTP\Util::toHTTPDate($lastMod));
                     return false;
                 }
             }
         }
     }
     if ($ifUnmodifiedSince = $this->httpRequest->getHeader('If-Unmodified-Since')) {
         // The If-Unmodified-Since will allow allow the request if the
         // entity has not changed since the specified date.
         $date = HTTP\Util::parseHTTPDate($ifUnmodifiedSince);
         // We must only check the date if it's valid
         if ($date) {
             if (is_null($node)) {
                 $node = $this->tree->getNodeForPath($uri);
             }
             $lastMod = $node->getLastModified();
             if ($lastMod) {
                 $lastMod = new \DateTime('@' . $lastMod);
                 if ($lastMod > $date) {
                     throw new Exception\PreconditionFailed('An If-Unmodified-Since header was specified, but the entity has been changed since the specified date.', 'If-Unmodified-Since');
                 }
             }
         }
     }
     return true;
 }
 /**
  * test userQuery method
  */
 public function testUserQuery()
 {
     $body = '<?xml version="1.0" encoding="UTF-8"?>
              <user-query xmlns="urn:inverse:params:xml:ns:inverse-dav">
                  <users match-name="' . Tinebase_Core::getUser()->accountFullName . '"/>
              </user-query>';
     $request = new Sabre\HTTP\Request(array('REQUEST_METHOD' => 'REPORT', 'REQUEST_URI' => '/calendars/' . Tinebase_Core::getUser()->contact_id . '/' . $this->objects['initialContainer']->id, 'HTTP_DEPTH' => '1'));
     $request->setBody($body);
     $this->server->httpRequest = $request;
     $this->server->exec();
     $this->assertEquals('HTTP/1.1 207 Multi-Status', $this->response->status);
     $this->assertContains('<displayName>' . Tinebase_Core::getUser()->accountDisplayName . '</displayName>', $this->response->body);
     $this->assertContains('<id>' . Tinebase_Core::getUser()->contact_id . '</id>', $this->response->body);
 }
 public function testDropBoxPut()
 {
     $event = $this->calDAVTests->testCreateEventWithInternalOrganizer();
     $request = new Sabre\HTTP\Request(array('REQUEST_METHOD' => 'PUT', 'REQUEST_URI' => '/calendars/' . Tinebase_Core::getUser()->contact_id . '/dropbox/' . $event->getRecord()->getId() . '.dropbox/agenda.txt'));
     $agenda = 'HELLO WORLD';
     $request->setBody($agenda);
     $this->server->httpRequest = $request;
     $this->server->exec();
     //         echo $this->response->body;
     $attachments = Tinebase_FileSystem_RecordAttachments::getInstance()->getRecordAttachments($event->getRecord());
     $this->assertEquals(1, $attachments->count());
     $this->assertEquals('agenda.txt', $attachments[0]->name);
 }