Permalink
Browse files

Fix to the WOPI server and HTTPS for the uploader

  • Loading branch information...
1 parent 00c1338 commit 4cbb836fe5d56c292c323294e45968484351a3dc @ghecquet ghecquet committed Sep 21, 2016
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: ghecquet
+ * Date: 21/09/16
+ * Time: 14:01
+ */
+
+namespace Pydio\Core\Exception;
+
+
+class RouteNotFoundException extends PydioException
+{
+ public function __construct()
+ {
+ parent::__construct("Could not find route", null);
+
+ $this->code = 404;
+ }
+}
@@ -41,7 +41,7 @@ public static function handleRoute($base, $route, $additionalAttributes = []){
if ($route === "/api") {
$server = new Rest\RestApiServer($base.$route, $additionalAttributes);
} else if ($route == "/wopi") {
- $server = new Wopi\RestWopiServer($base.$route, $additionalAttributes);
+ $server = new Wopi\Server($base.$route, $additionalAttributes);
} else if ($route === "/user") {
$_GET["get_action"] = "user_access_point";
$_GET["key"] = $additionalAttributes["key"];
@@ -69,6 +69,7 @@ public function handleRequest(ServerRequestInterface $request, ResponseInterface
if(headers_sent()){
return;
}
+
$this->emitResponse($request, $response);
}
@@ -239,7 +239,9 @@ public function catchError($code, $message, $fichier, $ligne, $context)
$req = $this->getRequest();
$resp = new Response();
$x = new SerializableResponseStream();
- $resp = $resp->withBody($x);
+ $resp = $resp
+ ->withStatus($code)
+ ->withBody($x);
$x->addChunk(new UserMessage($message, LOG_LEVEL_ERROR));
$this->topMiddleware->emitResponse($req, $resp);
@@ -0,0 +1,111 @@
+<?php
+/*
+ * Copyright 2007-2013 Charles du Jeu - Abstrium SAS <team (at) pyd.io>
+ * 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 JWT;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Pydio\Core\Services\ApiKeysService;
+use Pydio\Core\Services\AuthService;
+use Pydio\Auth\Frontend\Core\AbstractAuthFrontend;
+use Pydio\Conf\Sql\SqlConfDriver;
+
+defined('AJXP_EXEC') or die('Access not allowed');
+
+
+/**
+ * Class Pydio\Core\Http\Wopi\WopiJWTAuthFrontend;
+ */
+class AuthFrontend extends AbstractAuthFrontend
+{
+ const NOT_FOUND = "";
+
+ /**
+ * @var SqlConfDriver $storage
+ */
+ var $storage;
+
+ /**
+ * @param $httpVars
+ * @param $varName
+ * @return string
+ */
+ function detectVar(&$httpVars, $varName)
+ {
+ if (isSet($httpVars[$varName])) return $httpVars[$varName];
+ if (isSet($_SERVER["HTTP_PYDIO_" . strtoupper($varName)])) return $_SERVER["HTTP_" . strtoupper($varName)];
+ return "";
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ * @param ResponseInterface $response
+ * @param bool $isLast
+ * @return bool
+ */
+ function tryToLogUser(ServerRequestInterface &$request, ResponseInterface &$response, $isLast = false) {
+ // This plugin is depending on other authfront having found the current user
+ $currentUser = AuthService::getLoggedUser();
+ if (!isset($currentUser)) {
+ return false;
+ }
+
+ $httpVars = $request->getParsedBody();
+ $jwt = $this->detectVar($httpVars, "access_token");
+ if (empty($jwt)) {
+ return false;
+ }
+
+ // We have an access token - decode
+ $payload = JWT::decode($jwt);
+
+ if (!isset($payload->token) || !isset($payload->task)) {
+ return false;
+ }
+
+ // We have a token - retrieve private signature
+ $token = $payload->token;
+ $task = $payload->task;
+
+ $key = ApiKeysService::findPairForAdminTask($task, $currentUser->getId());
+ $signature = self::NOT_FOUND;
+
+ if ($key["t"] !== $token) {
+ return false;
+ }
+
+ $signature = $key["p"];
+
+ if ($signature == self::NOT_FOUND) {
+ return false;
+ }
+
+ // We have a signature - verify the payload
+ try {
+ JWT::decode($jwt, $signature, ['HS256']);
+ } catch (\Exception $e) {
+ return false;
+ }
+
+ // We're through
+ return true;
+ }
+}
@@ -45,7 +45,7 @@
* Authentication middleware used in Rest context
* @package Pydio\Core\Http\Rest
*/
-class RestWopiAuthMiddleware
+class AuthMiddleware
{
/**
@@ -64,6 +64,14 @@ public static function handleRequest(ServerRequestInterface $requestInterface, R
if($response != null){
return $response;
}
+
+ $response = (new AuthFrontend("jwt-auth-frontend", ""))->tryToLogUser($requestInterface, $responseInterface);
+ if(!$response != null) {
+ $responseInterface = $responseInterface->withStatus(401);
+ $responseInterface->getBody()->write('You are not authorized to access this API.');
+ return $responseInterface;
+ }
+
/** @var ContextInterface $ctx */
$ctx = $requestInterface->getAttribute("ctx");
@@ -24,22 +24,45 @@
use \Psr\Http\Message\ResponseInterface;
use Pydio\Access\Core\Model\AJXP_Node;
use Pydio\Access\Core\Model\NodesList;
-
+use Pydio\Core\Exception\PydioException;
+use Pydio\Core\Exception\RouteNotFoundException;
use Pydio\Core\Http\Message\Message;
use Pydio\Core\Http\Middleware\SapiMiddleware;
use Pydio\Core\Http\Response\SerializableResponseStream;
-use Zend\Diactoros\Response\EmptyResponse;
use Zend\Diactoros\Response\SapiEmitter;
defined('AJXP_EXEC') or die('Access not allowed');
/**
- * Class WopiMiddleware
- * Main Middleware for Wopi requests
- * @package Pydio\Core\Http\Middleware
+ * Class RestWopiMiddleware
+ * Specific middleware to handle Wopi actions
+ * @package Pydio\Core\Http\Wopi
*/
-class WopiMiddleware extends SapiMiddleware
+class Middleware extends SapiMiddleware
{
+ protected $base;
+
+ /**
+ * RestWopiMiddleware constructor.
+ * @param $base
+ */
+ public function __construct($base)
+ {
+ $this->base = $base;
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ * @param ResponseInterface $response
+ * @throws PydioException
+ */
+ protected function parseRequestRouteAndParams(ServerRequestInterface &$request, ResponseInterface &$response){
+
+ $router = new Router($this->base);
+ if(!$router->route($request, $response)) {
+ throw new RouteNotFoundException();
+ }
+ }
/**
* Output the response to the browser, if no headers were already sent.
@@ -50,32 +73,39 @@ class WopiMiddleware extends SapiMiddleware
public function emitResponse(ServerRequestInterface $request, ResponseInterface $response) {
if($response !== false && $response->getBody() && $response->getBody() instanceof SerializableResponseStream){
+
/**
* @var SerializableResponseStream $body;
*/
+ $status = &$response->getStatusCode();
- $body = &$response->getBody();
+ // Modifying the results
+ if ($status == 200) {
+ $body = &$response->getBody();
+
+ /** @var NodesList $originalData */
+ $originalData = $body->getChunks()[0];
+
+ /** @var AJXP_Node $node */
+ $node = $originalData->getChildren()[0];
+
+ // We modify the result to have the correct format required by the api
+ $x = new SerializableResponseStream();
+ $meta = $node->getNodeInfoMeta();
+ $userId = $node->getUser()->getId();
+ $data = [
+ "BaseFileName" => $node->getLabel(),
+ "OwnerId" => $userId,
+ "Size" => $meta["bytesize"],
+ "UserId" => $userId,
+ "Version" => "" . $meta["ajxp_modiftime"]
+ ];
+
+ $x->addChunk(new Message($data));
+ $response = $response->withBody($x);
+
+ }
- /** @var NodesList $originalData */
- $originalData = $body->getChunks()[0];
-
- /** @var AJXP_Node $node */
- $node = $originalData->getChildren()[0];
-
- // We modify the result to have the correct format required by the api
- $x = new SerializableResponseStream();
- $meta = $node->getNodeInfoMeta();
- $userId = $node->getUser()->getId();
- $data = [
- "BaseFileName" => $node->getLabel(),
- "OwnerId" => $userId,
- "Size" => $meta["bytesize"],
- "UserId" => $userId,
- "Version" => "" . $meta["ajxp_modiftime"]
- ];
-
- $x->addChunk(new Message($data));
- $response = $response->withBody($x);
$body = &$response->getBody();
$params = $request->getParsedBody();
@@ -91,9 +121,7 @@ public function emitResponse(ServerRequestInterface $request, ResponseInterface
} else {
$body->setSerializer(SerializableResponseStream::SERIALIZER_TYPE_JSON);
$response = $response->withHeader("Content-type", "application/json; charset=UTF-8");
-
}
-
}
if($response !== false && ($response->getBody()->getSize() || $response instanceof EmptyResponse) || $response->getStatusCode() != 200) {
@@ -1,60 +0,0 @@
-<?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 <https://pydio.com>.
- */
-namespace Pydio\Core\Http\Wopi;
-
-use \Psr\Http\Message\ServerRequestInterface;
-use \Psr\Http\Message\ResponseInterface;
-use Pydio\Core\Exception\PydioException;
-
-defined('AJXP_EXEC') or die('Access not allowed');
-
-/**
- * Class RestWopiMiddleware
- * Specific middleware to handle Wopi actions
- * @package Pydio\Core\Http\Wopi
- */
-class RestWopiMiddleware extends WopiMiddleware
-{
- protected $base;
-
- /**
- * RestWopiMiddleware constructor.
- * @param $base
- */
- public function __construct($base)
- {
- $this->base = $base;
- }
-
- /**
- * @param ServerRequestInterface $request
- * @param ResponseInterface $response
- * @throws PydioException
- */
- 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");
- }
- }
-
-}
@@ -32,7 +32,7 @@
* Simple router for /wopi/ endpoints
* @package Pydio\Core\Http\Wopi
*/
-class WopiRouter
+class Router
{
/**
* @var array
@@ -116,7 +116,7 @@ public function route(ServerRequestInterface &$request, ResponseInterface &$resp
switch ($routeInfo[0]) {
case Dispatcher::NOT_FOUND:
- //$response = $response->withStatus(404);
+ $response = $response->withStatus(404);
break;
case Dispatcher::METHOD_NOT_ALLOWED:
//$allowedMethods = $routeInfo[1];
Oops, something went wrong.

0 comments on commit 4cbb836

Please sign in to comment.