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

Commit

Permalink
Massive refactoring to change how plugins are loaded depending on the…
Browse files Browse the repository at this point in the history
… Context. Context should be passed around in all requests, hooks and wrappers.
  • Loading branch information
cdujeu committed Jun 4, 2016
1 parent ea81404 commit c702baf
Show file tree
Hide file tree
Showing 30 changed files with 687 additions and 408 deletions.
4 changes: 3 additions & 1 deletion core/src/core/src/pydio/Core/Controller/Controller.php
Expand Up @@ -26,6 +26,7 @@
use Pydio\Core\Exception\AuthRequiredException;
use Pydio\Core\Exception\PydioException;
use Pydio\Auth\Core\AJXP_Safe;
use Pydio\Core\Model\Context;
use Pydio\Core\Services;
use Pydio\Core\Services\AuthService;
use Pydio\Core\Services\ConfService;
Expand Down Expand Up @@ -69,7 +70,8 @@ class Controller
private static function initXPath($useCache = false)
{
if (!isSet(self::$xPath)) {
$registry = ConfService::getFilteredXMLRegistry(false, false, $useCache);
$ctx = Context::fromGlobalServices();
$registry = PluginsService::getInstance($ctx)->getFilteredXMLRegistry(false, false, $useCache);
self::$xPath = new \DOMXPath($registry);
}
return self::$xPath;
Expand Down
6 changes: 4 additions & 2 deletions core/src/core/src/pydio/Core/Controller/XMLWriter.php
Expand Up @@ -22,6 +22,7 @@

use Pydio\Access\Core\Model\AJXP_Node;
use Pydio\Access\Core\IAjxpWrapperProvider;
use Pydio\Core\Model\RepositoryInterface;
use Pydio\Core\Utils\Utils;
use Pydio\Core\Services;
use Pydio\Core\Services\AuthService;
Expand Down Expand Up @@ -420,15 +421,16 @@ public static function triggerBgJSAction($jsCode, $messageId, $print=true, $dela
* List all bookmmarks as XML
* @static
* @param $allBookmarks
* @param RepositoryInterface $repository
* @param bool $print
* @param string $format legacy|node_list
* @return string
*/
public static function writeBookmarks($allBookmarks, $print = true, $format = "legacy")
public static function writeBookmarks($allBookmarks, $repository, $print = true, $format = "legacy")
{
$driver = false;
if ($format == "node_list") {
$driver = ConfService::loadRepositoryDriver();
$driver = $repository->getDriverInstance();
if (!($driver instanceof IAjxpWrapperProvider)) {
$driver = false;
}
Expand Down
49 changes: 49 additions & 0 deletions core/src/core/src/pydio/Core/Exception/RepositoryLoadException.php
@@ -0,0 +1,49 @@
<?php
/*
* Copyright 2007-2016 Abstrium <contact (at) pydio.com>
* This file is part of Pydio.
*
* Pydio is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Pydio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Pydio. If not, see <http://www.gnu.org/licenses/>.
*
* The latest code can be found at <https://pydio.com/>.
*/
namespace Pydio\Core\Exception;

use Pydio\Core\Model\RepositoryInterface;

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


class RepositoryLoadException extends PydioException
{
/**
* @var RepositoryInterface
*/
private $repository;
/**
* RepositoryLoadException constructor.
* @param RepositoryInterface $repository
* @param array $errors
*/
public function __construct($repository, $errors)
{
$message = "Error while loading workspace ".$repository->getDisplay()." : ".implode("\n-", $errors);
$this->repository = $repository;
parent::__construct($message, null, 5000);
}

public function getRepository(){
return $this->repository;
}
}
18 changes: 16 additions & 2 deletions core/src/core/src/pydio/Core/Http/Cli/AuthCliMiddleware.php
Expand Up @@ -23,8 +23,11 @@
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Pydio\Auth\Core\AJXP_Safe;
use Pydio\Core\Controller\Controller;
use Pydio\Core\Exception\AuthRequiredException;
use Pydio\Core\Http\Server;
use Pydio\Core\Model\Context;
use Pydio\Core\PluginFramework\PluginsService;
use Pydio\Core\Services\AuthService;
use Pydio\Core\Services\ConfService;
use Zend\Diactoros\Response;
Expand All @@ -43,6 +46,8 @@ class AuthCliMiddleware
*/
public static function handleRequest(ServerRequestInterface $requestInterface, ResponseInterface $responseInterface, callable $next = null){

$driverImpl = ConfService::getAuthDriverImpl();
PluginsService::getInstance()->setPluginUniqueActiveForType("auth", $driverImpl->getName(), $driverImpl);

$options = $requestInterface->getAttribute("cli-options");
$optUser = $options["u"];
Expand Down Expand Up @@ -156,8 +161,12 @@ public static function handleRequest(ServerRequestInterface $requestInterface, R
$loggedUser = AuthService::getLoggedUser();
if($loggedUser == null) continue;
ConfService::switchRootDir($optRepoId, true);
ConfService::reloadServicesAndActivePlugins();
Controller::registryReset();
$subResponse = new Response();
$ctx = new Context();
$ctx->setUserObject($loggedUser);
$ctx->setRepositoryId($optRepoId);
$requestInterface = $requestInterface->withAttribute("ctx", $ctx);

$subResponse = Server::callNextMiddleWareAndRewind(function($middleware){
return (is_array($middleware) && $middleware["0"] == "Pydio\\Core\\Http\\Cli\\AuthCliMiddleware" && $middleware[1] == "handleRequest");
Expand All @@ -179,7 +188,12 @@ public static function handleRequest(ServerRequestInterface $requestInterface, R
}else{

ConfService::switchRootDir($optRepoId, true);
ConfService::reloadServicesAndActivePlugins();

$ctx = new Context();
$ctx->setUserObject($loggedUser);
$ctx->setRepositoryId($optRepoId);
$requestInterface = $requestInterface->withAttribute("ctx", $ctx);

return Server::callNextMiddleWare($requestInterface, $responseInterface, $next);

}
Expand Down
32 changes: 23 additions & 9 deletions core/src/core/src/pydio/Core/Http/Middleware/AuthMiddleware.php
Expand Up @@ -26,7 +26,10 @@
use Pydio\Core\Exception\AuthRequiredException;
use Pydio\Core\Exception\NoActiveWorkspaceException;
use Pydio\Core\Exception\PydioException;
use Pydio\Core\Exception\RepositoryLoadException;
use Pydio\Core\Http\Server;
use Pydio\Core\Model\Context;
use Pydio\Core\PluginFramework\PluginsService;
use Pydio\Core\Services\AuthService;
use Pydio\Core\Services\ConfService;
use Zend\Diactoros\Response\EmptyResponse;
Expand All @@ -46,27 +49,33 @@ class AuthMiddleware
*/
public static function handleRequest(\Psr\Http\Message\ServerRequestInterface &$requestInterface, \Psr\Http\Message\ResponseInterface &$responseInterface, callable $next = null){

$response = FrontendsLoader::frontendsAsAuthMiddlewares($requestInterface, $responseInterface);
if($response != null){
return $response;
}

self::bootSessionServer($requestInterface);

try{
$driverImpl = ConfService::getAuthDriverImpl();
PluginsService::getInstance()->setPluginUniqueActiveForType("auth", $driverImpl->getName(), $driverImpl);

ConfService::reloadServicesAndActivePlugins();
$response = FrontendsLoader::frontendsAsAuthMiddlewares($requestInterface, $responseInterface);
if($response != null){
return $response;
}
self::bootSessionServer($requestInterface);

}catch (NoActiveWorkspaceException $ex){
} catch (NoActiveWorkspaceException $ex){

$logged = AuthService::getLoggedUser();
if($logged !== null) $lock = $logged->getLock();
if(empty($lock)){
throw new AuthRequiredException();
}

} catch (RepositoryLoadException $r){

ConfService::switchBackAfterRepositoryError($r->getRepository());
throw $r;

}

$requestInterface = $requestInterface->withAttribute("ctx", Context::fromGlobalServices());
try{

return Server::callNextMiddleWare($requestInterface, $responseInterface, $next);
Expand All @@ -78,6 +87,11 @@ public static function handleRequest(\Psr\Http\Message\ServerRequestInterface &$
}else{
return new EmptyResponse();
}
} catch (RepositoryLoadException $r){

ConfService::switchBackAfterRepositoryError($r->getRepository());
throw $r;

}

}
Expand All @@ -99,7 +113,7 @@ protected static function bootSessionServer(ServerRequestInterface $request){
if ($loggedUser != null) {
$res = ConfService::switchUserToActiveRepository($loggedUser, (isSet($parameters["tmp_repository_id"])?$parameters["tmp_repository_id"]:"-1"));
if (!$res) {
AuthService::disconnect();
throw new NoActiveWorkspaceException();
}
}
}
Expand Down
22 changes: 14 additions & 8 deletions core/src/core/src/pydio/Core/Http/Rest/RestAuthMiddleware.php
Expand Up @@ -24,6 +24,8 @@
use Pydio\Authfront\Core\FrontendsLoader;
use Pydio\Core\Exception\PydioException;
use Pydio\Core\Exception\WorkspaceNotFoundException;
use Pydio\Core\Model\Context;
use Pydio\Core\PluginFramework\PluginsService;
use Pydio\Core\Services\AuthService;
use Pydio\Core\Services\ConfService;

Expand All @@ -42,35 +44,39 @@ class RestAuthMiddleware
*/
public static function handleRequest(\Psr\Http\Message\ServerRequestInterface &$requestInterface, \Psr\Http\Message\ResponseInterface &$responseInterface, callable $next = null){

$driverImpl = ConfService::getAuthDriverImpl();
PluginsService::getInstance()->setPluginUniqueActiveForType("auth", $driverImpl->getName(), $driverImpl);

$response = FrontendsLoader::frontendsAsAuthMiddlewares($requestInterface, $responseInterface);
if($response != null){
return $response;
}

if(AuthService::getLoggedUser() == null){
header('HTTP/1.0 401 Unauthorized');
echo 'You are not authorized to access this API.';
exit;
$responseInterface = $responseInterface->withStatus(401);
$responseInterface->getBody()->write('You are not authorized to access this API.');
return $responseInterface;
}

$repoID = $requestInterface->getAttribute("repository_id");
if($repoID == 'pydio'){
ConfService::switchRootDir();
ConfService::getRepository();
$repo = ConfService::getRepository();
}else{
$repo = ConfService::findRepositoryByIdOrAlias($repoID);
if ($repo == null) {
throw new WorkspaceNotFoundException($repoID);
}
if(!ConfService::repositoryIsAccessible($repo->getId(), $repo, AuthService::getLoggedUser(), false, true)){
header('HTTP/1.0 401 Unauthorized');
echo 'You are not authorized to access this workspace.';
exit;
$responseInterface = $responseInterface->withStatus(401);
$responseInterface->getBody()->write('You are not authorized to access this API.');
return $responseInterface;
}
ConfService::switchRootDir($repo->getId());
}

ConfService::reloadServicesAndActivePlugins();
$context = Context::contextWithObjects(AuthService::getLoggedUser(), $repo);
$requestInterface = $requestInterface->withAttribute("ctx", $context);

return RestServer::callNextMiddleWare($requestInterface, $responseInterface, $next);

Expand Down
49 changes: 46 additions & 3 deletions core/src/core/src/pydio/Core/Model/Context.php
Expand Up @@ -20,6 +20,7 @@
*/
namespace Pydio\Core\Model;

use Pydio\Core\Services\AuthService;
use Pydio\Core\Services\ConfService;

defined('AJXP_EXEC') or die('Access not allowed');
Expand Down Expand Up @@ -58,6 +59,28 @@ public function __construct($userId = null, $repositoryId = null)
}
}

/**
* @param $userObject
* @param $repositoryObject
* @return Context
*/
public static function contextWithObjects($userObject, $repositoryObject){
$ctx = new Context();
$ctx->setUserObject($userObject);
$ctx->setRepositoryObject($repositoryObject);
return $ctx;
}

/**
* @return ContextInterface
*/
public static function fromGlobalServices(){
$ctx = new Context();
$ctx->setUserObject(AuthService::getLoggedUser());
$ctx->setRepositoryObject(ConfService::getRepository());
return $ctx;
}

/**
* @return boolean
*/
Expand Down Expand Up @@ -95,7 +118,9 @@ public function setUserId($userId)
public function setUserObject($user)
{
$this->userObject = $user;
$this->userId = $user->getId();
if($user !== null){
$this->userId = $user->getId();
}
}

public function resetUser(){
Expand All @@ -108,7 +133,7 @@ public function resetUser(){
*/
public function hasRepository()
{
return (!empty($this->repositoryId));
return ($this->repositoryId !== null);
}

/**
Expand All @@ -133,13 +158,23 @@ public function setRepositoryId($repositoryId)
$this->repositoryId = $repositoryId;
}

/**
* @return string|null
*/
public function getRepositoryId()
{
return $this->repositoryId;
}

/**
* @param RepositoryInterface $repository
*/
public function setRepositoryObject($repository)
{
$this->repositoryObject = $repository;
$this->repositoryId = $repository->getId();
if($repository !== null){
$this->repositoryId = $repository->getId();
}
}

public function resetRepository()
Expand All @@ -159,4 +194,12 @@ public function getStringIdentifier()
return $u.":".$a;

}

/**
* @return bool
*/
public function isEmpty()
{
return !$this->hasRepository() && !$this->hasUser();
}
}
10 changes: 10 additions & 0 deletions core/src/core/src/pydio/Core/Model/ContextInterface.php
Expand Up @@ -25,6 +25,11 @@

interface ContextInterface
{
/**
* @return bool
*/
public function isEmpty();

/**
* @return boolean
*/
Expand Down Expand Up @@ -62,6 +67,11 @@ public function getRepository();
*/
public function setRepositoryId($repositoryId);

/**
* @return string|null
*/
public function getRepositoryId();

/**
* @param RepositoryInterface $repository
*/
Expand Down

0 comments on commit c702baf

Please sign in to comment.