7 * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
8 * @copyright Copyright (c) 2011-2015 Metaways Infosystems GmbH (http://www.metaways.de)
9 * @author Lars Kneschke <l.kneschke@metaways.de>
13 * webdav Server class with handle() function
18 class Tinebase_Server_WebDAV extends Tinebase_Server_Abstract implements Tinebase_Server_Interface
20 const REQUEST_TYPE = 'WebDAV';
23 * @var \Sabre\DAV\Server
25 protected static $_server;
29 * @see Tinebase_Server_Interface::handle()
31 public function handle(\Zend\Http\Request $request = null, $body = null)
33 $this->_request = $request instanceof \Zend\Http\Request ? $request : Tinebase_Core::get(Tinebase_Core::REQUEST);
36 } else if ($this->_request instanceof \Zend\Http\Request) {
37 $this->_body = fopen('php://temp', 'r+');
38 fwrite($this->_body, $request->getContent());
43 list($loginName, $password) = $this->_getAuthData($this->_request);
45 } catch (Tinebase_Exception_NotFound $tenf) {
46 header('WWW-Authenticate: Basic realm="WebDAV for Tine 2.0"');
47 header('HTTP/1.1 401 Unauthorized');
52 if (Tinebase_Core::isLogLevel(Zend_Log::INFO))
53 Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ .' is CalDav, CardDAV or WebDAV request.');
55 Tinebase_Core::initFramework();
57 if (null !== ($denyList = Tinebase_Config::getInstance()->get(Tinebase_Config::DENY_WEBDAV_CLIENT_LIST)) &&
58 is_array($denyList)) {
59 foreach ($denyList as $deny) {
60 if (preg_match($deny, $_SERVER['HTTP_USER_AGENT'])) {
61 header('HTTP/1.1 420 Policy Not Fulfilled User Agent Not Accepted');
67 if (Tinebase_Controller::getInstance()->login(
73 header('WWW-Authenticate: Basic realm="WebDAV for Tine 2.0"');
74 header('HTTP/1.1 401 Unauthorized');
79 if (Tinebase_Core::isLogLevel(Zend_Log::INFO))
80 Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ .' requestUri:' . $this->_request->getRequestUri());
82 self::$_server = new \Sabre\DAV\Server(new Tinebase_WebDav_Root());
83 \Sabre\DAV\Server::$exposeVersion = false;
85 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
86 self::$_server->debugExceptions = true;
87 $contentType = self::$_server->httpRequest->getHeader('Content-Type');
88 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " requestContentType: " . $contentType);
90 if (stripos($contentType, 'text') === 0 || stripos($contentType, '/xml') !== false) {
91 // NOTE inputstream can not be rewinded
92 $debugStream = fopen('php://temp','r+');
93 stream_copy_to_stream($this->_body, $debugStream);
95 $this->_body = $debugStream;
97 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " <<< *DAV request\n" . stream_get_contents($this->_body));
100 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " <<< *DAV request\n -- BINARY DATA --");
104 self::$_server->httpRequest->setBody($this->_body);
107 self::$_server->setBaseUri($this->_request->getBaseUrl() . '/');
109 $tempDir = Tinebase_Core::getTempDir();
110 if (!empty($tempDir)) {
111 self::$_server->addPlugin(
112 new \Sabre\DAV\Locks\Plugin(new \Sabre\DAV\Locks\Backend\File($tempDir . '/webdav.lock'))
116 self::$_server->addPlugin(
117 new \Sabre\DAV\Auth\Plugin(new Tinebase_WebDav_Auth(), null)
120 $aclPlugin = new \Sabre\DAVACL\Plugin();
121 $aclPlugin->defaultUsernamePath = Tinebase_WebDav_PrincipalBackend::PREFIX_USERS;
122 $aclPlugin->principalCollectionSet = array (Tinebase_WebDav_PrincipalBackend::PREFIX_USERS, Tinebase_WebDav_PrincipalBackend::PREFIX_GROUPS, Tinebase_WebDav_PrincipalBackend::PREFIX_INTELLIGROUPS);
124 $aclPlugin->principalSearchPropertySet = array(
125 '{DAV:}displayname' => 'Display name',
126 '{' . \Sabre\DAV\Server::NS_SABREDAV . '}email-address' => 'Email address',
127 '{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}email-address-set' => 'Email addresses',
128 '{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}first-name' => 'First name',
129 '{' . \Sabre\CalDAV\Plugin::NS_CALENDARSERVER . '}last-name' => 'Last name',
130 '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}calendar-user-address-set' => 'Calendar user address set',
131 '{' . \Sabre\CalDAV\Plugin::NS_CALDAV . '}calendar-user-type' => 'Calendar user type'
134 self::$_server->addPlugin($aclPlugin);
136 self::$_server->addPlugin(new \Sabre\CardDAV\Plugin());
137 self::$_server->addPlugin(new Calendar_Frontend_CalDAV_SpeedUpPlugin); // this plugin must be loaded before CalDAV plugin
138 self::$_server->addPlugin(new Calendar_Frontend_CalDAV_FixMultiGet404Plugin()); // replacement for new \Sabre\CalDAV\Plugin());
139 self::$_server->addPlugin(new \Sabre\CalDAV\SharingPlugin());
140 self::$_server->addPlugin(new Calendar_Frontend_CalDAV_PluginAutoSchedule());
141 self::$_server->addPlugin(new Calendar_Frontend_CalDAV_PluginDefaultAlarms());
142 self::$_server->addPlugin(new Calendar_Frontend_CalDAV_PluginManagedAttachments());
143 self::$_server->addPlugin(new Calendar_Frontend_CalDAV_PluginPrivateEvents());
144 self::$_server->addPlugin(new Tinebase_WebDav_Plugin_Inverse());
145 self::$_server->addPlugin(new Tinebase_WebDav_Plugin_OwnCloud());
146 self::$_server->addPlugin(new Tinebase_WebDav_Plugin_PrincipalSearch());
147 self::$_server->addPlugin(new Tinebase_WebDav_Plugin_ExpandedPropertiesReport());
148 self::$_server->addPlugin(new \Sabre\DAV\Browser\Plugin());
149 self::$_server->addPlugin(new Tinebase_WebDav_Plugin_SyncToken());
150 self::$_server->addPlugin(new Calendar_Frontend_CalDAV_SpeedUpPropfindPlugin());
152 $contentType = self::$_server->httpRequest->getHeader('Content-Type');
153 $logOutput = Tinebase_Core::isLogLevel(Zend_Log::DEBUG) && (stripos($contentType, 'text') === 0 || stripos($contentType, '/xml') !== false);
159 self::$_server->exec();
162 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " >>> *DAV response:\n" . ob_get_contents());
166 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " <<< *DAV response\n -- BINARY DATA --");
169 Tinebase_Controller::getInstance()->logout($this->_request->getServer('REMOTE_ADDR'));
173 * helper to return request
175 * @return Sabre\HTTP\Request
177 public static function getRequest()
179 return self::$_server ? self::$_server->httpRequest : new Sabre\HTTP\Request();
183 * helper to return response
185 * @return Sabre\HTTP\Response
187 public static function getResponse()
189 return self::$_server ? self::$_server->httpResponse : new Sabre\HTTP\Response();
193 * returns request method
197 public function getRequestMethod()
199 return self::getRequest()->getMethod();