Skip to content

Commit

Permalink
Merge pull request #1493 from siemens/feat/rest/uploadFromVCS
Browse files Browse the repository at this point in the history
feat(rest): Upload packages from VCS
       tested by : piotr.pszczola@orange.com
       reviewed by : anupam.ghosh@siemens.com
  • Loading branch information
ag4ums committed Oct 9, 2019
2 parents d0e90cd + 808fa1d commit d3cacdf
Show file tree
Hide file tree
Showing 8 changed files with 389 additions and 54 deletions.
3 changes: 3 additions & 0 deletions src/www/ui/api/Controllers/ReportController.php
Expand Up @@ -129,6 +129,9 @@ private function getUpload($uploadId)
if (! $uploadDao->isAccessible($uploadId, $this->restHelper->getGroupId())) {
$upload = new Info(403, "Upload is not accessible!", InfoType::ERROR);
}
if ($upload !== null) {
return $upload;
}
$upload = $uploadDao->getUpload($uploadId);
if ($upload === null) {
$upload = new Info(404, "Upload does not exists!", InfoType::ERROR);
Expand Down
22 changes: 16 additions & 6 deletions src/www/ui/api/Controllers/UploadController.php
Expand Up @@ -62,7 +62,17 @@ public function getUploads($request, $response, $args)
$returnVal = new Info(404, "Upload does not exist", InfoType::ERROR);
return $response->withJson($returnVal->getArray(), $returnVal->getCode());
}
$uploads = $uploads[0];
if (! empty($uploads)) {
$uploads = $uploads[0];
} else {
$returnVal = new Info(503,
"Ununpack job not started. Please check job status at " .
"/api/v1/jobs?upload=" . $id,
InfoType::INFO);
return $response->withHeader('Retry-After',
'60')->withHeader('Look-at', "/api/v1/jobs?upload=" .
$id)->withJson($returnVal->getArray(), $returnVal->getCode());
}
}
return $response->withJson($uploads, 200);
}
Expand Down Expand Up @@ -169,13 +179,13 @@ public function postUpload($request, $response, $args)
$description = $request->getHeaderLine('uploadDescription');
$public = $request->getHeaderLine('public');
$public = empty($public) ? 'protected' : $public;
$ignoreScm = $request->getHeaderLine('ignoreScm');
list ($status, $message, $statusDescription, $uploadId) = $uploadHelper->createNewUpload(
$request, $folderId, $description, $public);
$request, $folderId, $description, $public, $ignoreScm);
if (! $status) {
$info = new Info(500, [
$message,
$statusDescription
], InfoType::ERROR);
$info = new Info($uploadId != -1 ? $uploadId : 500,
$message . "\n" . $statusDescription,
InfoType::ERROR);
} else {
$info = new Info(201, intval($uploadId), InfoType::INFO);
}
Expand Down
255 changes: 212 additions & 43 deletions src/www/ui/api/Helper/UploadHelper.php
@@ -1,81 +1,250 @@
<?php
/***************************************************************
Copyright (C) 2018 Siemens AG
Author: Gaurav Mishra <mishra.gaurav@siemens.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
***************************************************************/
/**
* @file
* @brief Helper to handle file uploads
* *************************************************************
* Copyright (C) 2018 Siemens AG
* Author: Gaurav Mishra <mishra.gaurav@siemens.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *************************************************************
*/

/**
* @file
* @brief Helper to handle package uploads
*/
namespace Fossology\UI\Api\Helper;

use Fossology\UI\Page\UploadFilePage;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Http\UploadedFile;
use Fossology\UI\Api\Helper\UploadHelper\HelperToUploadFilePage;
use Fossology\UI\Api\Helper\UploadHelper\HelperToUploadVcsPage;

