Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Context propagation
Browse files Browse the repository at this point in the history
Refactor Dav Server (OCS probably broken)
  • Loading branch information
cdujeu committed Jun 7, 2016
1 parent 1e0dc69 commit 3907463
Show file tree
Hide file tree
Showing 305 changed files with 513 additions and 38,196 deletions.
3 changes: 2 additions & 1 deletion core/src/core/composer.json
Expand Up @@ -15,7 +15,8 @@
"commerceguys/guzzle-oauth2-plugin": "~2.0",
"nikic/fast-route":"~1.0",
"symfony/console":"^3.0",
"davegardnerisme/nsqphp": "dev-master"
"davegardnerisme/nsqphp": "dev-master",
"sabre/dav":"1.8.10"
}

}
Expand Up @@ -18,19 +18,26 @@
*
* The latest code can be found at <http://pyd.io/>.
*/

namespace Pydio\Core\Http\Dav;

use Pydio\Auth\Core\AJXP_Safe;
use Pydio\Core\Model\ContextInterface;
use Pydio\Core\Model\UserInterface;
use Pydio\Core\Services\AuthService;
use Pydio\Conf\Core\AbstractAjxpUser;
use Pydio\Core\Services\ConfService;
use Pydio\Log\Core\AJXP_Logger;
use \Sabre;

defined('AJXP_EXEC') or die( 'Access not allowed');


