diff --git a/core/Bootstrap.php b/core/Bootstrap.php index 64c6f454b..371f7876e 100644 --- a/core/Bootstrap.php +++ b/core/Bootstrap.php @@ -173,7 +173,8 @@ protected function _initRouter() $route1 = new Zend_Controller_Router_Route( Zend_Registry::get('configGlobal')->webdav->path.'/:action/*', array( - 'controller' => 'webdav', + 'module' => 'webdav', + 'controller' => ':action', 'action' => ':action' ) ); diff --git a/core/controllers/AdminController.php b/core/controllers/AdminController.php index bc3038f4a..0cd90e936 100644 --- a/core/controllers/AdminController.php +++ b/core/controllers/AdminController.php @@ -79,20 +79,26 @@ function indexAction() switch (Zend_Registry::get('configDatabase')->database->adapter) { case 'PDO_MYSQL': - $this->Component->Utility->run_mysql_from_file(BASE_PATH.'/modules/'.$moduleName.'/database/mysql/'.$allModules[$moduleName]->version.'.sql', - Zend_Registry::get('configDatabase')->database->params->host, - Zend_Registry::get('configDatabase')->database->params->username, - Zend_Registry::get('configDatabase')->database->params->password, - Zend_Registry::get('configDatabase')->database->params->dbname, - Zend_Registry::get('configDatabase')->database->params->port); + if(file_exists(BASE_PATH.'/modules/'.$moduleName.'/database/mysql/'.$allModules[$moduleName]->version.'.sql')) + { + $this->Component->Utility->run_mysql_from_file(BASE_PATH.'/modules/'.$moduleName.'/database/mysql/'.$allModules[$moduleName]->version.'.sql', + Zend_Registry::get('configDatabase')->database->params->host, + Zend_Registry::get('configDatabase')->database->params->username, + Zend_Registry::get('configDatabase')->database->params->password, + Zend_Registry::get('configDatabase')->database->params->dbname, + Zend_Registry::get('configDatabase')->database->params->port); + } break; case 'PDO_PGSQL': - $this->Component->Utility->run_pgsql_from_file(BASE_PATH.'/modules/'.$key.'/database/pgsql/'.$allModules[$moduleName]->version.'.sql', - Zend_Registry::get('configDatabase')->database->params->host, - Zend_Registry::get('configDatabase')->database->params->username, - Zend_Registry::get('configDatabase')->database->params->password, - Zend_Registry::get('configDatabase')->database->params->dbname, - Zend_Registry::get('configDatabase')->database->params->port); + if(file_exists(BASE_PATH.'/modules/'.$key.'/database/pgsql/'.$allModules[$moduleName]->version.'.sql')) + { + $this->Component->Utility->run_pgsql_from_file(BASE_PATH.'/modules/'.$key.'/database/pgsql/'.$allModules[$moduleName]->version.'.sql', + Zend_Registry::get('configDatabase')->database->params->host, + Zend_Registry::get('configDatabase')->database->params->username, + Zend_Registry::get('configDatabase')->database->params->password, + Zend_Registry::get('configDatabase')->database->params->dbname, + Zend_Registry::get('configDatabase')->database->params->port); + } break; } } diff --git a/library/SabreDAV/lib/Sabre/CalDAV/CalendarRootNode.php b/library/SabreDAV/lib/Sabre/CalDAV/CalendarRootNode.php deleted file mode 100644 index 322722a11..000000000 --- a/library/SabreDAV/lib/Sabre/CalDAV/CalendarRootNode.php +++ /dev/null @@ -1,74 +0,0 @@ -authBackend = $authBackend; - $this->caldavBackend = $caldavBackend; - - } - - /** - * Returns the name of the node - * - * @return string - */ - public function getName() { - - return Sabre_CalDAV_Plugin::CALENDAR_ROOT; - - } - - /** - * Returns the list of users as Sabre_CalDAV_User objects. - * - * @return array - */ - public function getChildren() { - - $users = $this->authBackend->getUsers(); - $children = array(); - foreach($users as $user) { - - $children[] = new Sabre_CalDAV_UserCalendars($this->authBackend, $this->caldavBackend, $user['uri']); - - } - return $children; - - } - -} diff --git a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/PDO.php b/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/PDO.php deleted file mode 100644 index c88085803..000000000 --- a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/PDO.php +++ /dev/null @@ -1,79 +0,0 @@ -pdo = $pdo; - - } - - /** - * Returns a users' information - * - * @param string $realm - * @param string $username - * @return string - */ - public function getUserInfo($realm,$username) { - - $stmt = $this->pdo->prepare('SELECT username, digesta1, email FROM users WHERE username = ?'); - $stmt->execute(array($username)); - $result = $stmt->fetchAll(); - - if (!count($result)) return false; - $user = array( - 'uri' => 'principals/' . $result[0]['username'], - 'digestHash' => $result[0]['digesta1'], - ); - if ($result[0]['email']) $user['{http://sabredav.org/ns}email-address'] = $result[0]['email']; - return $user; - - } - - /** - * Returns a list of all users - * - * @return array - */ - public function getUsers() { - - $result = $this->pdo->query('SELECT username, email FROM users')->fetchAll(); - - $rv = array(); - foreach($result as $user) { - - $r = array( - 'uri' => 'principals/' . $user['username'], - ); - if ($user['email']) $r['{http://sabredav.org/ns}email-address'] = $user['email']; - $rv[] = $r; - - } - - return $rv; - - } - -} diff --git a/library/SabreDAV/lib/Sabre/DAV/Auth/Plugin.php b/library/SabreDAV/lib/Sabre/DAV/Auth/Plugin.php deleted file mode 100644 index cc4f25f3f..000000000 --- a/library/SabreDAV/lib/Sabre/DAV/Auth/Plugin.php +++ /dev/null @@ -1,434 +0,0 @@ -authBackend = $authBackend; - $this->realm = $realm; - - } - - /** - * Initializes the plugin. This function is automatically called by the server - * - * @param Sabre_DAV_Server $server - * @return void - */ - public function initialize(Sabre_DAV_Server $server) { - - $this->server = $server; - $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'),10); - $this->server->subscribeEvent('afterGetProperties',array($this,'afterGetProperties')); - $this->server->subscribeEvent('report',array($this,'report')); - - } - - /** - * This method intercepts calls to PROPFIND and similar lookups - * - * This is done to inject the current-user-principal if this is requested. - * - * @todo support for 'unauthenticated' - * @return void - */ - public function afterGetProperties($href, &$properties) { - - if (array_key_exists('{DAV:}current-user-principal', $properties[404])) { - if ($ui = $this->authBackend->getCurrentUser()) { - $properties[200]['{DAV:}current-user-principal'] = new Sabre_DAV_Property_Principal(Sabre_DAV_Property_Principal::HREF, $ui['uri']); - } else { - $properties[200]['{DAV:}current-user-principal'] = new Sabre_DAV_Property_Principal(Sabre_DAV_Property_Principal::UNAUTHENTICATED); - } - unset($properties[404]['{DAV:}current-user-principal']); - } - if (array_key_exists('{DAV:}principal-collection-set', $properties[404])) { - $properties[200]['{DAV:}principal-collection-set'] = new Sabre_DAV_Property_Href('principals'); - unset($properties[404]['{DAV:}principal-collection-set']); - } - if (array_key_exists('{DAV:}supported-report-set', $properties[200])) { - $properties[200]['{DAV:}supported-report-set']->addReport(array( - '{DAV:}expand-property', - )); - } - - - } - - /** - * This method is called before any HTTP method and forces users to be authenticated - * - * @param string $method - * @throws Sabre_DAV_Exception_NotAuthenticated - * @return bool - */ - public function beforeMethod($method, $uri) { - - $this->authBackend->authenticate($this->server,$this->realm); - - } - - /** - * This functions handles REPORT requests - * - * @param string $reportName - * @param DOMNode $dom - * @return bool|null - */ - public function report($reportName,$dom) { - - switch($reportName) { - case '{DAV:}expand-property' : - $this->expandPropertyReport($dom); - return false; - case '{DAV:}principal-property-search' : - if ($this->server->getRequestUri()==='principals') { - $this->principalPropertySearchReport($dom); - return false; - } - break; - case '{DAV:}principal-search-property-set' : - if ($this->server->getRequestUri()==='principals') { - $this->principalSearchPropertySetReport($dom); - return false; - } - break; - - } - - } - - /** - * The expand-property report is defined in RFC3253 section 3-8. - * - * This report is very similar to a standard PROPFIND. The difference is - * that it has the additional ability to look at properties containing a - * {DAV:}href element, follow that property and grab additional elements - * there. - * - * Other rfc's, such as ACL rely on this report, so it made sense to put - * it in this plugin. - * - * @param DOMElement $dom - * @return void - */ - protected function expandPropertyReport($dom) { - - $requestedProperties = $this->parseExpandPropertyReportRequest($dom->firstChild->firstChild); - $depth = $this->server->getHTTPDepth(0); - $requestUri = $this->server->getRequestUri(); - - $result = $this->expandProperties($requestUri,$requestedProperties,$depth); - - $dom = new DOMDocument('1.0','utf-8'); - $dom->formatOutput = true; - $multiStatus = $dom->createElement('d:multistatus'); - $dom->appendChild($multiStatus); - - // Adding in default namespaces - foreach($this->server->xmlNamespaces as $namespace=>$prefix) { - - $multiStatus->setAttribute('xmlns:' . $prefix,$namespace); - - } - - foreach($result as $entry) { - - $entry->serialize($this->server,$multiStatus); - - } - - $xml = $dom->saveXML(); - $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8'); - $this->server->httpResponse->sendStatus(207); - $this->server->httpResponse->sendBody($xml); - - // Make sure the event chain is broken - return false; - - } - - /** - * This method is used by expandPropertyReport to parse - * out the entire HTTP request. - * - * @param DOMElement $node - * @return array - */ - protected function parseExpandPropertyReportRequest($node) { - - $requestedProperties = array(); - do { - - if (Sabre_DAV_XMLUtil::toClarkNotation($node)!=='{DAV:}property') continue; - - if ($node->firstChild) { - - $children = $this->parseExpandPropertyReportRequest($node->firstChild); - - } else { - - $children = array(); - - } - - $namespace = $node->getAttribute('namespace'); - if (!$namespace) $namespace = 'DAV:'; - - $propName = '{'.$namespace.'}' . $node->getAttribute('name'); - $requestedProperties[$propName] = $children; - - } while ($node = $node->nextSibling); - - return $requestedProperties; - - } - - /** - * This method expands all the properties and returns - * a list with property values - * - * @param array $path - * @param array $requestedProperties the list of required properties - * @param array $depth - */ - protected function expandProperties($path,array $requestedProperties,$depth) { - - $foundProperties = $this->server->getPropertiesForPath($path,array_keys($requestedProperties),$depth); - - $result = array(); - - foreach($foundProperties as $node) { - - foreach($requestedProperties as $propertyName=>$childRequestedProperties) { - - // We're only traversing if sub-properties were requested - if(count($childRequestedProperties)===0) continue; - - // We only have to do the expansion if the property was found - // and it contains an href element. - if (!array_key_exists($propertyName,$node[200])) continue; - if (!($node[200][$propertyName] instanceof Sabre_DAV_Property_IHref)) continue; - - $href = $node[200][$propertyName]->getHref(); - list($node[200][$propertyName]) = $this->expandProperties($href,$childRequestedProperties,0); - - } - $result[] = new Sabre_DAV_Property_Response($path, $node); - - } - - return $result; - - } - - protected function principalSearchPropertySetReport(DOMDocument $dom) { - - $searchProperties = array( - '{DAV:}displayname' => 'display name' - - ); - - $httpDepth = $this->server->getHTTPDepth(0); - if ($httpDepth!==0) { - throw new Sabre_DAV_Exception_BadRequest('This report is only defined when Depth: 0'); - } - - if ($dom->firstChild->hasChildNodes()) - throw new Sabre_DAV_Exception_BadRequest('The principal-search-property-set report element is not allowed to have child elements'); - - $dom = new DOMDocument('1.0','utf-8'); - $dom->formatOutput = true; - $root = $dom->createElement('d:principal-search-property-set'); - $dom->appendChild($root); - // Adding in default namespaces - foreach($this->server->xmlNamespaces as $namespace=>$prefix) { - - $root->setAttribute('xmlns:' . $prefix,$namespace); - - } - - $nsList = $this->server->xmlNamespaces; - - foreach($searchProperties as $propertyName=>$description) { - - $psp = $dom->createElement('d:principal-search-property'); - $root->appendChild($psp); - - $prop = $dom->createElement('d:prop'); - $psp->appendChild($prop); - - $propName = null; - preg_match('/^{([^}]*)}(.*)$/',$propertyName,$propName); - - //if (!isset($nsList[$propName[1]])) { - // $nsList[$propName[1]] = 'x' . count($nsList); - //} - - // If the namespace was defined in the top-level xml namespaces, it means - // there was already a namespace declaration, and we don't have to worry about it. - //if (isset($server->xmlNamespaces[$propName[1]])) { - $currentProperty = $dom->createElement($nsList[$propName[1]] . ':' . $propName[2]); - //} else { - // $currentProperty = $dom->createElementNS($propName[1],$nsList[$propName[1]].':' . $propName[2]); - //} - $prop->appendChild($currentProperty); - - $descriptionElem = $dom->createElement('d:description'); - $descriptionElem->setAttribute('xml:lang','en'); - $descriptionElem->appendChild($dom->createTextNode($description)); - $psp->appendChild($descriptionElem); - - - } - - $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8'); - $this->server->httpResponse->sendStatus(200); - $this->server->httpResponse->sendBody($dom->saveXML()); - - } - - protected function principalPropertySearchReport($dom) { - - $searchableProperties = array( - '{DAV:}displayname' => 'display name' - - ); - - list($searchProperties, $requestedProperties) = $this->parsePrincipalPropertySearchReportRequest($dom); - - $uri = $this->server->getRequestUri(); - - $result = array(); - - $lookupResults = $this->server->getPropertiesForPath($uri, array_keys($searchProperties), 1); - - // The first item in the results is the parent, so we get rid of it. - array_shift($lookupResults); - - $matches = array(); - - foreach($lookupResults as $lookupResult) { - - foreach($searchProperties as $searchProperty=>$searchValue) { - if (!isset($searchableProperties[$searchProperty])) { - throw new Sabre_DAV_Exception_BadRequest('Searching for ' . $searchProperty . ' is not supported'); - } - - if (isset($lookupResult[200][$searchProperty]) && - mb_stripos($lookupResult[200][$searchProperty], $searchValue, 0, 'UTF-8')!==false) { - $matches[] = $lookupResult['href']; - } - - } - - } - - $matchProperties = array(); - - foreach($matches as $match) { - - list($result) = $this->server->getPropertiesForPath($match, $requestedProperties, 0); - $matchProperties[] = $result; - - } - - $xml = $this->server->generateMultiStatus($matchProperties); - $this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8'); - $this->server->httpResponse->sendStatus(207); - $this->server->httpResponse->sendBody($xml); - - } - - protected function parsePrincipalPropertySearchReportRequest($dom) { - - $httpDepth = $this->server->getHTTPDepth(0); - if ($httpDepth!==0) { - throw new Sabre_DAV_Exception_BadRequest('This report is only defined when Depth: 0'); - } - - $searchProperties = array(); - - // Parsing the search request - foreach($dom->firstChild->childNodes as $searchNode) { - - if (Sabre_DAV_XMLUtil::toClarkNotation($searchNode)!=='{DAV:}property-search') - continue; - - $propertyName = null; - $propertyValue = null; - - foreach($searchNode->childNodes as $childNode) { - - switch(Sabre_DAV_XMLUtil::toClarkNotation($childNode)) { - - case '{DAV:}prop' : - $property = Sabre_DAV_XMLUtil::parseProperties($searchNode); - reset($property); - $propertyName = key($property); - break; - - case '{DAV:}match' : - $propertyValue = $childNode->textContent; - break; - - } - - - } - - if (is_null($propertyName) || is_null($propertyValue)) - throw new Sabre_DAV_Exception_BadRequest('Invalid search request. propertyname: ' . $propertyName . '. propertvvalue: ' . $propertyValue); - - $searchProperties[$propertyName] = $propertyValue; - - } - - return array($searchProperties, array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild))); - - } - -} diff --git a/library/SabreDAV/lib/Sabre/DAV/Auth/Principal.php b/library/SabreDAV/lib/Sabre/DAV/Auth/Principal.php deleted file mode 100644 index a69ce6f6f..000000000 --- a/library/SabreDAV/lib/Sabre/DAV/Auth/Principal.php +++ /dev/null @@ -1,147 +0,0 @@ -principalUri = $principalUri; - $this->principalProperties = $principalProperties; - - } - - /** - * Returns the name of the element - * - * @return void - */ - public function getName() { - - list(, $name) = Sabre_DAV_URLUtil::splitPath($this->principalUri); - return $name; - - } - - /** - * Returns the name of the user - * - * @return void - */ - public function getDisplayName() { - - if (isset($this->principalProperties['{DAV:}displayname'])) { - return $this->principalProperties['{DAV:}displayname']; - } else { - return $this->getName(); - } - - } - - /** - * Returns a list of properties - * - * @param array $requestedProperties - * @return void - */ - public function getProperties($requestedProperties) { - - if (!count($requestedProperties)) { - - // If all properties were requested - // we will only returns properties from this list - $requestedProperties = array( - '{DAV:}resourcetype', - '{DAV:}displayname', - ); - - } - - // We need to always return the resourcetype - // This is a bug in the core server, but it is easier to do it this way for now - $newProperties = array( - '{DAV:}resourcetype' => new Sabre_DAV_Property_ResourceType('{DAV:}principal') - ); - foreach($requestedProperties as $propName) switch($propName) { - - case '{DAV:}alternate-URI-set' : - if (isset($this->principalProperties['{http://sabredav.org/ns}email-address'])) { - $href = 'mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address']; - $newProperties[$propName] = new Sabre_DAV_Property_Href($href); - } else { - $newProperties[$propName] = null; - } - break; - case '{DAV:}group-member-set' : - case '{DAV:}group-membership' : - $newProperties[$propName] = null; - break; - - case '{DAV:}principal-URL' : - $newProperties[$propName] = new Sabre_DAV_Property_Href($this->principalUri); - break; - - case '{DAV:}displayname' : - $newProperties[$propName] = $this->getDisplayName(); - break; - - default : - if (isset($this->principalProperties[$propName])) { - $newProperties[$propName] = $this->principalProperties[$propName]; - } - break; - - } - - return $newProperties; - - - } - - /** - * Updates this principals properties. - * - * Currently this is not supported - * - * @param array $properties - * @see Sabre_DAV_IProperties::updateProperties - * @return bool|array - */ - public function updateProperties($properties) { - - return false; - - } - -} diff --git a/library/SabreDAV/lib/Sabre/DAV/Auth/PrincipalCollection.php b/library/SabreDAV/lib/Sabre/DAV/Auth/PrincipalCollection.php deleted file mode 100644 index 75cf3af96..000000000 --- a/library/SabreDAV/lib/Sabre/DAV/Auth/PrincipalCollection.php +++ /dev/null @@ -1,74 +0,0 @@ -authBackend = $authBackend; - - } - - /** - * Returns the name of this collection. - * - * @return string - */ - public function getName() { - - return self::NODENAME; - - } - - /** - * Retursn the list of users - * - * @return void - */ - public function getChildren() { - - $children = array(); - foreach($this->authBackend->getUsers() as $principalInfo) { - - $principalUri = $principalInfo['uri'] . '/'; - $children[] = new Sabre_DAV_Auth_Principal($principalUri,$principalInfo); - - - } - return $children; - - } - -} diff --git a/modules/template/emptymodule/AppController.php b/modules/template/emptymodule/AppController.php new file mode 100644 index 000000000..59d4cd25f --- /dev/null +++ b/modules/template/emptymodule/AppController.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/modules/template/emptymodule/configs/.gitignore b/modules/template/emptymodule/configs/.gitignore new file mode 100644 index 000000000..594cfe7c3 --- /dev/null +++ b/modules/template/emptymodule/configs/.gitignore @@ -0,0 +1,2 @@ +*.local.ini +*.local.ini.old \ No newline at end of file diff --git a/modules/template/emptymodule/configs/module.ini b/modules/template/emptymodule/configs/module.ini new file mode 100644 index 000000000..60400ff0b --- /dev/null +++ b/modules/template/emptymodule/configs/module.ini @@ -0,0 +1,9 @@ +[global] +; version of the module +version = 1.0.0 +; full name +fullname= name +; description +description= description +; if true, only an admini can enable the addon and it will be activated for everyone +system = true diff --git a/modules/template/emptymodule/constant/module.php b/modules/template/emptymodule/constant/module.php new file mode 100644 index 000000000..9671af98c --- /dev/null +++ b/modules/template/emptymodule/constant/module.php @@ -0,0 +1,3 @@ + diff --git a/modules/template/emptymodule/controllers/ConfigController.php b/modules/template/emptymodule/controllers/ConfigController.php new file mode 100644 index 000000000..2f83024dd --- /dev/null +++ b/modules/template/emptymodule/controllers/ConfigController.php @@ -0,0 +1,14 @@ +logged||!$this->userSession->Dao->getAdmin()==1) + { + throw new Zend_Exception("You should be an administrator"); + } + } + +}//end class \ No newline at end of file diff --git a/modules/template/emptymodule/controllers/IndexController.php b/modules/template/emptymodule/controllers/IndexController.php new file mode 100644 index 000000000..2f67e36bf --- /dev/null +++ b/modules/template/emptymodule/controllers/IndexController.php @@ -0,0 +1,22 @@ + diff --git a/modules/template/emptymodule/models/AppModel.php b/modules/template/emptymodule/models/AppModel.php new file mode 100644 index 000000000..73406d69c --- /dev/null +++ b/modules/template/emptymodule/models/AppModel.php @@ -0,0 +1,8 @@ + diff --git a/modules/template/emptymodule/translation/fr-main.csv b/modules/template/emptymodule/translation/fr-main.csv new file mode 100644 index 000000000..9d3cbd3ae --- /dev/null +++ b/modules/template/emptymodule/translation/fr-main.csv @@ -0,0 +1 @@ +Hello world;Boujour tout le monde \ No newline at end of file diff --git a/modules/template/emptymodule/views/config/index.phtml b/modules/template/emptymodule/views/config/index.phtml new file mode 100644 index 000000000..6d1710e00 --- /dev/null +++ b/modules/template/emptymodule/views/config/index.phtml @@ -0,0 +1 @@ +Config page \ No newline at end of file diff --git a/modules/template/emptymodule/views/index/index.phtml b/modules/template/emptymodule/views/index/index.phtml new file mode 100644 index 000000000..12fba4c5c --- /dev/null +++ b/modules/template/emptymodule/views/index/index.phtml @@ -0,0 +1 @@ +Main page \ No newline at end of file diff --git a/modules/webdav/AppController.php b/modules/webdav/AppController.php new file mode 100644 index 000000000..72f1967cd --- /dev/null +++ b/modules/webdav/AppController.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/modules/webdav/configs/.gitignore b/modules/webdav/configs/.gitignore new file mode 100644 index 000000000..594cfe7c3 --- /dev/null +++ b/modules/webdav/configs/.gitignore @@ -0,0 +1,2 @@ +*.local.ini +*.local.ini.old \ No newline at end of file diff --git a/modules/webdav/configs/module.ini b/modules/webdav/configs/module.ini new file mode 100644 index 000000000..0de4db3f3 --- /dev/null +++ b/modules/webdav/configs/module.ini @@ -0,0 +1,9 @@ +[global] +; version of the module +version = 1.0.0 +; full name +fullname= WebDav +; description +description= "Browse Midas files using SabreDab (Alpha version)" +; if true, only an admini can enable the addon and it will be activated for everyone +system = true diff --git a/modules/webdav/constant/module.php b/modules/webdav/constant/module.php new file mode 100644 index 000000000..9671af98c --- /dev/null +++ b/modules/webdav/constant/module.php @@ -0,0 +1,3 @@ + diff --git a/modules/webdav/controllers/ConfigController.php b/modules/webdav/controllers/ConfigController.php new file mode 100644 index 000000000..a1b1ab898 --- /dev/null +++ b/modules/webdav/controllers/ConfigController.php @@ -0,0 +1,14 @@ +logged||!$this->userSession->Dao->getAdmin()==1) + { + throw new Zend_Exception("You should be an administrator"); + } + } + +}//end class \ No newline at end of file diff --git a/modules/webdav/controllers/IndexController.php b/modules/webdav/controllers/IndexController.php new file mode 100644 index 000000000..bc4273011 --- /dev/null +++ b/modules/webdav/controllers/IndexController.php @@ -0,0 +1,88 @@ +_helper->layout->disableLayout(); + $this->_helper->viewRenderer->setNoRender(); + + // Now we're creating a whole bunch of objects + $fc = Zend_Controller_Front::getInstance(); + $webroot = $fc->getBaseUrl() ; + + // User authentication + $auth = new Sabre_HTTP_BasicAuth(); + $result = $auth->getUserPass(); + + if($result[0] != 'anonymous') + { + //$someone = $this->User->findByEmail($result[0]); + //if($someone['User']['password'] != md5($result[1])) + { + $auth->requireLogin(); + echo "Authentication required\n"; + die(); + } + //$userid = $someone['User']['eperson_id']; + } + else + { + $userid = 0; + } + + // Change public to something else, if you are using a different directory for your files + $rootDirectory = new Sabre_DAV_FS_Directory('C:/WEBS'); + + // The server object is responsible for making sense out of the WebDAV protocol + $server = new Sabre_DAV_Server($rootDirectory); + + // If your server is not on your webroot, make sure the following line has the correct information + $server->setBaseUri($webroot.'/webdav'); + + // $server->setBaseUri('/~evert/mydavfolder'); // if its in some kind of home directory + // $server->setBaseUri('/dav/index.php/'); // if you can't use mod_rewrite, use index.php as a base uri + // $server->setBaseUri('/'); // ideally, SabreDAV lives on a root directory with mod_rewrite sending every request to index.php + + // The lock manager is reponsible for making sure users don't overwrite each others changes. Change 'data' to a different + // directory, if you're storing your data somewhere else. + $lockBackend = new Sabre_DAV_Locks_Backend_FS('C:/WEBS'); + $lockPlugin = new Sabre_DAV_Locks_Plugin($lockBackend); + $browserPlugin = new Sabre_DAV_Browser_Plugin(); + $server->addPlugin($browserPlugin); + $server->addPlugin($lockPlugin); + + $tmpDir = $this->GetTempDirectory()."/webdav"; + + // Temporary file filter (necessary for MacOS at least) + $tempFF = new Sabre_DAV_TemporaryFileFilterPlugin($tmpDir); + $server->addPlugin($tempFF); + + // All we need to do now, is to fire up the server + $server->exec(); + + exit(); // do not process anything else + } // end method indexAction + + /*function indexAction() + { + } */ + +}//end class + \ No newline at end of file diff --git a/library/SabreDAV/ChangeLog b/modules/webdav/library/SabreDAV/ChangeLog similarity index 84% rename from library/SabreDAV/ChangeLog rename to modules/webdav/library/SabreDAV/ChangeLog index df57f2648..d3cda0f5b 100644 --- a/library/SabreDAV/ChangeLog +++ b/modules/webdav/library/SabreDAV/ChangeLog @@ -1,3 +1,76 @@ +1.4.2-beta (2011-04-01) + * Added: It's not possible to disable listing of nodes that are denied + read access by ACL. + * Fixed: Changed a few properties in CalDAV classes from private to + protected. + * Fixed: Issue 119: Terrible things could happen when relying on + guessBaseUri, the server was running on the root of the domain and a user + tried to access a file ending in .php. This is a slight BC break. + * Fixed: Issue 118: Lock tokens in If headers without a uri should be + treated as the request uri, not 'all relevant uri's. + * Fixed: Issue 120: PDO backend was incorrectly fetching too much locks in + cases where there were similar named locked files in a directory. + +1.4.1-beta (2011-02-26) + * Fixed: Sabre_DAV_Locks_Backend_PDO returned too many locks. + * Fixed: Sabre_HTTP_Request::getHeader didn't return Content-Type when + running on apache, so a few workarounds were added. + * Change: Slightly changed CalDAV Backend API's, to allow for heavy + optimizations. This is non-bc breaking. + +1.4.0-beta (2011-02-12) + * Added: Partly RFC3744 ACL support. + * Added: Calendar-delegation (caldav-proxy) support. + * BC break: In order to fix Issue 99, a new argument had to be added to + Sabre_DAV_Locks_Backend_*::getLocks classes. Consult the classes for + details. + * Deprecated: Sabre_DAV_Locks_Backend_FS is now deprecated and will be + removed in a later version. Use PDO or the new File class instead. + * Deprecated: The Sabre_CalDAV_ICalendarUtil class is now marked + deprecated, and will be removed in a future version. Please use + Sabre_VObject instead. + * Removed: All principal-related functionality has been removed from the + Sabre_DAV_Auth_Plugin, and moved to the Sabre_DAVACL_Plugin. + * Added: VObject library, for easy vcard/icalendar parsing using a natural + interface. + * Added: Ability to automatically generate full .ics feeds off calendars. + To use: Add the Sabre_CalDAV_ICSExportPlugin, and add ?export to your + calendar url. + * Added: Plugins can now specify a pluginname, for easy access using + Sabre_DAV_Server::getPlugin(). + * Added: beforeGetProperties event. + * Added: updateProperties event. + * Added: Principal listings and calendar-access can now be done privately, + disallowing users from accessing or modifying other users' data. + * Added: You can now pass arrays to the Sabre_DAV_Server constructor. If + it's an array with node-objects, a Root collection will automatically be + created, and the nodes are used as top-level children. + * Added: The principal base uri is now customizable. It used to be + hardcoded to 'principals/[user]'. + * Added: getSupportedReportSet method in ServerPlugin class. This allows + you to easily specify which reports you're implementing. + * Added: A '..' link to the HTML browser. + * Fixed: Issue 99: Locks on child elements were ignored when their parent + nodes were deleted. + * Fixed: Issue 90: lockdiscovery property and LOCK response now include a + {DAV}lockroot element. + * Fixed: Issue 96: support for 'default' collation in CalDAV text-match + filters. + * Fixed: Issue 102: Ensuring that copy and move with identical source and + destination uri's fails. + * Fixed: Issue 105: Supporting MKCALENDAR with no body. + * Fixed: Issue 109: Small fixes in Sabre_HTTP_Util. + * Fixed: Issue 111: Properly catching the ownername in a lock (if it's a + string) + * Fixed: Sabre_DAV_ObjectTree::nodeExist always returned false for the + root node. + * Added: Global way to easily supply new resourcetypes for cetain node + classes. + * Fixed: Issue 59: Allowing the user to override the authentication realm + in Sabre_CalDAV_Server. + * Update: Issue 97: Looser time-range checking if there's a reccurrence + rule in an event. This fixes 'missing recurring events'. + 1.3.0 (2010-10-14) * Added: childExists method to Sabre_DAV_ICollection. This is an api break, so if you implement Sabre_DAV_ICollection directly, add the method. diff --git a/library/SabreDAV/LICENSE b/modules/webdav/library/SabreDAV/LICENSE similarity index 97% rename from library/SabreDAV/LICENSE rename to modules/webdav/library/SabreDAV/LICENSE index 1eba437f9..0bf9461ef 100644 --- a/library/SabreDAV/LICENSE +++ b/modules/webdav/library/SabreDAV/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2007-2010 Rooftop Solutions. +Copyright (C) 2007-2011 Rooftop Solutions. Copyright (C) 2007-2009 FileMobile inc. All rights reserved. diff --git a/library/SabreDAV/lib/Sabre.autoload.php b/modules/webdav/library/SabreDAV/lib/Sabre.autoload.php similarity index 85% rename from library/SabreDAV/lib/Sabre.autoload.php rename to modules/webdav/library/SabreDAV/lib/Sabre.autoload.php index 1c3815f55..0e5601d89 100644 --- a/library/SabreDAV/lib/Sabre.autoload.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre.autoload.php @@ -7,7 +7,7 @@ * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @deprecated * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License diff --git a/library/SabreDAV/lib/Sabre.includes.php b/modules/webdav/library/SabreDAV/lib/Sabre.includes.php similarity index 93% rename from library/SabreDAV/lib/Sabre.includes.php rename to modules/webdav/library/SabreDAV/lib/Sabre.includes.php index 612e13c5e..6e4b50f51 100644 --- a/library/SabreDAV/lib/Sabre.includes.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre.includes.php @@ -8,7 +8,7 @@ * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ @@ -54,8 +54,10 @@ include 'Sabre/DAV/Property/LockDiscovery.php'; include 'Sabre/DAV/Property/IHref.php'; include 'Sabre/DAV/Property/Href.php'; +include 'Sabre/DAV/Property/HrefList.php'; include 'Sabre/DAV/Property/SupportedReportSet.php'; include 'Sabre/DAV/Property/Response.php'; +include 'Sabre/DAV/Property/ResponseList.php'; include 'Sabre/DAV/Property/Principal.php'; /* Node interfaces */ @@ -113,14 +115,12 @@ /* Authentication plugin */ include 'Sabre/DAV/Auth/Plugin.php'; -include 'Sabre/DAV/Auth/Backend/Abstract.php'; +include 'Sabre/DAV/Auth/IBackend.php'; include 'Sabre/DAV/Auth/Backend/AbstractDigest.php'; +include 'Sabre/DAV/Auth/Backend/AbstractBasic.php'; include 'Sabre/DAV/Auth/Backend/File.php'; include 'Sabre/DAV/Auth/Backend/PDO.php'; -include 'Sabre/DAV/Auth/Principal.php'; -include 'Sabre/DAV/Auth/PrincipalCollection.php'; - /* DavMount plugin */ include 'Sabre/DAV/Mount/Plugin.php'; diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Backend/Abstract.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Backend/Abstract.php similarity index 86% rename from library/SabreDAV/lib/Sabre/CalDAV/Backend/Abstract.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Backend/Abstract.php index c758a38ba..7ac282f44 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Backend/Abstract.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Backend/Abstract.php @@ -5,7 +5,7 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ @@ -104,6 +104,16 @@ abstract function deleteCalendar($calendarId); * * calendardata - The iCalendar-compatible calnedar data * * uri - a unique key which will be used to construct the uri. This can be any arbitrary string. * * lastmodified - a timestamp of the last modification time + * * etag - An arbitrary string, surrounded by double-quotes. (e.g.: + * ' "abcdef"') + * * calendarid - The calendarid as it was passed to this function. + * + * Note that the etag is optional, but it's highly encouraged to return for + * speed reasons. + * + * The calendardata is also optional. If it's not returned + * 'getCalendarObject' will be called later, which *is* expected to return + * calendardata. * * @param string $calendarId * @return array @@ -111,7 +121,12 @@ abstract function deleteCalendar($calendarId); abstract function getCalendarObjects($calendarId); /** - * Returns information from a single calendar object, based on it's object uri. + * Returns information from a single calendar object, based on it's object + * uri. + * + * The returned array must have the same keys as getCalendarObjects. The + * 'calendardata' object is required here though, while it's not required + * for getCalendarObjects. * * @param string $calendarId * @param string $objectUri diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Backend/PDO.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Backend/PDO.php similarity index 93% rename from library/SabreDAV/lib/Sabre/CalDAV/Backend/PDO.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Backend/PDO.php index f60d17370..429b6e80c 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Backend/PDO.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Backend/PDO.php @@ -8,7 +8,7 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ @@ -275,6 +275,16 @@ public function deleteCalendar($calendarId) { * * calendardata - The iCalendar-compatible calnedar data * * uri - a unique key which will be used to construct the uri. This can be any arbitrary string. * * lastmodified - a timestamp of the last modification time + * * etag - An arbitrary string, surrounded by double-quotes. (e.g.: + * ' "abcdef"') + * * calendarid - The calendarid as it was passed to this function. + * + * Note that the etag is optional, but it's highly encouraged to return for + * speed reasons. + * + * The calendardata is also optional. If it's not returned + * 'getCalendarObject' will be called later, which *is* expected to return + * calendardata. * * @param string $calendarId * @return array @@ -288,7 +298,12 @@ public function getCalendarObjects($calendarId) { } /** - * Returns information from a single calendar object, based on it's object uri. + * Returns information from a single calendar object, based on it's object + * uri. + * + * The returned array must have the same keys as getCalendarObjects. The + * 'calendardata' object is required here though, while it's not required + * for getCalendarObjects. * * @param string $calendarId * @param string $objectUri diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Calendar.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Calendar.php similarity index 66% rename from library/SabreDAV/lib/Sabre/CalDAV/Calendar.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Calendar.php index b99878b72..71fbdeb43 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Calendar.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Calendar.php @@ -8,32 +8,32 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Sabre_CalDAV_Calendar implements Sabre_DAV_ICollection, Sabre_DAV_IProperties { +class Sabre_CalDAV_Calendar implements Sabre_DAV_ICollection, Sabre_DAV_IProperties, Sabre_DAVACL_IACL { /** * This is an array with calendar information * * @var array */ - private $calendarInfo; + protected $calendarInfo; /** * CalDAV backend * * @var Sabre_CalDAV_Backend_Abstract */ - private $caldavBackend; + protected $caldavBackend; /** - * Authentication backend + * Principal backend * - * @var Sabre_DAV_Auth_Backend_Abstract + * @var Sabre_DAVACL_IPrincipalBackend */ - private $authBackend; + protected $principalBackend; /** * Constructor @@ -42,10 +42,10 @@ class Sabre_CalDAV_Calendar implements Sabre_DAV_ICollection, Sabre_DAV_IPropert * @param array $calendarInfo * @return void */ - public function __construct(Sabre_DAV_Auth_Backend_Abstract $authBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend,$calendarInfo) { + public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend, $calendarInfo) { $this->caldavBackend = $caldavBackend; - $this->authBackend = $authBackend; + $this->principalBackend = $principalBackend; $this->calendarInfo = $calendarInfo; @@ -70,7 +70,6 @@ public function getName() { */ public function updateProperties($mutations) { - if (!$this->hasPrivilege()) throw new Sabre_DAV_Exception_Forbidden('Permission denied to access this calendar'); return $this->caldavBackend->updateCalendar($this->calendarInfo['id'],$mutations); } @@ -85,13 +84,8 @@ public function getProperties($requestedProperties) { $response = array(); - if (!$this->hasPrivilege()) return array(); - foreach($requestedProperties as $prop) switch($prop) { - case '{DAV:}resourcetype' : - $response[$prop] = new Sabre_DAV_Property_ResourceType(array('{urn:ietf:params:xml:ns:caldav}calendar','{DAV:}collection')); - break; case '{urn:ietf:params:xml:ns:caldav}supported-calendar-data' : $response[$prop] = new Sabre_CalDAV_Property_SupportedCalendarData(); break; @@ -120,7 +114,6 @@ public function getProperties($requestedProperties) { */ public function getChild($name) { - if (!$this->hasPrivilege()) throw new Sabre_DAV_Exception_Forbidden('Permission denied to access this calendar'); $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'],$name); if (!$obj) throw new Sabre_DAV_Exception_FileNotFound('Calendar object not found'); return new Sabre_CalDAV_CalendarObject($this->caldavBackend,$this->calendarInfo,$obj); @@ -134,7 +127,6 @@ public function getChild($name) { */ public function getChildren() { - if (!$this->hasPrivilege()) throw new Sabre_DAV_Exception_Forbidden('Permission denied to access this calendar'); $objs = $this->caldavBackend->getCalendarObjects($this->calendarInfo['id']); $children = array(); foreach($objs as $obj) { @@ -152,7 +144,6 @@ public function getChildren() { */ public function childExists($name) { - if (!$this->hasPrivilege()) throw new Sabre_DAV_Exception_Forbidden('Permission denied to access this calendar'); $obj = $this->caldavBackend->getCalendarObject($this->calendarInfo['id'],$name); if (!$obj) return false; @@ -171,7 +162,6 @@ public function childExists($name) { */ public function createDirectory($name) { - if (!$this->hasPrivilege()) throw new Sabre_DAV_Exception_Forbidden('Permission denied to access this calendar'); throw new Sabre_DAV_Exception_MethodNotAllowed('Creating collections in calendar objects is not allowed'); } @@ -187,7 +177,6 @@ public function createDirectory($name) { */ public function createFile($name,$calendarData = null) { - if (!$this->hasPrivilege()) throw new Sabre_DAV_Exception_Forbidden('Permission denied to access this calendar'); $calendarData = stream_get_contents($calendarData); $supportedComponents = $this->calendarInfo['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}supported-calendar-component-set']->getValue(); @@ -204,7 +193,6 @@ public function createFile($name,$calendarData = null) { */ public function delete() { - if (!$this->hasPrivilege()) throw new Sabre_DAV_Exception_Forbidden('Permission denied to access this calendar'); $this->caldavBackend->deleteCalendar($this->calendarInfo['id']); } @@ -218,7 +206,6 @@ public function delete() { */ public function setName($newName) { - if (!$this->hasPrivilege()) throw new Sabre_DAV_Exception_Forbidden('Permission denied to access this calendar'); throw new Sabre_DAV_Exception_MethodNotAllowed('Renaming calendars is not yet supported'); } @@ -235,20 +222,90 @@ public function getLastModified() { } /** - * Check if user has access. + * Returns the owner principal * - * This method does a check if the currently logged in user - * has permission to access this calendar. There is only read-write - * access, so you're in or you're out. + * This must be a url to a principal, or null if there's no owner * - * @return bool + * @return string|null + */ + public function getOwner() { + + return $this->calendarInfo['principaluri']; + + } + + /** + * Returns a group principal + * + * This must be a url to a principal, or null if there's no owner + * + * @return string|null */ - protected function hasPrivilege() { + public function getGroup() { - if (!$user = $this->authBackend->getCurrentUser()) return false; - if ($user['uri']!==$this->calendarInfo['principaluri']) return false; - return true; + return null; } + /** + * Returns a list of ACE's for this node. + * + * Each ACE has the following properties: + * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are + * currently the only supported privileges + * * 'principal', a url to the principal who owns the node + * * 'protected' (optional), indicating that this ACE is not allowed to + * be updated. + * + * @return array + */ + public function getACL() { + + return array( + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->calendarInfo['principaluri'], + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}write', + 'principal' => $this->calendarInfo['principaluri'], + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}write', + 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read', + 'protected' => true, + ), + + ); + + } + + /** + * Updates the ACL + * + * This method will receive a list of new ACE's. + * + * @param array $acl + * @return void + */ + public function setACL(array $acl) { + + throw new Sabre_DAV_Exception_MethodNotAllowed('Changing ACL is not yet supported'); + + } + + + } diff --git a/library/SabreDAV/lib/Sabre/CalDAV/CalendarObject.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/CalendarObject.php similarity index 55% rename from library/SabreDAV/lib/Sabre/CalDAV/CalendarObject.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/CalendarObject.php index 937bab195..cda5ebc2c 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/CalendarObject.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/CalendarObject.php @@ -5,32 +5,32 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_DAV_IProperties { +class Sabre_CalDAV_CalendarObject extends Sabre_DAV_File implements Sabre_DAV_IProperties, Sabre_DAVACL_IACL { /** * Sabre_CalDAV_Backend_Abstract * * @var array */ - private $caldavBackend; + protected $caldavBackend; /** * Array with information about this CalendarObject * * @var array */ - private $objectData; + protected $objectData; /** * Array with information about the containing calendar * * @var array */ - private $calendarInfo; + protected $calendarInfo; /** * Constructor @@ -64,6 +64,11 @@ public function getName() { */ public function get() { + // Pre-populating the 'calendardata' is optional, if we don't have it + // already we fetch it from the backend. + if (!isset($this->objectData['calendardata'])) { + $this->objectData = $this->calendarBackend->getCalendarObject($this->objectData['calendarid'], $this->objectData['uri']); + } return $this->objectData['calendardata']; } @@ -118,7 +123,11 @@ public function getContentType() { */ public function getETag() { - return '"' . md5($this->objectData['calendardata']). '"'; + if (isset($this->objectData['etag'])) { + return $this->objectData['etag']; + } else { + return '"' . md5($this->get()). '"'; + } } @@ -172,5 +181,92 @@ public function getSize() { return strlen($this->objectData['calendardata']); } + + /** + * Returns the owner principal + * + * This must be a url to a principal, or null if there's no owner + * + * @return string|null + */ + public function getOwner() { + + return $this->calendarInfo['principaluri']; + + } + + /** + * Returns a group principal + * + * This must be a url to a principal, or null if there's no owner + * + * @return string|null + */ + public function getGroup() { + + return null; + + } + + /** + * Returns a list of ACE's for this node. + * + * Each ACE has the following properties: + * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are + * currently the only supported privileges + * * 'principal', a url to the principal who owns the node + * * 'protected' (optional), indicating that this ACE is not allowed to + * be updated. + * + * @return array + */ + public function getACL() { + + return array( + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->calendarInfo['principaluri'], + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}write', + 'principal' => $this->calendarInfo['principaluri'], + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}write', + 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-write', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->calendarInfo['principaluri'] . '/calendar-proxy-read', + 'protected' => true, + ), + + ); + + } + + /** + * Updates the ACL + * + * This method will receive a list of new ACE's. + * + * @param array $acl + * @return void + */ + public function setACL(array $acl) { + + throw new Sabre_DAV_Exception_MethodNotAllowed('Changing ACL is not yet supported'); + + } + + } diff --git a/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/CalendarRootNode.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/CalendarRootNode.php new file mode 100644 index 000000000..5c9b37e7d --- /dev/null +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/CalendarRootNode.php @@ -0,0 +1,68 @@ +caldavBackend = $caldavBackend; + + } + + /** + * Returns the nodename + * + * We're overriding this, because the default will be the 'principalPrefix', + * and we want it to be Sabre_CalDAV_Plugin::CALENDAR_ROOT + * + * @return void + */ + public function getName() { + + return Sabre_CalDAV_Plugin::CALENDAR_ROOT; + + } + + /** + * This method returns a node for a principal. + * + * The passed array contains principal information, and is guaranteed to + * at least contain a uri item. Other properties may or may not be + * supplied by the authentication backend. + * + * @param array $principal + * @return Sabre_DAV_INode + */ + public function getChildForPrincipal(array $principal) { + + return new Sabre_CalDAV_UserCalendars($this->principalBackend, $this->caldavBackend, $principal['uri']); + + } + +} diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Exception/InvalidICalendarObject.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Exception/InvalidICalendarObject.php similarity index 87% rename from library/SabreDAV/lib/Sabre/CalDAV/Exception/InvalidICalendarObject.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Exception/InvalidICalendarObject.php index 24873f5d2..656b7286a 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Exception/InvalidICalendarObject.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Exception/InvalidICalendarObject.php @@ -8,7 +8,7 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ diff --git a/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/ICSExportPlugin.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/ICSExportPlugin.php new file mode 100644 index 000000000..4e2c6eb93 --- /dev/null +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/ICSExportPlugin.php @@ -0,0 +1,124 @@ +server = $server; + $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'), 90); + + } + + /** + * 'beforeMethod' event handles. This event handles intercepts GET requests ending + * with ?export + * + * @param string $method + * @param string $uri + * @return void + */ + public function beforeMethod($method, $uri) { + + if ($method!='GET') return; + if ($this->server->httpRequest->getQueryString()!='export') return; + + // splitting uri + list($uri) = explode('?',$uri,2); + + $node = $this->server->tree->getNodeForPath($uri); + + if (!($node instanceof Sabre_CalDAV_Calendar)) return; + + $this->server->httpResponse->setHeader('Content-Type','text/calendar'); + $this->server->httpResponse->sendStatus(200); + $this->server->httpResponse->sendBody($this->generateICS($this->server->tree->getChildren($uri))); + + // Returning false to break the event chain + return false; + + } + + /** + * Merges all calendar objects, and builds one big ics export + * + * @param array $nodes + * @return void + */ + public function generateICS(array $nodes) { + + $calendar = new Sabre_VObject_Component('vcalendar'); + $calendar->version = '2.0'; + $calendar->prodid = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN'; + $calendar->calscale = 'GREGORIAN'; + + $collectedTimezones = array(); + + $timezones = array(); + $objects = array(); + + foreach($nodes as $node) { + + $nodeData = $node->get(); + $nodeComp = Sabre_VObject_Reader::read($nodeData); + + foreach($nodeComp->children() as $child) { + + switch($child->name) { + case 'VEVENT' : + case 'VTODO' : + case 'VJOURNAL' : + $objects[] = $child; + break; + + // VTIMEZONE is special, because we need to filter out the duplicates + case 'VTIMEZONE' : + // Naively just checking tzid. + if (in_array((string)$child->TZID, $collectedTimezones)) continue; + + $timezones[] = $child; + $collectedTimezones[] = $child->TZID; + break; + + + } + + + } + + + } + + foreach($timezones as $tz) $calendar->add($tz); + foreach($objects as $obj) $calendar->add($obj); + + return $calendar->serialize(); + + } + +} diff --git a/library/SabreDAV/lib/Sabre/CalDAV/ICalendarUtil.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/ICalendarUtil.php similarity index 95% rename from library/SabreDAV/lib/Sabre/CalDAV/ICalendarUtil.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/ICalendarUtil.php index 3772cc6ab..fbfef397a 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/ICalendarUtil.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/ICalendarUtil.php @@ -3,11 +3,15 @@ /** * This class contains several utilities related to the ICalendar (rfc2445) format * + * This class is now deprecated, and won't be further maintained. Please use + * the Sabre_VObject package for your ics parsing needs. + * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License + * @deprecated Use Sabre_VObject instead. */ class Sabre_CalDAV_ICalendarUtil { @@ -36,9 +40,6 @@ static function validateICalendarObject($icalData, array $allowedComponents) { $test = $xcal->xpath('/cal:iCalendar/cal:vcalendar/cal:' . $component); if (is_array($test)) $componentsFound = array_merge($componentsFound, $test); } - if (count($componentsFound)>1) { - throw new Sabre_CalDAV_Exception_InvalidICalendarObject('Only 1 of VEVENT, VTODO, VJOURNAL or VFREEBUSY may be specified per calendar object'); - } if (count($componentsFound)<1) { throw new Sabre_CalDAV_Exception_InvalidICalendarObject('One VEVENT, VTODO, VJOURNAL or VFREEBUSY must be specified. 0 found.'); } diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Plugin.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Plugin.php similarity index 82% rename from library/SabreDAV/lib/Sabre/CalDAV/Plugin.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Plugin.php index 7a29891bb..c034950d0 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Plugin.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Plugin.php @@ -8,7 +8,7 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ @@ -83,7 +83,44 @@ public function getHTTPMethods($uri) { */ public function getFeatures() { - return array('calendar-access'); + return array('calendar-access', 'calendar-proxy'); + + } + + /** + * Returns a plugin name. + * + * Using this name other plugins will be able to access other plugins + * using Sabre_DAV_Server::getPlugin + * + * @return string + */ + public function getPluginName() { + + return 'caldav'; + + } + + /** + * Returns a list of reports this plugin supports. + * + * This will be used in the {DAV:}supported-report-set property. + * Note that you still need to subscribe to the 'report' event to actually + * implement them + * + * @param string $uri + * @return array + */ + public function getSupportedReportSet($uri) { + + $node = $this->server->tree->getNodeForPath($uri); + if ($node instanceof Sabre_CalDAV_Calendar || $node instanceof Sabre_CalDAV_CalendarObject) { + return array( + '{' . self::NS_CALDAV . '}calendar-multiget', + '{' . self::NS_CALDAV . '}calendar-query', + ); + } + return array(); } @@ -106,6 +143,10 @@ public function initialize(Sabre_DAV_Server $server) { $server->propertyMap['{' . self::NS_CALDAV . '}supported-calendar-component-set'] = 'Sabre_CalDAV_Property_SupportedCalendarComponentSet'; + $server->resourceTypeMapping['Sabre_CalDAV_Calendar'] = '{urn:ietf:params:xml:ns:caldav}calendar'; + $server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyRead'] = '{http://calendarserver.org/ns/}calendar-proxy-read'; + $server->resourceTypeMapping['Sabre_CalDAV_Principal_ProxyWrite'] = '{http://calendarserver.org/ns/}calendar-proxy-write'; + array_push($server->protectedProperties, '{' . self::NS_CALDAV . '}supported-calendar-component-set', @@ -119,7 +160,12 @@ public function initialize(Sabre_DAV_Server $server) { '{' . self::NS_CALDAV . '}supported-collation-set', // scheduling extension - '{' . self::NS_CALDAV . '}calendar-user-address-set' + '{' . self::NS_CALDAV . '}calendar-user-address-set', + + // CalendarServer extensions + '{' . self::NS_CALENDARSERVER . '}getctag', + '{' . self::NS_CALENDARSERVER . '}calendar-proxy-read-for', + '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for' ); } @@ -156,8 +202,6 @@ public function report($reportName,$dom) { case '{'.self::NS_CALDAV.'}calendar-query' : $this->calendarQueryReport($dom); return false; - default : - return true; } @@ -181,16 +225,21 @@ public function httpMkCalendar($uri) { //} $body = $this->server->httpRequest->getBody(true); - $dom = Sabre_DAV_XMLUtil::loadDOMDocument($body); - $properties = array(); - foreach($dom->firstChild->childNodes as $child) { - if (Sabre_DAV_XMLUtil::toClarkNotation($child)!=='{DAV:}set') continue; - foreach(Sabre_DAV_XMLUtil::parseProperties($child,$this->server->propertyMap) as $k=>$prop) { - $properties[$k] = $prop; + if ($body) { + + $dom = Sabre_DAV_XMLUtil::loadDOMDocument($body); + + + foreach($dom->firstChild->childNodes as $child) { + + if (Sabre_DAV_XMLUtil::toClarkNotation($child)!=='{DAV:}set') continue; + foreach(Sabre_DAV_XMLUtil::parseProperties($child,$this->server->propertyMap) as $k=>$prop) { + $properties[$k] = $prop; + } + } - } $resourceType = array('{DAV:}collection','{urn:ietf:params:xml:ns:caldav}calendar'); @@ -216,7 +265,8 @@ public function afterGetProperties($path, &$properties) { // Find out if we are currently looking at a principal resource $currentNode = $this->server->tree->getNodeForPath($path); - if ($currentNode instanceof Sabre_DAV_Auth_Principal) { + + if ($currentNode instanceof Sabre_DAVACL_IPrincipal) { // calendar-home-set property $calHome = '{' . self::NS_CALDAV . '}calendar-home-set'; @@ -227,37 +277,54 @@ public function afterGetProperties($path, &$properties) { $properties[200][$calHome] = new Sabre_DAV_Property_Href($calendarHomePath); } + // calendar-user-address-set property $calProp = '{' . self::NS_CALDAV . '}calendar-user-address-set'; if (array_key_exists($calProp,$properties[404])) { - // Do we have an email address? - $props = $currentNode->getProperties(array('{http://sabredav.org/ns}email-address')); - if (isset($props['{http://sabredav.org/ns}email-address'])) { - $email = $props['{http://sabredav.org/ns}email-address']; - } else { - // We're going to make up an emailaddress - $email = $currentNode->getName() . '.sabredav@' . $this->server->httpRequest->getHeader('host'); - } - $properties[200][$calProp] = new Sabre_DAV_Property_Href('mailto:' . $email, false); + $addresses = $currentNode->getAlternateUriSet(); + $addresses[] = $this->server->getBaseUri() . $currentNode->getPrincipalUrl(); + $properties[200][$calProp] = new Sabre_DAV_Property_HrefList($addresses, false); unset($properties[404][$calProp]); } + // These two properties are shortcuts for ical to easily find + // other principals this principal has access to. + $propRead = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-read-for'; + $propWrite = '{' . self::NS_CALENDARSERVER . '}calendar-proxy-write-for'; + if (array_key_exists($propRead,$properties[404]) || array_key_exists($propWrite,$properties[404])) { + $membership = $currentNode->getGroupMembership(); + $readList = array(); + $writeList = array(); + + foreach($membership as $group) { + + $groupNode = $this->server->tree->getNodeForPath($group); + + // If the node is either ap proxy-read or proxy-write + // group, we grab the parent principal and add it to the + // list. + if ($groupNode instanceof Sabre_CalDAV_Principal_ProxyRead) { + list($readList[]) = Sabre_DAV_URLUtil::splitPath($group); + } + if ($groupNode instanceof Sabre_CalDAV_Principal_ProxyWrite) { + list($writeList[]) = Sabre_DAV_URLUtil::splitPath($group); + } - } + } + if (array_key_exists($propRead,$properties[404])) { + unset($properties[404][$propRead]); + $properties[200][$propRead] = new Sabre_DAV_Property_HrefList($readList); + } + if (array_key_exists($propWrite,$properties[404])) { + unset($properties[404][$propWrite]); + $properties[200][$propWrite] = new Sabre_DAV_Property_HrefList($writeList); + } - if ($currentNode instanceof Sabre_CalDAV_Calendar || $currentNode instanceof Sabre_CalDAV_CalendarObject) { - if (array_key_exists('{DAV:}supported-report-set', $properties[200])) { - $properties[200]['{DAV:}supported-report-set']->addReport(array( - '{' . self::NS_CALDAV . '}calendar-multiget', - '{' . self::NS_CALDAV . '}calendar-query', - // '{' . self::NS_CALDAV . '}supported-collation-set', - // '{' . self::NS_CALDAV . '}free-busy-query', - )); } - } + } } @@ -391,24 +458,28 @@ public function validateFilters($calendarData,$filters) { if ($result===false) return false; break; case 'vjournal' : + case 'vfreebusy' : + case 'valarm' : // TODO: not implemented break; + + /* + + case 'vjournal' : $result = $this->validateTimeRangeFilterForJournal($xml,$xpath,$filter); if ($result===false) return false; break; case 'vfreebusy' : - // TODO: not implemented - break; $result = $this->validateTimeRangeFilterForFreeBusy($xml,$xpath,$filter); if ($result===false) return false; break; case 'valarm' : - // TODO: not implemented - break; $result = $this->validateTimeRangeFilterForAlarm($xml,$xpath,$filter); if ($result===false) return false; break; + */ + } } @@ -427,6 +498,14 @@ public function validateFilters($calendarData,$filters) { } + /** + * Checks whether a time-range filter matches an event. + * + * @param SimpleXMLElement $xml Event as xml object + * @param string $currentXPath XPath to check + * @param array $currentFilter Filter information + * @return void + */ private function validateTimeRangeFilterForEvent(SimpleXMLElement $xml,$currentXPath,array $currentFilter) { // Grabbing the DTSTART property @@ -467,7 +546,7 @@ private function validateTimeRangeFilterForEvent(SimpleXMLElement $xml,$currentX $tz = null; } - // Since the VALUE parameter of both DTSTART and DTEND must be the same + // Since the VALUE prameter of both DTSTART and DTEND must be the same // we can assume we don't need to check the VALUE paramter of DTEND. if ($isDateTime) { $dtend = Sabre_CalDAV_XMLUtil::parseICalendarDateTime((string)$xdtend[0],$tz); @@ -510,9 +589,13 @@ private function validateTimeRangeFilterForEvent(SimpleXMLElement $xml,$currentX $dtend->modify('+1 day'); } } + // TODO: we need to properly parse RRULE's, but it's very difficult. + // For now, we're always returning events if they have an RRULE at all. + $rrule = $xml->xpath($currentXPath.'/c:rrule'); + $hasRrule = (count($rrule))>0; if (!is_null($currentFilter['time-range']['start']) && $currentFilter['time-range']['start'] >= $dtend) return false; - if (!is_null($currentFilter['time-range']['end']) && $currentFilter['time-range']['end'] <= $dtstart) return false; + if (!is_null($currentFilter['time-range']['end']) && $currentFilter['time-range']['end'] <= $dtstart && !$hasRrule) return false; return true; } diff --git a/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/Collection.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/Collection.php new file mode 100644 index 000000000..13435b244 --- /dev/null +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/Collection.php @@ -0,0 +1,31 @@ +principalBackend, $principalInfo); + + } + +} diff --git a/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/ProxyRead.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/ProxyRead.php new file mode 100644 index 000000000..f531d85d1 --- /dev/null +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/ProxyRead.php @@ -0,0 +1,178 @@ +principalInfo = $principalInfo; + $this->principalBackend = $principalBackend; + + } + + /** + * Returns this principals name. + * + * @return string + */ + public function getName() { + + return 'calendar-proxy-read'; + + } + + /** + * Returns the last modification time + * + * @return null + */ + public function getLastModified() { + + return null; + + } + + /** + * Deletes the current node + * + * @throws Sabre_DAV_Exception_Forbidden + * @return void + */ + public function delete() { + + throw new Sabre_DAV_Exception_Forbidden('Permission denied to delete node'); + + } + + /** + * Renames the node + * + * @throws Sabre_DAV_Exception_Forbidden + * @param string $name The new name + * @return void + */ + public function setName($name) { + + throw new Sabre_DAV_Exception_Forbidden('Permission denied to rename file'); + + } + + + /** + * Returns a list of altenative urls for a principal + * + * This can for example be an email address, or ldap url. + * + * @return array + */ + public function getAlternateUriSet() { + + return array(); + + } + + /** + * Returns the full principal url + * + * @return string + */ + public function getPrincipalUrl() { + + return $this->principalInfo['uri'] . '/' . $this->getName(); + + } + + /** + * Returns the list of group members + * + * If this principal is a group, this function should return + * all member principal uri's for the group. + * + * @return array + */ + public function getGroupMemberSet() { + + return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl()); + + } + + /** + * Returns the list of groups this principal is member of + * + * If this principal is a member of a (list of) groups, this function + * should return a list of principal uri's for it's members. + * + * @return array + */ + public function getGroupMembership() { + + return $this->principalBackend->getGroupMembership($this->getPrincipalUrl()); + + } + + /** + * Sets a list of group members + * + * If this principal is a group, this method sets all the group members. + * The list of members is always overwritten, never appended to. + * + * This method should throw an exception if the members could not be set. + * + * @param array $principals + * @return void + */ + public function setGroupMemberSet(array $principals) { + + $this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals); + + } + + /** + * Returns the displayname + * + * This should be a human readable name for the principal. + * If none is available, return the nodename. + * + * @return string + */ + public function getDisplayName() { + + return $this->getName(); + + } + +} diff --git a/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/ProxyWrite.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/ProxyWrite.php new file mode 100644 index 000000000..4d8face20 --- /dev/null +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/ProxyWrite.php @@ -0,0 +1,178 @@ +principalInfo = $principalInfo; + $this->principalBackend = $principalBackend; + + } + + /** + * Returns this principals name. + * + * @return string + */ + public function getName() { + + return 'calendar-proxy-write'; + + } + + /** + * Returns the last modification time + * + * @return null + */ + public function getLastModified() { + + return null; + + } + + /** + * Deletes the current node + * + * @throws Sabre_DAV_Exception_Forbidden + * @return void + */ + public function delete() { + + throw new Sabre_DAV_Exception_Forbidden('Permission denied to delete node'); + + } + + /** + * Renames the node + * + * @throws Sabre_DAV_Exception_Forbidden + * @param string $name The new name + * @return void + */ + public function setName($name) { + + throw new Sabre_DAV_Exception_Forbidden('Permission denied to rename file'); + + } + + + /** + * Returns a list of altenative urls for a principal + * + * This can for example be an email address, or ldap url. + * + * @return array + */ + public function getAlternateUriSet() { + + return array(); + + } + + /** + * Returns the full principal url + * + * @return string + */ + public function getPrincipalUrl() { + + return $this->principalInfo['uri'] . '/' . $this->getName(); + + } + + /** + * Returns the list of group members + * + * If this principal is a group, this function should return + * all member principal uri's for the group. + * + * @return array + */ + public function getGroupMemberSet() { + + return $this->principalBackend->getGroupMemberSet($this->getPrincipalUrl()); + + } + + /** + * Returns the list of groups this principal is member of + * + * If this principal is a member of a (list of) groups, this function + * should return a list of principal uri's for it's members. + * + * @return array + */ + public function getGroupMembership() { + + return $this->principalBackend->getGroupMembership($this->getPrincipalUrl()); + + } + + /** + * Sets a list of group members + * + * If this principal is a group, this method sets all the group members. + * The list of members is always overwritten, never appended to. + * + * This method should throw an exception if the members could not be set. + * + * @param array $principals + * @return void + */ + public function setGroupMemberSet(array $principals) { + + $this->principalBackend->setGroupMemberSet($this->getPrincipalUrl(), $principals); + + } + + /** + * Returns the displayname + * + * This should be a human readable name for the principal. + * If none is available, return the nodename. + * + * @return string + */ + public function getDisplayName() { + + return $this->getName(); + + } + +} diff --git a/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/User.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/User.php new file mode 100644 index 000000000..034629b89 --- /dev/null +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Principal/User.php @@ -0,0 +1,122 @@ +principalBackend, $this->principalProperties); + + if ($name === 'calendar-proxy-write') + return new Sabre_CalDAV_Principal_ProxyWrite($this->principalBackend, $this->principalProperties); + + throw new Sabre_DAV_Exception_FileNotFound('Node with name ' . $name . ' was not found'); + + } + + /** + * Returns an array with all the child nodes + * + * @return Sabre_DAV_INode[] + */ + public function getChildren() { + + return array( + new Sabre_CalDAV_Principal_ProxyRead($this->principalBackend, $this->principalProperties), + new Sabre_CalDAV_Principal_ProxyWrite($this->principalBackend, $this->principalProperties), + ); + + } + + /** + * Checks if a child-node with the specified name exists + * + * @return bool + */ + public function childExists($name) { + + return $name === 'calendar-proxy-read' || $name === 'calendar-proxy-write'; + + } + + /** + * Returns a list of ACE's for this node. + * + * Each ACE has the following properties: + * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are + * currently the only supported privileges + * * 'principal', a url to the principal who owns the node + * * 'protected' (optional), indicating that this ACE is not allowed to + * be updated. + * + * @return array + */ + public function getACL() { + + return array( + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->principalProperties['uri'], + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->principalProperties['uri'] . '/calendar-proxy-read', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->principalProperties['uri'] . '/calendar-proxy-write', + 'protected' => true, + ), + ); + + } + +} diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php similarity index 96% rename from library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php index 5a1862d03..1bbaca6b8 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php @@ -9,7 +9,7 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarData.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarData.php similarity index 94% rename from library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarData.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarData.php index 3e9a9d765..5010ee6d5 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarData.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCalendarData.php @@ -9,7 +9,7 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCollationSet.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCollationSet.php similarity index 73% rename from library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCollationSet.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCollationSet.php index 2f96591b7..515efb645 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCollationSet.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Property/SupportedCollationSet.php @@ -8,13 +8,20 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ class Sabre_CalDAV_Property_SupportedCollationSet extends Sabre_DAV_Property { - function serialize(Sabre_DAV_Server $server,DOMElement $node) { + /** + * Serializes the property in a DOM document + * + * @param Sabre_DAV_Server $server + * @param DOMElement $node + * @return void + */ + public function serialize(Sabre_DAV_Server $server,DOMElement $node) { $doc = $node->ownerDocument; diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Server.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Server.php similarity index 51% rename from library/SabreDAV/lib/Sabre/CalDAV/Server.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Server.php index 33f7a39c1..969d69c62 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Server.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Server.php @@ -6,15 +6,29 @@ * This script is a convenience script. It quickly sets up a WebDAV server * with caldav and ACL support, and it creates the root 'principals' and * 'calendars' collections. + * + * Note that if you plan to do anything moderately complex, you are advised to + * not subclass this server, but use Sabre_DAV_Server directly instead. This + * class is nothing more than an 'easy setup'. * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ class Sabre_CalDAV_Server extends Sabre_DAV_Server { + /** + * The authentication realm + * + * Note that if this changes, the hashes in the auth backend must also + * be recalculated. + * + * @var string + */ + public $authRealm = 'SabreDAV'; + /** * Sets up the object. A PDO object must be passed to setup all the backends. * @@ -25,23 +39,24 @@ public function __construct(PDO $pdo) { /* Backends */ $authBackend = new Sabre_DAV_Auth_Backend_PDO($pdo); $calendarBackend = new Sabre_CalDAV_Backend_PDO($pdo); + $principalBackend = new Sabre_DAVACL_PrincipalBackend_PDO($pdo); /* Directory structure */ - $root = new Sabre_DAV_SimpleDirectory('root'); - $principals = new Sabre_DAV_Auth_PrincipalCollection($authBackend); - $root->addChild($principals); - $calendars = new Sabre_CalDAV_CalendarRootNode($authBackend, $calendarBackend); - $root->addChild($calendars); - - $objectTree = new Sabre_DAV_ObjectTree($root); - + $tree = array( + new Sabre_CalDAV_Principal_Collection($principalBackend), + new Sabre_CalDAV_CalendarRootNode($principalBackend, $calendarBackend), + ); + /* Initializing server */ - parent::__construct($objectTree); + parent::__construct($tree); /* Server Plugins */ - $authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,'SabreDAV'); + $authPlugin = new Sabre_DAV_Auth_Plugin($authBackend,$this->authRealm); $this->addPlugin($authPlugin); + $aclPlugin = new Sabre_DAVACL_Plugin(); + $this->addPlugin($aclPlugin); + $caldavPlugin = new Sabre_CalDAV_Plugin(); $this->addPlugin($caldavPlugin); diff --git a/library/SabreDAV/lib/Sabre/CalDAV/UserCalendars.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/UserCalendars.php similarity index 53% rename from library/SabreDAV/lib/Sabre/CalDAV/UserCalendars.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/UserCalendars.php index c81b70bad..f52d65e9a 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/UserCalendars.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/UserCalendars.php @@ -5,45 +5,45 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection { +class Sabre_CalDAV_UserCalendars implements Sabre_DAV_IExtendedCollection, Sabre_DAVACL_IACL { /** - * Authentication backend + * Principal backend * - * @var Sabre_DAV_Auth_Backend_Abstract + * @var Sabre_DAVACL_IPrincipalBackend */ - protected $authBackend; + protected $principalBackend; /** - * Array with user information + * CalDAV backend * - * @var array + * @var Sabre_CalDAV_Backend_Abstract */ - protected $userUri; + protected $caldavBackend; /** - * CalDAV backend + * Principal information * - * @var Sabre_CalDAV_Backend_Abstract + * @var array */ - protected $caldavBackend; + protected $principalInfo; /** * Constructor * - * @param Sabre_DAV_Auth_Backend_Abstract $authBackend + * @param Sabre_DAVACL_IPrincipalBackend $principalBackend * @param Sabre_CalDAV_Backend_Abstract $caldavBackend * @param mixed $userUri */ - public function __construct(Sabre_DAV_Auth_Backend_Abstract $authBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend, $userUri) { + public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, Sabre_CalDAV_Backend_Abstract $caldavBackend, $userUri) { - $this->authBackend = $authBackend; + $this->principalBackend = $principalBackend; $this->caldavBackend = $caldavBackend; - $this->userUri = $userUri; + $this->principalInfo = $principalBackend->getPrincipalByPath($userUri); } @@ -54,7 +54,7 @@ public function __construct(Sabre_DAV_Auth_Backend_Abstract $authBackend, Sabre_ */ public function getName() { - list(,$name) = Sabre_DAV_URLUtil::splitPath($this->userUri); + list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalInfo['uri']); return $name; } @@ -165,10 +165,10 @@ public function childExists($name) { */ public function getChildren() { - $calendars = $this->caldavBackend->getCalendarsForUser($this->userUri); + $calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']); $objs = array(); foreach($calendars as $calendar) { - $objs[] = new Sabre_CalDAV_Calendar($this->authBackend, $this->caldavBackend, $calendar); + $objs[] = new Sabre_CalDAV_Calendar($this->principalBackend, $this->caldavBackend, $calendar); } return $objs; @@ -186,8 +186,95 @@ public function createExtendedCollection($name, array $resourceType, array $prop if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar',$resourceType) || count($resourceType)!==2) { throw new Sabre_DAV_Exception_InvalidResourceType('Unknown resourceType for this collection'); } - $this->caldavBackend->createCalendar($this->userUri, $name, $properties); + $this->caldavBackend->createCalendar($this->principalInfo['uri'], $name, $properties); + + } + + /** + * Returns the owner principal + * + * This must be a url to a principal, or null if there's no owner + * + * @return string|null + */ + public function getOwner() { + + return $this->principalInfo['uri']; } + /** + * Returns a group principal + * + * This must be a url to a principal, or null if there's no owner + * + * @return string|null + */ + public function getGroup() { + + return null; + + } + + /** + * Returns a list of ACE's for this node. + * + * Each ACE has the following properties: + * * 'privilege', a string such as {DAV:}read or {DAV:}write. These are + * currently the only supported privileges + * * 'principal', a url to the principal who owns the node + * * 'protected' (optional), indicating that this ACE is not allowed to + * be updated. + * + * @return array + */ + public function getACL() { + + return array( + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->principalInfo['uri'], + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}write', + 'principal' => $this->principalInfo['uri'], + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->principalInfo['uri'] . '/calendar-proxy-write', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}write', + 'principal' => $this->principalInfo['uri'] . '/calendar-proxy-write', + 'protected' => true, + ), + array( + 'privilege' => '{DAV:}read', + 'principal' => $this->principalInfo['uri'] . '/calendar-proxy-read', + 'protected' => true, + ), + + ); + + } + + /** + * Updates the ACL + * + * This method will receive a list of new ACE's. + * + * @param array $acl + * @return void + */ + public function setACL(array $acl) { + + throw new Sabre_DAV_Exception_MethodNotAllowed('Changing ACL is not yet supported'); + + } + + + } diff --git a/library/SabreDAV/lib/Sabre/CalDAV/Version.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Version.php similarity index 76% rename from library/SabreDAV/lib/Sabre/CalDAV/Version.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Version.php index d7b2e6aff..2ce00cd42 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/Version.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/Version.php @@ -5,7 +5,7 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ @@ -14,11 +14,11 @@ class Sabre_CalDAV_Version { /** * Full version number */ - const VERSION = '1.3.0'; + const VERSION = '1.4.2'; /** * Stability : alpha, beta, stable */ - const STABILITY = 'stable'; + const STABILITY = 'beta'; } diff --git a/library/SabreDAV/lib/Sabre/CalDAV/XMLUtil.php b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/XMLUtil.php similarity index 97% rename from library/SabreDAV/lib/Sabre/CalDAV/XMLUtil.php rename to modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/XMLUtil.php index dfa58a0a7..bf349a36a 100644 --- a/library/SabreDAV/lib/Sabre/CalDAV/XMLUtil.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/CalDAV/XMLUtil.php @@ -8,7 +8,7 @@ * * @package Sabre * @subpackage CalDAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ @@ -100,7 +100,7 @@ static public function parseCalendarQueryFilters($domNode,$basePath = '/c:iCalen if (!$collation) $collation = 'i;ascii-casemap'; $filters[$basePath]['text-match'] = array( - 'collation' => $collation, + 'collation' => ($collation == 'default'?'i;ascii-casemap':$collation), 'negate-condition' => $child->getAttribute('negate-condition')==='yes', 'value' => $child->nodeValue, ); diff --git a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php similarity index 66% rename from library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php rename to modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php index e81ca00f2..11bab8c7a 100644 --- a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractBasic.php @@ -4,43 +4,40 @@ * * This class can be used by authentication objects wishing to use HTTP Basic * Most of the digest logic is handled, implementors just need to worry about - * the authenticateInternal and getUserInfo methods + * the validateUserPass method. * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author James David Low (http://jameslow.com/) * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Sabre_DAV_Auth_Backend_AbstractBasic extends Sabre_DAV_Auth_Backend_Abstract { +abstract class Sabre_DAV_Auth_Backend_AbstractBasic implements Sabre_DAV_Auth_IBackend { /** - * This variable holds information about the currently - * logged in user. + * This variable holds the currently logged in username. * - * @var array|null + * @var string|null */ protected $currentUser; /** * Validates a username and password * - * If the username and password were correct, this method must return - * an array with at least a 'uri' key. + * This method should return true or false depending on if login + * succeeded. * - * If the credentials are incorrect, this method must return false. - * - * @return bool|array + * @return bool */ abstract protected function validateUserPass($username, $password); /** - * Returns information about the currently logged in user. + * Returns information about the currently logged in username. * * If nobody is currently logged in, this method should return null. * - * @return array|null + * @return string|null */ public function getCurrentUser() { return $this->currentUser; @@ -69,14 +66,11 @@ public function authenticate(Sabre_DAV_Server $server,$realm) { } // Authenticates the user - if (!($userData = $this->validateUserPass($userpass[0],$userpass[1]))) { + if (!$this->validateUserPass($userpass[0],$userpass[1])) { $auth->requireLogin(); throw new Sabre_DAV_Exception_NotAuthenticated('Username or password does not match'); } - if (!isset($userData['uri'])) { - throw new Sabre_DAV_Exception('The returned array from validateUserPass must contain at a uri element'); - } - $this->currentUser = $userData; + $this->currentUser = $userpass[0]; return true; } diff --git a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php similarity index 61% rename from library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php rename to modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php index d8cdcb184..5bdc72753 100644 --- a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/AbstractDigest.php @@ -5,38 +5,33 @@ * * This class can be used by authentication objects wishing to use HTTP Digest * Most of the digest logic is handled, implementors just need to worry about - * the getUserInfo method + * the getDigestHash method * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Sabre_DAV_Auth_Backend_AbstractDigest extends Sabre_DAV_Auth_Backend_Abstract { +abstract class Sabre_DAV_Auth_Backend_AbstractDigest implements Sabre_DAV_Auth_IBackend { /** - * This variable holds information about the currently - * logged in user. + * This variable holds the currently logged in username. * * @var array|null */ protected $currentUser; /** - * Returns a users information based on its username + * Returns a users digest hash based on the username and realm. * - * The returned struct must contain at least a uri - * element (which can be identical to username) as well as a digestHash - * element. - * - * If the user was not known, false must be returned. + * If the user was not known, null must be returned. * * @param string $realm * @param string $username - * @return array + * @return string|null */ - abstract public function getUserInfo($realm, $username); + abstract public function getDigestHash($realm,$username); /** * Authenticates the user based on the current request. @@ -66,35 +61,31 @@ public function authenticate(Sabre_DAV_Server $server,$realm) { throw new Sabre_DAV_Exception_NotAuthenticated('No digest authentication headers were found'); } - $userData = $this->getUserInfo($realm, $username); + $hash = $this->getDigestHash($realm, $username); // If this was false, the user account didn't exist - if ($userData===false) { + if ($hash===false || is_null($hash)) { $digest->requireLogin(); throw new Sabre_DAV_Exception_NotAuthenticated('The supplied username was not on file'); } - if (!is_array($userData)) { - throw new Sabre_DAV_Exception('The returntype for getUserInfo must be either false or an array'); - } - - if (!isset($userData['uri']) || !isset($userData['digestHash'])) { - throw new Sabre_DAV_Exception('The returned array from getUserInfo must contain at least a uri and digestHash element'); + if (!is_string($hash)) { + throw new Sabre_DAV_Exception('The returned value from getDigestHash must be a string or null'); } // If this was false, the password or part of the hash was incorrect. - if (!$digest->validateA1($userData['digestHash'])) { + if (!$digest->validateA1($hash)) { $digest->requireLogin(); throw new Sabre_DAV_Exception_NotAuthenticated('Incorrect username'); } - $this->currentUser = $userData; + $this->currentUser = $username; return true; } /** - * Returns information about the currently logged in user. + * Returns the currently logged in username. * - * @return array|null + * @return string|null */ public function getCurrentUser() { diff --git a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/Apache.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/Apache.php similarity index 69% rename from library/SabreDAV/lib/Sabre/DAV/Auth/Backend/Apache.php rename to modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/Apache.php index 0b46270fa..6bcd76bdc 100644 --- a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/Apache.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/Apache.php @@ -3,18 +3,18 @@ /** * Apache authenticator * - * This authentication backend assumes that auhtentication has been + * This authentication backend assumes that authentication has been * conifgured in apache, rather than within SabreDAV. * * Make sure apache is properly configured for this to work. * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -class Sabre_DAV_Auth_Backend_Apache extends Sabre_DAV_Auth_Backend_Abstract { +class Sabre_DAV_Auth_Backend_Apache implements Sabre_DAV_Auth_IBackend { /** * Current apache user @@ -52,24 +52,7 @@ public function authenticate(Sabre_DAV_Server $server,$realm) { */ public function getCurrentUser() { - return array( - 'uri' => 'principals/' . $this->remoteUser, - ); - - } - - /** - * Returns the full list of users. - * - * This method must at least return a uri for each user. - * - * It is optional to implement this. - * - * @return array - */ - public function getUsers() { - - return array($this->getCurrentUser()); + return $this->remoteUser; } diff --git a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/File.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/File.php similarity index 73% rename from library/SabreDAV/lib/Sabre/DAV/Auth/Backend/File.php rename to modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/File.php index 953c49e67..f11ef40d8 100644 --- a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/File.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/File.php @@ -7,7 +7,7 @@ * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ @@ -54,10 +54,7 @@ public function loadFile($filename) { if (!preg_match('/^[a-zA-Z0-9]{32}$/', $A1)) throw new Sabre_DAV_Exception('Malformed htdigest file. Invalid md5 hash'); - $this->users[$username] = array( - 'digestHash' => $A1, - 'uri' => 'principals/' . $username - ); + $this->users[$username] = $A1; } @@ -70,33 +67,10 @@ public function loadFile($filename) { * @param string $username * @return string */ - public function getUserInfo($realm, $username) { + public function getDigestHash($realm, $username) { return isset($this->users[$username])?$this->users[$username]:false; } - - /** - * Returns the full list of users. - * - * This method must at least return a uri for each user. - * - * @return array - */ - public function getUsers() { - - $re = array(); - foreach($this->users as $userName=>$A1) { - - $re[] = array( - 'uri'=>'principals/' . $userName - ); - - } - - return $re; - - } - } diff --git a/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/PDO.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/PDO.php new file mode 100644 index 000000000..ed743477f --- /dev/null +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/PDO.php @@ -0,0 +1,51 @@ +pdo = $pdo; + + } + + /** + * Returns the digest hash for a user. + * + * @param string $realm + * @param string $username + * @return string|null + */ + public function getDigestHash($realm,$username) { + + $stmt = $this->pdo->prepare('SELECT username, digesta1 FROM users WHERE username = ?'); + $stmt->execute(array($username)); + $result = $stmt->fetchAll(); + + if (!count($result)) return; + + return $result[0]['digesta1']; + + } + +} diff --git a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/Abstract.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/IBackend.php similarity index 50% rename from library/SabreDAV/lib/Sabre/DAV/Auth/Backend/Abstract.php rename to modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/IBackend.php index 79383fa31..1f67af4c2 100644 --- a/library/SabreDAV/lib/Sabre/DAV/Auth/Backend/Abstract.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/IBackend.php @@ -5,11 +5,11 @@ * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ -abstract class Sabre_DAV_Auth_Backend_Abstract { +interface Sabre_DAV_Auth_IBackend { /** * Authenticates the user based on the current request. @@ -19,31 +19,16 @@ abstract class Sabre_DAV_Auth_Backend_Abstract { * * @return bool */ - abstract public function authenticate(Sabre_DAV_Server $server,$realm); + function authenticate(Sabre_DAV_Server $server,$realm); /** - * Returns information about the currently logged in user. + * Returns information about the currently logged in username. * * If nobody is currently logged in, this method should return null. * - * @return array|null + * @return string|null */ - abstract public function getCurrentUser(); - - /** - * Returns the full list of users. - * - * This method must at least return a uri for each user. - * - * It is optional to implement this. - * - * @return array - */ - public function getUsers() { - - return array(); - - } + function getCurrentUser(); } diff --git a/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Plugin.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Plugin.php new file mode 100644 index 000000000..f3718fcf4 --- /dev/null +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Auth/Plugin.php @@ -0,0 +1,111 @@ +authBackend = $authBackend; + $this->realm = $realm; + + } + + /** + * Initializes the plugin. This function is automatically called by the server + * + * @param Sabre_DAV_Server $server + * @return void + */ + public function initialize(Sabre_DAV_Server $server) { + + $this->server = $server; + $this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'),10); + + } + + /** + * Returns a plugin name. + * + * Using this name other plugins will be able to access other plugins + * using Sabre_DAV_Server::getPlugin + * + * @return string + */ + public function getPluginName() { + + return 'auth'; + + } + + /** + * Returns the current users' principal uri. + * + * If nobody is logged in, this will return null. + * + * @return string|null + */ + public function getCurrentUser() { + + $userInfo = $this->authBackend->getCurrentUser(); + if (!$userInfo) return null; + + return $userInfo; + + } + + /** + * This method is called before any HTTP method and forces users to be authenticated + * + * @param string $method + * @throws Sabre_DAV_Exception_NotAuthenticated + * @return bool + */ + public function beforeMethod($method, $uri) { + + $this->authBackend->authenticate($this->server,$this->realm); + + } + +} diff --git a/library/SabreDAV/lib/Sabre/DAV/Browser/GuessContentType.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Browser/GuessContentType.php similarity index 97% rename from library/SabreDAV/lib/Sabre/DAV/Browser/GuessContentType.php rename to modules/webdav/library/SabreDAV/lib/Sabre/DAV/Browser/GuessContentType.php index 430ebde87..8b55ec3ad 100644 --- a/library/SabreDAV/lib/Sabre/DAV/Browser/GuessContentType.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Browser/GuessContentType.php @@ -13,7 +13,7 @@ * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ diff --git a/library/SabreDAV/lib/Sabre/DAV/Browser/MapGetToPropFind.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Browser/MapGetToPropFind.php similarity index 95% rename from library/SabreDAV/lib/Sabre/DAV/Browser/MapGetToPropFind.php rename to modules/webdav/library/SabreDAV/lib/Sabre/DAV/Browser/MapGetToPropFind.php index df60ae435..a66b57a3a 100644 --- a/library/SabreDAV/lib/Sabre/DAV/Browser/MapGetToPropFind.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Browser/MapGetToPropFind.php @@ -8,7 +8,7 @@ * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ diff --git a/library/SabreDAV/lib/Sabre/DAV/Browser/Plugin.php b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Browser/Plugin.php similarity index 88% rename from library/SabreDAV/lib/Sabre/DAV/Browser/Plugin.php rename to modules/webdav/library/SabreDAV/lib/Sabre/DAV/Browser/Plugin.php index f718b4fe9..ffc33747f 100644 --- a/library/SabreDAV/lib/Sabre/DAV/Browser/Plugin.php +++ b/modules/webdav/library/SabreDAV/lib/Sabre/DAV/Browser/Plugin.php @@ -11,7 +11,7 @@ * * @package Sabre * @subpackage DAV - * @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved. + * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved. * @author Evert Pot (http://www.rooftopsolutions.nl/) * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License */ @@ -165,6 +165,21 @@ public function generateDirectoryIndex($path) { '{DAV:}getlastmodified', ),1); + + if ($path) { + + list($parentUri) = Sabre_DAV_URLUtil::splitPath($path); + $fullPath = Sabre_DAV_URLUtil::encodePath($this->server->getBaseUri() . $parentUri); + + $html.= "