/**
* @class UploadHelper
* @brief Handle new file uploads from Slim framework and move to FOSSology
*/
class UploadHelper extends UploadFilePage
class UploadHelper
{
/**
* @var HelperToUploadFilePage $uploadFilePage
* Object to handle file based uploads
*/
private $uploadFilePage;

/**
* @var HelperToUploadVcsPage $uploadVcsPage
* Object to handle VCS based uploads
*/
private $uploadVcsPage;

/**
* @var array VALID_VCS_TYPES
* Array of valid inputs for vcsType parameter
*/
const VALID_VCS_TYPES = array(
"git",
"svn"
);

/**
* Constructor to get UploadFilePage and UploadVcsPage objects.
*/
public function __construct()
{
$this->uploadFilePage = new HelperToUploadFilePage();
$this->uploadVcsPage = new HelperToUploadVcsPage();
}

/**
* Get a request from Slim and translate to Symfony request to be
* processed by FOSSology
*
* @param ServerRequestInterface $request
* @param string $folderName
* @param string $fileDescription
* @param string $isPublic
* @return boolean[]|string[]|unknown[]|NULL[]|mixed[]
* @param string $folderName Name of the folder to upload the file
* @param string $fileDescription Description of file uploaded
* @param string $isPublic Upload is `public, private or protected`
* @param boolean $ignoreScm True if the SCM should be ignored.
* @return array Array with status, message and upload id
* @see createVcsUpload()
* @see createFileUpload()
*/
public function createNewUpload(ServerRequestInterface $request, $folderName,
$fileDescription, $isPublic)
$fileDescription, $isPublic, $ignoreScm)
{
$uploadedFile = $request->getUploadedFiles();
if (! isset($uploadedFile[self::FILE_INPUT_NAME])) {
return array(
false,
"Missing file",
"File " . self::FILE_INPUT_NAME . " missing from request",
-1
);
$vcsData = $request->getParsedBody();

if (! empty($ignoreScm) && ($ignoreScm == "true" || $ignoreScm)) {
// If SCM should be ignored
$ignoreScm = 1;
} else {
$ignoreScm = 0;
}

if (empty($uploadedFile) ||
! isset($uploadedFile[$this->uploadFilePage::FILE_INPUT_NAME])) {
if (empty($vcsData)) {
return array(false, "Missing input",
"Send file with parameter " . $this->uploadFilePage::FILE_INPUT_NAME .
" or JSON with VCS parameters.",
- 1
);
}
return $this->createVcsUpload($vcsData, $folderName, $fileDescription,
$isPublic, $ignoreScm);
} else {
$uploadedFile = $uploadedFile[self::FILE_INPUT_NAME];
$uploadedFile = $uploadedFile[$this->uploadFilePage::FILE_INPUT_NAME];
return $this->createFileUpload($uploadedFile, $folderName,
$fileDescription, $isPublic, $ignoreScm);
}
}

/**
* Create request required by UploadFilePage
*
* @param array $uploadedFile Uploaded file object by Slim
* @param string $folderName Name of the folder to upload the file
* @param string $fileDescription Description of file uploaded
* @param string $isPublic Upload is `public, private or protected`
* @param boolean $ignoreScm True if the SCM should be ignored.
* @return array Array with status, message and upload id
*/
private function createFileUpload($uploadedFile, $folderName, $fileDescription,
$isPublic, $ignoreScm = 0)
{
$path = $uploadedFile->file;
$originalName = $uploadedFile->getClientFilename();
$originalMime = $uploadedFile->getClientMediaType();
$originalError = $uploadedFile->getError();
$symfonyFile = new \Symfony\Component\HttpFoundation\File\UploadedFile($path,
$originalName, $originalMime, $originalError);
$symfonyFile = new \Symfony\Component\HttpFoundation\File\UploadedFile(
$path, $originalName, $originalMime, $originalError);
$symfonyRequest = new \Symfony\Component\HttpFoundation\Request();
$symfonySession = $GLOBALS['container']->get('session');
$symfonySession->set(self::UPLOAD_FORM_BUILD_PARAMETER_NAME, "restUpload");
$symfonySession->set(
$this->uploadFilePage::UPLOAD_FORM_BUILD_PARAMETER_NAME, "restUpload");

$symfonyRequest->request->set(self::FOLDER_PARAMETER_NAME, $folderName);
$symfonyRequest->request->set(self::DESCRIPTION_INPUT_NAME, $fileDescription);
$symfonyRequest->files->set(self::FILE_INPUT_NAME, $symfonyFile);
$symfonyRequest->request->set($this->uploadFilePage::FOLDER_PARAMETER_NAME,
$folderName);
$symfonyRequest->request->set($this->uploadFilePage::DESCRIPTION_INPUT_NAME,
$fileDescription);
$symfonyRequest->files->set($this->uploadFilePage::FILE_INPUT_NAME,
$symfonyFile);
$symfonyRequest->setSession($symfonySession);
$symfonyRequest->request->set(self::UPLOAD_FORM_BUILD_PARAMETER_NAME,
$symfonyRequest->request->set(
$this->uploadFilePage::UPLOAD_FORM_BUILD_PARAMETER_NAME, "restUpload");
$symfonyRequest->request->set('public', $isPublic);
$symfonyRequest->request->set('scm', $ignoreScm);

return $this->uploadFilePage->handleRequest($symfonyRequest);
}

/**
* Create request required by UploadVcsPage
*
* @param array $vcsData Parsed VCS object from request
* @param string $folderName Name of the folder to upload the file
* @param string $fileDescription Description of file uploaded
* @param string $isPublic Upload is `public, private or protected`
* @param boolean $ignoreScm True if the SCM should be ignored.
* @return array Array with status, message and upload id
*/
private function createVcsUpload($vcsData, $folderName, $fileDescription,
$isPublic, $ignoreScm = 0)
{
$sanity = $this->sanitizeVcsData($vcsData);
if ($sanity !== true) {
return $sanity;
}
$vcsType = $vcsData["vcsType"];
$vcsUrl = $vcsData["vcsUrl"];
$vcsName = $vcsData["vcsName"];
$vcsUsername = $vcsData["vcsUsername"];
$vcsPasswd = $vcsData["vcsPassword"];

$symfonySession = $GLOBALS['container']->get('session');
$symfonySession->set($this->uploadVcsPage::UPLOAD_FORM_BUILD_PARAMETER_NAME,
"restUpload");

$symfonyRequest = new \Symfony\Component\HttpFoundation\Request();
$symfonyRequest->setSession($symfonySession);

$symfonyRequest->request->set($this->uploadVcsPage::FOLDER_PARAMETER_NAME,
$folderName);
$symfonyRequest->request->set($this->uploadVcsPage::DESCRIPTION_INPUT_NAME,
$fileDescription);
$symfonyRequest->request->set($this->uploadVcsPage::GETURL_PARAM, $vcsUrl);
$symfonyRequest->request->set(
$this->uploadVcsPage::UPLOAD_FORM_BUILD_PARAMETER_NAME, "restUpload");
$symfonyRequest->request->set('public', $isPublic);
$symfonyRequest->request->set('name', $vcsName);
$symfonyRequest->request->set('vcstype', $vcsType);
$symfonyRequest->request->set('username', $vcsUsername);
$symfonyRequest->request->set('passwd', $vcsPasswd);
$symfonyRequest->request->set('scm', $ignoreScm);

return $this->uploadVcsPage->handleRequest($symfonyRequest);
}

/**
* @brief Check if the passed VCS object is correct or not.
*
* 1. Check if all the required parameters are passed by user.
* 2. Translate the `vcsType` to required values.
* 3. Add missing keys with empty data to prevent warnings.
*
* @param array $vcsData Parsed VCS object to be sanitized
* @return array|boolean True if everything is correct, error array otherwise
*/
private function sanitizeVcsData(&$vcsData)
{
$message = "";
$statusDescription = "";
$code = 0;

if (! array_key_exists("vcsType", $vcsData) ||
! in_array($vcsData["vcsType"], self::VALID_VCS_TYPES)) {
$message = "Missing vcsType";
$statusDescription = "vcsType should be any of (" .
implode(", ", self::VALID_VCS_TYPES) . ")";
$code = 400;
}
$vcsType = "";
if ($vcsData["vcsType"] == "git") {
$vcsType = "Git";
} else {
$vcsType = "SVN";
}

return $this->handleUpload($symfonyRequest);
if (! array_key_exists("vcsUrl", $vcsData)) {
$message = "Missing vcsUrl";
$statusDescription = "vcsUrl should be passed.";
$code = 400;
}

if (! array_key_exists("vcsName", $vcsData)) {
$vcsData["vcsName"] = "";
}
if (! array_key_exists("vcsUsername", $vcsData)) {
$vcsData["vcsUsername"] = "";
}
if (! array_key_exists("vcsPassword", $vcsData)) {
$vcsData["vcsPassword"] = "";
}
$vcsData["vcsType"] = $vcsType;
if ($code !== 0) {
return array(false, $message, $statusDescription, $code);
} else {
return true;
}
}
}
49 changes: 49 additions & 0 deletions src/www/ui/api/Helper/UploadHelper/HelperToUploadFilePage.php
@@ -0,0 +1,49 @@
<?php
/**
* *************************************************************
* Copyright (C) 2019 Siemens AG
* Author: Gaurav Mishra <mishra.gaurav@siemens.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* *************************************************************
*/

/**
* @file
* @brief Helper to handle file uploads via REST API
*/
namespace Fossology\UI\Api\Helper\UploadHelper;

use Fossology\UI\Page\UploadFilePage;
use Symfony\Component\HttpFoundation\Request;

/**
* @class HelperToUploadFilePage
* Child class helper to access protected methods of UploadFilePage
*/
class HelperToUploadFilePage extends UploadFilePage
{

/**
* Handles the Symfony Request object and pass it to handleUpload() of
* UploadFilePage.
*
* @param Request $request Symfony Request object holding information about
* the upload
*/
public function handleRequest(Request $request)
{
return $this->handleUpload($request);
}
}

0 comments on commit d3cacdf

Please sign in to comment.