FOSSology  4.4.0
Open Source License Compliance by Open Source Software
LicenseController.php
Go to the documentation of this file.
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2021 HH Partners
4  SPDX-FileCopyrightText: © 2023 Samuel Dushimimana <dushsam100@gmail.com>
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
13 namespace Fossology\UI\Api\Controllers;
14 
36 use Psr\Container\ContainerInterface;
37 use Psr\Http\Message\ServerRequestInterface as Request;
38 use Slim\Psr7\Factory\StreamFactory;
39 
45 {
49  const PAGE_PARAM = "page";
53  const LIMIT_PARAM = "limit";
57  const ACTIVE_PARAM = "active";
61  const LICENSE_FETCH_LIMIT = 100;
66  private $licenseDao;
67 
73 
79 
80 
84  public function __construct($container)
85  {
86  parent::__construct($container);
87  $this->licenseDao = $this->container->get('dao.license');
88  $this->adminLicenseAckDao = $this->container->get('dao.license.acknowledgement');
89  $this->licenseStdCommentDao = $this->container->get('dao.license.stdc');
90  }
91 
101  public function getLicense($request, $response, $args)
102  {
103  $shortName = $args["shortname"];
104 
105  if (empty($shortName)) {
106  throw new HttpBadRequestException("Short name missing from request.");
107  }
108 
109  $license = $this->licenseDao->getLicenseByShortName($shortName,
110  $this->restHelper->getGroupId());
111 
112  if ($license === null) {
113  throw new HttpNotFoundException(
114  "No license found with short name '$shortName'.");
115  }
116 
117  $obligations = $this->licenseDao->getLicenseObligations([$license->getId()],
118  false);
119  $obligations = array_merge($obligations,
120  $this->licenseDao->getLicenseObligations([$license->getId()], true));
121  $obligationList = [];
122  foreach ($obligations as $obligation) {
123  $obligationList[] = new Obligation(
124  $obligation['ob_pk'],
125  $obligation['ob_topic'],
126  $obligation['ob_type'],
127  $obligation['ob_text'],
128  $obligation['ob_classification'],
129  $obligation['ob_comment']
130  );
131  }
132 
133  $returnVal = new License(
134  $license->getId(),
135  $license->getShortName(),
136  $license->getFullName(),
137  $license->getText(),
138  $license->getUrl(),
139  $obligationList,
140  $license->getRisk()
141  );
142 
143  return $response->withJson($returnVal->getArray(), 200);
144  }
145 
155  public function getAllLicenses($request, $response, $args)
156  {
157  $apiVersion = ApiVersion::getVersion($request);
158  $query = $request->getQueryParams();
159  if ($apiVersion == ApiVersion::V2) {
160  $page = $query[self::PAGE_PARAM] ?? "";
161  $limit = $query[self::LIMIT_PARAM] ?? "";
162  $onlyActive = $query[self::ACTIVE_PARAM] ?? "";
163  } else {
164  $page = $request->getHeaderLine(self::PAGE_PARAM);
165  $limit = $request->getHeaderLine(self::LIMIT_PARAM);
166  $onlyActive = $request->getHeaderLine(self::ACTIVE_PARAM);
167  }
168  if (! empty($limit)) {
169  $limit = filter_var($limit, FILTER_VALIDATE_INT);
170  if ($limit < 1) {
171  throw new HttpBadRequestException(
172  "limit should be positive integer > 1");
173  }
174  } else {
175  $limit = self::LICENSE_FETCH_LIMIT;
176  }
177 
178  $kind = "all";
179  if (array_key_exists("kind", $query) && !empty($query["kind"]) &&
180  in_array($query["kind"], ["all", "candidate", "main"])) {
181  $kind = $query["kind"];
182  }
183 
184  $totalPages = $this->dbHelper->getLicenseCount($kind,
185  $this->restHelper->getGroupId());
186  $totalPages = intval(ceil($totalPages / $limit));
187 
188  if (! empty($page) || $page == "0") {
189  $page = filter_var($page, FILTER_VALIDATE_INT);
190  if ($page <= 0) {
191  throw new HttpBadRequestException(
192  "page should be positive integer > 0");
193  }
194  if ($totalPages != 0 && $page > $totalPages) {
195  throw (new HttpBadRequestException(
196  "Can not exceed total pages: $totalPages"))
197  ->setHeaders(["X-Total-Pages" => $totalPages]);
198  }
199  } else {
200  $page = 1;
201  }
202  if (! empty($onlyActive)) {
203  $onlyActive = filter_var($onlyActive, FILTER_VALIDATE_BOOLEAN);
204  } else {
205  $onlyActive = false;
206  }
207 
208  $licenses = $this->dbHelper->getLicensesPaginated($page, $limit,
209  $kind, $this->restHelper->getGroupId(), $onlyActive);
210  $licenseList = [];
211 
212  foreach ($licenses as $license) {
213  $newRow = new License(
214  $license['rf_pk'],
215  $license['rf_shortname'],
216  $license['rf_fullname'],
217  $license['rf_text'],
218  $license['rf_url'],
219  null,
220  $license['rf_risk'],
221  $license['group_fk'] != 0
222  );
223  $licenseList[] = $newRow->getArray();
224  }
225 
226  return $response->withHeader("X-Total-Pages", $totalPages)
227  ->withJson($licenseList, 200);
228  }
229 
239  public function createLicense($request, $response, $args)
240  {
241  $newLicense = $this->getParsedBody($request);
242  $newLicense = License::parseFromArray($newLicense);
243  if ($newLicense === -1) {
244  throw new HttpBadRequestException(
245  "Input contains additional properties.");
246  }
247  if ($newLicense === -2) {
248  throw new HttpBadRequestException("Property 'shortName' is required.");
249  }
250  if (! $newLicense->getIsCandidate() && ! Auth::isAdmin()) {
251  throw new HttpForbiddenException("Need to be admin to create " .
252  "non-candidate license.");
253  }
254  $tableName = "license_ref";
255  $assocData = [
256  "rf_shortname" => $newLicense->getShortName(),
257  "rf_fullname" => $newLicense->getFullName(),
258  "rf_text" => $newLicense->getText(),
259  "rf_md5" => md5($newLicense->getText()),
260  "rf_risk" => $newLicense->getRisk(),
261  "rf_url" => $newLicense->getUrl(),
262  "rf_detector_type" => 1
263  ];
264  $okToAdd = true;
265  if ($newLicense->getIsCandidate()) {
266  $tableName = "license_candidate";
267  $assocData["group_fk"] = $this->restHelper->getGroupId();
268  $assocData["rf_user_fk_created"] = $this->restHelper->getUserId();
269  $assocData["rf_user_fk_modified"] = $this->restHelper->getUserId();
270  $assocData["marydone"] = $newLicense->getMergeRequest();
271  $okToAdd = $this->isNewLicense($newLicense->getShortName(),
272  $this->restHelper->getGroupId());
273  } else {
274  $okToAdd = $this->isNewLicense($newLicense->getShortName());
275  }
276  if (! $okToAdd) {
277  throw new HttpConflictException("License with shortname '" .
278  $newLicense->getShortName() . "' already exists!");
279  }
280  try {
281  $rfPk = $this->dbHelper->getDbManager()->insertTableRow($tableName,
282  $assocData, __METHOD__ . ".newLicense", "rf_pk");
283  $newInfo = new Info(201, $rfPk, InfoType::INFO);
284  } catch (\Exception $e) {
285  throw new HttpConflictException(
286  "License with same text already exists!", $e);
287  }
288  return $response->withJson($newInfo->getArray(), $newInfo->getCode());
289  }
290 
300  public function updateLicense($request, $response, $args)
301  {
302  $newParams = $this->getParsedBody($request);
303  $shortName = $args["shortname"];
304  if (empty($shortName)) {
305  throw new HttpBadRequestException("Short name missing from request.");
306  }
307 
308  $license = $this->licenseDao->getLicenseByShortName($shortName,
309  $this->restHelper->getGroupId());
310 
311  if ($license === null) {
312  throw new HttpNotFoundException(
313  "No license found with short name '$shortName'.");
314  }
315  $isCandidate = $this->restHelper->getDbHelper()->doesIdExist(
316  "license_candidate", "rf_pk", $license->getId());
317  if (!$isCandidate && !Auth::isAdmin()) {
318  throw new HttpForbiddenException(
319  "Need to be admin to edit non-candidate license.");
320  }
321  if ($isCandidate && ! $this->restHelper->getUserDao()->isAdvisorOrAdmin(
322  $this->restHelper->getUserId(), $this->restHelper->getGroupId())) {
323  throw new HttpForbiddenException(
324  "Operation not permitted for this group.");
325  }
326 
327  $assocData = [];
328  if (array_key_exists('fullName', $newParams)) {
329  $assocData['rf_fullname'] = StringOperation::replaceUnicodeControlChar($newParams['fullName']);
330  }
331  if (array_key_exists('text', $newParams)) {
332  $assocData['rf_text'] = StringOperation::replaceUnicodeControlChar($newParams['text']);
333  }
334  if (array_key_exists('url', $newParams)) {
335  $assocData['rf_url'] = StringOperation::replaceUnicodeControlChar($newParams['url']);
336  }
337  if (array_key_exists('risk', $newParams)) {
338  $assocData['rf_risk'] = intval($newParams['risk']);
339  }
340  if (empty($assocData)) {
341  throw new HttpBadRequestException("Empty body sent.");
342  }
343 
344  $tableName = "license_ref";
345  if ($isCandidate) {
346  $tableName = "license_candidate";
347  }
348  $this->dbHelper->getDbManager()->updateTableRow($tableName, $assocData,
349  "rf_pk", $license->getId(), __METHOD__ . ".updateLicense");
350  $newInfo = new Info(200, "License " . $license->getShortName() .
351  " updated.", InfoType::INFO);
352  return $response->withJson($newInfo->getArray(), $newInfo->getCode());
353  }
354 
361  private function isNewLicense($shortName, $groupId = 0)
362  {
363  $tableName = "ONLY license_ref";
364  $where = "";
365  $params = [$shortName];
366  $statement = __METHOD__;
367  if ($groupId != 0) {
368  $tableName = "license_candidate";
369  $where = "AND group_fk = $2";
370  $params[] = $groupId;
371  $statement .= ".candidate";
372  }
373  $sql = "SELECT count(*) cnt FROM " .
374  "$tableName WHERE rf_shortname = $1 $where;";
375  $result = $this->dbHelper->getDbManager()->getSingleRow($sql, $params,
376  $statement);
377  return $result["cnt"] == 0;
378  }
379 
389  public function handleImportLicense($request, $response, $args)
390  {
391  $apiVersion = ApiVersion::getVersion($request);
392  $this->throwNotAdminException();
393  $symReq = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
395  $adminLicenseFromCsv = $this->restHelper->getPlugin('admin_license_from_csv');
396 
397  $uploadedFile = $symReq->files->get($adminLicenseFromCsv->getFileInputName($apiVersion),
398  null);
399 
400  $requestBody = $this->getParsedBody($request);
401  $delimiter = ',';
402  $enclosure = '"';
403  if (array_key_exists("delimiter", $requestBody) && !empty($requestBody["delimiter"])) {
404  $delimiter = $requestBody["delimiter"];
405  }
406  if (array_key_exists("enclosure", $requestBody) && !empty($requestBody["enclosure"])) {
407  $enclosure = $requestBody["enclosure"];
408  }
409 
410  $res = $adminLicenseFromCsv->handleFileUpload($uploadedFile, $delimiter,
411  $enclosure);
412 
413  if (!$res[0]) {
414  throw new HttpBadRequestException($res[1]);
415  }
416 
417  $newInfo = new Info($res[2], $res[1], InfoType::INFO);
418  return $response->withJson($newInfo->getArray(), $newInfo->getCode());
419  }
420 
430  public function getCandidates($request, $response, $args)
431  {
432  $apiVersion = ApiVersion::getVersion($request);
433  $this->throwNotAdminException();
435  $adminLicenseCandidate = $this->restHelper->getPlugin("admin_license_candidate");
436  $licenses = LicenseCandidate::convertDbArray($adminLicenseCandidate->getCandidateArrayData(), $apiVersion);
437  return $response->withJson($licenses, 200);
438  }
439 
449  public function deleteAdminLicenseCandidate($request, $response, $args)
450  {
451  $this->throwNotAdminException();
452  $id = intval($args['id']);
454  $adminLicenseCandidate = $this->restHelper->getPlugin('admin_license_candidate');
455 
456  if (!$adminLicenseCandidate->getDataRow($id)) {
457  throw new HttpNotFoundException("License candidate not found.");
458  }
459  $res = $adminLicenseCandidate->doDeleteCandidate($id,false);
460  $message = $res->getContent();
461  if ($res->getContent() !== 'true') {
462  throw new HttpConflictException(
463  "License used at following locations, can not delete: " .
464  $message);
465  }
466  $resInfo = new Info(202, "License candidate will be deleted.",
467  InfoType::INFO);
468  return $response->withJson($resInfo->getArray(), $resInfo->getCode());
469  }
470 
480  public function getAllAdminAcknowledgements($request, $response, $args)
481  {
482  $apiVersion = ApiVersion::getVersion($request);
483  $this->throwNotAdminException();
484  $rawData = $this->adminLicenseAckDao->getAllAcknowledgements();
485 
486  $acknowledgements = [];
487  foreach ($rawData as $ack) {
488  $acknowledgements[] = new AdminAcknowledgement(intval($ack['la_pk']), $ack['name'], $ack['acknowledgement'], $ack['is_enabled'] == "t");
489  }
490 
491  $res = array_map(fn($acknowledgement) => $acknowledgement->getArray($apiVersion), $acknowledgements);
492  return $response->withJson($res, 200);
493  }
494 
504  public function handleAdminLicenseAcknowledgement($request, $response, $args)
505  {
506  $body = $this->getParsedBody($request);
507  $errors = [];
508  $success = [];
509 
510  if (empty($body)) {
511  throw new HttpBadRequestException("Request body is missing or empty.");
512  }
513  if (!is_array($body)) {
514  throw new HttpBadRequestException("Request body should be an array.");
515  }
516  foreach (array_keys($body) as $index) {
517  $ackReq = $body[$index];
518  if ((!$ackReq['update'] && empty($ackReq['name'])) || ($ackReq['update'] && empty($ackReq['name']) && !$ackReq['toggle'])) {
519  $error = new Info(400, "Acknowledgement name missing from the request #" . ($index + 1), InfoType::ERROR);
520  $errors[] = $error->getArray();
521  continue;
522  } else if ((!$ackReq['update'] && empty($ackReq['ack'])) || ($ackReq['update'] && empty($ackReq['ack']) && !$ackReq['toggle'])) {
523  $error = new Info(400, "Acknowledgement text missing from the request #" . ($index + 1), InfoType::ERROR);
524  $errors[] = $error->getArray();
525  continue;
526  }
527 
528  if ($ackReq['update']) {
529 
530  if (empty($ackReq['id'])) {
531  $error = new Info(400, "Acknowledgement ID missing from the request #" . ($index + 1), InfoType::ERROR);
532  $errors[] = $error->getArray();
533  continue;
534  }
535 
536  $sql = "SELECT la_pk, name FROM license_std_acknowledgement WHERE la_pk = $1;";
537  $existingAck = $this->dbHelper->getDbManager()->getSingleRow($sql, [$ackReq['id']]);
538 
539  if (empty($existingAck)) {
540  $error = new Info(404, "Acknowledgement not found for the request #" . ($index + 1), InfoType::ERROR);
541  $errors[] = $error->getArray();
542  continue;
543  } else if ($existingAck["name"] != $ackReq["name"] && $this->dbHelper->doesIdExist("license_std_acknowledgement", "name", $ackReq["name"])) {
544  $error = new Info(400, "Name already exists.", InfoType::ERROR);
545  $errors[] = $error->getArray();
546  continue;
547  }
548 
549  if ($ackReq["name"] && $ackReq["ack"]) {
550  $this->adminLicenseAckDao->updateAcknowledgement($ackReq["id"], $ackReq["name"], $ackReq["ack"]);
551  }
552 
553  if ($ackReq["toggle"]) {
554  $this->adminLicenseAckDao->toggleAcknowledgement($ackReq["id"]);
555  }
556 
557  $info = new Info(200, "Successfully updated admin license acknowledgement with name '" . $existingAck["name"] . "'", InfoType::INFO);
558  } else {
559 
560  if ($this->dbHelper->doesIdExist("license_std_acknowledgement", "name", $ackReq["name"])) {
561  $error = new Info(400, "Name already exists for the request #" . ($index + 1), InfoType::ERROR);
562  $errors[] = $error->getArray();
563  continue;
564  }
565  $res = $this->adminLicenseAckDao->insertAcknowledgement($ackReq["name"], $ackReq["ack"]);
566  if ($res == -2) {
567  $error = new Info(500, "Error while inserting new acknowledgement.", InfoType::ERROR);
568  $errors[] = $error->getArray();
569  continue;
570  }
571  $info = new Info(201, "Acknowledgement added successfully.", InfoType::INFO);
572  }
573  $success[] = $info->getArray();
574  }
575  return $response->withJson([
576  'success' => $success,
577  'errors' => $errors
578  ], 200);
579  }
580 
589  public function getAllLicenseStandardComments($request, $response, $args)
590  {
591  $apiVersion = ApiVersion::getVersion($request);
592  $rawData = $this->licenseStdCommentDao->getAllComments();
593  $comments = [];
594  foreach ($rawData as $cmt) {
595  $comments[] = new LicenseStandardComment(intval($cmt['lsc_pk']), $cmt['name'], $cmt['comment'], $cmt['is_enabled'] == "t");
596  }
597  $res = array_map(fn($comment) => $comment->getArray($apiVersion), $comments);
598  return $response->withJson($res, 200);
599  }
600 
610  public function handleLicenseStandardComment($request, $response, $args)
611  {
612  $this->throwNotAdminException();
613 
614  $body = $this->getParsedBody($request);
615  $errors = [];
616  $success = [];
617 
618  if (empty($body)) {
619  throw new HttpBadRequestException("Request body is missing or empty.");
620  }
621  if (!is_array($body)) {
622  throw new HttpBadRequestException("Request body should be an array.");
623  }
624  foreach (array_keys($body) as $index) {
625  $commentReq = $body[$index];
626 
627  // Check if name and comment are present if update is false
628  if ((!$commentReq['update'] && empty($commentReq['name']))) {
629  $error = new Info(400, "Comment name missing from the request #" . ($index + 1), InfoType::ERROR);
630  $errors[] = $error->getArray();
631  continue;
632  } else if ((!$commentReq['update'] && empty($commentReq['comment']))) {
633  $error = new Info(400, "Comment text missing from the request #" . ($index + 1), InfoType::ERROR);
634  $errors[] = $error->getArray();
635  continue;
636  } else if ($commentReq['update'] && empty($commentReq['name']) && empty($commentReq['comment']) && empty($commentReq['toggle'])) {
637  $error = new Info(400, "Comment name, text or toggle missing from the request #" . ($index + 1), InfoType::ERROR);
638  $errors[] = $error->getArray();
639  continue;
640  }
641 
642  if ($commentReq['update']) {
643 
644  if (empty($commentReq['id'])) {
645  $error = new Info(400, "Standard Comment ID missing from the request #" . ($index + 1), InfoType::ERROR);
646  $errors[] = $error->getArray();
647  continue;
648  }
649 
650  $sql = "SELECT lsc_pk, name, comment FROM license_std_comment WHERE lsc_pk = $1;";
651  $existingComment = $this->dbHelper->getDbManager()->getSingleRow($sql, [$commentReq['id']]);
652 
653  if (empty($existingComment)) {
654  $error = new Info(404, "Standard comment not found for the request #" . ($index + 1), InfoType::ERROR);
655  $errors[] = $error->getArray();
656  continue;
657  // check if the new name doesn't already exist
658  } else if ($existingComment["name"] != $commentReq["name"] && $this->dbHelper->doesIdExist("license_std_comment", "name", $commentReq["name"])) {
659  $error = new Info(400, "Name already exists.", InfoType::ERROR);
660  $errors[] = $error->getArray();
661  continue;
662  }
663 
664  // if both fields were specified and are not empty, update the comment
665  if ($commentReq["name"] && $commentReq["comment"]) {
666  $this->licenseStdCommentDao->updateComment($commentReq["id"], $commentReq["name"], $commentReq["comment"]);
667  } else if ($commentReq["name"]) {
668  $this->licenseStdCommentDao->updateComment($commentReq["id"], $commentReq["name"], $existingComment["comment"]);
669  } else if ($commentReq["comment"]) {
670  $this->licenseStdCommentDao->updateComment($commentReq["id"], $existingComment["name"], $commentReq["comment"]);
671  }
672  // toggle the comment if the toggle field is set to true
673  if ($commentReq["toggle"]) {
674  $this->licenseStdCommentDao->toggleComment($commentReq["id"]);
675  }
676 
677  $info = new Info(200, "Successfully updated standard comment", InfoType::INFO);
678  } else {
679 
680  if ($this->dbHelper->doesIdExist("license_std_comment", "name", $commentReq["name"])) {
681  $error = new Info(400, "Name already exists for the request #" . ($index + 1), InfoType::ERROR);
682  $errors[] = $error->getArray();
683  continue;
684  }
685  $res = $this->licenseStdCommentDao->insertComment($commentReq["name"], $commentReq["comment"]);
686  if ($res == -2) {
687  $error = new Info(500, "Error while inserting new comment.", InfoType::ERROR);
688  $errors[] = $error->getArray();
689  continue;
690  }
691  $info = new Info(201, "Comment with name '". $commentReq['name'] ."' added successfully.", InfoType::INFO);
692  }
693  $success[] = $info->getArray();
694  }
695  return $response->withJson([
696  'success' => $success,
697  'errors' => $errors
698  ], 200);
699  }
700 
710  public function verifyLicense($request, $response, $args)
711  {
712  $this->throwNotAdminException();
713  $licenseShortName = $args["shortname"];
714  $body = $this->getParsedBody($request);
715  $parentName = $body["parentShortname"];
716 
717  if (empty($licenseShortName) || empty($parentName)) {
718  throw new HttpBadRequestException(
719  "License ShortName or Parent ShortName is missing.");
720  }
721 
722  $license = $this->licenseDao->getLicenseByShortName($licenseShortName, $this->restHelper->getGroupId());
723  if ($licenseShortName != $parentName) {
724  $parentLicense = $this->licenseDao->getLicenseByShortName($parentName, $this->restHelper->getGroupId());
725  } else {
726  $parentLicense = $license;
727  }
728 
729  if (empty($license) || empty($parentLicense)) {
730  throw new HttpNotFoundException("License not found.");
731  }
732 
733  try {
735  $adminLicenseCandidate = $this->restHelper->getPlugin('admin_license_candidate');
736  $ok = $adminLicenseCandidate->verifyCandidate($license->getId(), $licenseShortName, $parentLicense->getId());
737  } catch (\Throwable $th) {
738  throw new HttpConflictException('The license text already exists.', $th);
739  }
740 
741  if (!$ok) {
742  throw new HttpBadRequestException('Short name must be unique');
743  }
744  $with = $parentLicense->getId() === $license->getId() ? '' : " as variant of ($parentName).";
745  $info = new Info(200, 'Successfully verified candidate ('.$licenseShortName.')'.$with, InfoType::INFO);
746  return $response->withJson($info->getArray(), $info->getCode());
747  }
748 
758  public function mergeLicense($request, $response, $args)
759  {
760  $this->throwNotAdminException();
761  $licenseShortName = $args["shortname"];
762  $body = $this->getParsedBody($request);
763  $parentName = $body["parentShortname"];
764 
765  if (empty($licenseShortName) || empty($parentName)) {
766  throw new HttpBadRequestException(
767  "License ShortName or Parent ShortName is missing.");
768  }
769  if ($licenseShortName == $parentName) {
770  throw new HttpBadRequestException(
771  "License ShortName and Parent ShortName are same.");
772  }
773 
774  $license = $this->licenseDao->getLicenseByShortName($licenseShortName, $this->restHelper->getGroupId());
775  $mergeLicense = $this->licenseDao->getLicenseByShortName($parentName, $this->restHelper->getGroupId());
776 
777  if (empty($license) || empty($mergeLicense)) {
778  throw new HttpNotFoundException("License not found.");
779  }
780 
782  $adminLicenseCandidate = $this->restHelper->getPlugin('admin_license_candidate');
783  $vars = $adminLicenseCandidate->getDataRow($license->getId());
784  if (empty($vars)) {
785  throw new HttpNotFoundException("Candidate license not found.");
786  }
787 
788  try {
789  $vars['shortname'] = $vars['rf_shortname'];
790  $ok = $adminLicenseCandidate->mergeCandidate($license->getId(), $mergeLicense->getId(), $vars);
791  } catch (\Throwable $th) {
792  throw new HttpConflictException('The license text already exists.', $th);
793  }
794 
795  if (!$ok) {
796  throw new HttpInternalServerErrorException("Please try again later.");
797  }
798  $info = new Info(200, "Successfully merged candidate ($parentName) into ($licenseShortName).", InfoType::INFO);
799  return $response->withJson($info->getArray(), $info->getCode());
800  }
801 
811  public function getSuggestedLicense($request, $response, $args)
812  {
813  $this->throwNotAdminException();
814  $body = $this->getParsedBody($request);
815  $rfText = $body["referenceText"];
816  if (empty($rfText)) {
817  throw new HttpBadRequestException("Reference text is missing.");
818  }
820  $adminLicenseCandidate = $this->restHelper->getPlugin('admin_license_candidate');
821  list ($suggestIds, $rendered) = $adminLicenseCandidate->suggestLicenseId($rfText, true);
822  $highlights = [];
823 
824  foreach ($rendered as $value) {
825  $highlights[] = $value->getArray();
826  }
827 
828  if (! empty($suggestIds)) {
829  $suggest = $suggestIds[0];
830  $suggestLicense = $adminLicenseCandidate->getDataRow($suggest, 'ONLY license_ref');
831  $suggestLicense = [
832  'id' => intval($suggestLicense['rf_pk']),
833  'spdxName' => $suggestLicense['rf_spdx_id'],
834  'shortName' => $suggestLicense['rf_shortname'],
835  'fullName' => $suggestLicense['rf_fullname'],
836  'text' => $suggestLicense['rf_text'],
837  'url' => $suggestLicense['rf_url'],
838  'notes' => $suggestLicense['rf_notes'],
839  'risk' => intval($suggestLicense['rf_risk']),
840  'highlights' => $highlights,
841  ];
842  }
843  if (empty($suggestLicense)) {
844  $suggestLicense = [];
845  }
846  return $response->withJson($suggestLicense, 200);
847  }
848 
858  public function exportAdminLicenseToCSV($request, $response, $args)
859  {
860  $this->throwNotAdminException();
861  $query = $request->getQueryParams();
862  $rf = 0;
863  if (array_key_exists('id', $query)) {
864  $rf = intval($query['id']);
865  }
866  if ($rf != 0 &&
867  (! $this->dbHelper->doesIdExist("license_ref", "rf_pk", $rf) &&
868  ! $this->dbHelper->doesIdExist("license_candidate", "rf_pk", $rf))) {
869  throw new HttpNotFoundException("License not found.");
870  }
871  $dbManager = $this->dbHelper->getDbManager();
872  $licenseCsvExport = new LicenseCsvExport($dbManager);
873  $content = $licenseCsvExport->createCsv($rf);
874  $fileName = "fossology-license-export-" . date("YMj-Gis");
875  $newResponse = $response->withHeader('Content-type', 'text/csv, charset=UTF-8')
876  ->withHeader('Content-Disposition', 'attachment; filename=' . $fileName . '.csv')
877  ->withHeader('Pragma', 'no-cache')
878  ->withHeader('Cache-Control', 'no-cache, must-revalidate, maxage=1, post-check=0, pre-check=0')
879  ->withHeader('Expires', 'Expires: Thu, 19 Nov 1981 08:52:00 GMT');
880  $sf = new StreamFactory();
881  return $newResponse->withBody(
882  $content ? $sf->createStream($content) : $sf->createStream('')
883  );
884  }
885 
895  public function exportAdminLicenseToJSON($request, $response, $args)
896  {
897  $this->throwNotAdminException();
898  $query = $request->getQueryParams();
899  $rf = 0;
900  if (array_key_exists('id', $query)) {
901  $rf = intval($query['id']);
902  }
903  if ($rf != 0 &&
904  (! $this->dbHelper->doesIdExist("license_ref", "rf_pk", $rf) &&
905  ! $this->dbHelper->doesIdExist("license_candidate", "rf_pk", $rf))) {
906  throw new HttpNotFoundException("License not found.");
907  }
908  $dbManager = $this->dbHelper->getDbManager();
909  $licenseCsvExport = new LicenseCsvExport($dbManager);
910  $content = $licenseCsvExport->createCsv($rf, false, true);
911  $fileName = "fossology-license-export-" . date("YMj-Gis");
912  $newResponse = $response->withHeader('Content-type', 'text/json, charset=UTF-8')
913  ->withHeader('Content-Disposition', 'attachment; filename=' . $fileName . '.json')
914  ->withHeader('Pragma', 'no-cache')
915  ->withHeader('Cache-Control', 'no-cache, must-revalidate, maxage=1, post-check=0, pre-check=0')
916  ->withHeader('Expires', 'Expires: Thu, 19 Nov 1981 08:52:00 GMT');
917  $sf = new StreamFactory();
918  return $newResponse->withBody(
919  $content ? $sf->createStream($content) : $sf->createStream('')
920  );
921  }
922 }
Helper class to export license list as a CSV from the DB.
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
static isAdmin()
Check if user is admin.
Definition: Auth.php:92
Fossology exception.
Definition: Exception.php:15
static replaceUnicodeControlChar($input, $replace="")
handleLicenseStandardComment($request, $response, $args)
handleAdminLicenseAcknowledgement($request, $response, $args)
exportAdminLicenseToJSON($request, $response, $args)
getAllLicenseStandardComments($request, $response, $args)
getAllAdminAcknowledgements($request, $response, $args)
Base controller for REST calls.
getParsedBody(ServerRequestInterface $request)
Parse request body as JSON and return associative PHP array.
Override Slim response for withJson function.
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
static convertDbArray($rows, $version=ApiVersion::V1)
static parseFromArray($inputLicense)
Definition: License.php:338