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.