15 namespace Fossology\UI\Api;
17 $GLOBALS[
'apiCall'] =
true;
20 require_once dirname(__DIR__, 3) .
"/vendor/autoload.php";
21 require_once dirname(__FILE__, 4) .
"/lib/php/bootstrap.php";
54 use Psr\Http\Message\ServerRequestInterface;
55 use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
56 use Psr\Log\LoggerInterface;
57 use Slim\Exception\HttpMethodNotAllowedException;
58 use Slim\Exception\HttpNotFoundException;
59 use Slim\Factory\AppFactory;
60 use Slim\Middleware\ContentLengthMiddleware;
61 use Slim\Psr7\Request;
62 use Slim\Psr7\Response;
66 function getVersionFromUri ($uri)
69 preg_match(
'/\/repo\/api\/v(\d+)/', $uri, $matches);
70 return isset($matches[1]) ? intval($matches[1]) : null;
74 $requestedVersion = isset($_SERVER[
'REQUEST_URI']) ? getVersionFromUri($_SERVER[
'REQUEST_URI']) : null;
75 $apiVersion = in_array($requestedVersion, [ApiVersion::V1, ApiVersion::V2]) ? $requestedVersion : ApiVersion::V1;
78 $BASE_PATH =
"/repo/api/v" .$apiVersion;
80 const AUTH_METHOD =
"JWT_TOKEN";
82 $GLOBALS[
'apiBasePath'] = $BASE_PATH;
84 $startTime = microtime(
true);
91 $timingLogger = $container->get(
"log.timing");
92 $timingLogger->logWithStartTime(
"bootstrap", $startTime);
95 $loader = $container->get(
'twig.loader');
96 $loader->addPath(dirname(__FILE__, 2) .
'/template');
100 $error =
ConfigInit($GLOBALS[
'SYSCONFDIR'], $SysConf,
false);
104 $dbConnected =
false;
107 $timingLogger->toc(
"setup init");
109 $timingLogger->tic();
114 AppFactory::setContainer($container);
115 AppFactory::setResponseFactory(
new ResponseFactoryHelper());
116 $app = AppFactory::create();
117 $app->setBasePath($BASE_PATH);
120 $apiVersionMiddleware =
function (Request $request, RequestHandler $handler) use ($apiVersion) {
121 $request = $request->withAttribute(ApiVersion::ATTRIBUTE_NAME, $apiVersion);
122 return $handler->handle($request);
141 $app->add(
new FossologyInitMiddleware());
143 $app->add(
new RestAuthMiddleware());
145 $app->add(
new ContentLengthMiddleware());
147 $app->add($apiVersionMiddleware);
151 $app->get(
'/health',
function($req, $res) {
152 $handler =
new InfoController($GLOBALS[
'container']);
153 return $handler->getHealth($req, $res, -1);
156 $app->any(
'{route:.*}',
function(ServerRequestInterface $req, ResponseHelper $res) {
157 $error =
new Info(503,
"Unable to connect to DB.", InfoType::ERROR);
158 return $res->withJson($error->getArray(), $error->getCode());
167 $pattern =
"[\\w\\d\\-\\.@_]+}";
170 $app->options(
'/{routes:.+}', AuthController::class .
':optionsVerification');
173 $app->post(
'/tokens', AuthController::class .
':createNewJwtToken');
176 $app->group(
'/uploads',
177 function (\Slim\Routing\RouteCollectorProxy $app) {
178 $app->get(
'[/{id:\\d+}]', UploadController::class .
':getUploads');
179 $app->delete(
'/{id:\\d+}', UploadController::class .
':deleteUpload');
180 $app->patch(
'/{id:\\d+}', UploadController::class .
':updateUpload');
181 $app->put(
'/{id:\\d+}', UploadController::class .
':moveUpload');
182 $app->post(
'', UploadController::class .
':postUpload');
183 $app->post(
'/oneshot/nomos', OneShotController::class .
':runOneShotNomos');
184 $app->post(
'/oneshot/monk', OneShotController::class .
':runOneShotMonk');
185 $app->post(
'/oneshot/ceu', OneShotController::class .
':runOneShotCEU');
186 $app->put(
'/{id:\\d+}/permissions', UploadController::class .
':setUploadPermissions');
187 $app->get(
'/{id:\\d+}/perm-groups', UploadController::class .
':getGroupsWithPermissions');
188 $app->get(
'/{id:\\d+}/groups/permission', UploadController::class .
':getGroupsWithPermissions');
189 $app->get(
'/{id:\\d+}/summary', UploadController::class .
':getUploadSummary');
190 $app->get(
'/{id:\\d+}/agents', UploadController::class .
':getAllAgents');
191 $app->get(
'/{id:\\d+}/agents/revision', UploadController::class .
':getAgentsRevision');
192 $app->get(
'/{id:\\d+}/licenses', UploadController::class .
':getUploadLicenses');
193 $app->get(
'/{id:\\d+}/licenses/histogram', UploadController::class .
':getLicensesHistogram');
194 $app->get(
'/{id:\\d+}/licenses/edited', UploadController::class .
':getEditedLicenses');
195 $app->get(
'/{id:\\d+}/licenses/reuse', UploadController::class .
':getReuseReportSummary');
196 $app->get(
'/{id:\\d+}/licenses/scanned', UploadController::class .
':getScannedLicenses');
197 $app->get(
'/{id:\\d+}/licenses/main', UploadController::class .
':getMainLicenses');
198 $app->post(
'/{id:\\d+}/licenses/main', UploadController::class .
':setMainLicense');
199 $app->get(
'/{id:\\d+}/download', UploadController::class .
':uploadDownload');
200 $app->get(
'/{id:\\d+}/clearing-progress', UploadController::class .
':getClearingProgressInfo');
201 $app->delete(
'/{id:\\d+}/licenses/{shortName:[\\w\\- \\.]+}/main', UploadController::class .
':removeMainLicense');
202 $app->get(
'/{id:\\d+}/topitem', UploadController::class .
':getTopItem');
203 $app->put(
'/{id:\\d+}/item/{itemId:\\d+}/licenses', UploadTreeController::class .
':handleAddEditAndDeleteLicenseDecision');
204 $app->get(
'/{id:\\d+}/item/{itemId:\\d+}/view', UploadTreeController::class.
':viewLicenseFile');
205 $app->get(
'/{id:\\d+}/item/{itemId:\\d+}/prev-next', UploadTreeController::class .
':getNextPreviousItem');
206 $app->get(
'/{id:\\d+}/item/{itemId:\\d+}/licenses', UploadTreeController::class .
':getLicenseDecisions');
207 $app->put(
'/{id:\\d+}/item/{itemId:\\d+}/clearing-decision', UploadTreeController::class .
':setClearingDecision');
208 $app->get(
'/{id:\\d+}/item/{itemId:\\d+}/bulk-history', UploadTreeController::class .
':getBulkHistory');
209 $app->get(
'/{id:\\d+}/item/{itemId:\\d+}/clearing-history', UploadTreeController::class .
':getClearingHistory');
210 $app->get(
'/{id:\\d+}/item/{itemId:\\d+}/highlight', UploadTreeController::class .
':getHighlightEntries');
211 $app->get(
'/{id:\\d+}/item/{itemId:\\d+}/tree/view', UploadTreeController::class .
':getTreeView');
212 $app->get(
'/{id:\\d+}/item/{itemId:\\d+}/info', FileInfoController::class .
':getItemInfo');
213 $app->post(
'/{id:\\d+}/item/{itemId:\\d+}/bulk-scan', UploadTreeController::class .
':scheduleBulkScan');
214 $app->get(
'/{id:\\d+}/conf', ConfController::class .
':getConfInfo');
215 $app->put(
'/{id:\\d+}/conf', ConfController::class .
':updateConfData');
216 $app->get(
'/{id:\\d+}/copyrights', UploadController::class .
':getUploadCopyrights');
218 $app->group(
'/{id:\\d+}/item/{itemId:\\d+}',
function (\Slim\Routing\RouteCollectorProxy $app) {
219 $app->get(
'/copyrights', CopyrightController::class .
':getFileCopyrights');
220 $app->delete(
'/copyrights/{hash:.*}', CopyrightController::class .
':deleteFileCopyright');
221 $app->patch(
'/copyrights/{hash:.*}', CopyrightController::class .
':restoreFileCopyright');
222 $app->put(
'/copyrights/{hash:.*}', CopyrightController::class .
':updateFileCopyright');
223 $app->get(
'/totalcopyrights', CopyrightController::class .
':getTotalFileCopyrights');
224 $app->get(
'/scancode-copyrights', CopyrightController::class .
':getFileScanCodeCopyrights');
225 $app->delete(
'/scancode-copyrights/{hash:.*}', CopyrightController::class .
':deleteFileScanCodeCopyright');
226 $app->patch(
'/scancode-copyrights/{hash:.*}', CopyrightController::class .
':restoreFileScanCodeCopyright');
227 $app->put(
'/scancode-copyrights/{hash:.*}', CopyrightController::class .
':updateFileScanCodeCopyright');
228 $app->get(
'/user-copyrights', CopyrightController::class .
':getFileUserCopyrights');
229 $app->delete(
'/user-copyrights/{hash:.*}', CopyrightController::class .
':deleteFileUserCopyright');
230 $app->patch(
'/user-copyrights/{hash:.*}', CopyrightController::class .
':restoreFileUserCopyright');
231 $app->put(
'/user-copyrights/{hash:.*}', CopyrightController::class .
':updateFileUserCopyright');
232 $app->get(
'/totalusercopyrights', CopyrightController::class .
':getTotalFileUserCopyrights');
233 $app->get(
'/emails', CopyrightController::class .
':getFileEmail');
234 $app->delete(
'/emails/{hash:.*}', CopyrightController::class .
':deleteFileEmail');
235 $app->patch(
'/emails/{hash:.*}', CopyrightController::class .
':restoreFileEmail');
236 $app->put(
'/emails/{hash:.*}', CopyrightController::class .
':updateFileEmail');
237 $app->get(
'/scancode-emails', CopyrightController::class .
':getFileScanCodeEmail');
238 $app->delete(
'/scancode-emails/{hash:.*}', CopyrightController::class .
':deleteFileScanCodeEmail');
239 $app->patch(
'/scancode-emails/{hash:.*}', CopyrightController::class .
':restoreFileScanCodeEmail');
240 $app->put(
'/scancode-emails/{hash:.*}', CopyrightController::class .
':updateFileScanCodeEmail');
241 $app->get(
'/urls', CopyrightController::class .
':getFileUrl');
242 $app->delete(
'/urls/{hash:.*}', CopyrightController::class .
':deleteFileUrl');
243 $app->patch(
'/urls/{hash:.*}', CopyrightController::class .
':restoreFileUrl');
244 $app->put(
'/urls/{hash:.*}', CopyrightController::class .
':updateFileUrl');
245 $app->get(
'/scancode-urls', CopyrightController::class .
':getFileScanCodeUrl');
246 $app->delete(
'/scancode-urls/{hash:.*}', CopyrightController::class .
':deleteFileScanCodeUrl');
247 $app->patch(
'/scancode-urls/{hash:.*}', CopyrightController::class .
':restoreFileScanCodeUrl');
248 $app->put(
'/scancode-urls/{hash:.*}', CopyrightController::class .
':updateFileScanCodeUrl');
249 $app->get(
'/authors', CopyrightController::class .
':getFileAuthor');
250 $app->delete(
'/authors/{hash:.*}', CopyrightController::class .
':deleteFileAuthor');
251 $app->patch(
'/authors/{hash:.*}', CopyrightController::class .
':restoreFileAuthor');
252 $app->put(
'/authors/{hash:.*}', CopyrightController::class .
':updateFileAuthor');
253 $app->get(
'/scancode-authors', CopyrightController::class .
':getFileScanCodeAuthor');
254 $app->delete(
'/scancode-authors/{hash:.*}', CopyrightController::class .
':deleteFileScanCodeAuthor');
255 $app->patch(
'/scancode-authors/{hash:.*}', CopyrightController::class .
':restoreFileScanCodeAuthor');
256 $app->put(
'/scancode-authors/{hash:.*}', CopyrightController::class .
':updateFileScanCodeAuthor');
257 $app->get(
'/eccs', CopyrightController::class .
':getFileEcc');
258 $app->delete(
'/eccs/{hash:.*}', CopyrightController::class .
':deleteFileEcc');
259 $app->patch(
'/eccs/{hash:.*}', CopyrightController::class .
':restoreFileEcc');
260 $app->put(
'/eccs/{hash:.*}', CopyrightController::class .
':updateFileEcc');
261 $app->get(
'/keywords', CopyrightController::class .
':getFileKeyword');
262 $app->delete(
'/keywords/{hash:.*}', CopyrightController::class .
':deleteFileKeyword');
263 $app->patch(
'/keywords/{hash:.*}', CopyrightController::class .
':restoreFileKeyword');
264 $app->put(
'/keywords/{hash:.*}', CopyrightController::class .
':updateFileKeyword');
265 $app->get(
'/ipras', CopyrightController::class .
':getFileIpra');
266 $app->delete(
'/ipras/{hash:.*}', CopyrightController::class .
':deleteFileIpra');
267 $app->patch(
'/ipras/{hash:.*}', CopyrightController::class .
':restoreFileIpra');
268 $app->put(
'/ipras/{hash:.*}', CopyrightController::class .
':updateFileIpra');
270 $app->any(
'/{params:.*}', BadRequestController::class);
275 $app->group(
'/users',
276 function (\Slim\Routing\RouteCollectorProxy $app) use ($pattern) {
277 $app->get(
'/self', UserController::class .
':getCurrentUser');
278 $app->get(
"[/{pathParam:$pattern]", UserController::class .
':getUsers');
279 $app->put(
"/{pathParam:$pattern", UserController::class .
':updateUser');
280 $app->post(
'', UserController::class .
':addUser');
281 $app->delete(
"/{pathParam:$pattern", UserController::class .
':deleteUser');
282 $app->post(
'/tokens', UserController::class .
':createRestApiToken');
283 $app->get(
'/tokens/{type:\\w+}', UserController::class .
':getTokens');
284 $app->any(
'/{params:.*}', BadRequestController::class);
288 $app->group(
'/obligations',
289 function (\Slim\Routing\RouteCollectorProxy $app) {
290 $app->get(
'/list', ObligationController::class .
':obligationsList');
291 $app->get(
'/{id:\\d+}', ObligationController::class .
':obligationsDetails');
292 $app->get(
'', ObligationController::class .
':obligationsAllDetails');
293 $app->delete(
'/{id:\\d+}', ObligationController::class .
':deleteObligation');
294 $app->get(
'/export-csv', ObligationController::class .
':exportObligationsToCSV');
295 $app->post(
'/import-csv', ObligationController::class .
':importObligationsFromCSV');
296 $app->get(
'/export-json', ObligationController::class .
':exportObligationsToJSON');
297 $app->post(
'/import-json', ObligationController::class .
':importObligationsFromJSON');
298 $app->any(
'/{params:.*}', BadRequestController::class);
302 $app->group(
'/groups',
303 function (\Slim\Routing\RouteCollectorProxy $app) use ($pattern) {
304 $app->get(
'', GroupController::class .
':getGroups');
305 $app->post(
'', GroupController::class .
':createGroup');
306 $app->post(
"/{pathParam:$pattern/user/{userPathParam:$pattern", GroupController::class .
':addMember');
307 $app->delete(
"/{pathParam:$pattern", GroupController::class .
':deleteGroup');
308 $app->delete(
"/{pathParam:$pattern/user/{userPathParam:$pattern", GroupController::class .
':deleteGroupMember');
309 $app->get(
'/deletable', GroupController::class .
':getDeletableGroups');
310 $app->get(
"/{pathParam:$pattern/members", GroupController::class .
':getGroupMembers');
311 $app->put(
"/{pathParam:$pattern/user/{userPathParam:$pattern", GroupController::class .
':changeUserPermission');
312 $app->any(
'/{params:.*}', BadRequestController::class);
317 function (\Slim\Routing\RouteCollectorProxy $app) {
318 $app->get(
'[/{id:\\d+}]', JobController::class .
':getJobs');
319 $app->get(
'/all', JobController::class .
':getAllJobs');
320 $app->get(
'/dashboard/statistics', JobController::class .
':getJobStatistics');
321 $app->get(
'/scheduler/operation/{operationName:[\\w\\- \\.]+}', JobController::class .
':getSchedulerJobOptionsByOperation');
322 $app->post(
'/scheduler/operation/run', JobController::class .
':handleRunSchedulerOption');
323 $app->post(
'', JobController::class .
':createJob');
324 $app->get(
'/history', JobController::class .
':getJobsHistory');
325 $app->get(
'/dashboard', JobController::class .
':getAllServerJobsStatus');
326 $app->delete(
'/{id:\\d+}/{queue:\\d+}', JobController::class .
':deleteJob');
327 $app->any(
'/{params:.*}', BadRequestController::class);
331 $app->group(
'/search',
332 function (\Slim\Routing\RouteCollectorProxy $app) {
333 $app->get(
'', SearchController::class .
':performSearch');
337 $app->group(
'/maintenance',
338 function (\Slim\Routing\RouteCollectorProxy $app) {
339 $app->post(
'', MaintenanceController::class .
':createMaintenance');
340 $app->any(
'/{params:.*}', BadRequestController::class);
345 $app->group(
'/folders',
346 function (\Slim\Routing\RouteCollectorProxy $app) {
347 $app->get(
'[/{id:\\d+}]', FolderController::class .
':getFolders');
348 $app->post(
'', FolderController::class .
':createFolder');
349 $app->delete(
'/{id:\\d+}', FolderController::class .
':deleteFolder');
350 $app->patch(
'/{id:\\d+}', FolderController::class .
':editFolder');
351 $app->put(
'/{id:\\d+}', FolderController::class .
':copyFolder');
352 $app->get(
'/{id:\\d+}/contents/unlinkable', FolderController::class .
':getUnlinkableFolderContents');
353 $app->put(
'/contents/{contentId:\\d+}/unlink', FolderController::class .
':unlinkFolder');
354 $app->get(
'/{id:\\d+}/contents', FolderController::class .
':getAllFolderContents');
355 $app->any(
'/{params:.*}', BadRequestController::class);
359 $app->group(
'/report',
360 function (\Slim\Routing\RouteCollectorProxy $app) {
361 $app->get(
'', ReportController::class .
':getReport');
362 $app->get(
'/{id:\\d+}', ReportController::class .
':downloadReport');
363 $app->post(
'/import', ReportController::class .
':importReport');
364 $app->any(
'/{params:.*}', BadRequestController::class);
368 $app->group(
'/customise',
369 function (\Slim\Routing\RouteCollectorProxy $app) {
370 $app->get(
'', CustomiseController::class .
':getCustomiseData');
371 $app->put(
'', CustomiseController::class .
':updateCustomiseData');
372 $app->get(
'/banner', CustomiseController::class .
':getBannerMessage');
373 $app->any(
'/{params:.*}', BadRequestController::class);
378 function (\Slim\Routing\RouteCollectorProxy $app) {
379 $app->get(
'', InfoController::class .
':getInfo');
381 $app->group(
'/health',
382 function (\Slim\Routing\RouteCollectorProxy $app) {
383 $app->get(
'', InfoController::class .
':getHealth');
385 $app->group(
'/openapi',
386 function (\Slim\Routing\RouteCollectorProxy $app) {
387 $app->get(
'', InfoController::class .
':getOpenApi');
391 $app->group(
'/filesearch',
392 function (\Slim\Routing\RouteCollectorProxy $app) {
393 $app->post(
'', FileSearchController::class .
':getFiles');
394 $app->any(
'/{params:.*}', BadRequestController::class);
398 $app->group(
'/license',
399 function (\Slim\Routing\RouteCollectorProxy $app) {
400 $app->get(
'', LicenseController::class .
':getAllLicenses');
401 $app->post(
'/import-csv', LicenseController::class .
':handleImportLicense');
402 $app->get(
'/export-csv', LicenseController::class .
':exportAdminLicenseToCSV');
403 $app->post(
'/import-json', LicenseController::class .
':handleImportLicense');
404 $app->get(
'/export-json', LicenseController::class .
':exportAdminLicenseToJSON');
405 $app->post(
'', LicenseController::class .
':createLicense');
406 $app->put(
'/verify/{shortname:.+}', LicenseController::class .
':verifyLicense');
407 $app->put(
'/merge/{shortname:.+}', LicenseController::class .
':mergeLicense');
408 $app->get(
'/admincandidates', LicenseController::class .
':getCandidates');
409 $app->get(
'/adminacknowledgements', LicenseController::class .
':getAllAdminAcknowledgements');
410 $app->get(
'/stdcomments', LicenseController::class .
':getAllLicenseStandardComments');
411 $app->put(
'/stdcomments', LicenseController::class .
':handleLicenseStandardComment');
412 $app->post(
'/suggest', LicenseController::class .
':getSuggestedLicense');
413 $app->get(
'/{shortname:.+}', LicenseController::class .
':getLicense');
414 $app->patch(
'/{shortname:.+}', LicenseController::class .
':updateLicense');
415 $app->delete(
'/admincandidates/{id:\\d+}',
416 LicenseController::class .
':deleteAdminLicenseCandidate');
417 $app->put(
'/adminacknowledgements', LicenseController::class .
':handleAdminLicenseAcknowledgement');
418 $app->any(
'/{params:.*}', BadRequestController::class);
422 $app->group(
'/overview',
423 function (\Slim\Routing\RouteCollectorProxy $app) {
424 $app->get(
'/database/contents', OverviewController::class .
':getDatabaseContents');
425 $app->get(
'/disk/usage', OverviewController::class .
':getDiskSpaceUsage');
426 $app->get(
'/info/php', OverviewController::class .
':getPhpInfo');
427 $app->get(
'/database/metrics', OverviewController::class .
':getDatabaseMetrics');
428 $app->get(
'/queries/active', OverviewController::class .
':getActiveQueries');
429 $app->any(
'/{params:.*}', BadRequestController::class);
434 $customErrorHandler =
function (
435 ServerRequestInterface $request,
436 Throwable $exception,
437 bool $displayErrorDetails,
439 bool $logErrorDetails,
440 ?LoggerInterface $logger = null
442 if ($logger ===
null) {
443 $logger = $app->getContainer()->get(
'logger');
446 $logger->error($exception->getMessage(), $exception->getTrace());
448 if ($displayErrorDetails) {
449 $payload = [
'error'=> $exception->getMessage(),
450 'trace' => $exception->getTraceAsString()];
452 $error =
new Info(500,
"Something went wrong! Please try again later.",
454 $payload = $error->getArray();
457 $response = $app->getResponseFactory()->createResponse(500)
458 ->withHeader(
"Content-Type",
"application/json");
459 $response->getBody()->write(
460 json_encode($payload, JSON_UNESCAPED_UNICODE)
467 $errorMiddleware = $app->addErrorMiddleware(
false,
true,
true,
468 $container->get(
"logger"));
471 $errorMiddleware->setErrorHandler(
472 HttpNotFoundException::class,
473 function (ServerRequestInterface $request, Throwable $exception,
bool $displayErrorDetails) {
474 $response =
new ResponseHelper();
475 $error =
new Info(404,
"Resource not found", InfoType::ERROR);
476 $response = $response->withJson($error->getArray(), $error->getCode());
482 $errorMiddleware->setErrorHandler(
483 HttpMethodNotAllowedException::class,
484 function (ServerRequestInterface $request, Throwable $exception,
bool $displayErrorDetails) {
485 $response =
new Response();
486 $response->getBody()->write(
'405 NOT ALLOWED');
488 $response = $response->withStatus(405);
494 $errorMiddleware->setErrorHandler(
495 HttpErrorException::class,
496 function (ServerRequestInterface $request, HttpErrorException $exception,
bool $displayErrorDetails) {
497 $response =
new ResponseHelper();
498 $error =
new Info($exception->getCode(), $exception->getMessage(),
500 $response = $response->withJson($error->getArray(), $error->getCode());
501 if (!empty($exception->getHeaders())) {
502 foreach ($exception->getHeaders() as $key => $value) {
503 $response = $response->withHeader($key, $value);
511 $errorMiddleware->setDefaultErrorHandler($customErrorHandler);
515 $GLOBALS[
'container']->get(
"db.manager")->flushStats();
Controller for Auth requests.
Controller for file searching.
Controller for Folder model.
Controller for Group model.
Controller for REST API version.
Controller for Job model.
Controller for OneShot Analysis.
Controller for OverviewController model.
Controller for Maintenance model.
Controller for Search model.
Controller for Upload model.
Controller for UploadTree model.
Controller for User model.
static addCorsHeaders(ResponseInterface $response)
Override Slim response factory for custom response.
Override Slim response for withJson function.
Middleware to initialize FOSSology for Slim framework.
Authentication middleware for Slim framework.
Different type of infos provided by REST.
Info model to contain general error and return values.
plugin_load()
Load every module ui found in mods-enabled.
ConfigInit($sysconfdir, &$SysConf, $exitOnDbFail=true)
Initialize the fossology system after bootstrap().
bootstrap($sysconfdir="")
Bootstrap the fossology php library.