forked from friendica/deprecated-addons
moved deprecated communityhome, dav and yourls to the deprecated-addons repository
This commit is contained in:
parent
24444adef3
commit
31520f804d
675 changed files with 195144 additions and 0 deletions
154
dav/SabreDAV/lib/Sabre/DAVACL/AbstractPrincipalCollection.php
Normal file
154
dav/SabreDAV/lib/Sabre/DAVACL/AbstractPrincipalCollection.php
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Principals Collection
|
||||
*
|
||||
* This is a helper class that easily allows you to create a collection that
|
||||
* has a childnode for every principal.
|
||||
*
|
||||
* To use this class, simply implement the getChildForPrincipal method.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_AbstractPrincipalCollection extends Sabre_DAV_Collection {
|
||||
|
||||
/**
|
||||
* Node or 'directory' name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Principal backend
|
||||
*
|
||||
* @var Sabre_DAVACL_IPrincipalBackend
|
||||
*/
|
||||
protected $principalBackend;
|
||||
|
||||
/**
|
||||
* If this value is set to true, it effectively disables listing of users
|
||||
* it still allows user to find other users if they have an exact url.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $disableListing = false;
|
||||
|
||||
/**
|
||||
* Creates the object
|
||||
*
|
||||
* This object must be passed the principal backend. This object will
|
||||
* filter all principals from a specified prefix ($principalPrefix). The
|
||||
* default is 'principals', if your principals are stored in a different
|
||||
* collection, override $principalPrefix
|
||||
*
|
||||
*
|
||||
* @param Sabre_DAVACL_IPrincipalBackend $principalBackend
|
||||
* @param string $principalPrefix
|
||||
*/
|
||||
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, $principalPrefix = 'principals') {
|
||||
|
||||
$this->principalPrefix = $principalPrefix;
|
||||
$this->principalBackend = $principalBackend;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $principalInfo
|
||||
* @return Sabre_DAVACL_IPrincipal
|
||||
*/
|
||||
abstract function getChildForPrincipal(array $principalInfo);
|
||||
|
||||
/**
|
||||
* Returns the name of this collection.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
|
||||
list(,$name) = Sabre_DAV_URLUtil::splitPath($this->principalPrefix);
|
||||
return $name;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of users
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getChildren() {
|
||||
|
||||
if ($this->disableListing)
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed('Listing members of this collection is disabled');
|
||||
|
||||
$children = array();
|
||||
foreach($this->principalBackend->getPrincipalsByPrefix($this->principalPrefix) as $principalInfo) {
|
||||
|
||||
$children[] = $this->getChildForPrincipal($principalInfo);
|
||||
|
||||
|
||||
}
|
||||
return $children;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a child object, by its name.
|
||||
*
|
||||
* @param string $name
|
||||
* @throws Sabre_DAV_Exception_NotFound
|
||||
* @return Sabre_DAVACL_IPrincipal
|
||||
*/
|
||||
public function getChild($name) {
|
||||
|
||||
$principalInfo = $this->principalBackend->getPrincipalByPath($this->principalPrefix . '/' . $name);
|
||||
if (!$principalInfo) throw new Sabre_DAV_Exception_NotFound('Principal with name ' . $name . ' not found');
|
||||
return $this->getChildForPrincipal($principalInfo);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to search for principals matching a set of
|
||||
* properties.
|
||||
*
|
||||
* This search is specifically used by RFC3744's principal-property-search
|
||||
* REPORT. You should at least allow searching on
|
||||
* http://sabredav.org/ns}email-address.
|
||||
*
|
||||
* The actual search should be a unicode-non-case-sensitive search. The
|
||||
* keys in searchProperties are the WebDAV property names, while the values
|
||||
* are the property values to search on.
|
||||
*
|
||||
* If multiple properties are being searched on, the search should be
|
||||
* AND'ed.
|
||||
*
|
||||
* This method should simply return a list of 'child names', which may be
|
||||
* used to call $this->getChild in the future.
|
||||
*
|
||||
* @param array $searchProperties
|
||||
* @return array
|
||||
*/
|
||||
public function searchPrincipals(array $searchProperties) {
|
||||
|
||||
$result = $this->principalBackend->searchPrincipals($this->principalPrefix, $searchProperties);
|
||||
$r = array();
|
||||
|
||||
foreach($result as $row) {
|
||||
list(, $r[]) = Sabre_DAV_URLUtil::splitPath($row);
|
||||
}
|
||||
|
||||
return $r;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
32
dav/SabreDAV/lib/Sabre/DAVACL/Exception/AceConflict.php
Normal file
32
dav/SabreDAV/lib/Sabre/DAVACL/Exception/AceConflict.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Sabre_DAVACL_Exception_AceConflict
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Exception_AceConflict extends Sabre_DAV_Exception_Conflict {
|
||||
|
||||
/**
|
||||
* Adds in extra information in the xml response.
|
||||
*
|
||||
* This method adds the {DAV:}no-ace-conflict element as defined in rfc3744
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $errorNode
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
|
||||
|
||||
$doc = $errorNode->ownerDocument;
|
||||
|
||||
$np = $doc->createElementNS('DAV:','d:no-ace-conflict');
|
||||
$errorNode->appendChild($np);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
81
dav/SabreDAV/lib/Sabre/DAVACL/Exception/NeedPrivileges.php
Normal file
81
dav/SabreDAV/lib/Sabre/DAVACL/Exception/NeedPrivileges.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* NeedPrivileges
|
||||
*
|
||||
* The 403-need privileges is thrown when a user didn't have the appropriate
|
||||
* permissions to perform an operation
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Exception_NeedPrivileges extends Sabre_DAV_Exception_Forbidden {
|
||||
|
||||
/**
|
||||
* The relevant uri
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $uri;
|
||||
|
||||
/**
|
||||
* The privileges the user didn't have.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $privileges;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array $privileges
|
||||
*/
|
||||
public function __construct($uri,array $privileges) {
|
||||
|
||||
$this->uri = $uri;
|
||||
$this->privileges = $privileges;
|
||||
|
||||
parent::__construct('User did not have the required privileges (' . implode(',', $privileges) . ') for path "' . $uri . '"');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds in extra information in the xml response.
|
||||
*
|
||||
* This method adds the {DAV:}need-privileges element as defined in rfc3744
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $errorNode
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
|
||||
|
||||
$doc = $errorNode->ownerDocument;
|
||||
|
||||
$np = $doc->createElementNS('DAV:','d:need-privileges');
|
||||
$errorNode->appendChild($np);
|
||||
|
||||
foreach($this->privileges as $privilege) {
|
||||
|
||||
$resource = $doc->createElementNS('DAV:','d:resource');
|
||||
$np->appendChild($resource);
|
||||
|
||||
$resource->appendChild($doc->createElementNS('DAV:','d:href',$server->getBaseUri() . $this->uri));
|
||||
|
||||
$priv = $doc->createElementNS('DAV:','d:privilege');
|
||||
$resource->appendChild($priv);
|
||||
|
||||
preg_match('/^{([^}]*)}(.*)$/',$privilege,$privilegeParts);
|
||||
$priv->appendChild($doc->createElementNS($privilegeParts[1],'d:' . $privilegeParts[2]));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
32
dav/SabreDAV/lib/Sabre/DAVACL/Exception/NoAbstract.php
Normal file
32
dav/SabreDAV/lib/Sabre/DAVACL/Exception/NoAbstract.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Sabre_DAVACL_Exception_NoAbstract
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Exception_NoAbstract extends Sabre_DAV_Exception_PreconditionFailed {
|
||||
|
||||
/**
|
||||
* Adds in extra information in the xml response.
|
||||
*
|
||||
* This method adds the {DAV:}no-abstract element as defined in rfc3744
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $errorNode
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
|
||||
|
||||
$doc = $errorNode->ownerDocument;
|
||||
|
||||
$np = $doc->createElementNS('DAV:','d:no-abstract');
|
||||
$errorNode->appendChild($np);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Sabre_DAVACL_Exception_NotRecognizedPrincipal
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Exception_NotRecognizedPrincipal extends Sabre_DAV_Exception_PreconditionFailed {
|
||||
|
||||
/**
|
||||
* Adds in extra information in the xml response.
|
||||
*
|
||||
* This method adds the {DAV:}recognized-principal element as defined in rfc3744
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $errorNode
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
|
||||
|
||||
$doc = $errorNode->ownerDocument;
|
||||
|
||||
$np = $doc->createElementNS('DAV:','d:recognized-principal');
|
||||
$errorNode->appendChild($np);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Sabre_DAVACL_Exception_NotSupportedPrivilege
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Exception_NotSupportedPrivilege extends Sabre_DAV_Exception_PreconditionFailed {
|
||||
|
||||
/**
|
||||
* Adds in extra information in the xml response.
|
||||
*
|
||||
* This method adds the {DAV:}not-supported-privilege element as defined in rfc3744
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $errorNode
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $errorNode) {
|
||||
|
||||
$doc = $errorNode->ownerDocument;
|
||||
|
||||
$np = $doc->createElementNS('DAV:','d:not-supported-privilege');
|
||||
$errorNode->appendChild($np);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
73
dav/SabreDAV/lib/Sabre/DAVACL/IACL.php
Normal file
73
dav/SabreDAV/lib/Sabre/DAVACL/IACL.php
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* ACL-enabled node
|
||||
*
|
||||
* If you want to add WebDAV ACL to a node, you must implement this class
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
interface Sabre_DAVACL_IACL extends Sabre_DAV_INode {
|
||||
|
||||
/**
|
||||
* Returns the owner principal
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getOwner();
|
||||
|
||||
/**
|
||||
* Returns a group principal
|
||||
*
|
||||
* This must be a url to a principal, or null if there's no owner
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
function getGroup();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function getACL();
|
||||
|
||||
/**
|
||||
* Updates the ACL
|
||||
*
|
||||
* This method will receive a list of new ACE's as an array argument.
|
||||
*
|
||||
* @param array $acl
|
||||
* @return void
|
||||
*/
|
||||
function setACL(array $acl);
|
||||
|
||||
/**
|
||||
* Returns the list of supported privileges for this node.
|
||||
*
|
||||
* The returned data structure is a list of nested privileges.
|
||||
* See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
|
||||
* standard structure.
|
||||
*
|
||||
* If null is returned from this method, the default privilege set is used,
|
||||
* which is fine for most common usecases.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
function getSupportedPrivilegeSet();
|
||||
|
||||
|
||||
}
|
||||
75
dav/SabreDAV/lib/Sabre/DAVACL/IPrincipal.php
Normal file
75
dav/SabreDAV/lib/Sabre/DAVACL/IPrincipal.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* IPrincipal interface
|
||||
*
|
||||
* Implement this interface to define your own principals
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
interface Sabre_DAVACL_IPrincipal extends Sabre_DAV_INode {
|
||||
|
||||
/**
|
||||
* Returns a list of alternative urls for a principal
|
||||
*
|
||||
* This can for example be an email address, or ldap url.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getAlternateUriSet();
|
||||
|
||||
/**
|
||||
* Returns the full principal url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getPrincipalUrl();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function getGroupMemberSet();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function getGroupMembership();
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
function setGroupMemberSet(array $principals);
|
||||
|
||||
/**
|
||||
* Returns the displayname
|
||||
*
|
||||
* This should be a human readable name for the principal.
|
||||
* If none is available, return the nodename.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function getDisplayName();
|
||||
|
||||
}
|
||||
153
dav/SabreDAV/lib/Sabre/DAVACL/IPrincipalBackend.php
Normal file
153
dav/SabreDAV/lib/Sabre/DAVACL/IPrincipalBackend.php
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Implement this interface to create your own principal backends.
|
||||
*
|
||||
* Creating backends for principals is entirely optional. You can also
|
||||
* implement Sabre_DAVACL_IPrincipal directly. This interface is used solely by
|
||||
* Sabre_DAVACL_AbstractPrincipalCollection.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
interface Sabre_DAVACL_IPrincipalBackend {
|
||||
|
||||
/**
|
||||
* Returns a list of principals based on a prefix.
|
||||
*
|
||||
* This prefix will often contain something like 'principals'. You are only
|
||||
* expected to return principals that are in this base path.
|
||||
*
|
||||
* You are expected to return at least a 'uri' for every user, you can
|
||||
* return any additional properties if you wish so. Common properties are:
|
||||
* {DAV:}displayname
|
||||
* {http://sabredav.org/ns}email-address - This is a custom SabreDAV
|
||||
* field that's actually injected in a number of other properties. If
|
||||
* you have an email address, use this property.
|
||||
*
|
||||
* @param string $prefixPath
|
||||
* @return array
|
||||
*/
|
||||
function getPrincipalsByPrefix($prefixPath);
|
||||
|
||||
/**
|
||||
* Returns a specific principal, specified by it's path.
|
||||
* The returned structure should be the exact same as from
|
||||
* getPrincipalsByPrefix.
|
||||
*
|
||||
* @param string $path
|
||||
* @return array
|
||||
*/
|
||||
function getPrincipalByPath($path);
|
||||
|
||||
/**
|
||||
* Updates one ore more webdav properties on a principal.
|
||||
*
|
||||
* The list of mutations is supplied as an array. Each key in the array is
|
||||
* a propertyname, such as {DAV:}displayname.
|
||||
*
|
||||
* Each value is the actual value to be updated. If a value is null, it
|
||||
* must be deleted.
|
||||
*
|
||||
* This method should be atomic. It must either completely succeed, or
|
||||
* completely fail. Success and failure can simply be returned as 'true' or
|
||||
* 'false'.
|
||||
*
|
||||
* It is also possible to return detailed failure information. In that case
|
||||
* an array such as this should be returned:
|
||||
*
|
||||
* array(
|
||||
* 200 => array(
|
||||
* '{DAV:}prop1' => null,
|
||||
* ),
|
||||
* 201 => array(
|
||||
* '{DAV:}prop2' => null,
|
||||
* ),
|
||||
* 403 => array(
|
||||
* '{DAV:}prop3' => null,
|
||||
* ),
|
||||
* 424 => array(
|
||||
* '{DAV:}prop4' => null,
|
||||
* ),
|
||||
* );
|
||||
*
|
||||
* In this previous example prop1 was successfully updated or deleted, and
|
||||
* prop2 was succesfully created.
|
||||
*
|
||||
* prop3 failed to update due to '403 Forbidden' and because of this prop4
|
||||
* also could not be updated with '424 Failed dependency'.
|
||||
*
|
||||
* This last example was actually incorrect. While 200 and 201 could appear
|
||||
* in 1 response, if there's any error (403) the other properties should
|
||||
* always fail with 423 (failed dependency).
|
||||
*
|
||||
* But anyway, if you don't want to scratch your head over this, just
|
||||
* return true or false.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $mutations
|
||||
* @return array|bool
|
||||
*/
|
||||
function updatePrincipal($path, $mutations);
|
||||
|
||||
/**
|
||||
* This method is used to search for principals matching a set of
|
||||
* properties.
|
||||
*
|
||||
* This search is specifically used by RFC3744's principal-property-search
|
||||
* REPORT. You should at least allow searching on
|
||||
* http://sabredav.org/ns}email-address.
|
||||
*
|
||||
* The actual search should be a unicode-non-case-sensitive search. The
|
||||
* keys in searchProperties are the WebDAV property names, while the values
|
||||
* are the property values to search on.
|
||||
*
|
||||
* If multiple properties are being searched on, the search should be
|
||||
* AND'ed.
|
||||
*
|
||||
* This method should simply return an array with full principal uri's.
|
||||
*
|
||||
* If somebody attempted to search on a property the backend does not
|
||||
* support, you should simply return 0 results.
|
||||
*
|
||||
* You can also just return 0 results if you choose to not support
|
||||
* searching at all, but keep in mind that this may stop certain features
|
||||
* from working.
|
||||
*
|
||||
* @param string $prefixPath
|
||||
* @param array $searchProperties
|
||||
* @return array
|
||||
*/
|
||||
function searchPrincipals($prefixPath, array $searchProperties);
|
||||
|
||||
/**
|
||||
* Returns the list of members for a group-principal
|
||||
*
|
||||
* @param string $principal
|
||||
* @return array
|
||||
*/
|
||||
function getGroupMemberSet($principal);
|
||||
|
||||
/**
|
||||
* Returns the list of groups a principal is a member of
|
||||
*
|
||||
* @param string $principal
|
||||
* @return array
|
||||
*/
|
||||
function getGroupMembership($principal);
|
||||
|
||||
/**
|
||||
* Updates the list of group members for a group principal.
|
||||
*
|
||||
* The principals should be passed as a list of uri's.
|
||||
*
|
||||
* @param string $principal
|
||||
* @param array $members
|
||||
* @return void
|
||||
*/
|
||||
function setGroupMemberSet($principal, array $members);
|
||||
|
||||
}
|
||||
1349
dav/SabreDAV/lib/Sabre/DAVACL/Plugin.php
Normal file
1349
dav/SabreDAV/lib/Sabre/DAVACL/Plugin.php
Normal file
|
|
@ -0,0 +1,1349 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SabreDAV ACL Plugin
|
||||
*
|
||||
* This addon provides functionality to enforce ACL permissions.
|
||||
* ACL is defined in RFC3744.
|
||||
*
|
||||
* In addition it also provides support for the {DAV:}current-user-principal
|
||||
* property, defined in RFC5397 and the {DAV:}expand-property report, as
|
||||
* defined in RFC3253.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Plugin extends Sabre_DAV_ServerPlugin {
|
||||
|
||||
/**
|
||||
* Recursion constants
|
||||
*
|
||||
* This only checks the base node
|
||||
*/
|
||||
const R_PARENT = 1;
|
||||
|
||||
/**
|
||||
* Recursion constants
|
||||
*
|
||||
* This checks every node in the tree
|
||||
*/
|
||||
const R_RECURSIVE = 2;
|
||||
|
||||
/**
|
||||
* Recursion constants
|
||||
*
|
||||
* This checks every parentnode in the tree, but not leaf-nodes.
|
||||
*/
|
||||
const R_RECURSIVEPARENTS = 3;
|
||||
|
||||
/**
|
||||
* Reference to server object.
|
||||
*
|
||||
* @var Sabre_DAV_Server
|
||||
*/
|
||||
protected $server;
|
||||
|
||||
/**
|
||||
* List of urls containing principal collections.
|
||||
* Modify this if your principals are located elsewhere.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $principalCollectionSet = array(
|
||||
'principals',
|
||||
);
|
||||
|
||||
/**
|
||||
* By default ACL is only enforced for nodes that have ACL support (the
|
||||
* ones that implement Sabre_DAVACL_IACL). For any other node, access is
|
||||
* always granted.
|
||||
*
|
||||
* To override this behaviour you can turn this setting off. This is useful
|
||||
* if you plan to fully support ACL in the entire tree.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $allowAccessToNodesWithoutACL = true;
|
||||
|
||||
/**
|
||||
* By default nodes that are inaccessible by the user, can still be seen
|
||||
* in directory listings (PROPFIND on parent with Depth: 1)
|
||||
*
|
||||
* In certain cases it's desirable to hide inaccessible nodes. Setting this
|
||||
* to true will cause these nodes to be hidden from directory listings.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $hideNodesFromListings = false;
|
||||
|
||||
/**
|
||||
* This string is prepended to the username of the currently logged in
|
||||
* user. This allows the addon to determine the principal path based on
|
||||
* the username.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $defaultUsernamePath = 'principals';
|
||||
|
||||
/**
|
||||
* This list of properties are the properties a client can search on using
|
||||
* the {DAV:}principal-property-search report.
|
||||
*
|
||||
* The keys are the property names, values are descriptions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $principalSearchPropertySet = array(
|
||||
'{DAV:}displayname' => 'Display name',
|
||||
'{http://sabredav.org/ns}email-address' => 'Email address',
|
||||
);
|
||||
|
||||
/**
|
||||
* Any principal uri's added here, will automatically be added to the list
|
||||
* of ACL's. They will effectively receive {DAV:}all privileges, as a
|
||||
* protected privilege.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $adminPrincipals = array();
|
||||
|
||||
/**
|
||||
* Returns a list of features added by this addon.
|
||||
*
|
||||
* This list is used in the response of a HTTP OPTIONS request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFeatures() {
|
||||
|
||||
return array('access-control');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of available methods for a given url
|
||||
*
|
||||
* @param string $uri
|
||||
* @return array
|
||||
*/
|
||||
public function getMethods($uri) {
|
||||
|
||||
return array('ACL');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a addon name.
|
||||
*
|
||||
* Using this name other addons will be able to access other addons
|
||||
* using Sabre_DAV_Server::getPlugin
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPluginName() {
|
||||
|
||||
return 'acl';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of reports this addon 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) {
|
||||
|
||||
return array(
|
||||
'{DAV:}expand-property',
|
||||
'{DAV:}principal-property-search',
|
||||
'{DAV:}principal-search-property-set',
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the current user has the specified privilege(s).
|
||||
*
|
||||
* You can specify a single privilege, or a list of privileges.
|
||||
* This method will throw an exception if the privilege is not available
|
||||
* and return true otherwise.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param array|string $privileges
|
||||
* @param int $recursion
|
||||
* @param bool $throwExceptions if set to false, this method won't through exceptions.
|
||||
* @throws Sabre_DAVACL_Exception_NeedPrivileges
|
||||
* @return bool
|
||||
*/
|
||||
public function checkPrivileges($uri, $privileges, $recursion = self::R_PARENT, $throwExceptions = true) {
|
||||
|
||||
if (!is_array($privileges)) $privileges = array($privileges);
|
||||
|
||||
$acl = $this->getCurrentUserPrivilegeSet($uri);
|
||||
|
||||
if (is_null($acl)) {
|
||||
if ($this->allowAccessToNodesWithoutACL) {
|
||||
return true;
|
||||
} else {
|
||||
if ($throwExceptions)
|
||||
throw new Sabre_DAVACL_Exception_NeedPrivileges($uri,$privileges);
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$failed = array();
|
||||
foreach($privileges as $priv) {
|
||||
|
||||
if (!in_array($priv, $acl)) {
|
||||
$failed[] = $priv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($failed) {
|
||||
if ($throwExceptions)
|
||||
throw new Sabre_DAVACL_Exception_NeedPrivileges($uri,$failed);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the standard users' principal.
|
||||
*
|
||||
* This is one authorative principal url for the current user.
|
||||
* This method will return null if the user wasn't logged in.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getCurrentUserPrincipal() {
|
||||
|
||||
$authPlugin = $this->server->getPlugin('auth');
|
||||
if (is_null($authPlugin)) return null;
|
||||
/** @var $authPlugin Sabre_DAV_Auth_Plugin */
|
||||
|
||||
$userName = $authPlugin->getCurrentUser();
|
||||
if (!$userName) return null;
|
||||
|
||||
return $this->defaultUsernamePath . '/' . $userName;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of principals that's associated to the current
|
||||
* user, either directly or through group membership.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCurrentUserPrincipals() {
|
||||
|
||||
$currentUser = $this->getCurrentUserPrincipal();
|
||||
|
||||
if (is_null($currentUser)) return array();
|
||||
|
||||
$check = array($currentUser);
|
||||
$principals = array($currentUser);
|
||||
|
||||
while(count($check)) {
|
||||
|
||||
$principal = array_shift($check);
|
||||
|
||||
$node = $this->server->tree->getNodeForPath($principal);
|
||||
if ($node instanceof Sabre_DAVACL_IPrincipal) {
|
||||
foreach($node->getGroupMembership() as $groupMember) {
|
||||
|
||||
if (!in_array($groupMember, $principals)) {
|
||||
|
||||
$check[] = $groupMember;
|
||||
$principals[] = $groupMember;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $principals;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the supported privilege structure for this ACL addon.
|
||||
*
|
||||
* See RFC3744 for more details. Currently we default on a simple,
|
||||
* standard structure.
|
||||
*
|
||||
* You can either get the list of privileges by a uri (path) or by
|
||||
* specifying a Node.
|
||||
*
|
||||
* @param string|Sabre_DAV_INode $node
|
||||
* @return array
|
||||
*/
|
||||
public function getSupportedPrivilegeSet($node) {
|
||||
|
||||
if (is_string($node)) {
|
||||
$node = $this->server->tree->getNodeForPath($node);
|
||||
}
|
||||
|
||||
if ($node instanceof Sabre_DAVACL_IACL) {
|
||||
$result = $node->getSupportedPrivilegeSet();
|
||||
|
||||
if ($result)
|
||||
return $result;
|
||||
}
|
||||
|
||||
return self::getDefaultSupportedPrivilegeSet();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fairly standard set of privileges, which may be useful for
|
||||
* other systems to use as a basis.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static function getDefaultSupportedPrivilegeSet() {
|
||||
|
||||
return array(
|
||||
'privilege' => '{DAV:}all',
|
||||
'abstract' => true,
|
||||
'aggregates' => array(
|
||||
array(
|
||||
'privilege' => '{DAV:}read',
|
||||
'aggregates' => array(
|
||||
array(
|
||||
'privilege' => '{DAV:}read-acl',
|
||||
'abstract' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}read-current-user-privilege-set',
|
||||
'abstract' => true,
|
||||
),
|
||||
),
|
||||
), // {DAV:}read
|
||||
array(
|
||||
'privilege' => '{DAV:}write',
|
||||
'aggregates' => array(
|
||||
array(
|
||||
'privilege' => '{DAV:}write-acl',
|
||||
'abstract' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}write-properties',
|
||||
'abstract' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}write-content',
|
||||
'abstract' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}bind',
|
||||
'abstract' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}unbind',
|
||||
'abstract' => true,
|
||||
),
|
||||
array(
|
||||
'privilege' => '{DAV:}unlock',
|
||||
'abstract' => true,
|
||||
),
|
||||
),
|
||||
), // {DAV:}write
|
||||
),
|
||||
); // {DAV:}all
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the supported privilege set as a flat list
|
||||
*
|
||||
* This is much easier to parse.
|
||||
*
|
||||
* The returned list will be index by privilege name.
|
||||
* The value is a struct containing the following properties:
|
||||
* - aggregates
|
||||
* - abstract
|
||||
* - concrete
|
||||
*
|
||||
* @param string|Sabre_DAV_INode $node
|
||||
* @return array
|
||||
*/
|
||||
final public function getFlatPrivilegeSet($node) {
|
||||
|
||||
$privs = $this->getSupportedPrivilegeSet($node);
|
||||
|
||||
$flat = array();
|
||||
$this->getFPSTraverse($privs, null, $flat);
|
||||
|
||||
return $flat;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses the privilege set tree for reordering
|
||||
*
|
||||
* This function is solely used by getFlatPrivilegeSet, and would have been
|
||||
* a closure if it wasn't for the fact I need to support PHP 5.2.
|
||||
*
|
||||
* @param array $priv
|
||||
* @param $concrete
|
||||
* @param array $flat
|
||||
* @return void
|
||||
*/
|
||||
final private function getFPSTraverse($priv, $concrete, &$flat) {
|
||||
|
||||
$myPriv = array(
|
||||
'privilege' => $priv['privilege'],
|
||||
'abstract' => isset($priv['abstract']) && $priv['abstract'],
|
||||
'aggregates' => array(),
|
||||
'concrete' => isset($priv['abstract']) && $priv['abstract']?$concrete:$priv['privilege'],
|
||||
);
|
||||
|
||||
if (isset($priv['aggregates']))
|
||||
foreach($priv['aggregates'] as $subPriv) $myPriv['aggregates'][] = $subPriv['privilege'];
|
||||
|
||||
$flat[$priv['privilege']] = $myPriv;
|
||||
|
||||
if (isset($priv['aggregates'])) {
|
||||
|
||||
foreach($priv['aggregates'] as $subPriv) {
|
||||
|
||||
$this->getFPSTraverse($subPriv, $myPriv['concrete'], $flat);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full ACL list.
|
||||
*
|
||||
* Either a uri or a Sabre_DAV_INode may be passed.
|
||||
*
|
||||
* null will be returned if the node doesn't support ACLs.
|
||||
*
|
||||
* @param string|Sabre_DAV_INode $node
|
||||
* @return array
|
||||
*/
|
||||
public function getACL($node) {
|
||||
|
||||
if (is_string($node)) {
|
||||
$node = $this->server->tree->getNodeForPath($node);
|
||||
}
|
||||
if (!$node instanceof Sabre_DAVACL_IACL) {
|
||||
return null;
|
||||
}
|
||||
$acl = $node->getACL();
|
||||
foreach($this->adminPrincipals as $adminPrincipal) {
|
||||
$acl[] = array(
|
||||
'principal' => $adminPrincipal,
|
||||
'privilege' => '{DAV:}all',
|
||||
'protected' => true,
|
||||
);
|
||||
}
|
||||
return $acl;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of privileges the current user has
|
||||
* on a particular node.
|
||||
*
|
||||
* Either a uri or a Sabre_DAV_INode may be passed.
|
||||
*
|
||||
* null will be returned if the node doesn't support ACLs.
|
||||
*
|
||||
* @param string|Sabre_DAV_INode $node
|
||||
* @return array
|
||||
*/
|
||||
public function getCurrentUserPrivilegeSet($node) {
|
||||
|
||||
if (is_string($node)) {
|
||||
$node = $this->server->tree->getNodeForPath($node);
|
||||
}
|
||||
|
||||
$acl = $this->getACL($node);
|
||||
|
||||
if (is_null($acl)) return null;
|
||||
|
||||
$principals = $this->getCurrentUserPrincipals();
|
||||
|
||||
$collected = array();
|
||||
|
||||
foreach($acl as $ace) {
|
||||
|
||||
$principal = $ace['principal'];
|
||||
|
||||
switch($principal) {
|
||||
|
||||
case '{DAV:}owner' :
|
||||
$owner = $node->getOwner();
|
||||
if ($owner && in_array($owner, $principals)) {
|
||||
$collected[] = $ace;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// 'all' matches for every user
|
||||
case '{DAV:}all' :
|
||||
|
||||
// 'authenticated' matched for every user that's logged in.
|
||||
// Since it's not possible to use ACL while not being logged
|
||||
// in, this is also always true.
|
||||
case '{DAV:}authenticated' :
|
||||
$collected[] = $ace;
|
||||
break;
|
||||
|
||||
// 'unauthenticated' can never occur either, so we simply
|
||||
// ignore these.
|
||||
case '{DAV:}unauthenticated' :
|
||||
break;
|
||||
|
||||
default :
|
||||
if (in_array($ace['principal'], $principals)) {
|
||||
$collected[] = $ace;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Now we deduct all aggregated privileges.
|
||||
$flat = $this->getFlatPrivilegeSet($node);
|
||||
|
||||
$collected2 = array();
|
||||
while(count($collected)) {
|
||||
|
||||
$current = array_pop($collected);
|
||||
$collected2[] = $current['privilege'];
|
||||
|
||||
foreach($flat[$current['privilege']]['aggregates'] as $subPriv) {
|
||||
$collected2[] = $subPriv;
|
||||
$collected[] = $flat[$subPriv];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return array_values(array_unique($collected2));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Principal property search
|
||||
*
|
||||
* This method can search for principals matching certain values in
|
||||
* properties.
|
||||
*
|
||||
* This method will return a list of properties for the matched properties.
|
||||
*
|
||||
* @param array $searchProperties The properties to search on. This is a
|
||||
* key-value list. The keys are property
|
||||
* names, and the values the strings to
|
||||
* match them on.
|
||||
* @param array $requestedProperties This is the list of properties to
|
||||
* return for every match.
|
||||
* @param string $collectionUri The principal collection to search on.
|
||||
* If this is ommitted, the standard
|
||||
* principal collection-set will be used.
|
||||
* @return array This method returns an array structure similar to
|
||||
* Sabre_DAV_Server::getPropertiesForPath. Returned
|
||||
* properties are index by a HTTP status code.
|
||||
*
|
||||
*/
|
||||
public function principalSearch(array $searchProperties, array $requestedProperties, $collectionUri = null) {
|
||||
|
||||
if (!is_null($collectionUri)) {
|
||||
$uris = array($collectionUri);
|
||||
} else {
|
||||
$uris = $this->principalCollectionSet;
|
||||
}
|
||||
|
||||
$lookupResults = array();
|
||||
foreach($uris as $uri) {
|
||||
|
||||
$principalCollection = $this->server->tree->getNodeForPath($uri);
|
||||
if (!$principalCollection instanceof Sabre_DAVACL_AbstractPrincipalCollection) {
|
||||
// Not a principal collection, we're simply going to ignore
|
||||
// this.
|
||||
continue;
|
||||
}
|
||||
|
||||
$results = $principalCollection->searchPrincipals($searchProperties);
|
||||
foreach($results as $result) {
|
||||
$lookupResults[] = rtrim($uri,'/') . '/' . $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$matches = array();
|
||||
|
||||
foreach($lookupResults as $lookupResult) {
|
||||
|
||||
list($matches[]) = $this->server->getPropertiesForPath($lookupResult, $requestedProperties, 0);
|
||||
|
||||
}
|
||||
|
||||
return $matches;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the addon
|
||||
*
|
||||
* This method is automatically called by the server class.
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(Sabre_DAV_Server $server) {
|
||||
|
||||
$this->server = $server;
|
||||
$server->subscribeEvent('beforeGetProperties',array($this,'beforeGetProperties'));
|
||||
|
||||
$server->subscribeEvent('beforeMethod', array($this,'beforeMethod'),20);
|
||||
$server->subscribeEvent('beforeBind', array($this,'beforeBind'),20);
|
||||
$server->subscribeEvent('beforeUnbind', array($this,'beforeUnbind'),20);
|
||||
$server->subscribeEvent('updateProperties',array($this,'updateProperties'));
|
||||
$server->subscribeEvent('beforeUnlock', array($this,'beforeUnlock'),20);
|
||||
$server->subscribeEvent('report',array($this,'report'));
|
||||
$server->subscribeEvent('unknownMethod', array($this, 'unknownMethod'));
|
||||
|
||||
array_push($server->protectedProperties,
|
||||
'{DAV:}alternate-URI-set',
|
||||
'{DAV:}principal-URL',
|
||||
'{DAV:}group-membership',
|
||||
'{DAV:}principal-collection-set',
|
||||
'{DAV:}current-user-principal',
|
||||
'{DAV:}supported-privilege-set',
|
||||
'{DAV:}current-user-privilege-set',
|
||||
'{DAV:}acl',
|
||||
'{DAV:}acl-restrictions',
|
||||
'{DAV:}inherited-acl-set',
|
||||
'{DAV:}owner',
|
||||
'{DAV:}group'
|
||||
);
|
||||
|
||||
// Automatically mapping nodes implementing IPrincipal to the
|
||||
// {DAV:}principal resourcetype.
|
||||
$server->resourceTypeMapping['Sabre_DAVACL_IPrincipal'] = '{DAV:}principal';
|
||||
|
||||
// Mapping the group-member-set property to the HrefList property
|
||||
// class.
|
||||
$server->propertyMap['{DAV:}group-member-set'] = 'Sabre_DAV_Property_HrefList';
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* {{{ Event handlers */
|
||||
|
||||
/**
|
||||
* Triggered before any method is handled
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $uri
|
||||
* @return void
|
||||
*/
|
||||
public function beforeMethod($method, $uri) {
|
||||
|
||||
$exists = $this->server->tree->nodeExists($uri);
|
||||
|
||||
// If the node doesn't exists, none of these checks apply
|
||||
if (!$exists) return;
|
||||
|
||||
switch($method) {
|
||||
|
||||
case 'GET' :
|
||||
case 'HEAD' :
|
||||
case 'OPTIONS' :
|
||||
// For these 3 we only need to know if the node is readable.
|
||||
$this->checkPrivileges($uri,'{DAV:}read');
|
||||
break;
|
||||
|
||||
case 'PUT' :
|
||||
case 'LOCK' :
|
||||
case 'UNLOCK' :
|
||||
// This method requires the write-content priv if the node
|
||||
// already exists, and bind on the parent if the node is being
|
||||
// created.
|
||||
// The bind privilege is handled in the beforeBind event.
|
||||
$this->checkPrivileges($uri,'{DAV:}write-content');
|
||||
break;
|
||||
|
||||
|
||||
case 'PROPPATCH' :
|
||||
$this->checkPrivileges($uri,'{DAV:}write-properties');
|
||||
break;
|
||||
|
||||
case 'ACL' :
|
||||
$this->checkPrivileges($uri,'{DAV:}write-acl');
|
||||
break;
|
||||
|
||||
case 'COPY' :
|
||||
case 'MOVE' :
|
||||
// Copy requires read privileges on the entire source tree.
|
||||
// If the target exists write-content normally needs to be
|
||||
// checked, however, we're deleting the node beforehand and
|
||||
// creating a new one after, so this is handled by the
|
||||
// beforeUnbind event.
|
||||
//
|
||||
// The creation of the new node is handled by the beforeBind
|
||||
// event.
|
||||
//
|
||||
// If MOVE is used beforeUnbind will also be used to check if
|
||||
// the sourcenode can be deleted.
|
||||
$this->checkPrivileges($uri,'{DAV:}read',self::R_RECURSIVE);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered before a new node is created.
|
||||
*
|
||||
* This allows us to check permissions for any operation that creates a
|
||||
* new node, such as PUT, MKCOL, MKCALENDAR, LOCK, COPY and MOVE.
|
||||
*
|
||||
* @param string $uri
|
||||
* @return void
|
||||
*/
|
||||
public function beforeBind($uri) {
|
||||
|
||||
list($parentUri,$nodeName) = Sabre_DAV_URLUtil::splitPath($uri);
|
||||
$this->checkPrivileges($parentUri,'{DAV:}bind');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered before a node is deleted
|
||||
*
|
||||
* This allows us to check permissions for any operation that will delete
|
||||
* an existing node.
|
||||
*
|
||||
* @param string $uri
|
||||
* @return void
|
||||
*/
|
||||
public function beforeUnbind($uri) {
|
||||
|
||||
list($parentUri,$nodeName) = Sabre_DAV_URLUtil::splitPath($uri);
|
||||
$this->checkPrivileges($parentUri,'{DAV:}unbind',self::R_RECURSIVEPARENTS);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered before a node is unlocked.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param Sabre_DAV_Locks_LockInfo $lock
|
||||
* @TODO: not yet implemented
|
||||
* @return void
|
||||
*/
|
||||
public function beforeUnlock($uri, Sabre_DAV_Locks_LockInfo $lock) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggered before properties are looked up in specific nodes.
|
||||
*
|
||||
* @param string $uri
|
||||
* @param Sabre_DAV_INode $node
|
||||
* @param array $requestedProperties
|
||||
* @param array $returnedProperties
|
||||
* @TODO really should be broken into multiple methods, or even a class.
|
||||
* @return bool
|
||||
*/
|
||||
public function beforeGetProperties($uri, Sabre_DAV_INode $node, &$requestedProperties, &$returnedProperties) {
|
||||
|
||||
// Checking the read permission
|
||||
if (!$this->checkPrivileges($uri,'{DAV:}read',self::R_PARENT,false)) {
|
||||
|
||||
// User is not allowed to read properties
|
||||
if ($this->hideNodesFromListings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Marking all requested properties as '403'.
|
||||
foreach($requestedProperties as $key=>$requestedProperty) {
|
||||
unset($requestedProperties[$key]);
|
||||
$returnedProperties[403][$requestedProperty] = null;
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* Adding principal properties */
|
||||
if ($node instanceof Sabre_DAVACL_IPrincipal) {
|
||||
|
||||
if (false !== ($index = array_search('{DAV:}alternate-URI-set', $requestedProperties))) {
|
||||
|
||||
unset($requestedProperties[$index]);
|
||||
$returnedProperties[200]['{DAV:}alternate-URI-set'] = new Sabre_DAV_Property_HrefList($node->getAlternateUriSet());
|
||||
|
||||
}
|
||||
if (false !== ($index = array_search('{DAV:}principal-URL', $requestedProperties))) {
|
||||
|
||||
unset($requestedProperties[$index]);
|
||||
$returnedProperties[200]['{DAV:}principal-URL'] = new Sabre_DAV_Property_Href($node->getPrincipalUrl() . '/');
|
||||
|
||||
}
|
||||
if (false !== ($index = array_search('{DAV:}group-member-set', $requestedProperties))) {
|
||||
|
||||
unset($requestedProperties[$index]);
|
||||
$returnedProperties[200]['{DAV:}group-member-set'] = new Sabre_DAV_Property_HrefList($node->getGroupMemberSet());
|
||||
|
||||
}
|
||||
if (false !== ($index = array_search('{DAV:}group-membership', $requestedProperties))) {
|
||||
|
||||
unset($requestedProperties[$index]);
|
||||
$returnedProperties[200]['{DAV:}group-membership'] = new Sabre_DAV_Property_HrefList($node->getGroupMembership());
|
||||
|
||||
}
|
||||
|
||||
if (false !== ($index = array_search('{DAV:}displayname', $requestedProperties))) {
|
||||
|
||||
$returnedProperties[200]['{DAV:}displayname'] = $node->getDisplayName();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if (false !== ($index = array_search('{DAV:}principal-collection-set', $requestedProperties))) {
|
||||
|
||||
unset($requestedProperties[$index]);
|
||||
$val = $this->principalCollectionSet;
|
||||
// Ensuring all collections end with a slash
|
||||
foreach($val as $k=>$v) $val[$k] = $v . '/';
|
||||
$returnedProperties[200]['{DAV:}principal-collection-set'] = new Sabre_DAV_Property_HrefList($val);
|
||||
|
||||
}
|
||||
if (false !== ($index = array_search('{DAV:}current-user-principal', $requestedProperties))) {
|
||||
|
||||
unset($requestedProperties[$index]);
|
||||
if ($url = $this->getCurrentUserPrincipal()) {
|
||||
$returnedProperties[200]['{DAV:}current-user-principal'] = new Sabre_DAVACL_Property_Principal(Sabre_DAVACL_Property_Principal::HREF, $url . '/');
|
||||
} else {
|
||||
$returnedProperties[200]['{DAV:}current-user-principal'] = new Sabre_DAVACL_Property_Principal(Sabre_DAVACL_Property_Principal::UNAUTHENTICATED);
|
||||
}
|
||||
|
||||
}
|
||||
if (false !== ($index = array_search('{DAV:}supported-privilege-set', $requestedProperties))) {
|
||||
|
||||
unset($requestedProperties[$index]);
|
||||
$returnedProperties[200]['{DAV:}supported-privilege-set'] = new Sabre_DAVACL_Property_SupportedPrivilegeSet($this->getSupportedPrivilegeSet($node));
|
||||
|
||||
}
|
||||
if (false !== ($index = array_search('{DAV:}current-user-privilege-set', $requestedProperties))) {
|
||||
|
||||
if (!$this->checkPrivileges($uri, '{DAV:}read-current-user-privilege-set', self::R_PARENT, false)) {
|
||||
$returnedProperties[403]['{DAV:}current-user-privilege-set'] = null;
|
||||
unset($requestedProperties[$index]);
|
||||
} else {
|
||||
$val = $this->getCurrentUserPrivilegeSet($node);
|
||||
if (!is_null($val)) {
|
||||
unset($requestedProperties[$index]);
|
||||
$returnedProperties[200]['{DAV:}current-user-privilege-set'] = new Sabre_DAVACL_Property_CurrentUserPrivilegeSet($val);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* The ACL property contains all the permissions */
|
||||
if (false !== ($index = array_search('{DAV:}acl', $requestedProperties))) {
|
||||
|
||||
if (!$this->checkPrivileges($uri, '{DAV:}read-acl', self::R_PARENT, false)) {
|
||||
|
||||
unset($requestedProperties[$index]);
|
||||
$returnedProperties[403]['{DAV:}acl'] = null;
|
||||
|
||||
} else {
|
||||
|
||||
$acl = $this->getACL($node);
|
||||
if (!is_null($acl)) {
|
||||
unset($requestedProperties[$index]);
|
||||
$returnedProperties[200]['{DAV:}acl'] = new Sabre_DAVACL_Property_Acl($this->getACL($node));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* The acl-restrictions property contains information on how privileges
|
||||
* must behave.
|
||||
*/
|
||||
if (false !== ($index = array_search('{DAV:}acl-restrictions', $requestedProperties))) {
|
||||
unset($requestedProperties[$index]);
|
||||
$returnedProperties[200]['{DAV:}acl-restrictions'] = new Sabre_DAVACL_Property_AclRestrictions();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method intercepts PROPPATCH methods and make sure the
|
||||
* group-member-set is updated correctly.
|
||||
*
|
||||
* @param array $propertyDelta
|
||||
* @param array $result
|
||||
* @param Sabre_DAV_INode $node
|
||||
* @return bool
|
||||
*/
|
||||
public function updateProperties(&$propertyDelta, &$result, Sabre_DAV_INode $node) {
|
||||
|
||||
if (!array_key_exists('{DAV:}group-member-set', $propertyDelta))
|
||||
return;
|
||||
|
||||
if (is_null($propertyDelta['{DAV:}group-member-set'])) {
|
||||
$memberSet = array();
|
||||
} elseif ($propertyDelta['{DAV:}group-member-set'] instanceof Sabre_DAV_Property_HrefList) {
|
||||
$memberSet = $propertyDelta['{DAV:}group-member-set']->getHrefs();
|
||||
} else {
|
||||
throw new Sabre_DAV_Exception('The group-member-set property MUST be an instance of Sabre_DAV_Property_HrefList or null');
|
||||
}
|
||||
|
||||
if (!($node instanceof Sabre_DAVACL_IPrincipal)) {
|
||||
$result[403]['{DAV:}group-member-set'] = null;
|
||||
unset($propertyDelta['{DAV:}group-member-set']);
|
||||
|
||||
// Returning false will stop the updateProperties process
|
||||
return false;
|
||||
}
|
||||
|
||||
$node->setGroupMemberSet($memberSet);
|
||||
|
||||
$result[200]['{DAV:}group-member-set'] = null;
|
||||
unset($propertyDelta['{DAV:}group-member-set']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method handles HTTP REPORT requests
|
||||
*
|
||||
* @param string $reportName
|
||||
* @param DOMNode $dom
|
||||
* @return bool
|
||||
*/
|
||||
public function report($reportName, $dom) {
|
||||
|
||||
switch($reportName) {
|
||||
|
||||
case '{DAV:}principal-property-search' :
|
||||
$this->principalPropertySearchReport($dom);
|
||||
return false;
|
||||
case '{DAV:}principal-search-property-set' :
|
||||
$this->principalSearchPropertySetReport($dom);
|
||||
return false;
|
||||
case '{DAV:}expand-property' :
|
||||
$this->expandPropertyReport($dom);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This event is triggered for any HTTP method that is not known by the
|
||||
* webserver.
|
||||
*
|
||||
* @param string $method
|
||||
* @param string $uri
|
||||
* @return bool
|
||||
*/
|
||||
public function unknownMethod($method, $uri) {
|
||||
|
||||
if ($method!=='ACL') return;
|
||||
|
||||
$this->httpACL($uri);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is responsible for handling the 'ACL' event.
|
||||
*
|
||||
* @param string $uri
|
||||
* @return void
|
||||
*/
|
||||
public function httpACL($uri) {
|
||||
|
||||
$body = $this->server->httpRequest->getBody(true);
|
||||
$dom = Sabre_DAV_XMLUtil::loadDOMDocument($body);
|
||||
|
||||
$newAcl =
|
||||
Sabre_DAVACL_Property_Acl::unserialize($dom->firstChild)
|
||||
->getPrivileges();
|
||||
|
||||
// Normalizing urls
|
||||
foreach($newAcl as $k=>$newAce) {
|
||||
$newAcl[$k]['principal'] = $this->server->calculateUri($newAce['principal']);
|
||||
}
|
||||
|
||||
$node = $this->server->tree->getNodeForPath($uri);
|
||||
|
||||
if (!($node instanceof Sabre_DAVACL_IACL)) {
|
||||
throw new Sabre_DAV_Exception_MethodNotAllowed('This node does not support the ACL method');
|
||||
}
|
||||
|
||||
$oldAcl = $this->getACL($node);
|
||||
|
||||
$supportedPrivileges = $this->getFlatPrivilegeSet($node);
|
||||
|
||||
/* Checking if protected principals from the existing principal set are
|
||||
not overwritten. */
|
||||
foreach($oldAcl as $oldAce) {
|
||||
|
||||
if (!isset($oldAce['protected']) || !$oldAce['protected']) continue;
|
||||
|
||||
$found = false;
|
||||
foreach($newAcl as $newAce) {
|
||||
if (
|
||||
$newAce['privilege'] === $oldAce['privilege'] &&
|
||||
$newAce['principal'] === $oldAce['principal'] &&
|
||||
$newAce['protected']
|
||||
)
|
||||
$found = true;
|
||||
}
|
||||
|
||||
if (!$found)
|
||||
throw new Sabre_DAVACL_Exception_AceConflict('This resource contained a protected {DAV:}ace, but this privilege did not occur in the ACL request');
|
||||
|
||||
}
|
||||
|
||||
foreach($newAcl as $newAce) {
|
||||
|
||||
// Do we recognize the privilege
|
||||
if (!isset($supportedPrivileges[$newAce['privilege']])) {
|
||||
throw new Sabre_DAVACL_Exception_NotSupportedPrivilege('The privilege you specified (' . $newAce['privilege'] . ') is not recognized by this server');
|
||||
}
|
||||
|
||||
if ($supportedPrivileges[$newAce['privilege']]['abstract']) {
|
||||
throw new Sabre_DAVACL_Exception_NoAbstract('The privilege you specified (' . $newAce['privilege'] . ') is an abstract privilege');
|
||||
}
|
||||
|
||||
// Looking up the principal
|
||||
try {
|
||||
$principal = $this->server->tree->getNodeForPath($newAce['principal']);
|
||||
} catch (Sabre_DAV_Exception_NotFound $e) {
|
||||
throw new Sabre_DAVACL_Exception_NotRecognizedPrincipal('The specified principal (' . $newAce['principal'] . ') does not exist');
|
||||
}
|
||||
if (!($principal instanceof Sabre_DAVACL_IPrincipal)) {
|
||||
throw new Sabre_DAVACL_Exception_NotRecognizedPrincipal('The specified uri (' . $newAce['principal'] . ') is not a principal');
|
||||
}
|
||||
|
||||
}
|
||||
$node->setACL($newAcl);
|
||||
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* Reports {{{ */
|
||||
|
||||
/**
|
||||
* 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 addon.
|
||||
*
|
||||
* @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 $response) {
|
||||
$response->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);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 int $depth
|
||||
* @return array
|
||||
*/
|
||||
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) {
|
||||
$hrefs = array($node[200][$propertyName]->getHref());
|
||||
} elseif ($node[200][$propertyName] instanceof Sabre_DAV_Property_HrefList) {
|
||||
$hrefs = $node[200][$propertyName]->getHrefs();
|
||||
}
|
||||
|
||||
$childProps = array();
|
||||
foreach($hrefs as $href) {
|
||||
$childProps = array_merge($childProps, $this->expandProperties($href, $childRequestedProperties, 0));
|
||||
}
|
||||
$node[200][$propertyName] = new Sabre_DAV_Property_ResponseList($childProps);
|
||||
|
||||
}
|
||||
$result[] = new Sabre_DAV_Property_Response($path, $node);
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* principalSearchPropertySetReport
|
||||
*
|
||||
* This method responsible for handing the
|
||||
* {DAV:}principal-search-property-set report. This report returns a list
|
||||
* of properties the client may search on, using the
|
||||
* {DAV:}principal-property-search report.
|
||||
*
|
||||
* @param DOMDocument $dom
|
||||
* @return void
|
||||
*/
|
||||
protected function principalSearchPropertySetReport(DOMDocument $dom) {
|
||||
|
||||
$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($this->principalSearchPropertySet 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);
|
||||
|
||||
$currentProperty = $dom->createElement($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());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* principalPropertySearchReport
|
||||
*
|
||||
* This method is responsible for handing the
|
||||
* {DAV:}principal-property-search report. This report can be used for
|
||||
* clients to search for groups of principals, based on the value of one
|
||||
* or more properties.
|
||||
*
|
||||
* @param DOMDocument $dom
|
||||
* @return void
|
||||
*/
|
||||
protected function principalPropertySearchReport(DOMDocument $dom) {
|
||||
|
||||
list($searchProperties, $requestedProperties, $applyToPrincipalCollectionSet) = $this->parsePrincipalPropertySearchReportRequest($dom);
|
||||
|
||||
$uri = null;
|
||||
if (!$applyToPrincipalCollectionSet) {
|
||||
$uri = $this->server->getRequestUri();
|
||||
}
|
||||
$result = $this->principalSearch($searchProperties, $requestedProperties, $uri);
|
||||
|
||||
$xml = $this->server->generateMultiStatus($result);
|
||||
$this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
|
||||
$this->server->httpResponse->sendStatus(207);
|
||||
$this->server->httpResponse->sendBody($xml);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* parsePrincipalPropertySearchReportRequest
|
||||
*
|
||||
* This method parses the request body from a
|
||||
* {DAV:}principal-property-search report.
|
||||
*
|
||||
* This method returns an array with two elements:
|
||||
* 1. an array with properties to search on, and their values
|
||||
* 2. a list of propertyvalues that should be returned for the request.
|
||||
*
|
||||
* @param DOMDocument $dom
|
||||
* @return array
|
||||
*/
|
||||
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();
|
||||
|
||||
$applyToPrincipalCollectionSet = false;
|
||||
|
||||
// Parsing the search request
|
||||
foreach($dom->firstChild->childNodes as $searchNode) {
|
||||
|
||||
if (Sabre_DAV_XMLUtil::toClarkNotation($searchNode) == '{DAV:}apply-to-principal-collection-set') {
|
||||
$applyToPrincipalCollectionSet = true;
|
||||
}
|
||||
|
||||
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)), $applyToPrincipalCollectionSet);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* }}} */
|
||||
|
||||
}
|
||||
279
dav/SabreDAV/lib/Sabre/DAVACL/Principal.php
Normal file
279
dav/SabreDAV/lib/Sabre/DAVACL/Principal.php
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Principal class
|
||||
*
|
||||
* This class is a representation of a simple principal
|
||||
*
|
||||
* Many WebDAV specs require a user to show up in the directory
|
||||
* structure.
|
||||
*
|
||||
* This principal also has basic ACL settings, only allowing the principal
|
||||
* access it's own principal.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Principal extends Sabre_DAV_Node implements Sabre_DAVACL_IPrincipal, Sabre_DAV_IProperties, Sabre_DAVACL_IACL {
|
||||
|
||||
/**
|
||||
* Struct with principal information.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $principalProperties;
|
||||
|
||||
/**
|
||||
* Principal backend
|
||||
*
|
||||
* @var Sabre_DAVACL_IPrincipalBackend
|
||||
*/
|
||||
protected $principalBackend;
|
||||
|
||||
/**
|
||||
* Creates the principal object
|
||||
*
|
||||
* @param Sabre_DAVACL_IPrincipalBackend $principalBackend
|
||||
* @param array $principalProperties
|
||||
*/
|
||||
public function __construct(Sabre_DAVACL_IPrincipalBackend $principalBackend, array $principalProperties = array()) {
|
||||
|
||||
if (!isset($principalProperties['uri'])) {
|
||||
throw new Sabre_DAV_Exception('The principal properties must at least contain the \'uri\' key');
|
||||
}
|
||||
$this->principalBackend = $principalBackend;
|
||||
$this->principalProperties = $principalProperties;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full principal url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPrincipalUrl() {
|
||||
|
||||
return $this->principalProperties['uri'];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of alternative urls for a principal
|
||||
*
|
||||
* This can for example be an email address, or ldap url.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAlternateUriSet() {
|
||||
|
||||
$uris = array();
|
||||
if (isset($this->principalProperties['{DAV:}alternate-URI-set'])) {
|
||||
|
||||
$uris = $this->principalProperties['{DAV:}alternate-URI-set'];
|
||||
|
||||
}
|
||||
|
||||
if (isset($this->principalProperties['{http://sabredav.org/ns}email-address'])) {
|
||||
$uris[] = 'mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address'];
|
||||
}
|
||||
|
||||
return array_unique($uris);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->principalProperties['uri']);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->principalProperties['uri']);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 $groupMembers
|
||||
* @return void
|
||||
*/
|
||||
public function setGroupMemberSet(array $groupMembers) {
|
||||
|
||||
$this->principalBackend->setGroupMemberSet($this->principalProperties['uri'], $groupMembers);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns this principals name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
|
||||
$uri = $this->principalProperties['uri'];
|
||||
list(, $name) = Sabre_DAV_URLUtil::splitPath($uri);
|
||||
return $name;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the user
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
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 array
|
||||
*/
|
||||
public function getProperties($requestedProperties) {
|
||||
|
||||
$newProperties = array();
|
||||
foreach($requestedProperties as $propName) {
|
||||
|
||||
if (isset($this->principalProperties[$propName])) {
|
||||
$newProperties[$propName] = $this->principalProperties[$propName];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $newProperties;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this principals properties.
|
||||
*
|
||||
* @param array $mutations
|
||||
* @see Sabre_DAV_IProperties::updateProperties
|
||||
* @return bool|array
|
||||
*/
|
||||
public function updateProperties($mutations) {
|
||||
|
||||
return $this->principalBackend->updatePrincipal($this->principalProperties['uri'], $mutations);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->principalProperties['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->getPrincipalUrl(),
|
||||
'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('Updating ACLs is not allowed here');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of supported privileges for this node.
|
||||
*
|
||||
* The returned data structure is a list of nested privileges.
|
||||
* See Sabre_DAVACL_Plugin::getDefaultSupportedPrivilegeSet for a simple
|
||||
* standard structure.
|
||||
*
|
||||
* If null is returned from this method, the default privilege set is used,
|
||||
* which is fine for most common usecases.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getSupportedPrivilegeSet() {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
427
dav/SabreDAV/lib/Sabre/DAVACL/PrincipalBackend/PDO.php
Normal file
427
dav/SabreDAV/lib/Sabre/DAVACL/PrincipalBackend/PDO.php
Normal file
|
|
@ -0,0 +1,427 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PDO principal backend
|
||||
*
|
||||
* This is a simple principal backend that maps exactly to the users table, as
|
||||
* used by Sabre_DAV_Auth_Backend_PDO.
|
||||
*
|
||||
* It assumes all principals are in a single collection. The default collection
|
||||
* is 'principals/', but this can be overriden.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_PrincipalBackend_PDO implements Sabre_DAVACL_IPrincipalBackend {
|
||||
|
||||
/**
|
||||
* pdo
|
||||
*
|
||||
* @var PDO
|
||||
*/
|
||||
protected $pdo;
|
||||
|
||||
/**
|
||||
* PDO table name for 'principals'
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tableName;
|
||||
|
||||
/**
|
||||
* PDO table name for 'group members'
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $groupMembersTableName;
|
||||
|
||||
/**
|
||||
* A list of additional fields to support
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldMap = array(
|
||||
|
||||
/**
|
||||
* This property can be used to display the users' real name.
|
||||
*/
|
||||
'{DAV:}displayname' => array(
|
||||
'dbField' => 'displayname',
|
||||
),
|
||||
|
||||
/**
|
||||
* This property is actually used by the CardDAV addon, where it gets
|
||||
* mapped to {http://calendarserver.orgi/ns/}me-card.
|
||||
*
|
||||
* The reason we don't straight-up use that property, is because
|
||||
* me-card is defined as a property on the users' addressbook
|
||||
* collection.
|
||||
*/
|
||||
'{http://sabredav.org/ns}vcard-url' => array(
|
||||
'dbField' => 'vcardurl',
|
||||
),
|
||||
/**
|
||||
* This is the users' primary email-address.
|
||||
*/
|
||||
'{http://sabredav.org/ns}email-address' => array(
|
||||
'dbField' => 'email',
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Sets up the backend.
|
||||
*
|
||||
* @param PDO $pdo
|
||||
* @param string $tableName
|
||||
* @param string $groupMembersTableName
|
||||
*/
|
||||
public function __construct(PDO $pdo, $tableName = 'principals', $groupMembersTableName = 'groupmembers') {
|
||||
|
||||
$this->pdo = $pdo;
|
||||
$this->tableName = $tableName;
|
||||
$this->groupMembersTableName = $groupMembersTableName;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of principals based on a prefix.
|
||||
*
|
||||
* This prefix will often contain something like 'principals'. You are only
|
||||
* expected to return principals that are in this base path.
|
||||
*
|
||||
* You are expected to return at least a 'uri' for every user, you can
|
||||
* return any additional properties if you wish so. Common properties are:
|
||||
* {DAV:}displayname
|
||||
* {http://sabredav.org/ns}email-address - This is a custom SabreDAV
|
||||
* field that's actualy injected in a number of other properties. If
|
||||
* you have an email address, use this property.
|
||||
*
|
||||
* @param string $prefixPath
|
||||
* @return array
|
||||
*/
|
||||
public function getPrincipalsByPrefix($prefixPath) {
|
||||
|
||||
$fields = array(
|
||||
'uri',
|
||||
);
|
||||
|
||||
foreach($this->fieldMap as $key=>$value) {
|
||||
$fields[] = $value['dbField'];
|
||||
}
|
||||
$result = $this->pdo->query('SELECT '.implode(',', $fields).' FROM '. $this->tableName);
|
||||
|
||||
$principals = array();
|
||||
|
||||
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
// Checking if the principal is in the prefix
|
||||
list($rowPrefix) = Sabre_DAV_URLUtil::splitPath($row['uri']);
|
||||
if ($rowPrefix !== $prefixPath) continue;
|
||||
|
||||
$principal = array(
|
||||
'uri' => $row['uri'],
|
||||
);
|
||||
foreach($this->fieldMap as $key=>$value) {
|
||||
if ($row[$value['dbField']]) {
|
||||
$principal[$key] = $row[$value['dbField']];
|
||||
}
|
||||
}
|
||||
$principals[] = $principal;
|
||||
|
||||
}
|
||||
|
||||
return $principals;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a specific principal, specified by it's path.
|
||||
* The returned structure should be the exact same as from
|
||||
* getPrincipalsByPrefix.
|
||||
*
|
||||
* @param string $path
|
||||
* @return array
|
||||
*/
|
||||
public function getPrincipalByPath($path) {
|
||||
|
||||
$fields = array(
|
||||
'id',
|
||||
'uri',
|
||||
);
|
||||
|
||||
foreach($this->fieldMap as $key=>$value) {
|
||||
$fields[] = $value['dbField'];
|
||||
}
|
||||
$stmt = $this->pdo->prepare('SELECT '.implode(',', $fields).' FROM '. $this->tableName . ' WHERE uri = ?');
|
||||
$stmt->execute(array($path));
|
||||
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$row) return;
|
||||
|
||||
$principal = array(
|
||||
'id' => $row['id'],
|
||||
'uri' => $row['uri'],
|
||||
);
|
||||
foreach($this->fieldMap as $key=>$value) {
|
||||
if ($row[$value['dbField']]) {
|
||||
$principal[$key] = $row[$value['dbField']];
|
||||
}
|
||||
}
|
||||
return $principal;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates one ore more webdav properties on a principal.
|
||||
*
|
||||
* The list of mutations is supplied as an array. Each key in the array is
|
||||
* a propertyname, such as {DAV:}displayname.
|
||||
*
|
||||
* Each value is the actual value to be updated. If a value is null, it
|
||||
* must be deleted.
|
||||
*
|
||||
* This method should be atomic. It must either completely succeed, or
|
||||
* completely fail. Success and failure can simply be returned as 'true' or
|
||||
* 'false'.
|
||||
*
|
||||
* It is also possible to return detailed failure information. In that case
|
||||
* an array such as this should be returned:
|
||||
*
|
||||
* array(
|
||||
* 200 => array(
|
||||
* '{DAV:}prop1' => null,
|
||||
* ),
|
||||
* 201 => array(
|
||||
* '{DAV:}prop2' => null,
|
||||
* ),
|
||||
* 403 => array(
|
||||
* '{DAV:}prop3' => null,
|
||||
* ),
|
||||
* 424 => array(
|
||||
* '{DAV:}prop4' => null,
|
||||
* ),
|
||||
* );
|
||||
*
|
||||
* In this previous example prop1 was successfully updated or deleted, and
|
||||
* prop2 was succesfully created.
|
||||
*
|
||||
* prop3 failed to update due to '403 Forbidden' and because of this prop4
|
||||
* also could not be updated with '424 Failed dependency'.
|
||||
*
|
||||
* This last example was actually incorrect. While 200 and 201 could appear
|
||||
* in 1 response, if there's any error (403) the other properties should
|
||||
* always fail with 423 (failed dependency).
|
||||
*
|
||||
* But anyway, if you don't want to scratch your head over this, just
|
||||
* return true or false.
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $mutations
|
||||
* @return array|bool
|
||||
*/
|
||||
public function updatePrincipal($path, $mutations) {
|
||||
|
||||
$updateAble = array();
|
||||
foreach($mutations as $key=>$value) {
|
||||
|
||||
// We are not aware of this field, we must fail.
|
||||
if (!isset($this->fieldMap[$key])) {
|
||||
|
||||
$response = array(
|
||||
403 => array(
|
||||
$key => null,
|
||||
),
|
||||
424 => array(),
|
||||
);
|
||||
|
||||
// Adding the rest to the response as a 424
|
||||
foreach($mutations as $subKey=>$subValue) {
|
||||
if ($subKey !== $key) {
|
||||
$response[424][$subKey] = null;
|
||||
}
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
$updateAble[$this->fieldMap[$key]['dbField']] = $value;
|
||||
|
||||
}
|
||||
|
||||
// No fields to update
|
||||
$query = "UPDATE " . $this->tableName . " SET ";
|
||||
|
||||
$first = true;
|
||||
foreach($updateAble as $key => $value) {
|
||||
if (!$first) {
|
||||
$query.= ', ';
|
||||
}
|
||||
$first = false;
|
||||
$query.= "$key = :$key ";
|
||||
}
|
||||
$query.='WHERE uri = :uri';
|
||||
$stmt = $this->pdo->prepare($query);
|
||||
$updateAble['uri'] = $path;
|
||||
$stmt->execute($updateAble);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to search for principals matching a set of
|
||||
* properties.
|
||||
*
|
||||
* This search is specifically used by RFC3744's principal-property-search
|
||||
* REPORT. You should at least allow searching on
|
||||
* http://sabredav.org/ns}email-address.
|
||||
*
|
||||
* The actual search should be a unicode-non-case-sensitive search. The
|
||||
* keys in searchProperties are the WebDAV property names, while the values
|
||||
* are the property values to search on.
|
||||
*
|
||||
* If multiple properties are being searched on, the search should be
|
||||
* AND'ed.
|
||||
*
|
||||
* This method should simply return an array with full principal uri's.
|
||||
*
|
||||
* If somebody attempted to search on a property the backend does not
|
||||
* support, you should simply return 0 results.
|
||||
*
|
||||
* You can also just return 0 results if you choose to not support
|
||||
* searching at all, but keep in mind that this may stop certain features
|
||||
* from working.
|
||||
*
|
||||
* @param string $prefixPath
|
||||
* @param array $searchProperties
|
||||
* @return array
|
||||
*/
|
||||
public function searchPrincipals($prefixPath, array $searchProperties) {
|
||||
|
||||
$query = 'SELECT uri FROM ' . $this->tableName . ' WHERE 1=1 ';
|
||||
$values = array();
|
||||
foreach($searchProperties as $property => $value) {
|
||||
|
||||
switch($property) {
|
||||
|
||||
case '{DAV:}displayname' :
|
||||
$query.=' AND displayname LIKE ?';
|
||||
$values[] = '%' . $value . '%';
|
||||
break;
|
||||
case '{http://sabredav.org/ns}email-address' :
|
||||
$query.=' AND email LIKE ?';
|
||||
$values[] = '%' . $value . '%';
|
||||
break;
|
||||
default :
|
||||
// Unsupported property
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
$stmt = $this->pdo->prepare($query);
|
||||
$stmt->execute($values);
|
||||
|
||||
$principals = array();
|
||||
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
|
||||
// Checking if the principal is in the prefix
|
||||
list($rowPrefix) = Sabre_DAV_URLUtil::splitPath($row['uri']);
|
||||
if ($rowPrefix !== $prefixPath) continue;
|
||||
|
||||
$principals[] = $row['uri'];
|
||||
|
||||
}
|
||||
|
||||
return $principals;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of members for a group-principal
|
||||
*
|
||||
* @param string $principal
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupMemberSet($principal) {
|
||||
|
||||
$principal = $this->getPrincipalByPath($principal);
|
||||
if (!$principal) throw new Sabre_DAV_Exception('Principal not found');
|
||||
|
||||
$stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?');
|
||||
$stmt->execute(array($principal['id']));
|
||||
|
||||
$result = array();
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row['uri'];
|
||||
}
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of groups a principal is a member of
|
||||
*
|
||||
* @param string $principal
|
||||
* @return array
|
||||
*/
|
||||
public function getGroupMembership($principal) {
|
||||
|
||||
$principal = $this->getPrincipalByPath($principal);
|
||||
if (!$principal) throw new Sabre_DAV_Exception('Principal not found');
|
||||
|
||||
$stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM '.$this->groupMembersTableName.' AS groupmembers LEFT JOIN '.$this->tableName.' AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?');
|
||||
$stmt->execute(array($principal['id']));
|
||||
|
||||
$result = array();
|
||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = $row['uri'];
|
||||
}
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the list of group members for a group principal.
|
||||
*
|
||||
* The principals should be passed as a list of uri's.
|
||||
*
|
||||
* @param string $principal
|
||||
* @param array $members
|
||||
* @return void
|
||||
*/
|
||||
public function setGroupMemberSet($principal, array $members) {
|
||||
|
||||
// Grabbing the list of principal id's.
|
||||
$stmt = $this->pdo->prepare('SELECT id, uri FROM '.$this->tableName.' WHERE uri IN (? ' . str_repeat(', ? ', count($members)) . ');');
|
||||
$stmt->execute(array_merge(array($principal), $members));
|
||||
|
||||
$memberIds = array();
|
||||
$principalId = null;
|
||||
|
||||
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||
if ($row['uri'] == $principal) {
|
||||
$principalId = $row['id'];
|
||||
} else {
|
||||
$memberIds[] = $row['id'];
|
||||
}
|
||||
}
|
||||
if (!$principalId) throw new Sabre_DAV_Exception('Principal not found');
|
||||
|
||||
// Wiping out old members
|
||||
$stmt = $this->pdo->prepare('DELETE FROM '.$this->groupMembersTableName.' WHERE principal_id = ?;');
|
||||
$stmt->execute(array($principalId));
|
||||
|
||||
foreach($memberIds as $memberId) {
|
||||
|
||||
$stmt = $this->pdo->prepare('INSERT INTO '.$this->groupMembersTableName.' (principal_id, member_id) VALUES (?, ?);');
|
||||
$stmt->execute(array($principalId, $memberId));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
35
dav/SabreDAV/lib/Sabre/DAVACL/PrincipalCollection.php
Normal file
35
dav/SabreDAV/lib/Sabre/DAVACL/PrincipalCollection.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Principals Collection
|
||||
*
|
||||
* This collection represents a list of users. It uses
|
||||
* Sabre_DAV_Auth_Backend to determine which users are available on the list.
|
||||
*
|
||||
* The users are instances of Sabre_DAV_Auth_Principal
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_PrincipalCollection extends Sabre_DAVACL_AbstractPrincipalCollection {
|
||||
|
||||
/**
|
||||
* 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_DAVACL_Principal($this->principalBackend, $principal);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
209
dav/SabreDAV/lib/Sabre/DAVACL/Property/Acl.php
Normal file
209
dav/SabreDAV/lib/Sabre/DAVACL/Property/Acl.php
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This class represents the {DAV:}acl property
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Property_Acl extends Sabre_DAV_Property {
|
||||
|
||||
/**
|
||||
* List of privileges
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $privileges;
|
||||
|
||||
/**
|
||||
* Whether or not the server base url is required to be prefixed when
|
||||
* serializing the property.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $prefixBaseUrl;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* This object requires a structure similar to the return value from
|
||||
* Sabre_DAVACL_Plugin::getACL().
|
||||
*
|
||||
* Each privilege is a an array with at least a 'privilege' property, and a
|
||||
* 'principal' property. A privilege may have a 'protected' property as
|
||||
* well.
|
||||
*
|
||||
* The prefixBaseUrl should be set to false, if the supplied principal urls
|
||||
* are already full urls. If this is kept to true, the servers base url
|
||||
* will automatically be prefixed.
|
||||
*
|
||||
* @param bool $prefixBaseUrl
|
||||
* @param array $privileges
|
||||
*/
|
||||
public function __construct(array $privileges, $prefixBaseUrl = true) {
|
||||
|
||||
$this->privileges = $privileges;
|
||||
$this->prefixBaseUrl = $prefixBaseUrl;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of privileges for this property
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPrivileges() {
|
||||
|
||||
return $this->privileges;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the property into a DOMElement
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $node
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
|
||||
|
||||
$doc = $node->ownerDocument;
|
||||
foreach($this->privileges as $ace) {
|
||||
|
||||
$this->serializeAce($doc, $node, $ace, $server);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserializes the {DAV:}acl xml element.
|
||||
*
|
||||
* @param DOMElement $dom
|
||||
* @return Sabre_DAVACL_Property_Acl
|
||||
*/
|
||||
static public function unserialize(DOMElement $dom) {
|
||||
|
||||
$privileges = array();
|
||||
$xaces = $dom->getElementsByTagNameNS('DAV:','ace');
|
||||
for($ii=0; $ii < $xaces->length; $ii++) {
|
||||
|
||||
$xace = $xaces->item($ii);
|
||||
$principal = $xace->getElementsByTagNameNS('DAV:','principal');
|
||||
if ($principal->length !== 1) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('Each {DAV:}ace element must have one {DAV:}principal element');
|
||||
}
|
||||
$principal = Sabre_DAVACL_Property_Principal::unserialize($principal->item(0));
|
||||
|
||||
switch($principal->getType()) {
|
||||
case Sabre_DAVACL_Property_Principal::HREF :
|
||||
$principal = $principal->getHref();
|
||||
break;
|
||||
case Sabre_DAVACL_Property_Principal::AUTHENTICATED :
|
||||
$principal = '{DAV:}authenticated';
|
||||
break;
|
||||
case Sabre_DAVACL_Property_Principal::UNAUTHENTICATED :
|
||||
$principal = '{DAV:}unauthenticated';
|
||||
break;
|
||||
case Sabre_DAVACL_Property_Principal::ALL :
|
||||
$principal = '{DAV:}all';
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
$protected = false;
|
||||
|
||||
if ($xace->getElementsByTagNameNS('DAV:','protected')->length > 0) {
|
||||
$protected = true;
|
||||
}
|
||||
|
||||
$grants = $xace->getElementsByTagNameNS('DAV:','grant');
|
||||
if ($grants->length < 1) {
|
||||
throw new Sabre_DAV_Exception_NotImplemented('Every {DAV:}ace element must have a {DAV:}grant element. {DAV:}deny is not yet supported');
|
||||
}
|
||||
$grant = $grants->item(0);
|
||||
|
||||
$xprivs = $grant->getElementsByTagNameNS('DAV:','privilege');
|
||||
for($jj=0; $jj<$xprivs->length; $jj++) {
|
||||
|
||||
$xpriv = $xprivs->item($jj);
|
||||
|
||||
$privilegeName = null;
|
||||
|
||||
for ($kk=0;$kk<$xpriv->childNodes->length;$kk++) {
|
||||
|
||||
$childNode = $xpriv->childNodes->item($kk);
|
||||
if ($t = Sabre_DAV_XMLUtil::toClarkNotation($childNode)) {
|
||||
$privilegeName = $t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_null($privilegeName)) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('{DAV:}privilege elements must have a privilege element contained within them.');
|
||||
}
|
||||
|
||||
$privileges[] = array(
|
||||
'principal' => $principal,
|
||||
'protected' => $protected,
|
||||
'privilege' => $privilegeName,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return new self($privileges);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a single access control entry.
|
||||
*
|
||||
* @param DOMDocument $doc
|
||||
* @param DOMElement $node
|
||||
* @param array $ace
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @return void
|
||||
*/
|
||||
private function serializeAce($doc,$node,$ace, $server) {
|
||||
|
||||
$xace = $doc->createElementNS('DAV:','d:ace');
|
||||
$node->appendChild($xace);
|
||||
|
||||
$principal = $doc->createElementNS('DAV:','d:principal');
|
||||
$xace->appendChild($principal);
|
||||
switch($ace['principal']) {
|
||||
case '{DAV:}authenticated' :
|
||||
$principal->appendChild($doc->createElementNS('DAV:','d:authenticated'));
|
||||
break;
|
||||
case '{DAV:}unauthenticated' :
|
||||
$principal->appendChild($doc->createElementNS('DAV:','d:unauthenticated'));
|
||||
break;
|
||||
case '{DAV:}all' :
|
||||
$principal->appendChild($doc->createElementNS('DAV:','d:all'));
|
||||
break;
|
||||
default:
|
||||
$principal->appendChild($doc->createElementNS('DAV:','d:href',($this->prefixBaseUrl?$server->getBaseUri():'') . $ace['principal'] . '/'));
|
||||
}
|
||||
|
||||
$grant = $doc->createElementNS('DAV:','d:grant');
|
||||
$xace->appendChild($grant);
|
||||
|
||||
$privParts = null;
|
||||
|
||||
preg_match('/^{([^}]*)}(.*)$/',$ace['privilege'],$privParts);
|
||||
|
||||
$xprivilege = $doc->createElementNS('DAV:','d:privilege');
|
||||
$grant->appendChild($xprivilege);
|
||||
|
||||
$xprivilege->appendChild($doc->createElementNS($privParts[1],'d:'.$privParts[2]));
|
||||
|
||||
if (isset($ace['protected']) && $ace['protected'])
|
||||
$xace->appendChild($doc->createElement('d:protected'));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
32
dav/SabreDAV/lib/Sabre/DAVACL/Property/AclRestrictions.php
Normal file
32
dav/SabreDAV/lib/Sabre/DAVACL/Property/AclRestrictions.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* AclRestrictions property
|
||||
*
|
||||
* This property represents {DAV:}acl-restrictions, as defined in RFC3744.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Property_AclRestrictions extends Sabre_DAV_Property {
|
||||
|
||||
/**
|
||||
* Serializes the property into a DOMElement
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $elem
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $elem) {
|
||||
|
||||
$doc = $elem->ownerDocument;
|
||||
|
||||
$elem->appendChild($doc->createElementNS('DAV:','d:grant-only'));
|
||||
$elem->appendChild($doc->createElementNS('DAV:','d:no-invert'));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* CurrentUserPrivilegeSet
|
||||
*
|
||||
* This class represents the current-user-privilege-set property. When
|
||||
* requested, it contain all the privileges a user has on a specific node.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Property_CurrentUserPrivilegeSet extends Sabre_DAV_Property {
|
||||
|
||||
/**
|
||||
* List of privileges
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $privileges;
|
||||
|
||||
/**
|
||||
* Creates the object
|
||||
*
|
||||
* Pass the privileges in clark-notation
|
||||
*
|
||||
* @param array $privileges
|
||||
*/
|
||||
public function __construct(array $privileges) {
|
||||
|
||||
$this->privileges = $privileges;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the property in the DOM
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $node
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
|
||||
|
||||
$doc = $node->ownerDocument;
|
||||
foreach($this->privileges as $privName) {
|
||||
|
||||
$this->serializePriv($doc,$node,$privName);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes one privilege
|
||||
*
|
||||
* @param DOMDocument $doc
|
||||
* @param DOMElement $node
|
||||
* @param string $privName
|
||||
* @return void
|
||||
*/
|
||||
protected function serializePriv($doc,$node,$privName) {
|
||||
|
||||
$xp = $doc->createElementNS('DAV:','d:privilege');
|
||||
$node->appendChild($xp);
|
||||
|
||||
$privParts = null;
|
||||
preg_match('/^{([^}]*)}(.*)$/',$privName,$privParts);
|
||||
|
||||
$xp->appendChild($doc->createElementNS($privParts[1],'d:'.$privParts[2]));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
160
dav/SabreDAV/lib/Sabre/DAVACL/Property/Principal.php
Normal file
160
dav/SabreDAV/lib/Sabre/DAVACL/Property/Principal.php
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Principal property
|
||||
*
|
||||
* The principal property represents a principal from RFC3744 (ACL).
|
||||
* The property can be used to specify a principal or pseudo principals.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Property_Principal extends Sabre_DAV_Property implements Sabre_DAV_Property_IHref {
|
||||
|
||||
/**
|
||||
* To specify a not-logged-in user, use the UNAUTHENTICATED principal
|
||||
*/
|
||||
const UNAUTHENTICATED = 1;
|
||||
|
||||
/**
|
||||
* To specify any principal that is logged in, use AUTHENTICATED
|
||||
*/
|
||||
const AUTHENTICATED = 2;
|
||||
|
||||
/**
|
||||
* Specific principals can be specified with the HREF
|
||||
*/
|
||||
const HREF = 3;
|
||||
|
||||
/**
|
||||
* Everybody, basically
|
||||
*/
|
||||
const ALL = 4;
|
||||
|
||||
/**
|
||||
* Principal-type
|
||||
*
|
||||
* Must be one of the UNAUTHENTICATED, AUTHENTICATED or HREF constants.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* Url to principal
|
||||
*
|
||||
* This value is only used for the HREF principal type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $href;
|
||||
|
||||
/**
|
||||
* Creates the property.
|
||||
*
|
||||
* The 'type' argument must be one of the type constants defined in this class.
|
||||
*
|
||||
* 'href' is only required for the HREF type.
|
||||
*
|
||||
* @param int $type
|
||||
* @param string|null $href
|
||||
*/
|
||||
public function __construct($type, $href = null) {
|
||||
|
||||
$this->type = $type;
|
||||
|
||||
if ($type===self::HREF && is_null($href)) {
|
||||
throw new Sabre_DAV_Exception('The href argument must be specified for the HREF principal type.');
|
||||
}
|
||||
$this->href = $href;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the principal type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getType() {
|
||||
|
||||
return $this->type;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the principal uri.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHref() {
|
||||
|
||||
return $this->href;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the property into a DOMElement.
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $node
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server, DOMElement $node) {
|
||||
|
||||
$prefix = $server->xmlNamespaces['DAV:'];
|
||||
switch($this->type) {
|
||||
|
||||
case self::UNAUTHENTICATED :
|
||||
$node->appendChild(
|
||||
$node->ownerDocument->createElement($prefix . ':unauthenticated')
|
||||
);
|
||||
break;
|
||||
case self::AUTHENTICATED :
|
||||
$node->appendChild(
|
||||
$node->ownerDocument->createElement($prefix . ':authenticated')
|
||||
);
|
||||
break;
|
||||
case self::HREF :
|
||||
$href = $node->ownerDocument->createElement($prefix . ':href');
|
||||
$href->nodeValue = $server->getBaseUri() . $this->href;
|
||||
$node->appendChild($href);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a DOM element into a property object.
|
||||
*
|
||||
* @param DOMElement $dom
|
||||
* @return Sabre_DAVACL_Property_Principal
|
||||
*/
|
||||
static public function unserialize(DOMElement $dom) {
|
||||
|
||||
$parent = $dom->firstChild;
|
||||
while(!Sabre_DAV_XMLUtil::toClarkNotation($parent)) {
|
||||
$parent = $parent->nextSibling;
|
||||
}
|
||||
|
||||
switch(Sabre_DAV_XMLUtil::toClarkNotation($parent)) {
|
||||
|
||||
case '{DAV:}unauthenticated' :
|
||||
return new self(self::UNAUTHENTICATED);
|
||||
case '{DAV:}authenticated' :
|
||||
return new self(self::AUTHENTICATED);
|
||||
case '{DAV:}href':
|
||||
return new self(self::HREF, $parent->textContent);
|
||||
case '{DAV:}all':
|
||||
return new self(self::ALL);
|
||||
default :
|
||||
throw new Sabre_DAV_Exception_BadRequest('Unexpected element (' . Sabre_DAV_XMLUtil::toClarkNotation($parent) . '). Could not deserialize');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SupportedPrivilegeSet property
|
||||
*
|
||||
* This property encodes the {DAV:}supported-privilege-set property, as defined
|
||||
* in rfc3744. Please consult the rfc for details about it's structure.
|
||||
*
|
||||
* This class expects a structure like the one given from
|
||||
* Sabre_DAVACL_Plugin::getSupportedPrivilegeSet as the argument in its
|
||||
* constructor.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Property_SupportedPrivilegeSet extends Sabre_DAV_Property {
|
||||
|
||||
/**
|
||||
* privileges
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $privileges;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $privileges
|
||||
*/
|
||||
public function __construct(array $privileges) {
|
||||
|
||||
$this->privileges = $privileges;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the property into a domdocument.
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @param DOMElement $node
|
||||
* @return void
|
||||
*/
|
||||
public function serialize(Sabre_DAV_Server $server,DOMElement $node) {
|
||||
|
||||
$doc = $node->ownerDocument;
|
||||
$this->serializePriv($doc, $node, $this->privileges);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a property
|
||||
*
|
||||
* This is a recursive function.
|
||||
*
|
||||
* @param DOMDocument $doc
|
||||
* @param DOMElement $node
|
||||
* @param array $privilege
|
||||
* @return void
|
||||
*/
|
||||
private function serializePriv($doc,$node,$privilege) {
|
||||
|
||||
$xsp = $doc->createElementNS('DAV:','d:supported-privilege');
|
||||
$node->appendChild($xsp);
|
||||
|
||||
$xp = $doc->createElementNS('DAV:','d:privilege');
|
||||
$xsp->appendChild($xp);
|
||||
|
||||
$privParts = null;
|
||||
preg_match('/^{([^}]*)}(.*)$/',$privilege['privilege'],$privParts);
|
||||
|
||||
$xp->appendChild($doc->createElementNS($privParts[1],'d:'.$privParts[2]));
|
||||
|
||||
if (isset($privilege['abstract']) && $privilege['abstract']) {
|
||||
$xsp->appendChild($doc->createElementNS('DAV:','d:abstract'));
|
||||
}
|
||||
|
||||
if (isset($privilege['description'])) {
|
||||
$xsp->appendChild($doc->createElementNS('DAV:','d:description',$privilege['description']));
|
||||
}
|
||||
|
||||
if (isset($privilege['aggregates'])) {
|
||||
foreach($privilege['aggregates'] as $subPrivilege) {
|
||||
$this->serializePriv($doc,$xsp,$subPrivilege);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
24
dav/SabreDAV/lib/Sabre/DAVACL/Version.php
Normal file
24
dav/SabreDAV/lib/Sabre/DAVACL/Version.php
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This class contains the SabreDAV version constants.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 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_DAVACL_Version {
|
||||
|
||||
/**
|
||||
* Full version number
|
||||
*/
|
||||
const VERSION = '1.6.0';
|
||||
|
||||
/**
|
||||
* Stability : alpha, beta, stable
|
||||
*/
|
||||
const STABILITY = 'stable';
|
||||
|
||||
}
|
||||
38
dav/SabreDAV/lib/Sabre/DAVACL/includes.php
Normal file
38
dav/SabreDAV/lib/Sabre/DAVACL/includes.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Sabre_DAVACL includes file
|
||||
*
|
||||
* Including this file will automatically include all files from the
|
||||
* Sabre_DAVACL package.
|
||||
*
|
||||
* This often allows faster loadtimes, as autoload-speed is often quite slow.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAVACL
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
|
||||
// Begin includes
|
||||
include __DIR__ . '/AbstractPrincipalCollection.php';
|
||||
include __DIR__ . '/Exception/AceConflict.php';
|
||||
include __DIR__ . '/Exception/NeedPrivileges.php';
|
||||
include __DIR__ . '/Exception/NoAbstract.php';
|
||||
include __DIR__ . '/Exception/NotRecognizedPrincipal.php';
|
||||
include __DIR__ . '/Exception/NotSupportedPrivilege.php';
|
||||
include __DIR__ . '/IACL.php';
|
||||
include __DIR__ . '/IPrincipal.php';
|
||||
include __DIR__ . '/IPrincipalBackend.php';
|
||||
include __DIR__ . '/Plugin.php';
|
||||
include __DIR__ . '/Principal.php';
|
||||
include __DIR__ . '/PrincipalBackend/PDO.php';
|
||||
include __DIR__ . '/PrincipalCollection.php';
|
||||
include __DIR__ . '/Property/Acl.php';
|
||||
include __DIR__ . '/Property/AclRestrictions.php';
|
||||
include __DIR__ . '/Property/CurrentUserPrivilegeSet.php';
|
||||
include __DIR__ . '/Property/Principal.php';
|
||||
include __DIR__ . '/Property/SupportedPrivilegeSet.php';
|
||||
include __DIR__ . '/Version.php';
|
||||
// End includes
|
||||
Loading…
Add table
Add a link
Reference in a new issue