FOSSology  4.7.1
Open Source License Compliance by Open Source Software
CompatibilityDao.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2024 Siemens AG
4 
5  SPDX-License-Identifier: GPL-2.0-only
6 */
7 
8 namespace Fossology\Lib\Dao;
9 
15 use Monolog\Logger;
16 
22 {
27  const RULE_SELECT = "SELECT lr_pk, first_rf_fk, second_rf_fk,
28  lrf.rf_shortname AS first_rf_shortname,
29  lrs.rf_shortname AS second_rf_shortname, first_type, second_type,
30  comment, compatibility
31  FROM license_rules
32  LEFT JOIN license_ref lrf ON lrf.rf_pk = first_rf_fk
33  LEFT JOIN license_ref lrs ON lrs.rf_pk = second_rf_fk";
34 
36  private $dbManager;
38  private $logger;
40  private $licenseDao;
42  private $agentDao;
44  private $defaultCompatibility;
46  private $agentName;
47 
48  public function __construct(DbManager $dbManager, Logger $logger,LicenseDao $licenseDao, AgentDao $agentDao)
49  {
50  $this->dbManager = $dbManager;
51  $this->logger = $logger;
52  $this->licenseDao = $licenseDao;
53  $this->agentDao = $agentDao;
54  $this->agentName = "compatibility";
55  $sql = "SELECT compatibility FROM license_rules
56  WHERE first_rf_fk IS NULL AND second_rf_fk IS NULL
57  AND first_type IS NULL AND second_type IS NULL;";
58  $result = $this->dbManager->getSingleRow($sql, [], __METHOD__ .
59  "defaultComp");
60  if (!empty($result) && array_key_exists("compatibility", $result)) {
61  $this->defaultCompatibility = $result["compatibility"];
62  } else {
63  $this->defaultCompatibility = false;
64  }
65  }
66 
75  public function getCompatibilityForFile($itemTreeBounds, $shortname)
76  {
77  $uploadTreeTableName = $itemTreeBounds->getUploadTreeTableName();
78  $uploadTreePk = $itemTreeBounds->getItemId();
79  $stmt = __METHOD__.$uploadTreeTableName;
80  $sql = "SELECT pfile_fk FROM $uploadTreeTableName UT
81  WHERE UT.uploadtree_pk = $1";
82  $result = $this->dbManager->getSingleRow($sql, [$uploadTreePk], $stmt);
83  $pfileId = $result["pfile_fk"];
84  $uploadId = $itemTreeBounds->getUploadId();
86  $scanJobProxy = new ScanJobProxy($this->agentDao, $uploadId);
87  $scanJobProxy->createAgentStatus([$this->agentName]);
88  $selectedScanners = $scanJobProxy->getLatestSuccessfulAgentIds();
89  if (!array_key_exists($this->agentName, $selectedScanners)) {
90  throw new InvalidAgentStageException("Agent " . $this->agentName .
91  " has not been scheduled/completed on the upload.");
92  }
93  $latestAgentId = $selectedScanners[$this->agentName];
94  $license = $this->licenseDao->getLicenseByShortName($shortname, $groupId=null);
95  if ($license === null) {
96  return true;
97  }
98  $licenseId = $license->getId();
99  $stmt = __METHOD__ . "getCompResult";
100  $sql = "SELECT result FROM comp_result
101  WHERE pfile_fk = $1 AND agent_fk= $2 AND result = FALSE AND
102  (first_rf_fk = $3 OR second_rf_fk = $3);";
103  $res = $this->dbManager->getSingleRow($sql,
104  [$pfileId, $latestAgentId, $licenseId], $stmt);
105  return empty($res); // If not empty, there is at least 1 false result.
106  }
107 
115  public function getAllRules($limit = 10, $offset = 0, $searchTerm = '')
116  {
117  $stmt = __METHOD__;
118  $params = [];
119  $sql = self::RULE_SELECT;
120  if (!empty($searchTerm)) {
121  $params[] = $searchTerm;
122  $sql .= ' WHERE comment ILIKE $' . count($params);
123  $stmt .= '.search';
124  }
125  $params[] = $limit;
126  $sql .= ' ORDER BY lr_pk LIMIT $' . count($params);
127  $params[] = $offset;
128  $sql .= ' OFFSET $' . count($params) . ';';
129  return $this->dbManager->getRows($sql, $params, $stmt);
130  }
131 
137  public function getRuleById($rulePk)
138  {
139  $row = $this->dbManager->getSingleRow(self::RULE_SELECT .
140  ' WHERE lr_pk = $1;', [$rulePk], __METHOD__);
141  return empty($row) ? null : $row;
142  }
143 
149  public function getTotalRulesCount($searchTerm = '')
150  {
151  $stmt = __METHOD__;
152  $params = [];
153  $query = "SELECT COUNT(*) as count FROM license_rules";
154  if (!empty($searchTerm)) {
155  $params[] = $searchTerm;
156  $query .= ' WHERE comment ILIKE $' . count($params);
157  $stmt .= '.search';
158  }
159  $count = $this->dbManager->getSingleRow($query, $params, $stmt);
160  return $count ? intval($count['count']) : 0;
161  }
162 
167  public function insertEmptyRule()
168  {
169  if (!Auth::isAdmin()) {
170  return -1;
171  }
172  $params = [
173  'first_rf_fk' => null,
174  'second_rf_fk' => null,
175  'first_type' => null,
176  'second_type' => null,
177  'comment' => '',
178  'compatibility' => false
179  ];
180 
181  $statement = __METHOD__ . ".insertEmptyLicCompatibilityRule";
182  $returning = "lr_pk";
183  $returnVal = -1;
184 
185  try {
186  $returnVal = $this->dbManager->insertTableRow("license_rules", $params, $statement, $returning);
187  } catch (\Exception $_) {
188  $returnVal = -2;
189  }
190  return $returnVal;
191  }
192 
203  function insertRule($firstName, $secondName, $firstType, $secondType, $comment,
204  $result)
205  {
206  if (! Auth::isAdmin()) {
207  // Only admins can add rules.
208  return -1;
209  }
210  $comment = trim($comment);
211  if (empty($comment)) {
212  // Cannot insert empty fields.
213  return -1;
214  }
215  $params = [
216  'first_rf_fk' => $firstName,
217  'second_rf_fk' => $secondName,
218  'first_type' => $firstType,
219  'second_type' => $secondType,
220  'comment' => $comment,
221  'compatibility' => $result
222  ];
223  $statement = __METHOD__ . ".insertNewLicCompatibilityRule";
224  $returning = "lr_pk";
225  $returnVal = -1;
226  try {
227  $returnVal = $this->dbManager->insertTableRow("license_rules",
228  $params, $statement, $returning);
229  } catch (\Exception $_) {
230  $returnVal = -2;
231  }
232  return $returnVal;
233  }
234 
241  function updateRuleFromArray($ruleArray)
242  {
243  if (!Auth::isAdmin()) {
244  // Only admins can update the rules.
245  return -1;
246  }
247  $updated = 0;
248  foreach ($ruleArray as $rulePk => $rule) {
249  if (count($rule) < 1) {
250  throw new \UnexpectedValueException("Rule has no values");
251  }
252  $this->isRuleIdValid($rulePk);
253  $statement = __METHOD__;
254  $params = [$rulePk];
255  $updateStatement = [];
256  if (array_key_exists("firstLic", $rule)) {
257  $params[] = $rule["firstLic"];
258  $updateStatement[] = "first_rf_fk = $" . count($params);
259  $statement .= ".first_rf_fk";
260  }
261  if (array_key_exists("secondLic", $rule)) {
262  $params[] = $rule["secondLic"];
263  $updateStatement[] = "second_rf_fk = $" . count($params);
264  $statement .= ".second_rf_fk";
265  }
266  if (array_key_exists("firstType", $rule)) {
267  $params[] = $rule["firstType"];
268  $updateStatement[] = "first_type = $" . count($params);
269  $statement .= ".first_type";
270  }
271  if (array_key_exists("secondType", $rule)) {
272  $params[] = $rule["secondType"];
273  $updateStatement[] = "second_type = $" . count($params);
274  $statement .= ".second_type";
275  }
276  if (array_key_exists("comment", $rule)) {
277  $params[] = $rule["comment"];
278  $updateStatement[] = "comment = $" . count($params);
279  $statement .= ".comment";
280  }
281  if (array_key_exists("result", $rule)) {
282  // Booleans are not casted by the driver, unlike on insert.
283  $params[] = is_bool($rule["result"]) ?
284  $this->dbManager->booleanToDb($rule["result"]) : $rule["result"];
285  $updateStatement[] = "compatibility = $" . count($params);
286  $statement .= ".compatibility";
287  }
288  $sql = "UPDATE license_rules " .
289  "SET " . join(",", $updateStatement) .
290  " WHERE lr_pk = $1 " .
291  "RETURNING 1 AS updated;";
292  $retVal = $this->dbManager->getSingleRow($sql, $params, $statement);
293  $updated += intval($retVal["updated"]);
294  }
295  return $updated;
296  }
297 
303  private function isRuleIdValid($rulePk)
304  {
305  if (! is_int($rulePk)) {
306  throw new \UnexpectedValueException("Invalid rule id $rulePk");
307  }
308  $sql = "SELECT count(*) AS cnt FROM license_rules " .
309  "WHERE lr_pk = $1;";
310 
311  $ruleCount = $this->dbManager->getSingleRow($sql, [$rulePk]);
312  if ($ruleCount['cnt'] < 1) {
313  // Invalid rule id
314  throw new \UnexpectedValueException("Invalid rule id $rulePk");
315  }
316  }
317 
323  function deleteRule($rulePk)
324  {
325  if (!Auth::isAdmin()) {
326  // Only admins can delete the rules.
327  return false;
328  }
329 
330  $stmt = __METHOD__ . "DeletionOfRule";
331  $sql = "DELETE FROM license_rules " .
332  "WHERE lr_pk = $1 " .
333  "RETURNING lr_pk;";
334 
335  $retVal = $this->dbManager->getSingleRow($sql, [$rulePk], $stmt);
336  if ($retVal["lr_pk"] == $rulePk) {
337  return true;
338  } else {
339  return false;
340  }
341  }
342 
347  public function getDefaultCompatibility()
348  {
349  return $this->defaultCompatibility;
350  }
351 }
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
static isAdmin()
Check if user is admin.
Definition: Auth.php:92
deleteRule($rulePk)
Delete a license compatibility rule.
updateRuleFromArray($ruleArray)
Update the existing rules.
getTotalRulesCount($searchTerm='')
Get the total count of license compatibility rules.
insertRule($firstName, $secondName, $firstType, $secondType, $comment, $result)
Insert new rule in the database.
insertEmptyRule()
Insert a new empty rule in the database.
getAllRules($limit=10, $offset=0, $searchTerm='')
Get all the existing license compatibility rules from the database.
getRuleById($rulePk)
Get a single license compatibility rule from the database.
isRuleIdValid($rulePk)
Check if rule ID exists in DB.
Fossology exception.
Definition: Exception.php:15
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:690
fo_dbManager * dbManager
fo_dbManager object
Definition: process.c:16