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

Commit

Permalink
Adding WOPI Route Handler
Browse files Browse the repository at this point in the history
  • Loading branch information
ghecquet committed Aug 22, 2016
1 parent 91faaa3 commit 2951072
Show file tree
Hide file tree
Showing 11 changed files with 546 additions and 22 deletions.
21 changes: 8 additions & 13 deletions core/src/core/src/pydio/Core/Http/Base.php
Expand Up @@ -34,25 +34,20 @@ class Base
*/ */
public static function handleRoute($base, $route){ public static function handleRoute($base, $route){


if($route === "/api") { if ($route === "/api") {

$server = new Rest\RestApiServer($base.$route);
$server = new Rest\RestServer($base.$route); } else if ($route == "/wopi") {

$server = new Wopi\RestWopiServer($base.$route);
}else if($route === "/user") { } else if ($route === "/user") {

$_GET["get_action"] = "user_access_point"; $_GET["get_action"] = "user_access_point";
$server = new Server($base); $server = new Server($base);

} else if ($route == "/favicon"){
}else if($route == "/favicon"){

$_GET["get_action"] = "serve_favicon"; $_GET["get_action"] = "serve_favicon";
$server = new Server($base); $server = new Server($base);

} else {
}else{

$server = new Server($base); $server = new Server($base);

} }

$server->registerCatchAll(); $server->registerCatchAll();


ConfService::init(); ConfService::init();
Expand Down
53 changes: 53 additions & 0 deletions core/src/core/src/pydio/Core/Http/Message/Message.php
@@ -0,0 +1,53 @@
<?php
/*
* Copyright 2007-2015 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 <http://pyd.io/>.
*/
namespace Pydio\Core\Http\Message;

use Pydio\Core\Controller\XMLWriter;
use Pydio\Core\Http\Response\JSONSerializableResponseChunk;
use Pydio\Core\Http\Response\XMLSerializableResponseChunk;

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

class Message implements XMLSerializableResponseChunk, JSONSerializableResponseChunk
{

private $message;

public function __construct($message)
{
$this->message = $message;
}

public function toXML()
{
return XMLWriter::sendMessage($this->message, $this->message);
}

public function jsonSerializableData()
{
return $this->message;
}

public function jsonSerializableKey()
{
return 'message';
}
}
3 changes: 2 additions & 1 deletion core/src/core/src/pydio/Core/Http/Rest/RestApiMiddleware.php
Expand Up @@ -23,11 +23,12 @@
use \Psr\Http\Message\ServerRequestInterface; use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Message\ResponseInterface; use \Psr\Http\Message\ResponseInterface;
use Pydio\Core\Exception\PydioException; use Pydio\Core\Exception\PydioException;
use Pydio\Core\Http\Middleware\SapiMiddleware;


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




class RestApiMiddleware extends \Pydio\Core\Http\Middleware\SapiMiddleware class RestApiMiddleware extends SapiMiddleware
{ {
protected $base; protected $base;


Expand Down
Expand Up @@ -21,12 +21,13 @@


namespace Pydio\Core\Http\Rest; namespace Pydio\Core\Http\Rest;


use Pydio\Core\Http\Server;
use Pydio\Core\Services\ConfService; use Pydio\Core\Services\ConfService;


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




class RestServer extends \Pydio\Core\Http\Server class RestApiServer extends Server
{ {


public function __construct($base) public function __construct($base)
Expand Down
6 changes: 4 additions & 2 deletions core/src/core/src/pydio/Core/Http/Rest/RestAuthMiddleware.php
Expand Up @@ -20,12 +20,14 @@
*/ */
namespace Pydio\Core\Http\Rest; namespace Pydio\Core\Http\Rest;


use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Pydio\Auth\Frontend\Core\FrontendsLoader; use Pydio\Auth\Frontend\Core\FrontendsLoader;
use Pydio\Core\Exception\NoActiveWorkspaceException; use Pydio\Core\Exception\NoActiveWorkspaceException;
use Pydio\Core\Exception\PydioException; use Pydio\Core\Exception\PydioException;
use Pydio\Core\Exception\WorkspaceForbiddenException; use Pydio\Core\Exception\WorkspaceForbiddenException;


use Pydio\Core\Http\Server;
use Pydio\Core\Model\Context; use Pydio\Core\Model\Context;
use Pydio\Core\Model\ContextInterface; use Pydio\Core\Model\ContextInterface;
use Pydio\Core\PluginFramework\PluginsService; use Pydio\Core\PluginFramework\PluginsService;
Expand Down Expand Up @@ -53,7 +55,7 @@ class RestAuthMiddleware
* @param callable|null $next * @param callable|null $next
* @throws PydioException * @throws PydioException
*/ */
public static function handleRequest(\Psr\Http\Message\ServerRequestInterface &$requestInterface, \Psr\Http\Message\ResponseInterface &$responseInterface, callable $next = null){ public static function handleRequest(ServerRequestInterface &$requestInterface, ResponseInterface &$responseInterface, callable $next = null){


$driverImpl = ConfService::getAuthDriverImpl(); $driverImpl = ConfService::getAuthDriverImpl();
PluginsService::getInstance(Context::emptyContext())->setPluginUniqueActiveForType("auth", $driverImpl->getName(), $driverImpl); PluginsService::getInstance(Context::emptyContext())->setPluginUniqueActiveForType("auth", $driverImpl->getName(), $driverImpl);
Expand Down Expand Up @@ -97,7 +99,7 @@ public static function handleRequest(\Psr\Http\Message\ServerRequestInterface &$
RolesService::bootSequence(); RolesService::bootSequence();
} }


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


} }


Expand Down
11 changes: 6 additions & 5 deletions core/src/core/src/pydio/Core/Http/TopLevelRouter.php
Expand Up @@ -20,7 +20,8 @@
*/ */
namespace Pydio\Core\Http; namespace Pydio\Core\Http;


use Psr\Http\Message\ResponseInterface; use FastRoute\Dispatcher;
use FastRoute\RouteCollector;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Pydio\Core\Exception\PydioException; use Pydio\Core\Exception\PydioException;


Expand Down Expand Up @@ -61,7 +62,7 @@ public function __construct($cacheOptions = []){
* @param string $base Base URI (empty string if "/"). * @param string $base Base URI (empty string if "/").
* @param \FastRoute\RouteCollector $r * @param \FastRoute\RouteCollector $r
*/ */
public function configureRoutes($base, \FastRoute\RouteCollector &$r){ public function configureRoutes($base, RouteCollector &$r){


$allMethods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'OPTIONS', 'CONNECT', 'PATCH', 'PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK']; $allMethods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'OPTIONS', 'CONNECT', 'PATCH', 'PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK'];
$file = AJXP_DATA_PATH."/".AJXP_PLUGINS_FOLDER."/boot.conf/routes.json"; $file = AJXP_DATA_PATH."/".AJXP_PLUGINS_FOLDER."/boot.conf/routes.json";
Expand Down Expand Up @@ -102,7 +103,7 @@ public function route(){
$request = ServerRequestFactory::fromGlobals(); $request = ServerRequestFactory::fromGlobals();
$this->base = rtrim(dirname($request->getServerParams()["SCRIPT_NAME"]), "/"); $this->base = rtrim(dirname($request->getServerParams()["SCRIPT_NAME"]), "/");


$dispatcher = \FastRoute\cachedDispatcher(function(\FastRoute\RouteCollector $r) { $dispatcher = \FastRoute\cachedDispatcher(function(RouteCollector $r) {
$this->configureRoutes($this->base, $r); $this->configureRoutes($this->base, $r);
}, $this->cacheOptions); }, $this->cacheOptions);


Expand All @@ -111,14 +112,14 @@ public function route(){
$routeInfo = $dispatcher->dispatch($httpMethod, $uri); $routeInfo = $dispatcher->dispatch($httpMethod, $uri);


switch ($routeInfo[0]) { switch ($routeInfo[0]) {
case \FastRoute\Dispatcher::FOUND: case Dispatcher::FOUND:
$data = $routeInfo[1]; $data = $routeInfo[1];
if(isSet($data["path"])){ if(isSet($data["path"])){
require_once (AJXP_INSTALL_PATH."/".$data["path"]); require_once (AJXP_INSTALL_PATH."/".$data["path"]);
} }
call_user_func(array($data["class"], $data["method"]), $this->base, $data["short"], $routeInfo[2]); call_user_func(array($data["class"], $data["method"]), $this->base, $data["short"], $routeInfo[2]);
break; break;
case \FastRoute\Dispatcher::NOT_FOUND: case Dispatcher::NOT_FOUND:
default: default:
throw new PydioException("Oups, could not find any valid route for ".$uri.", method was was ".$httpMethod); throw new PydioException("Oups, could not find any valid route for ".$uri.", method was was ".$httpMethod);
break; break;
Expand Down
107 changes: 107 additions & 0 deletions core/src/core/src/pydio/Core/Http/Wopi/RestWopiAuthMiddleware.php
@@ -0,0 +1,107 @@
<?php
/*
* Copyright 2007-2015 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 <http://pyd.io/>.
*/
namespace Pydio\Core\Http\Wopi;

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Pydio\Auth\Frontend\Core\FrontendsLoader;
use Pydio\Core\Exception\NoActiveWorkspaceException;
use Pydio\Core\Exception\PydioException;
use Pydio\Core\Exception\WorkspaceForbiddenException;

use Pydio\Core\Http\Server;
use Pydio\Core\Model\Context;
use Pydio\Core\Model\ContextInterface;
use Pydio\Core\PluginFramework\PluginsService;
use Pydio\Core\Services\ConfService;

use Pydio\Core\Services\RolesService;
use Pydio\Core\Services\UsersService;
use Pydio\Core\Utils\ApplicationState;
use Pydio\Log\Core\Logger;

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


/**
* Authentication middleware used in Rest context
* @package Pydio\Core\Http\Rest
*/
class RestWopiAuthMiddleware
{

/**
* @param ServerRequestInterface $requestInterface
* @param \Psr\Http\Message\ResponseInterface $responseInterface
* @return \Psr\Http\Message\ResponseInterface
* @param callable|null $next
* @throws PydioException
*/
public static function handleRequest(ServerRequestInterface &$requestInterface, ResponseInterface &$responseInterface, callable $next = null){

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

$response = FrontendsLoader::frontendsAsAuthMiddlewares($requestInterface, $responseInterface);
if($response != null){
return $response;
}
/** @var ContextInterface $ctx */
$ctx = $requestInterface->getAttribute("ctx");

if(!$ctx->hasUser()){
$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'){
$userRepositories = UsersService::getRepositoriesForUser($ctx->getUser());
if(empty($userRepositories)){
throw new NoActiveWorkspaceException();
}
$repo = array_shift($userRepositories);
}else{
try{
$repo = UsersService::getRepositoryWithPermission($ctx->getUser(), $repoID);
}catch (WorkspaceForbiddenException $w){
$responseInterface = $responseInterface->withStatus(401);
$responseInterface->getBody()->write('You are not authorized to access this API.');
return $responseInterface;
}
}

$ctx->setRepositoryObject($repo);
$requestInterface = $requestInterface->withAttribute("ctx", $ctx);

Logger::updateContext($ctx);

if(UsersService::usersEnabled() && ApplicationState::detectApplicationFirstRun()){
RolesService::bootSequence();
}

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

}


}
48 changes: 48 additions & 0 deletions core/src/core/src/pydio/Core/Http/Wopi/RestWopiMiddleware.php
@@ -0,0 +1,48 @@
<?php
/*
* Copyright 2007-2015 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 <http://pyd.io/>.
*/
namespace Pydio\Core\Http\Wopi;

use \Psr\Http\Message\ServerRequestInterface;
use \Psr\Http\Message\ResponseInterface;
use Pydio\Core\Exception\PydioException;
use Pydio\Core\Http\Wopi\WopiMiddleware;

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


class RestWopiMiddleware extends WopiMiddleware
{
protected $base;

public function __construct($base)
{
$this->base = $base;
}

protected function parseRequestRouteAndParams(ServerRequestInterface &$request, ResponseInterface &$response){

$router = new WopiRouter($this->base);
if(!$router->route($request, $response)){
throw new PydioException("Could not find any endpoint for this URI");
}
}

}

0 comments on commit 2951072

Please sign in to comment.