diff options
author | redmatrix <git@macgirvin.com> | 2016-05-10 17:26:44 -0700 |
---|---|---|
committer | redmatrix <git@macgirvin.com> | 2016-05-10 17:26:44 -0700 |
commit | 0b02a6d123b2014705998c94ddf3d460948d3eac (patch) | |
tree | 78ff2cab9944a4f5ab3f80ec93cbe1120de90bb2 /vendor/sabre/dav/lib/DAV/Auth | |
parent | 40b5b6e9d2da7ab65c8b4d38cdceac83a4d78deb (diff) | |
download | volse-hubzilla-0b02a6d123b2014705998c94ddf3d460948d3eac.tar.gz volse-hubzilla-0b02a6d123b2014705998c94ddf3d460948d3eac.tar.bz2 volse-hubzilla-0b02a6d123b2014705998c94ddf3d460948d3eac.zip |
initial sabre upgrade (needs lots of work - to wit: authentication, redo the browser interface, and rework event export/import)
Diffstat (limited to 'vendor/sabre/dav/lib/DAV/Auth')
-rw-r--r-- | vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php | 144 | ||||
-rw-r--r-- | vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php | 138 | ||||
-rw-r--r-- | vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php | 162 | ||||
-rw-r--r-- | vendor/sabre/dav/lib/DAV/Auth/Backend/Apache.php | 96 | ||||
-rw-r--r-- | vendor/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php | 70 | ||||
-rw-r--r-- | vendor/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php | 58 | ||||
-rw-r--r-- | vendor/sabre/dav/lib/DAV/Auth/Backend/File.php | 77 | ||||
-rw-r--r-- | vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php | 57 | ||||
-rw-r--r-- | vendor/sabre/dav/lib/DAV/Auth/Plugin.php | 213 |
9 files changed, 1015 insertions, 0 deletions
diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php new file mode 100644 index 000000000..40a95f8bf --- /dev/null +++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBasic.php @@ -0,0 +1,144 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\DAV; +use Sabre\HTTP; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; + +/** + * 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 validateUserPass method. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author James David Low (http://jameslow.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +abstract class AbstractBasic implements BackendInterface { + + /** + * Authentication Realm. + * + * The realm is often displayed by browser clients when showing the + * authentication dialog. + * + * @var string + */ + protected $realm = 'sabre/dav'; + + /** + * This is the prefix that will be used to generate principal urls. + * + * @var string + */ + protected $principalPrefix = 'principals/'; + + /** + * Validates a username and password + * + * This method should return true or false depending on if login + * succeeded. + * + * @param string $username + * @param string $password + * @return bool + */ + abstract protected function validateUserPass($username, $password); + + /** + * Sets the authentication realm for this backend. + * + * @param string $realm + * @return void + */ + function setRealm($realm) { + + $this->realm = $realm; + + } + + /** + * When this method is called, the backend must check if authentication was + * successful. + * + * The returned value must be one of the following + * + * [true, "principals/username"] + * [false, "reason for failure"] + * + * If authentication was successful, it's expected that the authentication + * backend returns a so-called principal url. + * + * Examples of a principal url: + * + * principals/admin + * principals/user1 + * principals/users/joe + * principals/uid/123457 + * + * If you don't use WebDAV ACL (RFC3744) we recommend that you simply + * return a string such as: + * + * principals/users/[username] + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return array + */ + function check(RequestInterface $request, ResponseInterface $response) { + + $auth = new HTTP\Auth\Basic( + $this->realm, + $request, + $response + ); + + $userpass = $auth->getCredentials(); + if (!$userpass) { + return [false, "No 'Authorization: Basic' header found. Either the client didn't send one, or the server is misconfigured"]; + } + if (!$this->validateUserPass($userpass[0], $userpass[1])) { + return [false, "Username or password was incorrect"]; + } + return [true, $this->principalPrefix . $userpass[0]]; + + } + + /** + * This method is called when a user could not be authenticated, and + * authentication was required for the current request. + * + * This gives you the opportunity to set authentication headers. The 401 + * status code will already be set. + * + * In this case of Basic Auth, this would for example mean that the + * following header needs to be set: + * + * $response->addHeader('WWW-Authenticate', 'Basic realm=SabreDAV'); + * + * Keep in mind that in the case of multiple authentication backends, other + * WWW-Authenticate headers may already have been set, and you'll want to + * append your own WWW-Authenticate header instead of overwriting the + * existing one. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return void + */ + function challenge(RequestInterface $request, ResponseInterface $response) { + + $auth = new HTTP\Auth\Basic( + $this->realm, + $request, + $response + ); + $auth->requireLogin(); + + } + +} diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php new file mode 100644 index 000000000..ae7a8a12f --- /dev/null +++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractBearer.php @@ -0,0 +1,138 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\DAV; +use Sabre\HTTP; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; + +/** + * HTTP Bearer authentication backend class + * + * This class can be used by authentication objects wishing to use HTTP Bearer + * Most of the digest logic is handled, implementors just need to worry about + * the validateBearerToken method. + * + * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/). + * @author François Kooman (https://tuxed.net/) + * @author James David Low (http://jameslow.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +abstract class AbstractBearer implements BackendInterface { + + /** + * Authentication Realm. + * + * The realm is often displayed by browser clients when showing the + * authentication dialog. + * + * @var string + */ + protected $realm = 'sabre/dav'; + + /** + * Validates a Bearer token + * + * This method should return the full principal url, or false if the + * token was incorrect. + * + * @param string $bearerToken + * @return string|false + */ + abstract protected function validateBearerToken($bearerToken); + + /** + * Sets the authentication realm for this backend. + * + * @param string $realm + * @return void + */ + function setRealm($realm) { + + $this->realm = $realm; + + } + + /** + * When this method is called, the backend must check if authentication was + * successful. + * + * The returned value must be one of the following + * + * [true, "principals/username"] + * [false, "reason for failure"] + * + * If authentication was successful, it's expected that the authentication + * backend returns a so-called principal url. + * + * Examples of a principal url: + * + * principals/admin + * principals/user1 + * principals/users/joe + * principals/uid/123457 + * + * If you don't use WebDAV ACL (RFC3744) we recommend that you simply + * return a string such as: + * + * principals/users/[username] + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return array + */ + function check(RequestInterface $request, ResponseInterface $response) { + + $auth = new HTTP\Auth\Bearer( + $this->realm, + $request, + $response + ); + + $bearerToken = $auth->getToken($request); + if (!$bearerToken) { + return [false, "No 'Authorization: Bearer' header found. Either the client didn't send one, or the server is mis-configured"]; + } + $principalUrl = $this->validateBearerToken($bearerToken); + if (!$principalUrl) { + return [false, "Bearer token was incorrect"]; + } + return [true, $principalUrl]; + + } + + /** + * This method is called when a user could not be authenticated, and + * authentication was required for the current request. + * + * This gives you the opportunity to set authentication headers. The 401 + * status code will already be set. + * + * In this case of Bearer Auth, this would for example mean that the + * following header needs to be set: + * + * $response->addHeader('WWW-Authenticate', 'Bearer realm=SabreDAV'); + * + * Keep in mind that in the case of multiple authentication backends, other + * WWW-Authenticate headers may already have been set, and you'll want to + * append your own WWW-Authenticate header instead of overwriting the + * existing one. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return void + */ + function challenge(RequestInterface $request, ResponseInterface $response) { + + $auth = new HTTP\Auth\Bearer( + $this->realm, + $request, + $response + ); + $auth->requireLogin(); + + } + +} diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php new file mode 100644 index 000000000..0251decc1 --- /dev/null +++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/AbstractDigest.php @@ -0,0 +1,162 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\HTTP; +use Sabre\DAV; +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; + +/** + * 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 getDigestHash method + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +abstract class AbstractDigest implements BackendInterface { + + /** + * Authentication Realm. + * + * The realm is often displayed by browser clients when showing the + * authentication dialog. + * + * @var string + */ + protected $realm = 'SabreDAV'; + + /** + * This is the prefix that will be used to generate principal urls. + * + * @var string + */ + protected $principalPrefix = 'principals/'; + + /** + * Sets the authentication realm for this backend. + * + * Be aware that for Digest authentication, the realm influences the digest + * hash. Choose the realm wisely, because if you change it later, all the + * existing hashes will break and nobody can authenticate. + * + * @param string $realm + * @return void + */ + function setRealm($realm) { + + $this->realm = $realm; + + } + + /** + * Returns a users digest hash based on the username and realm. + * + * If the user was not known, null must be returned. + * + * @param string $realm + * @param string $username + * @return string|null + */ + abstract function getDigestHash($realm, $username); + + /** + * When this method is called, the backend must check if authentication was + * successful. + * + * The returned value must be one of the following + * + * [true, "principals/username"] + * [false, "reason for failure"] + * + * If authentication was successful, it's expected that the authentication + * backend returns a so-called principal url. + * + * Examples of a principal url: + * + * principals/admin + * principals/user1 + * principals/users/joe + * principals/uid/123457 + * + * If you don't use WebDAV ACL (RFC3744) we recommend that you simply + * return a string such as: + * + * principals/users/[username] + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return array + */ + function check(RequestInterface $request, ResponseInterface $response) { + + $digest = new HTTP\Auth\Digest( + $this->realm, + $request, + $response + ); + $digest->init(); + + $username = $digest->getUsername(); + + // No username was given + if (!$username) { + return [false, "No 'Authorization: Digest' header found. Either the client didn't send one, or the server is misconfigured"]; + } + + $hash = $this->getDigestHash($this->realm, $username); + // If this was false, the user account didn't exist + if ($hash === false || is_null($hash)) { + return [false, "Username or password was incorrect"]; + } + if (!is_string($hash)) { + throw new DAV\Exception('The returned value from getDigestHash must be a string or null'); + } + + // If this was false, the password or part of the hash was incorrect. + if (!$digest->validateA1($hash)) { + return [false, "Username or password was incorrect"]; + } + + return [true, $this->principalPrefix . $username]; + + } + + /** + * This method is called when a user could not be authenticated, and + * authentication was required for the current request. + * + * This gives you the opportunity to set authentication headers. The 401 + * status code will already be set. + * + * In this case of Basic Auth, this would for example mean that the + * following header needs to be set: + * + * $response->addHeader('WWW-Authenticate', 'Basic realm=SabreDAV'); + * + * Keep in mind that in the case of multiple authentication backends, other + * WWW-Authenticate headers may already have been set, and you'll want to + * append your own WWW-Authenticate header instead of overwriting the + * existing one. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return void + */ + function challenge(RequestInterface $request, ResponseInterface $response) { + + $auth = new HTTP\Auth\Digest( + $this->realm, + $request, + $response + ); + $auth->init(); + $auth->requireLogin(); + + } + +} diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/Apache.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/Apache.php new file mode 100644 index 000000000..e203d2685 --- /dev/null +++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/Apache.php @@ -0,0 +1,96 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; + +/** + * Apache authenticator + * + * This authentication backend assumes that authentication has been + * configured in apache, rather than within SabreDAV. + * + * Make sure apache is properly configured for this to work. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class Apache implements BackendInterface { + + /** + * This is the prefix that will be used to generate principal urls. + * + * @var string + */ + protected $principalPrefix = 'principals/'; + + /** + * When this method is called, the backend must check if authentication was + * successful. + * + * The returned value must be one of the following + * + * [true, "principals/username"] + * [false, "reason for failure"] + * + * If authentication was successful, it's expected that the authentication + * backend returns a so-called principal url. + * + * Examples of a principal url: + * + * principals/admin + * principals/user1 + * principals/users/joe + * principals/uid/123457 + * + * If you don't use WebDAV ACL (RFC3744) we recommend that you simply + * return a string such as: + * + * principals/users/[username] + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return array + */ + function check(RequestInterface $request, ResponseInterface $response) { + + $remoteUser = $request->getRawServerValue('REMOTE_USER'); + if (is_null($remoteUser)) { + $remoteUser = $request->getRawServerValue('REDIRECT_REMOTE_USER'); + } + if (is_null($remoteUser)) { + return [false, 'No REMOTE_USER property was found in the PHP $_SERVER super-global. This likely means your server is not configured correctly']; + } + + return [true, $this->principalPrefix . $remoteUser]; + + } + + /** + * This method is called when a user could not be authenticated, and + * authentication was required for the current request. + * + * This gives you the opportunity to set authentication headers. The 401 + * status code will already be set. + * + * In this case of Basic Auth, this would for example mean that the + * following header needs to be set: + * + * $response->addHeader('WWW-Authenticate', 'Basic realm=SabreDAV'); + * + * Keep in mind that in the case of multiple authentication backends, other + * WWW-Authenticate headers may already have been set, and you'll want to + * append your own WWW-Authenticate header instead of overwriting the + * existing one. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return void + */ + function challenge(RequestInterface $request, ResponseInterface $response) { + + } + +} diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php new file mode 100644 index 000000000..0fb2210f4 --- /dev/null +++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/BackendInterface.php @@ -0,0 +1,70 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; + +/** + * This is the base class for any authentication object. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +interface BackendInterface { + + /** + * When this method is called, the backend must check if authentication was + * successful. + * + * The returned value must be one of the following + * + * [true, "principals/username"] + * [false, "reason for failure"] + * + * If authentication was successful, it's expected that the authentication + * backend returns a so-called principal url. + * + * Examples of a principal url: + * + * principals/admin + * principals/user1 + * principals/users/joe + * principals/uid/123457 + * + * If you don't use WebDAV ACL (RFC3744) we recommend that you simply + * return a string such as: + * + * principals/users/[username] + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return array + */ + function check(RequestInterface $request, ResponseInterface $response); + + /** + * This method is called when a user could not be authenticated, and + * authentication was required for the current request. + * + * This gives you the opportunity to set authentication headers. The 401 + * status code will already be set. + * + * In this case of Basic Auth, this would for example mean that the + * following header needs to be set: + * + * $response->addHeader('WWW-Authenticate', 'Basic realm=SabreDAV'); + * + * Keep in mind that in the case of multiple authentication backends, other + * WWW-Authenticate headers may already have been set, and you'll want to + * append your own WWW-Authenticate header instead of overwriting the + * existing one. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return void + */ + function challenge(RequestInterface $request, ResponseInterface $response); + +} diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php new file mode 100644 index 000000000..7ad8f48b2 --- /dev/null +++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/BasicCallBack.php @@ -0,0 +1,58 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +/** + * Extremely simply HTTP Basic auth backend. + * + * This backend basically works by calling a callback, which receives a + * username and password. + * The callback must return true or false depending on if authentication was + * correct. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class BasicCallBack extends AbstractBasic { + + /** + * Callback + * + * @var callable + */ + protected $callBack; + + /** + * Creates the backend. + * + * A callback must be provided to handle checking the username and + * password. + * + * @param callable $callBack + * @return void + */ + function __construct(callable $callBack) { + + $this->callBack = $callBack; + + } + + /** + * Validates a username and password + * + * This method should return true or false depending on if login + * succeeded. + * + * @param string $username + * @param string $password + * @return bool + */ + protected function validateUserPass($username, $password) { + + $cb = $this->callBack; + return $cb($username, $password); + + } + +} diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php new file mode 100644 index 000000000..6756e68df --- /dev/null +++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/File.php @@ -0,0 +1,77 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +use Sabre\DAV; + +/** + * This is an authentication backend that uses a file to manage passwords. + * + * The backend file must conform to Apache's htdigest format + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class File extends AbstractDigest { + + /** + * List of users + * + * @var array + */ + protected $users = []; + + /** + * Creates the backend object. + * + * If the filename argument is passed in, it will parse out the specified file fist. + * + * @param string|null $filename + */ + 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 + */ + function loadFile($filename) { + + foreach (file($filename, FILE_IGNORE_NEW_LINES) as $line) { + + if (substr_count($line, ":") !== 2) + throw new 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 DAV\Exception('Malformed htdigest file. Invalid md5 hash'); + + $this->users[$realm . ':' . $username] = $A1; + + } + + } + + /** + * Returns a users' information + * + * @param string $realm + * @param string $username + * @return string + */ + function getDigestHash($realm, $username) { + + return isset($this->users[$realm . ':' . $username]) ? $this->users[$realm . ':' . $username] : false; + + } + +} diff --git a/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php b/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php new file mode 100644 index 000000000..76ad89391 --- /dev/null +++ b/vendor/sabre/dav/lib/DAV/Auth/Backend/PDO.php @@ -0,0 +1,57 @@ +<?php + +namespace Sabre\DAV\Auth\Backend; + +/** + * This is an authentication backend that uses a database to manage passwords. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class PDO extends AbstractDigest { + + /** + * Reference to PDO connection + * + * @var PDO + */ + protected $pdo; + + /** + * PDO table name we'll be using + * + * @var string + */ + public $tableName = 'users'; + + + /** + * Creates the backend object. + * + * If the filename argument is passed in, it will parse out the specified file fist. + * + * @param PDO $pdo + */ + function __construct(\PDO $pdo) { + + $this->pdo = $pdo; + + } + + /** + * Returns the digest hash for a user. + * + * @param string $realm + * @param string $username + * @return string|null + */ + function getDigestHash($realm, $username) { + + $stmt = $this->pdo->prepare('SELECT digesta1 FROM ' . $this->tableName . ' WHERE username = ?'); + $stmt->execute([$username]); + return $stmt->fetchColumn() ?: null; + + } + +} diff --git a/vendor/sabre/dav/lib/DAV/Auth/Plugin.php b/vendor/sabre/dav/lib/DAV/Auth/Plugin.php new file mode 100644 index 000000000..818d8a4ad --- /dev/null +++ b/vendor/sabre/dav/lib/DAV/Auth/Plugin.php @@ -0,0 +1,213 @@ +<?php + +namespace Sabre\DAV\Auth; + +use Sabre\HTTP\RequestInterface; +use Sabre\HTTP\ResponseInterface; +use Sabre\HTTP\URLUtil; +use Sabre\DAV\Exception\NotAuthenticated; +use Sabre\DAV\Server; +use Sabre\DAV\ServerPlugin; + +/** + * This plugin provides Authentication for a WebDAV server. + * + * It works by providing a Auth\Backend class. Several examples of these + * classes can be found in the Backend directory. + * + * It's possible to provide more than one backend to this plugin. If more than + * one backend was provided, each backend will attempt to authenticate. Only if + * all backends fail, we throw a 401. + * + * @copyright Copyright (C) fruux GmbH (https://fruux.com/) + * @author Evert Pot (http://evertpot.com/) + * @license http://sabre.io/license/ Modified BSD License + */ +class Plugin extends ServerPlugin { + + /** + * authentication backends + */ + protected $backends; + + /** + * The currently logged in principal. Will be `null` if nobody is currently + * logged in. + * + * @var string|null + */ + protected $currentPrincipal; + + /** + * Creates the authentication plugin + * + * @param Backend\BackendInterface $authBackend + */ + function __construct(Backend\BackendInterface $authBackend = null) { + + if (!is_null($authBackend)) { + $this->addBackend($authBackend); + } + + } + + /** + * Adds an authentication backend to the plugin. + * + * @param Backend\BackendInterface $authBackend + * @return void + */ + function addBackend(Backend\BackendInterface $authBackend) { + + $this->backends[] = $authBackend; + + } + + /** + * Initializes the plugin. This function is automatically called by the server + * + * @param Server $server + * @return void + */ + function initialize(Server $server) { + + $server->on('beforeMethod', [$this, 'beforeMethod'], 10); + + } + + /** + * Returns a plugin name. + * + * Using this name other plugins will be able to access other plugins + * using DAV\Server::getPlugin + * + * @return string + */ + function getPluginName() { + + return 'auth'; + + } + + /** + * Returns the currently logged-in principal. + * + * This will return a string such as: + * + * principals/username + * principals/users/username + * + * This method will return null if nobody is logged in. + * + * @return string|null + */ + function getCurrentPrincipal() { + + return $this->currentPrincipal; + + } + + /** + * Returns the current username. + * + * This method is deprecated and is only kept for backwards compatibility + * purposes. Please switch to getCurrentPrincipal(). + * + * @deprecated Will be removed in a future version! + * @return string|null + */ + function getCurrentUser() { + + // We just do a 'basename' on the principal to give back a sane value + // here. + list(, $userName) = URLUtil::splitPath( + $this->getCurrentPrincipal() + ); + + return $userName; + + } + + /** + * This method is called before any HTTP method and forces users to be authenticated + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @return bool + */ + function beforeMethod(RequestInterface $request, ResponseInterface $response) { + + if ($this->currentPrincipal) { + + // We already have authentication information. This means that the + // event has already fired earlier, and is now likely fired for a + // sub-request. + // + // We don't want to authenticate users twice, so we simply don't do + // anything here. See Issue #700 for additional reasoning. + // + // This is not a perfect solution, but will be fixed once the + // "currently authenticated principal" is information that's not + // not associated with the plugin, but rather per-request. + // + // See issue #580 for more information about that. + return; + + } + if (!$this->backends) { + throw new \Sabre\DAV\Exception('No authentication backends were configured on this server.'); + } + $reasons = []; + foreach ($this->backends as $backend) { + + $result = $backend->check( + $request, + $response + ); + + if (!is_array($result) || count($result) !== 2 || !is_bool($result[0]) || !is_string($result[1])) { + throw new \Sabre\DAV\Exception('The authentication backend did not return a correct value from the check() method.'); + } + + if ($result[0]) { + $this->currentPrincipal = $result[1]; + // Exit early + return; + } + $reasons[] = $result[1]; + + } + + // If we got here, it means that no authentication backend was + // successful in authenticating the user. + $this->currentPrincipal = null; + + foreach ($this->backends as $backend) { + $backend->challenge($request, $response); + } + throw new NotAuthenticated(implode(', ', $reasons)); + + } + + /** + * Returns a bunch of meta-data about the plugin. + * + * Providing this information is optional, and is mainly displayed by the + * Browser plugin. + * + * The description key in the returned array may contain html and will not + * be sanitized. + * + * @return array + */ + function getPluginInfo() { + + return [ + 'name' => $this->getPluginName(), + 'description' => 'Generic authentication plugin', + 'link' => 'http://sabre.io/dav/authentication/', + ]; + + } + +} |