FOSSology  4.7.0-rc1
Open Source License Compliance by Open Source Software
UploadController.php
Go to the documentation of this file.
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2018, 2020 Siemens AG
4  SPDX-FileContributor: Gaurav Mishra <mishra.gaurav@siemens.com>
5  SPDX-FileCopyrightText: © 2022 Soham Banerjee <sohambanerjee4abc@hotmail.com>
6  SPDX-FileCopyrightText: © 2022, 2023 Samuel Dushimimana <dushsam100@gmail.com>
7  SPDX-FileContributor: Kaushlendra Pratap <kaushlendra-pratap.singh@siemens.com>
8 
9  SPDX-License-Identifier: GPL-2.0-only
10 */
11 
17 namespace Fossology\UI\Api\Controllers;
18 
51 use Psr\Http\Message\ServerRequestInterface;
52 use Slim\Psr7\Factory\StreamFactory;
53 
59 {
60 
64  const AGENT_PARAM = "agent";
65 
69  const FOLDER_PARAM = "folderId";
70 
74  const RECURSIVE_PARAM = "recursive";
75 
79  const FILTER_NAME = "name";
80 
84  const FILTER_STATUS = "status";
85 
89  const FILTER_ASSIGNEE = "assignee";
90 
94  const FILTER_DATE = "since";
95 
99  const PAGE_PARAM = "page";
100 
104  const LIMIT_PARAM = "limit";
105 
109  const UPLOAD_FETCH_LIMIT = 100;
110 
114  const CONTAINER_PARAM = "containers";
115 
119  const VALID_STATUS = ["open", "inprogress", "closed", "rejected"];
120 
124  private $agentNames = AgentRef::AGENT_LIST;
125 
130  private $agentDao;
131 
132  public function __construct($container)
133  {
134  parent::__construct($container);
135  $groupId = $this->restHelper->getGroupId();
136  $dbManager = $this->dbHelper->getDbManager();
137  $this->agentDao = $this->container->get('dao.agent');
138  $uploadBrowseProxy = new UploadBrowseProxy($groupId, 0, $dbManager, false);
139  $uploadBrowseProxy->sanity();
140  }
141 
151  public function getUploads($request, $response, $args)
152  {
153  $id = null;
154  $folderId = null;
155  $recursive = true;
156  $query = $request->getQueryParams();
157  $name = null;
158  $status = null;
159  $assignee = null;
160  $since = null;
161  $apiVersion = ApiVersion::getVersion($request);
162 
163  if (array_key_exists(self::FOLDER_PARAM, $query)) {
164  $folderId = filter_var($query[self::FOLDER_PARAM], FILTER_VALIDATE_INT);
165  if (! $this->restHelper->getFolderDao()->isFolderAccessible($folderId,
166  $this->restHelper->getUserId())) {
167  throw new HttpNotFoundException("Folder does not exist");
168  }
169  }
170 
171  if (array_key_exists(self::RECURSIVE_PARAM, $query)) {
172  $recursive = filter_var($query[self::RECURSIVE_PARAM],
173  FILTER_VALIDATE_BOOLEAN);
174  }
175  if (array_key_exists(self::FILTER_NAME, $query)) {
176  $name = $query[self::FILTER_NAME];
177  }
178  if (array_key_exists(self::FILTER_STATUS, $query)) {
179  switch (strtolower($query[self::FILTER_STATUS])) {
180  case "open":
181  $status = UploadStatus::OPEN;
182  break;
183  case "inprogress":
184  $status = UploadStatus::IN_PROGRESS;
185  break;
186  case "closed":
187  $status = UploadStatus::CLOSED;
188  break;
189  case "rejected":
190  $status = UploadStatus::REJECTED;
191  break;
192  default:
193  $status = null;
194  }
195  }
196  if (array_key_exists(self::FILTER_ASSIGNEE, $query)) {
197  $username = $query[self::FILTER_ASSIGNEE];
198  if (strcasecmp($username, "-me-") === 0) {
199  $assignee = $this->restHelper->getUserId();
200  } elseif (strcasecmp($username, "-unassigned-") === 0) {
201  $assignee = 1;
202  } else {
203  $assignee = $this->restHelper->getUserDao()->getUserByName($username);
204  if (empty($assignee)) {
205  throw new HttpNotFoundException("No user with user name '$username'");
206  }
207  $assignee = $assignee['user_pk'];
208  }
209  }
210  if (array_key_exists(self::FILTER_DATE, $query)) {
211  $date = filter_var($query[self::FILTER_DATE], FILTER_VALIDATE_REGEXP,
212  ["options" => [
213  "regexp" => "/^\d{4}\-\d{2}\-\d{2}$/",
214  "flags" => FILTER_NULL_ON_FAILURE
215  ]]);
216  $since = strtotime($date);
217  }
218  if ($apiVersion == ApiVersion::V2) {
219  $page = $query[self::PAGE_PARAM] ?? "";
220  $limit = $query[self::LIMIT_PARAM] ?? "";
221  } else {
222  $page = $request->getHeaderLine(self::PAGE_PARAM);
223  $limit = $request->getHeaderLine(self::LIMIT_PARAM);
224  }
225  if (! empty($page) || $page == "0") {
226  $page = filter_var($page, FILTER_VALIDATE_INT);
227  if ($page <= 0) {
228  throw new HttpBadRequestException(
229  "page should be positive integer > 0");
230  }
231  } else {
232  $page = 1;
233  }
234  if (! empty($limit)) {
235  $limit = filter_var($limit, FILTER_VALIDATE_INT);
236  if ($limit < 1) {
237  throw new HttpBadRequestException(
238  "limit should be positive integer > 1");
239  }
240  } else {
241  $limit = self::UPLOAD_FETCH_LIMIT;
242  }
243 
244  if (isset($args['id'])) {
245  $id = intval($args['id']);
246  $this->uploadAccessible($id);
247  $this->isAdj2nestDone($id);
248  }
249  $options = [
250  "folderId" => $folderId,
251  "name" => $name,
252  "status" => $status,
253  "assignee" => $assignee,
254  "since" => $since
255  ];
256  list($pages, $uploads) = $this->dbHelper->getUploads(
257  $this->restHelper->getUserId(), $this->restHelper->getGroupId(), $limit,
258  $page, $id, $options, $recursive, $apiVersion);
259  if ($id !== null && ! empty($uploads)) {
260  $uploads = $uploads[0];
261  $pages = 1;
262  }
263  return $response->withHeader("X-Total-Pages", $pages)->withJson($uploads,
264  200);
265  }
266 
276  public function uploadDownload($request, $response, $args)
277  {
279  $ui_download = $this->restHelper->getPlugin('download');
280  $id = null;
281 
282  if (isset($args['id'])) {
283  $id = intval($args['id']);
284  $this->uploadAccessible($id);
285  }
286  $dbManager = $this->restHelper->getDbHelper()->getDbManager();
287  $uploadDao = $this->restHelper->getUploadDao();
288  $uploadTreeTableName = $uploadDao->getUploadtreeTableName($id);
289  $itemTreeBounds = $uploadDao->getParentItemBounds($id,$uploadTreeTableName);
290  $sql = "SELECT pfile_fk , ufile_name FROM uploadtree_a WHERE uploadtree_pk=$1";
291  $params = array($itemTreeBounds->getItemId());
292  $descendants = $dbManager->getSingleRow($sql,$params);
293  $path= RepPath(($descendants['pfile_fk']));
294  $responseFile = $ui_download->getDownload($path, $descendants['ufile_name']);
295  $responseContent = $responseFile->getFile();
296  $newResponse = $response->withHeader('Content-Description',
297  'File Transfer')
298  ->withHeader('Content-Type',
299  $responseContent->getMimeType())
300  ->withHeader('Content-Disposition',
301  $responseFile->headers->get('Content-Disposition'))
302  ->withHeader('Cache-Control', 'must-revalidate')
303  ->withHeader('Pragma', 'private')
304  ->withHeader('Content-Length', filesize($responseContent->getPathname()));
305  $sf = new StreamFactory();
306  return $newResponse->withBody(
307  $sf->createStreamFromFile($responseContent->getPathname())
308  );
309  }
310 
320  public function getUploadSummary($request, $response, $args)
321  {
322  $id = intval($args['id']);
323  $query = $request->getQueryParams();
324  $selectedAgentId = $query['agentId'] ?? null;
325  $agentDao = $this->container->get('dao.agent');
326  $this->uploadAccessible($id);
327  if ($selectedAgentId !== null && !$this->dbHelper->doesIdExist("agent", "agent_pk", $selectedAgentId)) {
328  throw new HttpNotFoundException("Agent does not exist");
329  }
330  $this->isAdj2nestDone($id);
331  $uploadHelper = new UploadHelper();
332  $uploadSummary = $uploadHelper->generateUploadSummary($id, $this->restHelper->getGroupId());
333  $browseLicense = $this->restHelper->getPlugin('license');
334  $uploadDao = $this->restHelper->getUploadDao();
335  $uploadTreeTableName = $uploadDao->getUploadtreeTableName($id);
336  $itemTreeBounds = $uploadDao->getParentItemBounds($id, $uploadTreeTableName);
337  $scanJobProxy = new ScanJobProxy($agentDao, $id);
338  $scannerAgents = array_keys(AgentRef::AGENT_LIST);
339  $scanJobProxy->createAgentStatus($scannerAgents);
340  $selectedAgentIds = empty($selectedAgentId) ? $scanJobProxy->getLatestSuccessfulAgentIds() : $selectedAgentId;
341  $res = $browseLicense->createLicenseHistogram("", "", $itemTreeBounds, $selectedAgentIds, $this->restHelper->getGroupId());
342  $uploadSummary->setUniqueConcludedLicenses($res['editedUniqueLicenseCount']);
343  $uploadSummary->setTotalConcludedLicenses($res['editedLicenseCount']);
344  $uploadSummary->setTotalLicenses($res['scannerLicenseCount']);
345  $uploadSummary->setUniqueLicenses($res['uniqueLicenseCount']);
346  $uploadSummary->setConcludedNoLicenseFoundCount($res['editedNoLicenseFoundCount']);
347  $uploadSummary->setFileCount($res['fileCount']);
348  $uploadSummary->setNoScannerLicenseFoundCount($res['noScannerLicenseFoundCount']);
349  $uploadSummary->setScannerUniqueLicenseCount($res['scannerUniqueLicenseCount']);
350 
351  return $response->withJson($uploadSummary->getArray(), 200);
352  }
353 
363  public function deleteUpload($request, $response, $args)
364  {
365  require_once dirname(__DIR__, 4) . "/delagent/ui/delete-helper.php";
366  $id = intval($args['id']);
367 
368  $this->uploadAccessible($id);
369  $result = TryToDelete($id, $this->restHelper->getUserId(),
370  $this->restHelper->getGroupId(), $this->restHelper->getUploadDao());
371  if ($result->getDeleteMessageCode() !== DeleteMessages::SUCCESS) {
373  $result->getDeleteMessageString());
374  }
375  $returnVal = new Info(202, "Delete Job for file with id " . $id,
376  InfoType::INFO);
377  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
378  }
379 
388  public function moveUpload($request, $response, $args)
389  {
390  if (ApiVersion::getVersion($request) == ApiVersion::V2) {
391  $queryParams = $request->getQueryParams();
392  $action = $queryParams['action'] ?? "";
393  } else {
394  $action = $request->getHeaderLine('action');
395  }
396  if (strtolower($action) == "move") {
397  $copy = false;
398  } else {
399  $copy = true;
400  }
401  return $this->changeUpload($request, $response, $args, $copy);
402  }
403 
414  private function changeUpload($request, $response, $args, $isCopy)
415  {
416  $queryParams = $request->getQueryParams();
417  $isApiVersionV2 = (ApiVersion::getVersion($request) == ApiVersion::V2);
418  $paramType = ($isApiVersionV2) ? 'parameter' : 'header';
419 
420  if ((!$isApiVersionV2 && !$request->hasHeader('folderId') || $isApiVersionV2 && !isset($queryParams['folderId']))
421  || !is_numeric($newFolderID = ($isApiVersionV2 ? $queryParams['folderId'] : $request->getHeaderLine('folderId')))) {
422  throw new HttpBadRequestException("For API version " . ($isApiVersionV2 ? 'V2' : 'V1') . ", 'folderId' $paramType should be present and an integer.");
423  }
424 
425  $id = intval($args['id']);
426  $returnVal = $this->restHelper->copyUpload($id, $newFolderID, $isCopy);
427  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
428  }
429 
439  public function postUpload($request, $response, $args)
440  {
441  $reqBody = $this->getParsedBody($request);
442  if (ApiVersion::getVersion($request) == ApiVersion::V2) {
443  $uploadType = $reqBody['uploadType'] ?? null;
444  $folderId = $reqBody['folderId'] ?? null;
445  $description = $reqBody['uploadDescription'] ?? "";
446  $public = $reqBody['public'] ?? null;
447  $applyGlobal = filter_var($reqBody['applyGlobal'] ?? null,
448  FILTER_VALIDATE_BOOLEAN);
449  $ignoreScm = $reqBody['ignoreScm'] ?? null;
450  $excludefolder = $reqBody['excludefolder'] ?? false;
451  } else {
452  $uploadType = $request->getHeaderLine('uploadType');
453  $folderId = $request->getHeaderLine('folderId');
454  $description = $request->getHeaderLine('uploadDescription');
455  $public = $request->getHeaderLine('public');
456  $applyGlobal = filter_var($request->getHeaderLine('applyGlobal'),
457  FILTER_VALIDATE_BOOLEAN);
458  $ignoreScm = $request->getHeaderLine('ignoreScm');
459  }
460 
461  $public = empty($public) ? 'protected' : $public;
462 
463  if (empty($uploadType)) {
464  throw new HttpBadRequestException("Require uploadType");
465  }
466  $scanOptions = [];
467  if (array_key_exists('scanOptions', $reqBody)) {
468  if ($uploadType == 'file') {
469  $scanOptions = json_decode($reqBody['scanOptions'], true);
470  } else {
471  $scanOptions = $reqBody['scanOptions'];
472  }
473  }
474 
475  if (! is_array($scanOptions)) {
476  $scanOptions = [];
477  }
478 
479  $uploadHelper = new UploadHelper();
480 
481  if ($uploadType != "file" && (empty($reqBody) ||
482  ! array_key_exists("location", $reqBody))) {
483  throw new HttpBadRequestException(
484  "Require location object if uploadType != file");
485  }
486  if (empty($folderId) ||
487  !is_numeric($folderId) ||
488  intval($folderId) <= 0) {
489  throw new HttpBadRequestException("folderId must be a positive integer!");
490  }
491 
492  $allFolderIds = $this->restHelper->getFolderDao()->getAllFolderIds();
493  if (!in_array($folderId, $allFolderIds)) {
494  throw new HttpNotFoundException("folderId $folderId does not exists!");
495  }
496  if (!$this->restHelper->getFolderDao()->isFolderAccessible($folderId)) {
497  throw new HttpForbiddenException("folderId $folderId is not accessible!");
498  }
499 
500  $locationObject = [];
501  if (array_key_exists("location", $reqBody)) {
502  $locationObject = $reqBody["location"];
503  } elseif ($uploadType != 'file') {
504  throw new HttpBadRequestException(
505  "Require location object if uploadType != file");
506  }
507 
508  if (ApiVersion::getVersion($request) == ApiVersion::V2) {
509  $uploadResponse = $uploadHelper->createNewUpload($locationObject,
510  $folderId, $description, $public, $ignoreScm, $uploadType,
511  $applyGlobal, $excludefolder);
512  } else {
513  $uploadResponse = $uploadHelper->createNewUpload($locationObject,
514  $folderId, $description, $public, $ignoreScm, $uploadType,
515  $applyGlobal);
516  }
517  $status = $uploadResponse[0];
518  $message = $uploadResponse[1];
519  $statusDescription = $uploadResponse[2];
520  if (! $status) {
521  throw new HttpInternalServerErrorException($message . "\n" .
522  $statusDescription);
523  }
524 
525  $uploadId = $uploadResponse[3];
526  if (! empty($scanOptions)) {
527  $info = $uploadHelper->handleScheduleAnalysis(intval($uploadId),
528  intval($folderId), $scanOptions, true);
529  if ($info->getCode() == 201) {
530  $info = new Info($info->getCode(), intval($uploadId), $info->getType());
531  }
532  } else {
533  $info = new Info(201, intval($uploadId), InfoType::INFO);
534  }
535  if (array_key_exists("mainLicense", $reqBody) &&
536  ! empty($reqBody["mainLicense"])) {
537  global $container;
539  $licenseDao = $container->get('dao.license');
540  $mainLicense = $licenseDao
541  ->getLicenseByShortName($reqBody["mainLicense"]);
542  if ($mainLicense !== null) {
544  $clearingDao = $container->get('dao.clearing');
545  $clearingDao->makeMainLicense($uploadId,
546  $this->restHelper->getGroupId(), $mainLicense->getId());
547  }
548  }
549  return $response->withJson($info->getArray(), $info->getCode());
550  }
551 
561  public function getUploadLicenses($request, $response, $args)
562  {
563  $id = intval($args['id']);
564  $query = $request->getQueryParams();
565  $apiVersion = ApiVersion::getVersion($request);
566  if ($apiVersion == ApiVersion::V2) {
567  $page = $query['page'] ?? "";
568  $limit = $query['limit'] ?? "";
569  } else {
570  $page = $request->getHeaderLine("page");
571  $limit = $request->getHeaderLine("limit");
572  }
573  if (! array_key_exists(self::AGENT_PARAM, $query)) {
574  throw new HttpBadRequestException("agent parameter missing from query.");
575  }
576  $agents = explode(",", $query[self::AGENT_PARAM]);
577  $containers = true;
578  if (array_key_exists(self::CONTAINER_PARAM, $query)) {
579  $containers = (strcasecmp($query[self::CONTAINER_PARAM], "true") === 0);
580  }
581 
582  $license = true;
583  if (array_key_exists('license', $query)) {
584  $license = (strcasecmp($query['license'], "true") === 0);
585  }
586 
587  $copyright = false;
588  if (array_key_exists('copyright', $query)) {
589  $copyright = (strcasecmp($query['copyright'], "true") === 0);
590  }
591 
592  if (!$license && !$copyright) {
593  throw new HttpBadRequestException(
594  "'license' and 'copyright' atleast one should be true.");
595  }
596 
597  $this->uploadAccessible($id);
598  $this->isAdj2nestDone($id);
599 
600  $this->areAgentsScheduled($id, $agents, $response);
601 
602  /*
603  * check if page && limit are numeric, if existing
604  */
605  if ((! ($page==='') && (! is_numeric($page) || $page < 1)) ||
606  (! ($limit==='') && (! is_numeric($limit) || $limit < 1))) {
607  throw new HttpBadRequestException(
608  "page and limit need to be positive integers!");
609  }
610 
611  // set page to 1 by default
612  if (empty($page)) {
613  $page = 1;
614  }
615 
616  // set limit to 50 by default and max as 1000
617  if (empty($limit)) {
618  $limit = 50;
619  } else if ($limit > 1000) {
620  $limit = 1000;
621  }
622 
623  $uploadHelper = new UploadHelper();
624  list($licenseList, $count) = $uploadHelper->getUploadLicenseList($id, $agents, $containers, $license, $copyright, $page-1, $limit, $apiVersion);
625  $totalPages = intval(ceil($count / $limit));
626  return $response->withHeader("X-Total-Pages", $totalPages)->withJson($licenseList, 200);
627  }
628 
638  public function getUploadCopyrights($request, $response, $args)
639  {
640  $id = intval($args['id']);
641  $this->uploadAccessible($id);
642  $this->isAdj2nestDone($id);
643  $uploadHelper = new UploadHelper();
644  $licenseList = $uploadHelper->getUploadCopyrightList($id);
645  return $response->withJson($licenseList, 200);
646  }
647 
657  public function updateUpload($request, $response, $args)
658  {
659  $id = intval($args['id']);
660  $query = $request->getQueryParams();
661  $userDao = $this->restHelper->getUserDao();
662  $userId = $this->restHelper->getUserId();
663  $groupId = $this->restHelper->getGroupId();
664  $isJsonRequest = $this->isJsonRequest($request);
665 
666  $perm = $userDao->isAdvisorOrAdmin($userId, $groupId);
667  if (!$perm) {
668  throw new HttpForbiddenException("Not advisor or admin of current group. " .
669  "Can not update upload.");
670  }
671  $uploadBrowseProxy = new UploadBrowseProxy(
672  $groupId,
673  $perm,
674  $this->dbHelper->getDbManager()
675  );
676 
677  $assignee = null;
678  $status = null;
679  $comment = null;
680  $newName = null;
681  $newDescription = null;
682 
683  if ($isJsonRequest) {
684  $bodyContent = $this->getParsedBody($request);
685  } else {
686  $body = $request->getBody();
687  $bodyContent = $body->getContents();
688  $body->close();
689  }
690 
691  // Handle assignee info
692  if (array_key_exists(self::FILTER_ASSIGNEE, $query)) {
693  $assignee = filter_var($query[self::FILTER_ASSIGNEE], FILTER_VALIDATE_INT);
694  $userList = $userDao->getUserChoices($groupId);
695  if (!array_key_exists($assignee, $userList)) {
696  throw new HttpNotFoundException(
697  "New assignee does not have permission on upload.");
698  }
699  $uploadBrowseProxy->updateTable("assignee", $id, $assignee);
700  }
701  // Handle new status
702  if (
703  array_key_exists(self::FILTER_STATUS, $query) &&
704  in_array(strtolower($query[self::FILTER_STATUS]), self::VALID_STATUS)
705  ) {
706  $newStatus = strtolower($query[self::FILTER_STATUS]);
707  $comment = '';
708  if (in_array($newStatus, ["closed", "rejected"])) {
709  if ($isJsonRequest && array_key_exists("comment", $bodyContent)) {
710  $comment = $bodyContent["comment"];
711  } else {
712  $comment = $bodyContent;
713  }
714  }
715  $status = 0;
716  if ($newStatus == self::VALID_STATUS[1]) {
717  $status = UploadStatus::IN_PROGRESS;
718  } elseif ($newStatus == self::VALID_STATUS[2]) {
719  $status = UploadStatus::CLOSED;
720  } elseif ($newStatus == self::VALID_STATUS[3]) {
721  $status = UploadStatus::REJECTED;
722  } else {
723  $status = UploadStatus::OPEN;
724  }
725  $uploadBrowseProxy->setStatusAndComment($id, $status, $comment);
726  }
727  // Handle update of name
728  if (
729  $isJsonRequest &&
730  array_key_exists(self::FILTER_NAME, $bodyContent) &&
731  strlen(trim($bodyContent[self::FILTER_NAME])) > 0
732  ) {
733  $newName = trim($bodyContent[self::FILTER_NAME]);
734  }
735  // Handle update of description
736  if (
737  $isJsonRequest &&
738  array_key_exists("uploadDescription", $bodyContent) &&
739  strlen(trim($bodyContent["uploadDescription"])) > 0
740  ) {
741  $newDescription = trim($bodyContent["uploadDescription"]);
742  }
743  if ($newName != null || $newDescription != null) {
745  $uploadProperties = $this->restHelper->getPlugin('upload_properties');
746  $updated = $uploadProperties->UpdateUploadProperties($id, $newName, $newDescription);
747  if ($updated == 2) {
748  throw new HttpBadRequestException("Invalid request to update upload name and description.");
749  }
750  }
751 
752  $returnVal = new Info(202, "Upload updated successfully.", InfoType::INFO);
753  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
754  }
755 
761  private function isAdj2nestDone($id): void
762  {
763  $itemTreeBounds = $this->restHelper->getUploadDao()->getParentItemBounds(
764  $id);
765  if ($itemTreeBounds === false || empty($itemTreeBounds->getLeft())) {
767  "Ununpack job not started. Please check job status at " .
768  "/api/v1/jobs?upload=" . $id))
769  ->setHeaders(['Retry-After' => '60',
770  'Look-at' => "/api/v1/jobs?upload=" . $id]);
771  }
772  }
773 
783  private function areAgentsScheduled($uploadId, $agents, $response): void
784  {
785  global $container;
786  $agentDao = $container->get('dao.agent');
787 
788  $agentList = array_keys(AgentRef::AGENT_LIST);
789  $intersectArray = array_intersect($agents, $agentList);
790 
791  if (count($agents) != count($intersectArray)) {
792  throw new HttpBadRequestException("Agent should be any of " .
793  implode(", ", $agentList) . ". " . implode(",", $agents) . " passed.");
794  } else {
795  // Agent is valid, check if they have ars tables.
796  foreach ($agents as $agent) {
797  if (! $agentDao->arsTableExists($agent)) {
799  "Agent $agent not scheduled for the upload. " .
800  "Please POST to /jobs");
801  }
802  }
803  }
804 
805  $scanProxy = new ScanJobProxy($agentDao, $uploadId);
806  $agentList = $scanProxy->createAgentStatus($agents);
807 
808  foreach ($agentList as $agent) {
809  if (! array_key_exists('currentAgentId', $agent)) {
811  "Agent " . $agent["agentName"] .
812  " not scheduled for the upload. Please POST to /jobs");
813  }
814  if (array_key_exists('isAgentRunning', $agent) &&
815  $agent['isAgentRunning']) {
817  "Agent " . $agent["agentName"] . " is running. " .
818  "Please check job status at /api/v1/jobs?upload=" . $uploadId))
819  ->setHeaders(['Retry-After' => '60',
820  'Look-at' => "/api/v1/jobs?upload=" . $uploadId]);
821  }
822  }
823  }
824 
834  public function setUploadPermissions($request, $response, $args)
835  {
836  $returnVal = null;
837  // checking if the scheduler is running or not
838  $commu_status = fo_communicate_with_scheduler('status', $response_from_scheduler, $error_info);
839  if (!$commu_status) {
840  throw new HttpServiceUnavailableException("Scheduler is not running!");
841  }
842  // Initialising upload-permissions plugin
843  global $container;
844  $restHelper = $container->get('helper.restHelper');
845  $uploadPermissionObj = $restHelper->getPlugin('upload_permissions');
846 
847  $dbManager = $this->dbHelper->getDbManager();
848  // parsing the request body
849  $reqBody = $this->getParsedBody($request);
850 
851  $folder_pk = intval($reqBody['folderId']);
852  $upload_pk = intval($args['id']);
853  $this->uploadAccessible($upload_pk);
854  $allUploadsPerm = $reqBody['allUploadsPermission'] ? 1 : 0;
855  $newgroup = intval($reqBody['groupId']);
856  $newperm = $this->getEquivalentValueForPermission($reqBody['newPermission']);
857  $public_perm = isset($reqBody['publicPermission']) ? $this->getEquivalentValueForPermission($reqBody['publicPermission']) : -1;
858 
859  $query = "SELECT perm, perm_upload_pk FROM perm_upload WHERE upload_fk=$1 and group_fk=$2;";
860  $result = $dbManager->getSingleRow($query, [$upload_pk, $newgroup], __METHOD__.".getOldPerm");
861  $perm_upload_pk = 0;
862  $perm = 0;
863  if (!empty($result)) {
864  $perm_upload_pk = intVal($result['perm_upload_pk']);
865  $perm = $newperm;
866  }
867 
868  $uploadPermissionObj->editPermissionsForUpload($commu_status, $folder_pk, $upload_pk, $allUploadsPerm, $perm_upload_pk, $perm, $newgroup, $newperm, $public_perm);
869 
870  $returnVal = new Info(202, "Permissions updated successfully!", InfoType::INFO);
871  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
872  }
873 
874  public function getEquivalentValueForPermission($perm)
875  {
876  switch ($perm) {
877  case 'read_only':
878  return Auth::PERM_READ;
879  case 'read_write':
880  return Auth::PERM_WRITE;
881  case 'clearing_admin':
882  return Auth::PERM_CADMIN;
883  case 'admin':
884  return Auth::PERM_ADMIN;
885  default:
886  return Auth::PERM_NONE;
887  }
888  }
889 
899  public function getGroupsWithPermissions($request, $response, $args)
900  {
901  $apiVersion = ApiVersion::getVersion($request);
902  $upload_pk = intval($args['id']);
903  $this->uploadAccessible($upload_pk);
904  $publicPerm = $this->restHelper->getUploadPermissionDao()->getPublicPermission($upload_pk);
905  $permGroups = $this->restHelper->getUploadPermissionDao()->getPermissionGroups($upload_pk);
906 
907  // Removing the perm_upload_pk parameter in response
908  $finalPermGroups = [];
909  foreach ($permGroups as $value) {
910  $groupPerm = new GroupPermission($value['perm'], $value['group_pk'], $value['group_name']);
911  $finalPermGroups[] = $groupPerm->getArray($apiVersion);
912  }
913  $res = new Permissions($publicPerm, $finalPermGroups);
914  return $response->withJson($res->getArray($apiVersion), 200);
915  }
916 
926  public function getMainLicenses($request, $response, $args)
927  {
928  $uploadId = intval($args['id']);
929  $this->uploadAccessible($uploadId);
930 
932  $clearingDao = $this->container->get('dao.clearing');
933  $licenseIds = $clearingDao->getMainLicenseIds($uploadId, $this->restHelper->getGroupId());
934  $licenseDao = $this->container->get('dao.license');
935  $licenses = array();
936 
937  foreach ($licenseIds as $value) {
938  $licenseId = intval($value);
939  $obligations = $licenseDao->getLicenseObligations([$licenseId],
940  false);
941  $obligations = array_merge($obligations,
942  $licenseDao->getLicenseObligations([$licenseId], true));
943  $obligationList = [];
944  foreach ($obligations as $obligation) {
945  $obligationList[] = new Obligation(
946  $obligation['ob_pk'],
947  $obligation['ob_topic'],
948  $obligation['ob_type'],
949  $obligation['ob_text'],
950  $obligation['ob_classification'],
951  $obligation['ob_comment']
952  );
953  }
954  $license = $licenseDao->getLicenseById($licenseId);
955  $licenseObj = new License(
956  $license->getId(),
957  $license->getShortName(),
958  $license->getFullName(),
959  $license->getText(),
960  $license->getUrl(),
961  $obligationList,
962  $license->getRisk()
963  );
964  $licenses[] = $licenseObj->getArray();
965  }
966  return $response->withJson($licenses, 200);
967  }
968 
978  public function setMainLicense($request, $response, $args)
979  {
980  $uploadId = intval($args['id']);
981  $body = $this->getParsedBody($request);
982  $shortName = $body['shortName'];
983  $licenseDao = $this->container->get('dao.license');
984  $clearingDao = $this->container->get('dao.clearing');
985 
986  $this->uploadAccessible($uploadId);
987 
988  if (empty($shortName)) {
989  throw new HttpBadRequestException("Short name missing from request.");
990  }
991  $license = $licenseDao->getLicenseByShortName($shortName,
992  $this->restHelper->getGroupId());
993 
994  if ($license === null) {
995  throw new HttpNotFoundException(
996  "No license with shortname '$shortName' found.");
997  }
998 
999  $licenseIds = $clearingDao->getMainLicenseIds($uploadId, $this->restHelper->getGroupId());
1000  if (in_array($license->getId(), $licenseIds)) {
1001  throw new HttpBadRequestException(
1002  "License already exists for this upload.");
1003  }
1004 
1006  $clearingDao = $this->container->get('dao.clearing');
1007  $clearingDao->makeMainLicense($uploadId, $this->restHelper->getGroupId(), $license->getId());
1008  $returnVal = new Info(200, "Successfully added new main license", InfoType::INFO);
1009  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
1010  }
1011 
1012  /***
1013  * Remove the main license from the upload
1014  *
1015  * @param ServerRequestInterface $request
1016  * @param ResponseHelper $response
1017  * @param array $args
1018  * @return ResponseHelper
1019  * @throws HttpErrorException
1020  */
1021  public function removeMainLicense($request, $response, $args)
1022  {
1023  $uploadId = intval($args['id']);
1024  $shortName = $args['shortName'];
1025  $licenseDao = $this->container->get('dao.license');
1026  $clearingDao = $this->container->get('dao.clearing');
1027  $license = $licenseDao->getLicenseByShortName($shortName, $this->restHelper->getGroupId());
1028 
1029  $this->uploadAccessible($uploadId);
1030 
1031  if ($license === null) {
1032  throw new HttpNotFoundException(
1033  "No license with shortname '$shortName' found.");
1034  }
1035  $licenseIds = $clearingDao->getMainLicenseIds($uploadId, $this->restHelper->getGroupId());
1036  if (!in_array($license->getId(), $licenseIds)) {
1037  throw new HttpBadRequestException(
1038  "License '$shortName' is not a main license for this upload.");
1039  }
1040 
1041  $clearingDao = $this->container->get('dao.clearing');
1042  $clearingDao->removeMainLicense($uploadId, $this->restHelper->getGroupId(), $license->getId());
1043  $returnVal = new Info(200, "Main license removed successfully.", InfoType::INFO);
1044 
1045  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
1046  }
1047 
1057  public function getClearingProgressInfo($request, $response, $args)
1058  {
1059  $uploadId = intval($args['id']);
1060  $uploadDao = $this->restHelper->getUploadDao();
1061 
1062  $this->uploadAccessible($uploadId);
1063 
1064  $uploadTreeTableName = $uploadDao->getUploadtreeTableName($uploadId);
1065 
1066  $noLicenseUploadTreeView = new UploadTreeProxy($uploadId,
1067  array(UploadTreeProxy::OPT_SKIP_THESE => "noLicense",
1068  UploadTreeProxy::OPT_GROUP_ID => $this->restHelper->getGroupId()),
1069  $uploadTreeTableName,
1070  'no_license_uploadtree' . $uploadId);
1071 
1072  $filesOfInterest = $noLicenseUploadTreeView->count();
1073 
1074  $nonClearedUploadTreeView = new UploadTreeProxy($uploadId,
1075  array(UploadTreeProxy::OPT_SKIP_THESE => "alreadyCleared",
1076  UploadTreeProxy::OPT_GROUP_ID => $this->restHelper->getGroupId()),
1077  $uploadTreeTableName,
1078  'already_cleared_uploadtree' . $uploadId);
1079  $filesToBeCleared = $nonClearedUploadTreeView->count();
1080 
1081  $filesAlreadyCleared = $filesOfInterest - $filesToBeCleared;
1082 
1083  $res = [
1084  "totalFilesOfInterest" => intval($filesOfInterest),
1085  "totalFilesCleared" => intval($filesAlreadyCleared),
1086  ];
1087  return $response->withJson($res, 200);
1088  }
1089 
1099  public function getLicensesHistogram($request, $response, $args)
1100  {
1101  $agentDao = $this->container->get('dao.agent');
1102  $clearingDao = $this->container->get('dao.clearing');
1103  $licenseDao = $this->container->get('dao.license');
1104 
1105  $uploadId = intval($args['id']);
1106  $uploadDao = $this->restHelper->getUploadDao();
1107  $query = $request->getQueryParams();
1108  $selectedAgentId = $query['agentId'] ?? null;
1109 
1110  $this->uploadAccessible($uploadId);
1111 
1112  if ($selectedAgentId !== null && !$this->dbHelper->doesIdExist("agent", "agent_pk", $selectedAgentId)) {
1113  throw new HttpNotFoundException("Agent does not exist.");
1114  }
1115 
1116  $scannerAgents = array_keys($this->agentNames);
1117  $scanJobProxy = new ScanJobProxy($agentDao, $uploadId);
1118  $scanJobProxy->createAgentStatus($scannerAgents);
1119  $uploadTreeTableName = $uploadDao->getUploadtreeTableName($uploadId);
1120  $itemTreeBounds = $uploadDao->getParentItemBounds($uploadId, $uploadTreeTableName);
1121  $editedLicenses = $clearingDao->getClearedLicenseIdAndMultiplicities($itemTreeBounds, $this->restHelper->getGroupId());
1122  $selectedAgentIds = empty($selectedAgentId) ? $scanJobProxy->getLatestSuccessfulAgentIds() : $selectedAgentId;
1123  $scannedLicenses = $licenseDao->getLicenseHistogram($itemTreeBounds, $selectedAgentIds);
1124  $allScannerLicenseNames = array_keys($scannedLicenses);
1125  $allEditedLicenseNames = array_keys($editedLicenses);
1126  $allLicNames = array_unique(array_merge($allScannerLicenseNames, $allEditedLicenseNames));
1127  $realLicNames = array_diff($allLicNames, array(LicenseDao::NO_LICENSE_FOUND));
1128  $totalScannerLicenseCount = 0;
1129  $editedTotalLicenseCount = 0;
1130 
1131  $res = array();
1132  foreach ($realLicNames as $licenseShortName) {
1133  $count = 0;
1134  if (array_key_exists($licenseShortName, $scannedLicenses)) {
1135  $count = $scannedLicenses[$licenseShortName]['unique'];
1136  $rfId = $scannedLicenses[$licenseShortName]['rf_pk'];
1137  } else {
1138  $rfId = $editedLicenses[$licenseShortName]['rf_pk'];
1139  }
1140  $editedCount = array_key_exists($licenseShortName, $editedLicenses) ? $editedLicenses[$licenseShortName]['count'] : 0;
1141  $totalScannerLicenseCount += $count;
1142  $editedTotalLicenseCount += $editedCount;
1143  $scannerCountLink = $count;
1144  $editedLink = $editedCount;
1145 
1146  $res[] = array($scannerCountLink, $editedLink, array($licenseShortName, $rfId));
1147  }
1148 
1149  $outputArray = [];
1150 
1151  foreach ($res as $item) {
1152  $outputArray[] = [
1153  "id" => intval($item[2][1]),
1154  "name" => $item[2][0],
1155  "scannerCount" => intval($item[0]),
1156  "concludedCount" => intval($item[1]),
1157  ];
1158  }
1159  return $response->withJson($outputArray, 200);
1160  }
1161 
1171  public function getAllAgents($request, $response, $args)
1172  {
1173  $uploadId = intval($args['id']);
1174 
1175  $this->uploadAccessible($uploadId);
1176 
1177  $scannerAgents = array_keys($this->agentNames);
1178  $agentDao = $this->container->get('dao.agent');
1179  $scanJobProxy = new ScanJobProxy($agentDao, $uploadId);
1180  $res = $scanJobProxy->createAgentStatus($scannerAgents);
1181 
1182  $outputArray = [];
1183  foreach ($res as &$item) {
1184  $successfulAgents = [];
1185  if (count($item['successfulAgents']) > 0) {
1186  $item['isAgentRunning'] = false;
1187  } else {
1188  $item['currentAgentId'] = $agentDao->getCurrentAgentRef($item["agentName"])->getAgentId();
1189  $item['currentAgentRev'] = "";
1190  }
1191  foreach ($item['successfulAgents'] as &$agent) {
1192  $successfulAgent = new SuccessfulAgent(intval($agent['agent_id']), $agent['agent_rev'], $agent['agent_name']);
1193  $successfulAgents[] = $successfulAgent->getArray(ApiVersion::getVersion($request));
1194  }
1195  $agent = new Agent($successfulAgents, $item['uploadId'], $item['agentName'], $item['currentAgentId'], $item['currentAgentRev'], $item['isAgentRunning']);
1196  $outputArray[] = $agent->getArray(ApiVersion::getVersion($request));
1197  }
1198  return $response->withJson($outputArray, 200);
1199  }
1200 
1210  public function getEditedLicenses($request, $response, $args)
1211  {
1212  $uploadId = intval($args['id']);
1213 
1214  $this->uploadAccessible($uploadId);
1215 
1216  $clearingDao = $this->container->get('dao.clearing');
1217  $uploadDao = $this->restHelper->getUploadDao();
1218  $uploadTreeTableName = $uploadDao->getUploadtreeTableName($uploadId);
1219  $itemTreeBounds = $uploadDao->getParentItemBounds($uploadId, $uploadTreeTableName);
1220  $res = $clearingDao->getClearedLicenseIdAndMultiplicities($itemTreeBounds, $this->restHelper->getGroupId());
1221  $outputArray = [];
1222 
1223  foreach ($res as $key => $value) {
1224  $editedLicense = new EditedLicense(intval($value["rf_pk"]), $key, intval($value["count"]), $value["spdx_id"]);
1225  $outputArray[] = $editedLicense->getArray(ApiVersion::getVersion($request));
1226  }
1227  return $response->withJson($outputArray, 200);
1228  }
1229 
1239  public function getReuseReportSummary($request, $response, $args)
1240  {
1241  $uploadId = intval($args['id']);
1242  $this->uploadAccessible($uploadId);
1243 
1245  $reuseReportProcess = $this->container->get('businessrules.reusereportprocessor');
1246  $res = $reuseReportProcess->getReuseSummary($uploadId);
1247  return $response->withJson($res, 200);
1248  }
1249 
1259  public function getScannedLicenses($request, $response, $args)
1260  {
1261  $uploadId = intval($args['id']);
1262  $query = $request->getQueryParams();
1263  $selectedAgentId = $query['agentId'] ?? null;
1264  $licenseDao = $this->container->get('dao.license');
1265 
1266  $this->uploadAccessible($uploadId);
1267  if ($selectedAgentId !== null && !$this->dbHelper->doesIdExist("agent", "agent_pk", $selectedAgentId)) {
1268  throw new HttpNotFoundException("Agent does not exist.");
1269  }
1270  $scannerAgents = array_keys(AgentRef::AGENT_LIST);
1271  $scanJobProxy = new ScanJobProxy($this->agentDao, $uploadId);
1272  $scanJobProxy->createAgentStatus($scannerAgents);
1273  $uploadDao = $this->restHelper->getUploadDao();
1274  $uploadTreeTableName = $uploadDao->getUploadtreeTableName($uploadId);
1275  $itemTreeBounds = $uploadDao->getParentItemBounds($uploadId, $uploadTreeTableName);
1276  $selectedAgentIds = empty($selectedAgentId) ? $scanJobProxy->getLatestSuccessfulAgentIds() : $selectedAgentId;
1277  $res = $licenseDao->getLicenseHistogram($itemTreeBounds, $selectedAgentIds);
1278  $outputArray = [];
1279 
1280  foreach ($res as $key => $value) {
1281  $scannedLicense = new ScannedLicense(
1282  $value['rf_pk'],
1283  $key,
1284  $value['count'],
1285  $value['unique'],
1286  $value['spdx_id']
1287  );
1288  $outputArray[] = $scannedLicense->getArray(ApiVersion::getVersion($request));
1289  }
1290  return $response->withJson($outputArray, 200);
1291  }
1301  public function getAgentsRevision($request, $response, $args)
1302  {
1303  $agentDao = $this->container->get('dao.agent');
1304  $uploadId = intval($args['id']);
1305 
1306  $this->uploadAccessible($uploadId);
1307 
1308  $scannerAgents = array_keys($this->agentNames);
1309  $scanJobProxy = new ScanJobProxy($agentDao, $uploadId);
1310  $scanJobProxy->createAgentStatus($scannerAgents);
1311 
1312  $res = array();
1313  foreach ($scanJobProxy->getSuccessfulAgents() as $agent) {
1314  $res[] = array(
1315  "id" => $agent->getAgentId(),
1316  "name" => $agent->getAgentName(),
1317  "revision" => $agent->getAgentRevision(),
1318  );
1319  }
1320  return $response->withJson($res, 200);
1321  }
1322 
1332  public function getTopItem($request, $response, $args)
1333  {
1334  $uploadId = intval($args['id']);
1335  if (!$this->dbHelper->doesIdExist("upload", "upload_pk", $uploadId)) {
1336  $returnVal = new Info(404, "Upload does not exist", InfoType::ERROR);
1337  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
1338  }
1339  $uploadDao = $this->restHelper->getUploadDao();
1340  $itemTreeBounds = $uploadDao->getParentItemBounds($uploadId,
1341  $uploadDao->getUploadtreeTableName($uploadId));
1342  if ($itemTreeBounds === false) {
1343  $error = new Info(500, "Unable to get top item.", InfoType::ERROR);
1344  return $response->withJson($error->getArray(), $error->getCode());
1345  }
1346  $info = new Info(200, $itemTreeBounds->getItemId(), InfoType::INFO);
1347  return $response->withJson($info->getArray(), $info->getCode());
1348  }
1349 }
Messages which can be generated by delagent.
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
Fossology exception.
Definition: Exception.php:15
Base controller for REST calls.
getParsedBody(ServerRequestInterface $request)
Parse request body as JSON and return associative PHP array.
areAgentsScheduled($uploadId, $agents, $response)
getClearingProgressInfo($request, $response, $args)
setUploadPermissions($request, $response, $args)
getGroupsWithPermissions($request, $response, $args)
changeUpload($request, $response, $args, $isCopy)
Override Slim response for withJson function.
Handle new file uploads from Slim framework and move to FOSSology.
static getVersion(ServerRequestInterface $request)
Definition: ApiVersion.php:29
Different type of infos provided by REST.
Definition: InfoType.php:16
Info model to contain general error and return values.
Definition: Info.php:19
RepPath($PfilePk, $Repo="files")
Given a pfile id, retrieve the pfile path.
Definition: common-repo.php:58
fo_communicate_with_scheduler($input, &$output, &$error_msg)
Communicate with scheduler, send commands to the scheduler, then get the output.
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:690
Definition: monk.h:55