Version 3.2.3
This commit is contained in:
1 parent
ae5c01cc78
commit
78706903a2
2641 files changed
+228363
-201264
No files matched your search
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is the base class for any authentication object.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAV
|
||||
* @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
abstract class Sabre_DAV_Auth_Backend_Abstract {
|
||||
|
||||
/**
|
||||
* Authenticates the user based on the current request.
|
||||
*
|
||||
* If authentication is succesful, true must be returned.
|
||||
* If authentication fails, an exception must be thrown.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function authenticate(Sabre_DAV_Server $server,$realm);
|
||||
|
||||
/**
|
||||
* Returns information about the currently logged in user.
|
||||
*
|
||||
* If nobody is currently logged in, this method should return null.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
abstract public function getCurrentUser();
|
||||
|
||||
/**
|
||||
* Returns the full list of users.
|
||||
*
|
||||
* This method must at least return a uri for each user.
|
||||
*
|
||||
* It is optional to implement this.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUsers() {
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP Basic authentication backend class
|
||||
*
|
||||
* This class can be used by authentication objects wishing to use HTTP Basic
|
||||
* Most of the digest logic is handled, implementors just need to worry about
|
||||
* the authenticateInternal and getUserInfo methods
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAV
|
||||
* @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved.
|
||||
* @author James David Low (http://jameslow.com/)
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
abstract class Sabre_DAV_Auth_Backend_AbstractBasic extends Sabre_DAV_Auth_Backend_Abstract {
|
||||
|
||||
/**
|
||||
* This variable holds information about the currently
|
||||
* logged in user.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Validates a username and password
|
||||
*
|
||||
* If the username and password were correct, this method must return
|
||||
* an array with at least a 'uri' key.
|
||||
*
|
||||
* If the credentials are incorrect, this method must return false.
|
||||
*
|
||||
* @return bool|array
|
||||
*/
|
||||
abstract protected function validateUserPass($username, $password);
|
||||
|
||||
/**
|
||||
* Returns information about the currently logged in user.
|
||||
*
|
||||
* If nobody is currently logged in, this method should return null.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getCurrentUser() {
|
||||
return $this->currentUser;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Authenticates the user based on the current request.
|
||||
*
|
||||
* If authentication is succesful, true must be returned.
|
||||
* If authentication fails, an exception must be thrown.
|
||||
*
|
||||
* @throws Sabre_DAV_Exception_NotAuthenticated
|
||||
* @return bool
|
||||
*/
|
||||
public function authenticate(Sabre_DAV_Server $server,$realm) {
|
||||
|
||||
$auth = new Sabre_HTTP_BasicAuth();
|
||||
$auth->setHTTPRequest($server->httpRequest);
|
||||
$auth->setHTTPResponse($server->httpResponse);
|
||||
$auth->setRealm($realm);
|
||||
$userpass = $auth->getUserPass();
|
||||
if (!$userpass) {
|
||||
$auth->requireLogin();
|
||||
throw new Sabre_DAV_Exception_NotAuthenticated('No basic authentication headers were found');
|
||||
}
|
||||
|
||||
// Authenticates the user
|
||||
if (!($userData = $this->validateUserPass($userpass[0],$userpass[1]))) {
|
||||
$auth->requireLogin();
|
||||
throw new Sabre_DAV_Exception_NotAuthenticated('Username or password does not match');
|
||||
}
|
||||
if (!isset($userData['uri'])) {
|
||||
throw new Sabre_DAV_Exception('The returned array from validateUserPass must contain at a uri element');
|
||||
}
|
||||
$this->currentUser = $userData;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* HTTP Digest authentication backend class
|
||||
*
|
||||
* This class can be used by authentication objects wishing to use HTTP Digest
|
||||
* Most of the digest logic is handled, implementors just need to worry about
|
||||
* the getUserInfo method
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAV
|
||||
* @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
abstract class Sabre_DAV_Auth_Backend_AbstractDigest extends Sabre_DAV_Auth_Backend_Abstract {
|
||||
|
||||
/**
|
||||
* This variable holds information about the currently
|
||||
* logged in user.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* Returns a users information based on its username
|
||||
*
|
||||
* The returned struct must contain at least a uri
|
||||
* element (which can be identical to username) as well as a digestHash
|
||||
* element.
|
||||
*
|
||||
* If the user was not known, false must be returned.
|
||||
*
|
||||
* @param string $realm
|
||||
* @param string $username
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getUserInfo($realm, $username);
|
||||
|
||||
/**
|
||||
* Authenticates the user based on the current request.
|
||||
*
|
||||
* If authentication is succesful, true must be returned.
|
||||
* If authentication fails, an exception must be thrown.
|
||||
*
|
||||
* @throws Sabre_DAV_Exception_NotAuthenticated
|
||||
* @return bool
|
||||
*/
|
||||
public function authenticate(Sabre_DAV_Server $server,$realm) {
|
||||
|
||||
$digest = new Sabre_HTTP_DigestAuth();
|
||||
|
||||
// Hooking up request and response objects
|
||||
$digest->setHTTPRequest($server->httpRequest);
|
||||
$digest->setHTTPResponse($server->httpResponse);
|
||||
|
||||
$digest->setRealm($realm);
|
||||
$digest->init();
|
||||
|
||||
$username = $digest->getUsername();
|
||||
|
||||
// No username was given
|
||||
if (!$username) {
|
||||
$digest->requireLogin();
|
||||
throw new Sabre_DAV_Exception_NotAuthenticated('No digest authentication headers were found');
|
||||
}
|
||||
|
||||
$userData = $this->getUserInfo($realm, $username);
|
||||
// If this was false, the user account didn't exist
|
||||
if ($userData===false) {
|
||||
$digest->requireLogin();
|
||||
throw new Sabre_DAV_Exception_NotAuthenticated('The supplied username was not on file');
|
||||
}
|
||||
if (!is_array($userData)) {
|
||||
throw new Sabre_DAV_Exception('The returntype for getUserInfo must be either false or an array');
|
||||
}
|
||||
|
||||
if (!isset($userData['uri']) || !isset($userData['digestHash'])) {
|
||||
throw new Sabre_DAV_Exception('The returned array from getUserInfo must contain at least a uri and digestHash element');
|
||||
}
|
||||
|
||||
// If this was false, the password or part of the hash was incorrect.
|
||||
if (!$digest->validateA1($userData['digestHash'])) {
|
||||
$digest->requireLogin();
|
||||
throw new Sabre_DAV_Exception_NotAuthenticated('Incorrect username');
|
||||
}
|
||||
|
||||
$this->currentUser = $userData;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the currently logged in user.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getCurrentUser() {
|
||||
|
||||
return $this->currentUser;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Apache authenticator
|
||||
*
|
||||
* This authentication backend assumes that auhtentication has been
|
||||
* conifgured in apache, rather than within SabreDAV.
|
||||
*
|
||||
* Make sure apache is properly configured for this to work.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAV
|
||||
* @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_DAV_Auth_Backend_Apache extends Sabre_DAV_Auth_Backend_Abstract {
|
||||
|
||||
/**
|
||||
* Current apache user
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $remoteUser;
|
||||
|
||||
/**
|
||||
* Authenticates the user based on the current request.
|
||||
*
|
||||
* If authentication is succesful, true must be returned.
|
||||
* If authentication fails, an exception must be thrown.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authenticate(Sabre_DAV_Server $server,$realm) {
|
||||
|
||||
$remoteUser = $server->httpRequest->getRawServerValue('REMOTE_USER');
|
||||
if (is_null($remoteUser)) {
|
||||
throw new Sabre_DAV_Exception('We did not receive the $_SERVER[REMOTE_USER] property. This means that apache might have been misconfigured');
|
||||
}
|
||||
|
||||
$this->remoteUser = $remoteUser;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the currently logged in user.
|
||||
*
|
||||
* If nobody is currently logged in, this method should return null.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getCurrentUser() {
|
||||
|
||||
return array(
|
||||
'uri' => 'principals/' . $this->remoteUser,
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full list of users.
|
||||
*
|
||||
* This method must at least return a uri for each user.
|
||||
*
|
||||
* It is optional to implement this.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUsers() {
|
||||
|
||||
return array($this->getCurrentUser());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is an authentication backend that uses a file to manage passwords.
|
||||
*
|
||||
* The backend file must conform to Apache's htdigest format
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAV
|
||||
* @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_DAV_Auth_Backend_File extends Sabre_DAV_Auth_Backend_AbstractDigest {
|
||||
|
||||
/**
|
||||
* List of users
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $users = array();
|
||||
|
||||
/**
|
||||
* Creates the backend object.
|
||||
*
|
||||
* If the filename argument is passed in, it will parse out the specified file fist.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($filename=null) {
|
||||
|
||||
if (!is_null($filename))
|
||||
$this->loadFile($filename);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an htdigest-formatted file. This method can be called multiple times if
|
||||
* more than 1 file is used.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return void
|
||||
*/
|
||||
public function loadFile($filename) {
|
||||
|
||||
foreach(file($filename,FILE_IGNORE_NEW_LINES) as $line) {
|
||||
|
||||
if (substr_count($line, ":") !== 2)
|
||||
throw new Sabre_DAV_Exception('Malformed htdigest file. Every line should contain 2 colons');
|
||||
|
||||
list($username,$realm,$A1) = explode(':',$line);
|
||||
|
||||
if (!preg_match('/^[a-zA-Z0-9]{32}$/', $A1))
|
||||
throw new Sabre_DAV_Exception('Malformed htdigest file. Invalid md5 hash');
|
||||
|
||||
$this->users[$username] = array(
|
||||
'digestHash' => $A1,
|
||||
'uri' => 'principals/' . $username
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a users' information
|
||||
*
|
||||
* @param string $realm
|
||||
* @param string $username
|
||||
* @return string
|
||||
*/
|
||||
public function getUserInfo($realm, $username) {
|
||||
|
||||
return isset($this->users[$username])?$this->users[$username]:false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the full list of users.
|
||||
*
|
||||
* This method must at least return a uri for each user.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUsers() {
|
||||
|
||||
$re = array();
|
||||
foreach($this->users as $userName=>$A1) {
|
||||
|
||||
$re[] = array(
|
||||
'uri'=>'principals/' . $userName
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return $re;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is an authentication backend that uses a file to manage passwords.
|
||||
*
|
||||
* The backend file must conform to Apache's htdigest format
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAV
|
||||
* @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_DAV_Auth_Backend_PDO extends Sabre_DAV_Auth_Backend_AbstractDigest {
|
||||
|
||||
private $pdo;
|
||||
|
||||
/**
|
||||
* Creates the backend object.
|
||||
*
|
||||
* If the filename argument is passed in, it will parse out the specified file fist.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(PDO $pdo) {
|
||||
|
||||
$this->pdo = $pdo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a users' information
|
||||
*
|
||||
* @param string $realm
|
||||
* @param string $username
|
||||
* @return string
|
||||
*/
|
||||
public function getUserInfo($realm,$username) {
|
||||
|
||||
$stmt = $this->pdo->prepare('SELECT username, digesta1, email FROM users WHERE username = ?');
|
||||
$stmt->execute(array($username));
|
||||
$result = $stmt->fetchAll();
|
||||
|
||||
if (!count($result)) return false;
|
||||
$user = array(
|
||||
'uri' => 'principals/' . $result[0]['username'],
|
||||
'digestHash' => $result[0]['digesta1'],
|
||||
);
|
||||
if ($result[0]['email']) $user['{http://sabredav.org/ns}email-address'] = $result[0]['email'];
|
||||
return $user;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all users
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getUsers() {
|
||||
|
||||
$result = $this->pdo->query('SELECT username, email FROM users')->fetchAll();
|
||||
|
||||
$rv = array();
|
||||
foreach($result as $user) {
|
||||
|
||||
$r = array(
|
||||
'uri' => 'principals/' . $user['username'],
|
||||
);
|
||||
if ($user['email']) $r['{http://sabredav.org/ns}email-address'] = $user['email'];
|
||||
$rv[] = $r;
|
||||
|
||||
}
|
||||
|
||||
return $rv;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com/">IP.Board</a>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,434 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This plugin provides Authentication for a WebDAV server.
|
||||
*
|
||||
* It relies on a Backend object, which provides user information.
|
||||
*
|
||||
* Additionally, it provides support for:
|
||||
* * {DAV:}current-user-principal property from RFC5397
|
||||
* * {DAV:}principal-collection-set property from RFC3744
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAV
|
||||
* @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_DAV_Auth_Plugin extends Sabre_DAV_ServerPlugin {
|
||||
|
||||
/**
|
||||
* Reference to main server object
|
||||
*
|
||||
* @var Sabre_DAV_Server
|
||||
*/
|
||||
private $server;
|
||||
|
||||
/**
|
||||
* Authentication backend
|
||||
*
|
||||
* @var Sabre_DAV_Auth_Backend_Abstract
|
||||
*/
|
||||
private $authBackend;
|
||||
|
||||
/**
|
||||
* The authentication realm.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $realm;
|
||||
|
||||
/**
|
||||
* __construct
|
||||
*
|
||||
* @param Sabre_DAV_Auth_Backend_Abstract $authBackend
|
||||
* @param string $realm
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Sabre_DAV_Auth_Backend_Abstract $authBackend, $realm) {
|
||||
|
||||
$this->authBackend = $authBackend;
|
||||
$this->realm = $realm;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the plugin. This function is automatically called by the server
|
||||
*
|
||||
* @param Sabre_DAV_Server $server
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(Sabre_DAV_Server $server) {
|
||||
|
||||
$this->server = $server;
|
||||
$this->server->subscribeEvent('beforeMethod',array($this,'beforeMethod'),10);
|
||||
$this->server->subscribeEvent('afterGetProperties',array($this,'afterGetProperties'));
|
||||
$this->server->subscribeEvent('report',array($this,'report'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method intercepts calls to PROPFIND and similar lookups
|
||||
*
|
||||
* This is done to inject the current-user-principal if this is requested.
|
||||
*
|
||||
* @todo support for 'unauthenticated'
|
||||
* @return void
|
||||
*/
|
||||
public function afterGetProperties($href, &$properties) {
|
||||
|
||||
if (array_key_exists('{DAV:}current-user-principal', $properties[404])) {
|
||||
if ($ui = $this->authBackend->getCurrentUser()) {
|
||||
$properties[200]['{DAV:}current-user-principal'] = new Sabre_DAV_Property_Principal(Sabre_DAV_Property_Principal::HREF, $ui['uri']);
|
||||
} else {
|
||||
$properties[200]['{DAV:}current-user-principal'] = new Sabre_DAV_Property_Principal(Sabre_DAV_Property_Principal::UNAUTHENTICATED);
|
||||
}
|
||||
unset($properties[404]['{DAV:}current-user-principal']);
|
||||
}
|
||||
if (array_key_exists('{DAV:}principal-collection-set', $properties[404])) {
|
||||
$properties[200]['{DAV:}principal-collection-set'] = new Sabre_DAV_Property_Href('principals');
|
||||
unset($properties[404]['{DAV:}principal-collection-set']);
|
||||
}
|
||||
if (array_key_exists('{DAV:}supported-report-set', $properties[200])) {
|
||||
$properties[200]['{DAV:}supported-report-set']->addReport(array(
|
||||
'{DAV:}expand-property',
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called before any HTTP method and forces users to be authenticated
|
||||
*
|
||||
* @param string $method
|
||||
* @throws Sabre_DAV_Exception_NotAuthenticated
|
||||
* @return bool
|
||||
*/
|
||||
public function beforeMethod($method, $uri) {
|
||||
|
||||
$this->authBackend->authenticate($this->server,$this->realm);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This functions handles REPORT requests
|
||||
*
|
||||
* @param string $reportName
|
||||
* @param DOMNode $dom
|
||||
* @return bool|null
|
||||
*/
|
||||
public function report($reportName,$dom) {
|
||||
|
||||
switch($reportName) {
|
||||
case '{DAV:}expand-property' :
|
||||
$this->expandPropertyReport($dom);
|
||||
return false;
|
||||
case '{DAV:}principal-property-search' :
|
||||
if ($this->server->getRequestUri()==='principals') {
|
||||
$this->principalPropertySearchReport($dom);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '{DAV:}principal-search-property-set' :
|
||||
if ($this->server->getRequestUri()==='principals') {
|
||||
$this->principalSearchPropertySetReport($dom);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The expand-property report is defined in RFC3253 section 3-8.
|
||||
*
|
||||
* This report is very similar to a standard PROPFIND. The difference is
|
||||
* that it has the additional ability to look at properties containing a
|
||||
* {DAV:}href element, follow that property and grab additional elements
|
||||
* there.
|
||||
*
|
||||
* Other rfc's, such as ACL rely on this report, so it made sense to put
|
||||
* it in this plugin.
|
||||
*
|
||||
* @param DOMElement $dom
|
||||
* @return void
|
||||
*/
|
||||
protected function expandPropertyReport($dom) {
|
||||
|
||||
$requestedProperties = $this->parseExpandPropertyReportRequest($dom->firstChild->firstChild);
|
||||
$depth = $this->server->getHTTPDepth(0);
|
||||
$requestUri = $this->server->getRequestUri();
|
||||
|
||||
$result = $this->expandProperties($requestUri,$requestedProperties,$depth);
|
||||
|
||||
$dom = new DOMDocument('1.0','utf-8');
|
||||
$dom->formatOutput = true;
|
||||
$multiStatus = $dom->createElement('d:multistatus');
|
||||
$dom->appendChild($multiStatus);
|
||||
|
||||
// Adding in default namespaces
|
||||
foreach($this->server->xmlNamespaces as $namespace=>$prefix) {
|
||||
|
||||
$multiStatus->setAttribute('xmlns:' . $prefix,$namespace);
|
||||
|
||||
}
|
||||
|
||||
foreach($result as $entry) {
|
||||
|
||||
$entry->serialize($this->server,$multiStatus);
|
||||
|
||||
}
|
||||
|
||||
$xml = $dom->saveXML();
|
||||
$this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
|
||||
$this->server->httpResponse->sendStatus(207);
|
||||
$this->server->httpResponse->sendBody($xml);
|
||||
|
||||
// Make sure the event chain is broken
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used by expandPropertyReport to parse
|
||||
* out the entire HTTP request.
|
||||
*
|
||||
* @param DOMElement $node
|
||||
* @return array
|
||||
*/
|
||||
protected function parseExpandPropertyReportRequest($node) {
|
||||
|
||||
$requestedProperties = array();
|
||||
do {
|
||||
|
||||
if (Sabre_DAV_XMLUtil::toClarkNotation($node)!=='{DAV:}property') continue;
|
||||
|
||||
if ($node->firstChild) {
|
||||
|
||||
$children = $this->parseExpandPropertyReportRequest($node->firstChild);
|
||||
|
||||
} else {
|
||||
|
||||
$children = array();
|
||||
|
||||
}
|
||||
|
||||
$namespace = $node->getAttribute('namespace');
|
||||
if (!$namespace) $namespace = 'DAV:';
|
||||
|
||||
$propName = '{'.$namespace.'}' . $node->getAttribute('name');
|
||||
$requestedProperties[$propName] = $children;
|
||||
|
||||
} while ($node = $node->nextSibling);
|
||||
|
||||
return $requestedProperties;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method expands all the properties and returns
|
||||
* a list with property values
|
||||
*
|
||||
* @param array $path
|
||||
* @param array $requestedProperties the list of required properties
|
||||
* @param array $depth
|
||||
*/
|
||||
protected function expandProperties($path,array $requestedProperties,$depth) {
|
||||
|
||||
$foundProperties = $this->server->getPropertiesForPath($path,array_keys($requestedProperties),$depth);
|
||||
|
||||
$result = array();
|
||||
|
||||
foreach($foundProperties as $node) {
|
||||
|
||||
foreach($requestedProperties as $propertyName=>$childRequestedProperties) {
|
||||
|
||||
// We're only traversing if sub-properties were requested
|
||||
if(count($childRequestedProperties)===0) continue;
|
||||
|
||||
// We only have to do the expansion if the property was found
|
||||
// and it contains an href element.
|
||||
if (!array_key_exists($propertyName,$node[200])) continue;
|
||||
if (!($node[200][$propertyName] instanceof Sabre_DAV_Property_IHref)) continue;
|
||||
|
||||
$href = $node[200][$propertyName]->getHref();
|
||||
list($node[200][$propertyName]) = $this->expandProperties($href,$childRequestedProperties,0);
|
||||
|
||||
}
|
||||
$result[] = new Sabre_DAV_Property_Response($path, $node);
|
||||
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
protected function principalSearchPropertySetReport(DOMDocument $dom) {
|
||||
|
||||
$searchProperties = array(
|
||||
'{DAV:}displayname' => 'display name'
|
||||
|
||||
);
|
||||
|
||||
$httpDepth = $this->server->getHTTPDepth(0);
|
||||
if ($httpDepth!==0) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('This report is only defined when Depth: 0');
|
||||
}
|
||||
|
||||
if ($dom->firstChild->hasChildNodes())
|
||||
throw new Sabre_DAV_Exception_BadRequest('The principal-search-property-set report element is not allowed to have child elements');
|
||||
|
||||
$dom = new DOMDocument('1.0','utf-8');
|
||||
$dom->formatOutput = true;
|
||||
$root = $dom->createElement('d:principal-search-property-set');
|
||||
$dom->appendChild($root);
|
||||
// Adding in default namespaces
|
||||
foreach($this->server->xmlNamespaces as $namespace=>$prefix) {
|
||||
|
||||
$root->setAttribute('xmlns:' . $prefix,$namespace);
|
||||
|
||||
}
|
||||
|
||||
$nsList = $this->server->xmlNamespaces;
|
||||
|
||||
foreach($searchProperties as $propertyName=>$description) {
|
||||
|
||||
$psp = $dom->createElement('d:principal-search-property');
|
||||
$root->appendChild($psp);
|
||||
|
||||
$prop = $dom->createElement('d:prop');
|
||||
$psp->appendChild($prop);
|
||||
|
||||
$propName = null;
|
||||
preg_match('/^{([^}]*)}(.*)$/',$propertyName,$propName);
|
||||
|
||||
//if (!isset($nsList[$propName[1]])) {
|
||||
// $nsList[$propName[1]] = 'x' . count($nsList);
|
||||
//}
|
||||
|
||||
// If the namespace was defined in the top-level xml namespaces, it means
|
||||
// there was already a namespace declaration, and we don't have to worry about it.
|
||||
//if (isset($server->xmlNamespaces[$propName[1]])) {
|
||||
$currentProperty = $dom->createElement($nsList[$propName[1]] . ':' . $propName[2]);
|
||||
//} else {
|
||||
// $currentProperty = $dom->createElementNS($propName[1],$nsList[$propName[1]].':' . $propName[2]);
|
||||
//}
|
||||
$prop->appendChild($currentProperty);
|
||||
|
||||
$descriptionElem = $dom->createElement('d:description');
|
||||
$descriptionElem->setAttribute('xml:lang','en');
|
||||
$descriptionElem->appendChild($dom->createTextNode($description));
|
||||
$psp->appendChild($descriptionElem);
|
||||
|
||||
|
||||
}
|
||||
|
||||
$this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
|
||||
$this->server->httpResponse->sendStatus(200);
|
||||
$this->server->httpResponse->sendBody($dom->saveXML());
|
||||
|
||||
}
|
||||
|
||||
protected function principalPropertySearchReport($dom) {
|
||||
|
||||
$searchableProperties = array(
|
||||
'{DAV:}displayname' => 'display name'
|
||||
|
||||
);
|
||||
|
||||
list($searchProperties, $requestedProperties) = $this->parsePrincipalPropertySearchReportRequest($dom);
|
||||
|
||||
$uri = $this->server->getRequestUri();
|
||||
|
||||
$result = array();
|
||||
|
||||
$lookupResults = $this->server->getPropertiesForPath($uri, array_keys($searchProperties), 1);
|
||||
|
||||
// The first item in the results is the parent, so we get rid of it.
|
||||
array_shift($lookupResults);
|
||||
|
||||
$matches = array();
|
||||
|
||||
foreach($lookupResults as $lookupResult) {
|
||||
|
||||
foreach($searchProperties as $searchProperty=>$searchValue) {
|
||||
if (!isset($searchableProperties[$searchProperty])) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('Searching for ' . $searchProperty . ' is not supported');
|
||||
}
|
||||
|
||||
if (isset($lookupResult[200][$searchProperty]) &&
|
||||
mb_stripos($lookupResult[200][$searchProperty], $searchValue, 0, 'UTF-8')!==false) {
|
||||
$matches[] = $lookupResult['href'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$matchProperties = array();
|
||||
|
||||
foreach($matches as $match) {
|
||||
|
||||
list($result) = $this->server->getPropertiesForPath($match, $requestedProperties, 0);
|
||||
$matchProperties[] = $result;
|
||||
|
||||
}
|
||||
|
||||
$xml = $this->server->generateMultiStatus($matchProperties);
|
||||
$this->server->httpResponse->setHeader('Content-Type','application/xml; charset=utf-8');
|
||||
$this->server->httpResponse->sendStatus(207);
|
||||
$this->server->httpResponse->sendBody($xml);
|
||||
|
||||
}
|
||||
|
||||
protected function parsePrincipalPropertySearchReportRequest($dom) {
|
||||
|
||||
$httpDepth = $this->server->getHTTPDepth(0);
|
||||
if ($httpDepth!==0) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('This report is only defined when Depth: 0');
|
||||
}
|
||||
|
||||
$searchProperties = array();
|
||||
|
||||
// Parsing the search request
|
||||
foreach($dom->firstChild->childNodes as $searchNode) {
|
||||
|
||||
if (Sabre_DAV_XMLUtil::toClarkNotation($searchNode)!=='{DAV:}property-search')
|
||||
continue;
|
||||
|
||||
$propertyName = null;
|
||||
$propertyValue = null;
|
||||
|
||||
foreach($searchNode->childNodes as $childNode) {
|
||||
|
||||
switch(Sabre_DAV_XMLUtil::toClarkNotation($childNode)) {
|
||||
|
||||
case '{DAV:}prop' :
|
||||
$property = Sabre_DAV_XMLUtil::parseProperties($searchNode);
|
||||
reset($property);
|
||||
$propertyName = key($property);
|
||||
break;
|
||||
|
||||
case '{DAV:}match' :
|
||||
$propertyValue = $childNode->textContent;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (is_null($propertyName) || is_null($propertyValue))
|
||||
throw new Sabre_DAV_Exception_BadRequest('Invalid search request. propertyname: ' . $propertyName . '. propertvvalue: ' . $propertyValue);
|
||||
|
||||
$searchProperties[$propertyName] = $propertyValue;
|
||||
|
||||
}
|
||||
|
||||
return array($searchProperties, array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Principal class
|
||||
*
|
||||
* This class represents a user in the directory tree.
|
||||
* Many WebDAV specs require a user to show up in the directory
|
||||
* structure. The principal is defined in RFC 3744.
|
||||
*
|
||||
* @package Sabre
|
||||
* @subpackage DAV
|
||||
* @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_DAV_Auth_Principal extends Sabre_DAV_Node implements Sabre_DAV_IProperties {
|
||||
|
||||
/**
|
||||
* Full uri for this principal resource
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $principalUri;/*noLibHook*/
|
||||
|
||||
/**
|
||||
* Struct with principal information.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $principalProperties;
|
||||
|
||||
/**
|
||||
* Creates the principal object
|
||||
*
|
||||
* @param string $principalUri Full uri to the principal resource
|
||||
* @param array $principalProperties
|
||||
*/
|
||||
public function __construct($principalUri,array $principalProperties = array()) {
|
||||
|
||||
$this->principalUri = $principalUri;
|
||||
$this->principalProperties = $principalProperties;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the element
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getName() {
|
||||
|
||||
list(, $name) = Sabre_DAV_URLUtil::splitPath($this->principalUri);
|
||||
return $name;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the user
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getDisplayName() {
|
||||
|
||||
if (isset($this->principalProperties['{DAV:}displayname'])) {
|
||||
return $this->principalProperties['{DAV:}displayname'];
|
||||
} else {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of properties
|
||||
*
|
||||
* @param array $requestedProperties
|
||||
* @return void
|
||||
*/
|
||||
public function getProperties($requestedProperties) {
|
||||
|
||||
if (!count($requestedProperties)) {
|
||||
|
||||
// If all properties were requested
|
||||
// we will only returns properties from this list
|
||||
$requestedProperties = array(
|
||||
'{DAV:}resourcetype',
|
||||
'{DAV:}displayname',
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// We need to always return the resourcetype
|
||||
// This is a bug in the core server, but it is easier to do it this way for now
|
||||
$newProperties = array(
|
||||
'{DAV:}resourcetype' => new Sabre_DAV_Property_ResourceType('{DAV:}principal')
|
||||
);
|
||||
foreach($requestedProperties as $propName) switch($propName) {
|
||||
|
||||
case '{DAV:}alternate-URI-set' :
|
||||
if (isset($this->principalProperties['{http://sabredav.org/ns}email-address'])) {
|
||||
$href = 'mailto:' . $this->principalProperties['{http://sabredav.org/ns}email-address'];
|
||||
$newProperties[$propName] = new Sabre_DAV_Property_Href($href);
|
||||
} else {
|
||||
$newProperties[$propName] = null;
|
||||
}
|
||||
break;
|
||||
case '{DAV:}group-member-set' :
|
||||
case '{DAV:}group-membership' :
|
||||
$newProperties[$propName] = null;
|
||||
break;
|
||||
|
||||
case '{DAV:}principal-URL' :
|
||||
$newProperties[$propName] = new Sabre_DAV_Property_Href($this->principalUri);
|
||||
break;
|
||||
|
||||
case '{DAV:}displayname' :
|
||||
$newProperties[$propName] = $this->getDisplayName();
|
||||
break;
|
||||
|
||||
default :
|
||||
if (isset($this->principalProperties[$propName])) {
|
||||
$newProperties[$propName] = $this->principalProperties[$propName];
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return $newProperties;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates this principals properties.
|
||||
*
|
||||
* Currently this is not supported
|
||||
*
|
||||
* @param array $properties
|
||||
* @see Sabre_DAV_IProperties::updateProperties
|
||||
* @return bool|array
|
||||
*/
|
||||
public function updateProperties($properties) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?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 DAV
|
||||
* @copyright Copyright (C) 2007-2010 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_DAV_Auth_PrincipalCollection extends Sabre_DAV_Directory {
|
||||
|
||||
/**
|
||||
* The name of this object. It is not adviced to change this.
|
||||
* The plugins that depend on the principals collection to exist need to
|
||||
* be have a common name to find it.
|
||||
*/
|
||||
const NODENAME = 'principals';
|
||||
|
||||
/**
|
||||
* Authentication backend
|
||||
*
|
||||
* @var Sabre_DAV_Auth_Backend
|
||||
*/
|
||||
protected $authBackend;
|
||||
|
||||
/**
|
||||
* Creates the object
|
||||
*
|
||||
* @param Sabre_DAV_Auth_Backend_Abstract $authBackend
|
||||
*/
|
||||
public function __construct(Sabre_DAV_Auth_Backend_Abstract $authBackend) {
|
||||
|
||||
$this->authBackend = $authBackend;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this collection.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
|
||||
return self::NODENAME;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Retursn the list of users
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getChildren() {
|
||||
|
||||
$children = array();
|
||||
foreach($this->authBackend->getUsers() as $principalInfo) {
|
||||
|
||||
$principalUri = $principalInfo['uri'] . '/';
|
||||
$children[] = new Sabre_DAV_Auth_Principal($principalUri,$principalInfo);
|
||||
|
||||
|
||||
}
|
||||
return $children;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head><title>IP.Board - Bulletin Board System</title></head>
|
||||
<body>
|
||||
<h1>403: IP.Board -> Forbidden</h1>
|
||||
<hr>
|
||||
You have reached this page in error, please use your back button to return to the forum.
|
||||
<hr>
|
||||
<a href="http://www.invisionpower.com/">IP.Board</a>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user