FOSSology  4.4.0
Open Source License Compliance by Open Source Software
DbHelper.php
Go to the documentation of this file.
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2017 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
12 namespace Fossology\UI\Api\Helper;
13 
14 require_once dirname(dirname(dirname(dirname(__DIR__)))) .
15  "/lib/php/common-db.php";
16 
32 
37 class DbHelper
38 {
43  private $dbManager;
44 
49  private $folderDao;
50 
55  private $uploadDao;
56 
66  {
67  $this->dbManager = $dbManager;
68  $this->folderDao = $folderDao;
69  $this->uploadDao = $uploadDao;
70  }
71 
77  public function getDbManager()
78  {
79  return $this->dbManager;
80  }
81 
97  public function getUploads($userId, $groupId, $limit, $page = 1,
98  $uploadId = null, $options = null, $recursive = true, $apiVersion=ApiVersion::V1)
99  {
100  $uploadProxy = new UploadBrowseProxy($groupId, 0, $this->dbManager);
101  $folderId = $options["folderId"];
102  if ($folderId === null) {
103  $users = $this->getUsers($userId);
104  $folderId = $users[0]->getRootFolderId();
105  }
106  $folders = [$folderId];
107 
108  if ($uploadId !== null) {
109  $recursive = true;
110  $users = $this->getUsers($userId);
111  $folderId = $users[0]->getRootFolderId();
112  $folders = [$folderId];
113  }
114 
115  if ($recursive) {
116  $tree = $this->folderDao->getFolderStructure($folderId);
117  $folders = array_map(function ($folder) {
118  return $folder[$this->folderDao::FOLDER_KEY]->getId();
119  }, $tree);
120  }
121 
122  $params = [$folders];
123  $partialQuery = $uploadProxy->getFolderPartialQuery($params);
124 
125  $where = "";
126  $statementCount = __METHOD__ . ".countAllUploads";
127  $statementGet = __METHOD__ . ".getAllUploads.$limit";
128  if ($uploadId !== null) {
129  $params[] = $uploadId;
130  $where .= " AND upload.upload_pk = $" . count($params);
131  $statementGet .= ".upload";
132  $statementCount .= ".upload";
133  }
134  if (! empty($options["name"])) {
135  $params[] = strtolower("%" . $options["name"] . "%");
136  $where .= " AND (LOWER(upload_desc) LIKE $" . count($params) .
137  " OR LOWER(ufile_name) LIKE $" . count($params) .
138  " OR LOWER(upload_filename) LIKE $" . count($params) . ")";
139  $statementGet .= ".name";
140  $statementCount .= ".name";
141  }
142  if (! empty($options["status"])) {
143  $params[] = $options["status"];
144  $where .= " AND status_fk = $" . count($params);
145  $statementGet .= ".stat";
146  $statementCount .= ".stat";
147  }
148  if (! empty($options["assignee"])) {
149  $params[] = $options["assignee"];
150  $where .= " AND assignee = $" . count($params);
151  $statementGet .= ".assi";
152  $statementCount .= ".assi";
153  }
154  if (! empty($options["since"])) {
155  $params[] = $options["since"];
156  $where .= " AND upload_ts >= to_timestamp($" . count($params) . ")";
157  $statementGet .= ".since";
158  $statementCount .= ".since";
159  }
160  $sql = "SELECT count(*) AS cnt FROM $partialQuery $where;";
161  $totalResult = $this->dbManager->getSingleRow($sql, $params, $statementCount);
162  $totalResult = intval($totalResult['cnt']);
163  $totalResult = intval(ceil($totalResult / $limit));
164 
165  $params[] = ($page - 1) * $limit;
166 
167  $sql = "SELECT
168 upload.upload_pk, upload.upload_desc, upload.upload_ts, upload.upload_filename, upload_clearing.assignee
169 FROM $partialQuery $where ORDER BY upload_pk ASC LIMIT $limit OFFSET $" .
170  count($params) . ";";
171  $results = $this->dbManager->getRows($sql, $params, $statementGet);
172  $uploads = [];
173  foreach ($results as $row) {
174  $uploadId = $row["upload_pk"];
175  $pfile_size = null;
176  $pfile_sha1 = null;
177  $pfile_md5 = null;
178  $pfile_sha256 = null;
179  $pfile = $this->getPfileInfoForUpload($uploadId);
180  if ($pfile !== null) {
181  $pfile_size = $pfile['pfile_size'];
182  $pfile_sha1 = $pfile['pfile_sha1'];
183  $pfile_md5 = $pfile['pfile_md5'];
184  $pfile_sha256 = $pfile['pfile_sha256'];
185  }
186 
187  $folder = $this->getFolderForUpload($uploadId);
188  if ($folder === null) {
189  continue;
190  }
191  $folderId = $folder->getId();
192  $folderName = $folder->getName();
193 
194  $hash = new Hash($pfile_sha1, $pfile_md5, $pfile_sha256, $pfile_size);
195  $upload = new Upload($folderId, $folderName, $uploadId,
196  $row["upload_desc"], $row["upload_filename"], $row["upload_ts"], $row["assignee"], $hash);
197  if (! empty($row["assignee"]) && $row["assignee"] != 1) {
198  $upload->setAssigneeDate($this->uploadDao->getAssigneeDate($uploadId));
199  }
200  $upload->setClosingDate($this->uploadDao->getClosedDate($uploadId));
201  $uploads[] = $upload->getArray($apiVersion);
202  }
203  return [$totalResult, $uploads];
204  }
205 
212  public function getFilenameFromUploadTree($uploadTreePk)
213  {
214  return $this->dbManager->getSingleRow(
215  "SELECT DISTINCT ufile_name FROM uploadtree
216 WHERE uploadtree_pk=$1", [$uploadTreePk])["ufile_name"];
217  }
218 
227  public function doesIdExist($tableName, $idRowName, $id)
228  {
229  return (0 < (intval($this->getDbManager()->getSingleRow("SELECT COUNT(*)
230 FROM $tableName WHERE $idRowName = $1", [$id],
231  __METHOD__ . $tableName . $idRowName)["count"])));
232  }
233 
239  public function deleteUser($id)
240  {
241  require_once dirname(dirname(__DIR__)) . "/user-del-helper.php";
242  deleteUser($id, $this->getDbManager());
243  }
244 
252  public function getUsers($id = null)
253  {
254  if ($id == null) {
255  $usersSQL = "SELECT user_pk, user_name, user_desc, user_email,
256  email_notify, root_folder_fk, group_fk, user_perm, user_agent_list, default_bucketpool_fk FROM users;";
257  $statement = __METHOD__ . ".getAllUsers";
258  } else {
259  $usersSQL = "SELECT user_pk, user_name, user_desc, user_email,
260  email_notify, root_folder_fk, group_fk, user_perm, user_agent_list, default_bucketpool_fk FROM users
261  WHERE user_pk = $1;";
262  $statement = __METHOD__ . ".getSpecificUser";
263  }
264  $users = [];
265  if ($id === null) {
266  $result = $this->dbManager->getRows($usersSQL, [], $statement);
267  } else {
268  $result = $this->dbManager->getRows($usersSQL, [$id], $statement);
269  }
270  $currentUser = Auth::getUserId();
271  $userIsAdmin = Auth::isAdmin();
272  foreach ($result as $row) {
273  $user = null;
274  if ($userIsAdmin ||
275  ($row["user_pk"] == $currentUser)) {
276  $user = new User($row["user_pk"], $row["user_name"], $row["user_desc"],
277  $row["user_email"], $row["user_perm"], $row["root_folder_fk"],
278  $row["email_notify"], $row["user_agent_list"], $row["group_fk"], $row["default_bucketpool_fk"]);
279  } else {
280  $user = new User($row["user_pk"], $row["user_name"], $row["user_desc"],
281  null, null, null, null, null, null);
282  }
283  $users[] = $user;
284  }
285 
286  return $users;
287  }
288 
302  public function getJobs($id = null, $limit = 0, $page = 1, $uploadId = null)
303  {
304  $jobSQL = "SELECT job_pk, job_queued, job_name, job_upload_fk," .
305  " job_user_fk, job_group_fk FROM job";
306  $totalJobSql = "SELECT count(*) AS cnt FROM job";
307 
308  $filter = "";
309  $pagination = "";
310 
311  $params = [];
312  $statement = __METHOD__ . ".getJobs";
313  $countStatement = __METHOD__ . ".getJobCount";
314  if ($id == null) {
315  if ($uploadId !== null) {
316  $params[] = $uploadId;
317  $filter = "WHERE job_upload_fk = $" . count($params);
318  $statement .= ".withUploadFilter";
319  $countStatement .= ".withUploadFilter";
320  }
321  } else {
322  $params[] = $id;
323  $filter = "WHERE job_pk = $" . count($params);
324  $statement .= ".withJobFilter";
325  $countStatement .= ".withJobFilter";
326  }
327 
328  $result = $this->dbManager->getSingleRow("$totalJobSql $filter;", $params,
329  $countStatement);
330 
331  $totalResult = $result['cnt'];
332 
333  $offset = ($page - 1) * $limit;
334  if ($limit > 0) {
335  $params[] = $limit;
336  $pagination = "LIMIT $" . count($params);
337  $params[] = $offset;
338  $pagination .= " OFFSET $" . count($params);
339  $statement .= ".withLimit";
340  $totalResult = ceil($totalResult / $limit);
341  } else {
342  $totalResult = 1;
343  }
344 
345  $jobs = [];
346  $result = $this->dbManager->getRows("$jobSQL $filter $pagination;", $params,
347  $statement);
348  foreach ($result as $row) {
349  $job = new Job($row["job_pk"]);
350  $job->setName($row["job_name"]);
351  $job->setQueueDate($row["job_queued"]);
352  $job->setUploadId($row["job_upload_fk"]);
353  $job->setUserId($row["job_user_fk"]);
354  $job->setGroupId($row["job_group_fk"]);
355  $jobs[] = $job;
356  }
357  return [$jobs, $totalResult];
358  }
359 
374  public function getUserJobs($id = null, $uid=null, $limit = 0, $page = 1, $uploadId = null)
375  {
376  $jobSQL = "SELECT job_pk, job_queued, job_name, job_upload_fk," .
377  " job_user_fk, job_group_fk FROM job WHERE job_user_fk=$1";
378  $totalJobSql = "SELECT count(*) AS cnt FROM job WHERE job_user_fk=$1";
379  $filter = "";
380  $pagination = "";
381  $params = [];
382  $params[] = $uid;
383  $statement = __METHOD__ . ".getUserJobs";
384  $countStatement = __METHOD__ . ".getJobCount";
385  if ($id == null) {
386  if ($uploadId !== null) {
387  $params[] = $uploadId;
388  $filter = "WHERE job_upload_fk = $" . count($params);
389  $statement .= ".withUploadFilter";
390  $countStatement .= ".withUploadFilter";
391  }
392  } else {
393  $params[] = $id;
394  $filter = "WHERE job_pk = $" . count($params);
395  $statement .= ".withJobFilter";
396  $countStatement .= ".withJobFilter";
397  }
398 
399  $result = $this->dbManager->getSingleRow("$totalJobSql $filter;", $params,
400  $countStatement);
401 
402  $totalResult = $result['cnt'];
403 
404  $offset = ($page - 1) * $limit;
405  if ($limit > 0) {
406  $params[] = $limit;
407  $pagination = "LIMIT $" . count($params);
408  $params[] = $offset;
409  $pagination .= " OFFSET $" . count($params);
410  $statement .= ".withLimit";
411  $totalResult = ceil($totalResult / $limit);
412  } else {
413  $totalResult = 1;
414  }
415 
416  $jobs = [];
417  $result = $this->dbManager->getRows("$jobSQL $filter $pagination;", $params,
418  $statement);
419  foreach ($result as $row) {
420  $job = new Job($row["job_pk"]);
421  $job->setName($row["job_name"]);
422  $job->setQueueDate($row["job_queued"]);
423  $job->setUploadId($row["job_upload_fk"]);
424  $job->setUserId($row["job_user_fk"]);
425  $job->setGroupId($row["job_group_fk"]);
426  $jobs[] = $job;
427  }
428  return [$jobs, $totalResult];
429  }
430 
438  public function getTokenKey($tokenId)
439  {
440  $sql = "SELECT token_key, client_id, created_on, expire_on, user_fk, active, token_scope " .
441  "FROM personal_access_tokens WHERE pat_pk = $1;";
442  return $this->dbManager->getSingleRow($sql, [$tokenId],
443  __METHOD__ . ".getTokenSecret");
444  }
445 
451  public function invalidateToken($tokenId)
452  {
453  $sql = "UPDATE personal_access_tokens SET active = false WHERE pat_pk = $1;";
454  $this->dbManager->getSingleRow($sql, [$tokenId], __METHOD__ . ".invalidateToken");
455  }
456 
472  public function insertNewTokenKey($userId, $expire, $scope, $name, $key)
473  {
474  if (! $this->checkTokenNameUnique($userId, $name)) {
475  throw new DuplicateTokenNameException(
476  "Already have a token with same name.", 409);
477  }
478  if (! $this->checkTokenKeyUnique($userId, $name)) {
479  throw new DuplicateTokenKeyException();
480  }
481  $sql = "INSERT INTO personal_access_tokens " .
482  "(user_fk, created_on, expire_on, token_scope, token_name, token_key, active) " .
483  "VALUES ($1, NOW(), $2, $3, $4, $5, true) " .
484  "RETURNING pat_pk || '.' || user_fk AS jti, created_on";
485  return $this->dbManager->getSingleRow($sql, [
486  $userId, $expire, $scope, $name, $key
487  ], __METHOD__ . ".insertNewToken");
488  }
489 
498  public function addNewClient($name, $userId, $clientId, $scope)
499  {
500  $sql = "INSERT INTO personal_access_tokens" .
501  "(user_fk, created_on, token_scope, token_name, client_id, active)" .
502  "VALUES ($1, NOW(), $2, $3, $4, true);";
503  $this->dbManager->getSingleRow($sql, [
504  $userId, $scope, $name, $clientId
505  ], __METHOD__);
506  }
507 
516  private function checkTokenNameUnique($userId, $tokenName)
517  {
518  $tokenIsUnique = true;
519  $sql = "SELECT count(*) AS cnt FROM personal_access_tokens " .
520  "WHERE user_fk = $1 AND token_name = $2;";
521  $result = $this->dbManager->getSingleRow($sql, [$userId, $tokenName],
522  __METHOD__ . ".checkTokenNameUnique");
523  if ($result['cnt'] != 0) {
524  $tokenIsUnique = false;
525  }
526  return $tokenIsUnique;
527  }
528 
537  private function checkTokenKeyUnique($userId, $tokenKey)
538  {
539  $tokenIsUnique = true;
540  $sql = "SELECT count(*) AS cnt FROM personal_access_tokens " .
541  "WHERE user_fk = $1 AND token_key = $2;";
542  $result = $this->dbManager->getSingleRow($sql, [$userId, $tokenKey],
543  __METHOD__ . ".checkTokenKeyUnique");
544  if ($result['cnt'] != 0) {
545  $tokenIsUnique = false;
546  }
547  return $tokenIsUnique;
548  }
549 
555  public function getMaxTokenValidity()
556  {
557  $sql = "SELECT conf_value FROM sysconfig WHERE variablename = $1;";
558  $result = $this->dbManager->getSingleRow($sql, ["PATMaxExipre"],
559  __METHOD__ . ".tokenMaxValidFromSysconfig");
560  $validity = 30;
561  if (! empty($result['conf_value'])) {
562  $validity = intval($result['conf_value']);
563  }
564  return $validity;
565  }
566 
572  public function getPfileInfoForUpload($uploadId)
573  {
574  $sql = "SELECT pfile.* FROM upload INNER JOIN pfile " .
575  "ON pfile_fk = pfile_pk WHERE upload_pk = $1;";
576  $result = $this->dbManager->getSingleRow($sql, [$uploadId],
577  __METHOD__ . ".getPfileFromUpload");
578  if (! empty($result)) {
579  return $result;
580  }
581  return null;
582  }
583 
589  private function getFolderForUpload($uploadId)
590  {
591  $contentId = $this->folderDao->getFolderContentsId($uploadId,
592  $this->folderDao::MODE_UPLOAD);
593  $content = $this->folderDao->getContent($contentId);
594  return $this->folderDao->getFolder($content['parent_fk']);
595  }
596 
607  public function getLicensesPaginated($page, $limit, $kind, $groupId, $active)
608  {
609  $statementName = __METHOD__;
610  $rfTable = 'license_all';
611  $options = ['columns' => ['rf_pk', 'rf_shortname', 'rf_fullname', 'rf_text',
612  'rf_url', 'rf_risk', 'group_fk']];
613  if ($active) {
614  $options['extraCondition'] = "rf_active = '" .
615  $this->dbManager->booleanToDb($active) . "'";
616  }
617  if ($kind == "candidate") {
618  $options['diff'] = true;
619  } elseif ($kind == "main") {
620  $groupId = 0;
621  }
622  $licenseViewDao = new LicenseViewProxy($groupId, $options, $rfTable);
623  $withCte = $licenseViewDao->asCTE();
624 
625  return $this->dbManager->getRows($withCte .
626  " SELECT * FROM $rfTable ORDER BY LOWER(rf_shortname) " .
627  "LIMIT $1 OFFSET $2;",
628  [$limit, ($page - 1) * $limit], $statementName);
629  }
630 
638  public function getLicenseCount($kind, $groupId)
639  {
640  $sql = "SELECT sum(cnt) AS total FROM (";
641  $mainLicSql = " SELECT count(*) AS cnt FROM ONLY license_ref ";
642  $candidateLicSql = " SELECT count(*) AS cnt FROM license_candidate WHERE group_fk = $1";
643  $params = [];
644 
645  if ($kind == "main") {
646  $sql .= $mainLicSql;
647  } elseif ($kind == "candidate") {
648  $sql .= $candidateLicSql;
649  $params[] = $groupId;
650  } else {
651  $sql .= $mainLicSql . " UNION ALL " . $candidateLicSql;
652  $params[] = $groupId;
653  }
654  $sql .= ") as all_lic;";
655 
656  $statement = __METHOD__ . ".getLicenseCount.$kind";
657  $result = $this->dbManager->getSingleRow($sql, $params, $statement);
658  return intval($result['total']);
659  }
660 
661  /*
662  * Get the OAuth token ID from a client id
663  *
664  * @param string $clientId Client ID to get info for
665  * @return integer Token ID
666  */
667  public function getTokenIdFromClientId($clientId)
668  {
669  $sql = "SELECT pat_pk FROM personal_access_tokens " .
670  "WHERE client_id = $1;";
671  $result = $this->dbManager->getSingleRow($sql, [$clientId], __METHOD__);
672  if (!empty($result)) {
673  return $result['pat_pk'];
674  }
675  return null;
676  }
677 }
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
static getUserId()
Get the current user's id.
Definition: Auth.php:68
static isAdmin()
Check if user is admin.
Definition: Auth.php:92
Exception when a token has duplicate key for same user.
Exception when a token has duplicate name for same user.
Provides helper methods to access database for REST api.
Definition: DbHelper.php:38
checkTokenKeyUnique($userId, $tokenKey)
Definition: DbHelper.php:537
getFilenameFromUploadTree($uploadTreePk)
Definition: DbHelper.php:212
getLicensesPaginated($page, $limit, $kind, $groupId, $active)
Definition: DbHelper.php:607
doesIdExist($tableName, $idRowName, $id)
Definition: DbHelper.php:227
addNewClient($name, $userId, $clientId, $scope)
Definition: DbHelper.php:498
getLicenseCount($kind, $groupId)
Definition: DbHelper.php:638
getUserJobs($id=null, $uid=null, $limit=0, $page=1, $uploadId=null)
Get the recent jobs created by an user.
Definition: DbHelper.php:374
getJobs($id=null, $limit=0, $page=1, $uploadId=null)
Get the recent jobs.
Definition: DbHelper.php:302
checkTokenNameUnique($userId, $tokenName)
Definition: DbHelper.php:516
insertNewTokenKey($userId, $expire, $scope, $name, $key)
Definition: DbHelper.php:472
__construct(DbManager $dbManager, FolderDao $folderDao, UploadDao $uploadDao)
Definition: DbHelper.php:64
getUploads($userId, $groupId, $limit, $page=1, $uploadId=null, $options=null, $recursive=true, $apiVersion=ApiVersion::V1)
Definition: DbHelper.php:97
Hash model holding information about file like checksums and size.
Definition: Hash.php:18
Model class to hold Upload info.
Definition: Upload.php:17
Model to hold user information.
Definition: User.php:21
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16
REST api helper classes.