class AJXP_Sabre_AuthBackendBasic extends Sabre\DAV\Auth\Backend\AbstractBasic
class AuthBackendBasic extends Sabre\DAV\Auth\Backend\AbstractBasic
{
protected $currentUser;
private $repositoryId;
/**
* @var ContextInterface
*/
private $context;

/**
* Utilitary method to detect basic header.
Expand All @@ -45,9 +52,9 @@ public static function detectBasicHeader()
return (strpos(strtolower($value),'basic') ===0) ;
}

public function __construct($repositoryId)
public function __construct(ContextInterface $ctx)
{
$this->repositoryId = $repositoryId;
$this->context = $ctx;
}


Expand Down Expand Up @@ -105,10 +112,16 @@ public function authenticate(Sabre\DAV\Server $server, $realm)
if (ConfService::getCoreConf("SESSION_SET_CREDENTIALS", "auth")) {
AJXP_Safe::storeCredentials($this->currentUser, $userpass[1]);
}
if(isSet($this->repositoryId) && ConfService::getRepositoryById($this->repositoryId)->getOption("AJXP_WEBDAV_DISABLED") === true){
$repoId = $this->context->getRepositoryId();
if(isSet($repoId) && ConfService::getRepositoryById($repoId)->getOption("AJXP_WEBDAV_DISABLED") === true){
throw new Sabre\DAV\Exception\NotAuthenticated('You are not allowed to access this workspace');
}
ConfService::switchRootDir($this->repositoryId);
ConfService::switchRootDir($repoId);

// NOW UPDATE CONTEXT
$this->context->setUserId($this->currentUser);
$this->context->setRepositoryId(ConfService::getCurrentRepositoryId());

// the method used here will invalidate the cached password every minute on the minute
if (!$cachedPasswordValid) {
$webdavData["TMP_PASS"] = $encryptedPass;
Expand All @@ -122,17 +135,19 @@ public function authenticate(Sabre\DAV\Server $server, $realm)


/**
* @param AbstractAjxpUser $user
* @param UserInterface $user
* @return bool
* @throws Sabre\DAV\Exception\NotAuthenticated
*/
protected function updateCurrentUserRights($user)
{
if ($this->repositoryId == null) {
if (!$this->context->hasRepository()) {
return true;
}
if (!$user->canSwitchTo($this->repositoryId)) {
if (!$user->canSwitchTo($this->context->getRepositoryId())) {
throw new Sabre\DAV\Exception\NotAuthenticated();
}
return true;
}


Expand Down
Expand Up @@ -18,7 +18,11 @@
*
* The latest code can be found at <http://pyd.io/>.
*/
namespace Pydio\Core\Http\Dav;

use \Sabre;
use Pydio\Auth\Core\AJXP_Safe;
use Pydio\Core\Model\ContextInterface;
use Pydio\Core\Services\AuthService;
use Pydio\Core\Services\ConfService;
use Pydio\Log\Core\AJXP_Logger;
Expand All @@ -29,15 +33,18 @@
* @package Pydio
* @subpackage SabreDav
*/
class AJXP_Sabre_AuthBackendDigest extends Sabre\DAV\Auth\Backend\AbstractDigest
class AuthBackendDigest extends Sabre\DAV\Auth\Backend\AbstractDigest
{
protected $currentUser;
private $secretKey;
private $repositoryId;
/**
* @var ContextInterface
*/
private $context;

public function __construct($repositoryId)
public function __construct($context)
{
$this->repositoryId = $repositoryId;
$this->context = $context;
if (defined('AJXP_SAFE_SECRET_KEY')) {
$this->secretKey = AJXP_SAFE_SECRET_KEY;
} else {
Expand Down Expand Up @@ -68,16 +75,18 @@ public function getDigestHash($realm, $username)
public function authenticate(Sabre\DAV\Server $server, $realm)
{
//AJXP_Logger::debug("Try authentication on $realm", $server);

$errmsg = "";
try {

$success = parent::authenticate($server, $realm);
}
catch(Exception $e) {

} catch(\Exception $e) {
$success = 0;
$errmsg = $e->getMessage();
if ($errmsg != "No digest authentication headers were found")
$success = false;
}

if ($success) {
$res = AuthService::logUser($this->currentUser, null, true);
if ($res < 1) {
Expand All @@ -88,17 +97,26 @@ public function authenticate(Sabre\DAV\Server $server, $realm)
$webdavData = AuthService::getLoggedUser()->getPref("AJXP_WEBDAV_DATA");
AJXP_Safe::storeCredentials($this->currentUser, $this->_decodePassword($webdavData["PASS"], $this->currentUser));
}
}
else {
} else {
if ($success === false) {
AJXP_Logger::warning(__CLASS__, "Login failed", array("user" => $this->currentUser, "error" => "Invalid WebDAV user or password"));
}
throw new Sabre\DAV\Exception\NotAuthenticated($errmsg);
}
ConfService::switchRootDir($this->repositoryId);

// NOW UPDATE CONTEXT
$this->context->setUserId($this->currentUser);
$this->context->setRepositoryId(ConfService::getCurrentRepositoryId());

return true;
}

/**
* @param \Pydio\Core\Model\UserInterface $user
* @return bool
* @throws \Sabre\DAV\Exception\NotAuthenticated
*/
protected function updateCurrentUserRights($user)
{
if ($this->repositoryId == null) {
Expand All @@ -107,6 +125,7 @@ protected function updateCurrentUserRights($user)
if (!$user->canSwitchTo($this->repositoryId)) {
throw new Sabre\DAV\Exception\NotAuthenticated();
}
return true;
}

private function _decodePassword($encoded, $user)
Expand Down
Expand Up @@ -18,6 +18,9 @@
*
* The latest code can be found at <http://pyd.io/>.
*/
namespace Pydio\Core\Http\Dav;

use \Sabre;
use Pydio\Core\Services\ConfService;

defined('AJXP_EXEC') or die( 'Access not allowed');
Expand All @@ -26,7 +29,7 @@
* @package Pydio
* @subpackage SabreDav
*/
class AJXP_Sabre_BrowserPlugin extends Sabre\DAV\Browser\Plugin
class BrowserPlugin extends Sabre\DAV\Browser\Plugin
{

protected $repositoryLabel;
Expand Down
Expand Up @@ -18,6 +18,9 @@
*
* The latest code can be found at <http://pyd.io/>.
*/
namespace Pydio\Core\Http\Dav;

use \Sabre;
use Pydio\Access\Core\Model\AJXP_Node;
use Pydio\Core\Controller\Controller;
use Pydio\Log\Core\AJXP_Logger;
Expand All @@ -28,7 +31,7 @@
* @package Pydio
* @subpackage SabreDav
*/
class AJXP_Sabre_Collection extends AJXP_Sabre_Node implements Sabre\DAV\ICollection
class Collection extends Node implements Sabre\DAV\ICollection
{

protected $children;
Expand Down Expand Up @@ -64,16 +67,22 @@ public function createFile($name, $data = null)
AJXP_Logger::debug("CREATE FILE $name");

$request = new \Zend\Diactoros\ServerRequest();
$request = $request->withParsedBody([
"dir" => $this->path,
"filename" => $name
])->withAttribute("action", "mkfile")->withAttribute("api", "session");
$request = $request
->withParsedBody([
"dir" => $this->path,
"filename" => $name
])
->withAttribute("action", "mkfile")
->withAttribute("api", "session")
->withAttribute("ctx", $this->context)
;
Controller::run($request);

if ( $data != null && is_file($this->getUrl()."/".$name)) {

$p = $this->path."/".$name;
$this->getAccessDriver()->nodeWillChange($p, intval($_SERVER["CONTENT_LENGTH"]));
$newNode = new AJXP_Node($this->getUrl().$p);
Controller::applyHook("node.before_change", array($newNode, $_SERVER["CONTENT_LENGTH"]));
//AJXP_Logger::debug("Should now copy stream or string in ".$this->getUrl()."/".$name);
if (is_resource($data)) {
$stream = fopen($this->getUrl()."/".$name, "w");
Expand All @@ -84,16 +93,16 @@ public function createFile($name, $data = null)
}

$toto = null;
$this->getAccessDriver()->nodeChanged($toto, $p);
Controller::applyHook("node.change", array(null, $newNode, false));

}
$node = new AJXP_Sabre_NodeLeaf($this->path."/".$name, $this->repository, $this->getAccessDriver());
$node = new NodeLeaf($this->path."/".$name, $this->context);
if (isSet($this->children)) {
$this->children = null;
}
return $node->getETag();

} catch (Exception $e) {
} catch (\Exception $e) {
AJXP_Logger::debug("Error ".$e->getMessage(), $e->getTraceAsString());
return null;
}
Expand All @@ -113,10 +122,15 @@ public function createDirectory($name)
$this->children = null;
}
$request = new \Zend\Diactoros\ServerRequest();
$request = $request->withParsedBody([
"dir" => $this->path,
"dirname" => $name
])->withAttribute("action", "mkdir")->withAttribute("api", "session");
$request = $request
->withParsedBody([
"dir" => $this->path,
"dirname" => $name
])
->withAttribute("action", "mkdir")
->withAttribute("api", "session")
->withAttribute("ctx", $this->context)
;
Controller::run($request);

}
Expand Down Expand Up @@ -162,15 +176,15 @@ public function getChildren()
}
// This function will perform the is_dir() call and update $isLeaf variable.
$isLeaf = "";
if (!$this->getAccessDriver()->filterNodeName($this->getUrl(), $file, $isLeaf, array("d"=>true, "f"=>true, "z"=>true))){
if (!$this->getAccessDriver()->filterNodeName($this->context, $this->getUrl(), $file, $isLeaf, array("d"=>true, "f"=>true, "z"=>true))){
continue;
}
if ( !$isLeaf ) {
// Add collection without any children
$contents[] = new AJXP_Sabre_Collection($this->path."/".$file, $this->repository, $this->getAccessDriver());
$contents[] = new Collection($this->path."/".$file, $this->context);
} else {
// Add files without content
$contents[] = new AJXP_Sabre_NodeLeaf($this->path."/".$file, $this->repository, $this->getAccessDriver());
$contents[] = new NodeLeaf($this->path."/".$file, $this->context);
}
}
$this->children = $contents;
Expand Down

0 comments on commit 3907463

Please sign in to comment.