7 namespace Fossology\UI\Api\Controllers;
 
   18 use Symfony\Component\HttpFoundation\Request;
 
   38     if (empty($SysConf[
'SYSCONFIG'][
'EnableOsselotReuse']) ||
 
   39           !$SysConf[
'SYSCONFIG'][
'EnableOsselotReuse']) {
 
   40         $error = 
new Info(501, 
"OSSelot integration is disabled", InfoType::ERROR);
 
   41         return $response->withJson($error->getArray(), $error->getCode());
 
   44       $package = $args[
'package'] ?? 
"";
 
   45     if (strlen(
trim($package)) == 0) {
 
   51         $versions = $helper->getVersions($package);
 
   53       if (empty($versions)) {
 
   54           $error = 
new Info(404, 
"No curated versions found for '$package'", InfoType::ERROR);
 
   55           return $response->withJson($error->getArray(), $error->getCode());
 
   58         rsort($versions, SORT_NATURAL);
 
   60         return $response->withJson($versions, 200);
 
   63         $error = 
new Info(502, 
"OSSelot unavailable, try later", InfoType::ERROR);
 
   64         return $response->withJson($error->getArray(), $error->getCode());
 
   80     if (empty($SysConf[
'SYSCONFIG'][
'EnableOsselotReuse']) ||
 
   81           !$SysConf[
'SYSCONFIG'][
'EnableOsselotReuse']) {
 
   82         $err = 
new Info(501, 
"OSSelot integration is disabled", InfoType::ERROR);
 
   83         return $response->withJson($err->getArray(), $err->getCode());
 
   86       $uploadId = (int)($args[
'id'] ?? 0);
 
   88     if (!$this->dbHelper->doesIdExist(
'upload', 
'upload_pk', $uploadId)) {
 
   89         $err = 
new Info(404, 
"Upload does not exist", InfoType::ERROR);
 
   90         return $response->withJson($err->getArray(), $err->getCode());
 
   94       $pkg = $body[
'package'] ?? 
null;
 
   95       $ver = $body[
'version'] ?? 
null;
 
   96       $options = $body[
'options'] ?? 
null;
 
   98     if (!$pkg || !$ver || !is_array($options)) {
 
  102           'addLicenseInfoFromInfoInFile',
 
  103           'addLicenseInfoFromConcluded',
 
  104           'addConcludedAsDecisions',
 
  108       foreach ($requiredOptions as $optKey) {
 
  109         if (!array_key_exists($optKey, $options)) {
 
  114       $jobDao = $this->restHelper->getJobDao();
 
  115       if (method_exists($jobDao, 
'hasPendingReportImport') &&
 
  116           $jobDao->hasPendingReportImport($uploadId)) {
 
  117           $err = 
new Info(409, 
"An import job is already in progress for this upload", InfoType::ERROR);
 
  118           return $response->withJson($err->getArray(), $err->getCode());
 
  123           $cachedPath = $helper->fetchSpdxFile($pkg, $ver);
 
  125         if (!$cachedPath || !is_file($cachedPath) || !is_readable($cachedPath)) {
 
  126             $err = 
new Info(404, 
"No curated SPDX report found for '$pkg' version '$ver'", InfoType::ERROR);
 
  127             return $response->withJson($err->getArray(), $err->getCode());
 
  130           $fileBase = $SysConf[
'FOSSOLOGY'][
'path'] . 
"/ReportImport/";
 
  131         if (!is_dir($fileBase) && !mkdir($fileBase, 0755, 
true)) {
 
  132             throw new \RuntimeException(
'Failed to create ReportImport directory');
 
  135           $originalName = basename($cachedPath);
 
  136         if (!str_ends_with($originalName, 
'.rdf.xml')) {
 
  137             $baseName = pathinfo($originalName, PATHINFO_FILENAME);
 
  138             $originalName = str_ends_with($originalName, 
'.rdf') ?
 
  139                 $baseName . 
'.rdf.xml' : $originalName . 
'.rdf.xml';
 
  142           $targetFile = time() . 
'_' . random_int(0, getrandmax()) . 
'_osselot_' . $originalName;
 
  143           $targetPath = $fileBase . $targetFile;
 
  145         if (!copy($cachedPath, $targetPath)) {
 
  146             throw new \RuntimeException(
'Failed to copy SPDX file to target location');
 
  149           $reportImportAgent = 
plugin_find(
'agent_reportImport');
 
  150         if (!$reportImportAgent || !method_exists($reportImportAgent, 
'addReport') ||
 
  151               !method_exists($reportImportAgent, 
'setAdditionalJqCmdArgs') ||
 
  152               !method_exists($reportImportAgent, 
'AgentAdd')) {
 
  153             throw new \RuntimeException(
'ReportImport agent not available or missing required methods');
 
  156           $importRequest = 
new Request();
 
  158           $addNewLicensesAs = $options[
'addNewLicensesAs'] ?? 
'candidate';
 
  159         if (!in_array($addNewLicensesAs, [
'candidate', 
'approved', 
'rejected'], 
true)) {
 
  160             $addNewLicensesAs = 
'candidate';
 
  162           $importRequest->request->set(
'addNewLicensesAs', $addNewLicensesAs);
 
  165               'addLicenseInfoFromInfoInFile' => $options[
'addLicenseInfoFromInfoInFile'],
 
  166               'addLicenseInfoFromConcluded' => $options[
'addLicenseInfoFromConcluded'],
 
  167               'addConcludedAsDecisions' => $options[
'addConcludedAsDecisions'],
 
  168               'addConcludedAsDecisionsOverwrite' => $options[
'addConcludedAsDecisionsOverwrite'] ?? 
false,
 
  169               'addConcludedAsDecisionsTBD' => $options[
'addConcludedAsDecisionsTBD'] ?? 
false,
 
  170               'addCopyrights' => $options[
'addCopyrights']
 
  173           foreach ($booleanOptions as $key => $value) {
 
  174               $importRequest->request->set($key, $value ? 
'true' : 
'false');
 
  177           $licenseMatch = $options[
'licenseMatch'] ?? 
'spdxid';
 
  178           if (!in_array($licenseMatch, [
'spdxid', 
'name', 
'text'], 
true)) {
 
  179               $licenseMatch = 
'spdxid';
 
  181           $importRequest->request->set(
'licenseMatch', $licenseMatch);
 
  183           $jqCmdArgs = $reportImportAgent->addReport($targetFile);
 
  184           $additionalArgs = $reportImportAgent->setAdditionalJqCmdArgs($importRequest);
 
  185           $jqCmdArgs .= $additionalArgs;
 
  190           $jobId = JobAddJob($userId, $groupId, 
"OSSelot Import", $uploadId);
 
  193           $dependencies = array();
 
  194           $jobQueueId = $reportImportAgent->AgentAdd($jobId, $uploadId, $error, $dependencies, $jqCmdArgs);
 
  196           if ($jobQueueId < 0) {
 
  197             if (file_exists($targetPath)) {
 
  200               throw new \RuntimeException(
"Cannot schedule import job: " . $error);
 
  203           $info = 
new Info(202, 
"Import job scheduled successfully", InfoType::INFO);
 
  204           $responseData = $info->getArray();
 
  205           $responseData[
'jobId'] = intval($jobQueueId);
 
  207           return $response->withJson($responseData, $info->getCode());
 
  209       } 
catch (\InvalidArgumentException $e) {
 
  210           $err = 
new Info(400, $e->getMessage(), InfoType::ERROR);
 
  211           return $response->withJson($err->getArray(), $err->getCode());
 
  212       } 
catch (\RuntimeException $e) {
 
  213         if (isset($targetPath) && file_exists($targetPath)) {
 
  217         if (strpos($e->getMessage(), 
'Could not fetch') !== 
false ||
 
  218               strpos($e->getMessage(), 
'No curated') !== 
false) {
 
  219             $err = 
new Info(404, 
"No curated SPDX report found for '$pkg' version '$ver'", InfoType::ERROR);
 
  221             $err = 
new Info(502, 
"OSSelot service unavailable, try later", InfoType::ERROR);
 
  223           return $response->withJson($err->getArray(), $err->getCode());
 
  225         if (isset($targetPath) && file_exists($targetPath)) {
 
  229           error_log(
"OSSelot import error: " . $e->getMessage());
 
  230           $err = 
new Info(502, 
"OSSelot service unavailable, try later", InfoType::ERROR);
 
  231           return $response->withJson($err->getArray(), $err->getCode());
 
Contains the constants and helpers for authentication of user.
static getUserId()
Get the current user's id.
static getGroupId()
Get the current user's group id.
Controller for OSSelot REST API endpoints.
importOsselotReport($request, $response, $args)
getPackageVersions($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.
Different type of infos provided by REST.
Info model to contain general error and return values.
plugin_find($pluginName)
Given the official name of a plugin, return the $Plugins object.
char * trim(char *ptext)
Trimming whitespace.