1<?php
2/***********************************************************
3 Copyright (C) 2010-2012 Hewlett-Packard Development Company, L.P.
4 Copyright (C) 2013-2016, 2018 Siemens AG
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 version 2 as published by the Free Software Foundation.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18***********************************************************/
19
20use Fossology\Lib\Auth\Auth;
21use Fossology\Lib\Dao\UploadDao;
22use Fossology\Lib\Db\DbManager;
23
24/**
25 * \file list.php
26 * \brief This plugin is used to:
27 * List files for a given copyright statement/email/url in a given
28 * uploadtree.
29 */
30
31define("TITLE_COPYRIGHT_LIST", _("List Files for Copyright/Email/URL"));
32
33class copyright_list extends FO_Plugin
34{
35  /** @var DbManager
36   * DbManager object
37   */
38  private $dbManager;
39
40  /** @var UploadDao
41   * UploadDao opbject
42   */
43  private $uploadDao;
44
45  function __construct()
46  {
47    $this->Name = "copyright-list";
48    $this->Title = TITLE_COPYRIGHT_LIST;
49    $this->Version = "1.0";
50    $this->Dependency = array("copyright-hist", "ecc-hist");
51    $this->DBaccess = PLUGIN_DB_READ;
52    $this->LoginFlag = 0;
53    $this->NoMenu = 0;
54
55    parent::__construct();
56    global $container;
57    $this->dbManager = $container->get('db.manager');
58    $this->uploadDao = $container->get('dao.upload');
59  }
60
61  /**
62   * @copydoc FO_Plugin::RegisterMenus()
63   * @see FO_Plugin::RegisterMenus()
64   */
65  function RegisterMenus()
66  {
67    if ($this->State != PLUGIN_STATE_READY) {
68      return(0);
69    }
70
71    // micro-menu
72    $agent_pk = GetParm("agent",PARM_INTEGER);
73    $uploadtree_pk = GetParm("item",PARM_INTEGER);
74    $hash = GetParm("hash",PARM_RAW);
75    $type = GetParm("type",PARM_RAW);
76    $Excl = GetParm("excl",PARM_RAW);
77
78    $URL = $this->Name . "&agent=$agent_pk&item=$uploadtree_pk&hash=$hash&type=$type&page=-1";
79    if (!empty($Excl)) {
80      $URL .= "&excl=$Excl";
81    }
82    $text = _("Show All Files");
83    menu_insert($this->Name."::Show All",0, $URL, $text);
84  } // RegisterMenus()
85
86  /**
87   * @brief Get statement rows for a specified set
88   * @param int $Uploadtree_pk Uploadtree id
89   * @param int $Agent_pk Agent id
90   * @param int $upload_pk Upload id
91   * @param string $hash Content hash
92   * @param string $type Content type
93   * @param string $tableName Content table name (copyright|ecc|author)
94   * @param string $filter Filter activated/deactivated statements
95   * @throws Exception
96   * @return array Rows to process, and $upload_pk
97   */
98  function GetRows($Uploadtree_pk, $Agent_pk, &$upload_pk, $hash, $type, $tableName, $filter="")
99  {
100    /*******  Get license names and counts  ******/
101    $row = $this->uploadDao->getUploadEntry($Uploadtree_pk);
102    $lft = $row["lft"];
103    $rgt = $row["rgt"];
104    $upload_pk = $row["upload_fk"];
105    $params = [];
106
107    if ($type == "copyFindings") {
108      $sql = "SELECT textfinding AS content, '$type' AS type, uploadtree_pk, ufile_name, PF, hash
109              FROM $tableName,
110              (SELECT uploadtree_pk, pfile_fk AS PF, ufile_name FROM uploadtree
111                 WHERE upload_fk=$1
112                   AND uploadtree.lft BETWEEN $2 AND $3) AS SS
113              WHERE PF=pfile_fk AND hash=$4 ORDER BY uploadtree_pk";
114      $params = [
115        $upload_pk, $lft, $rgt, $hash
116      ];
117    } else {
118      $eventTable = $tableName . "_event";
119      $eventFk = $tableName . "_fk";
120      $tablePk = $tableName . "_pk";
121      $active_filter = "";
122      if (!empty($filter)) {
123        if ($filter == "active") {
124          $active_filter = "AND (ce.is_enabled IS NULL OR ce.is_enabled = 'true')";
125        } elseif ($filter = "inactive") {
126          $active_filter = "AND ce.is_enabled = 'false'";
127        }
128      }
129      /* get all the copyright records for this uploadtree.  */
130      $sql = "SELECT
131(CASE WHEN (ce.content IS NULL OR ce.content = '') THEN cp.content ELSE ce.content END) AS content,
132(CASE WHEN (ce.hash IS NULL OR ce.hash = '') THEN cp.hash ELSE ce.hash END) AS hash,
133type, uploadtree_pk, ufile_name, cp.pfile_fk AS PF
134                FROM $tableName AS cp
135              INNER JOIN uploadtree UT ON cp.pfile_fk = ut.pfile_fk
136                AND ut.upload_fk=$1
137                AND ut.lft BETWEEN $2 AND $3
138              LEFT JOIN $eventTable AS ce ON ce.$eventFk = cp.$tablePk
139                AND ce.upload_fk = ut.upload_fk AND ce.uploadtree_fk = ut.uploadtree_pk
140              WHERE agent_fk=$4 AND (cp.hash=$5 OR ce.hash=$5) AND type=$6
141                $active_filter
142              ORDER BY uploadtree_pk";
143      $params = [
144        $upload_pk, $lft, $rgt, $Agent_pk, $hash, $type
145      ];
146    }
147    $statement = __METHOD__.$tableName;
148    $this->dbManager->prepare($statement, $sql);
149    $result = $this->dbManager->execute($statement,$params);
150
151    $rows = $this->dbManager->fetchAll($result);
152    $this->dbManager->freeResult($result);
153
154    return $rows;
155  }
156
157  /**
158   * \brief Remove unwanted rows by hash and type and
159   * exclusions and filter
160   * \param array $rows
161   * \param string $excl
162   * \param int $NumRows the number of instances.
163   * \param string $filter
164   * \param string $hash
165   * \return array new array and $NumRows
166   */
167  function GetRequestedRows($rows, $excl, &$NumRows, $filter, $hash)
168  {
169    $NumRows = count($rows);
170    $prev = 0;
171    $ExclArray = explode(":", $excl);
172
173    /* filter will need to know the rf_pk of "No_license_found" or "Void" */
174    if (!empty($filter) && ($filter == "nolic"))
175    {
176      $NoLicStr = "No_license_found";
177      $VoidLicStr = "Void";
178      $rf_clause = "";
179
180      $sql = "select rf_pk from license_ref where rf_shortname IN ($1, $2)";
181      $statement = __METHOD__."NoLicenseFoundORVoid";
182      $this->dbManager->prepare($statement, $sql);
183      $result = $this->dbManager->execute($statement,array("$NoLicStr", "$VoidLicStr"));
184      $rf_rows = $this->dbManager->fetchAll($result);
185      if(!empty($rf_rows)){
186        foreach($rf_rows as $row)
187        {
188          if (!empty($rf_clause)) { $rf_clause .= " or ";
189          }
190          $rf_clause .= " rf_fk=$row[rf_pk]";
191        }
192      }
193      $this->dbManager->freeResult($result);
194    }
195
196    for($RowIdx = 0; $RowIdx < $NumRows; $RowIdx++)
197    {
198      $row = $rows[$RowIdx];
199      /* remove non matching entries */
200      if ($row['hash'] != $hash) {
201        unset($rows[$RowIdx]);
202      }
203      /* remove excluded files */
204      if ($excl)
205      {
206        $FileExt = GetFileExt($rows[$RowIdx]['ufile_name']);
207        if (in_array($FileExt, $ExclArray))
208        {
209          unset($rows[$RowIdx]);
210          continue;
211        }
212      }
213
214      /* apply filters */
215      if (($filter == "nolic") && ($rf_clause))
216      {
217        /* discard file unless it has no license */
218        $sql = "select rf_fk from license_file where ($rf_clause) and pfile_fk=$1";
219        $statement = __METHOD__."CheckForNoLicenseFound";
220        $this->dbManager->prepare($statement, $sql);
221        $result = $this->dbManager->execute($statement,array("{$row['pf']}"));
222        $FoundRows = $this->dbManager->fetchAll($result);
223        if (empty($FoundRows))
224        {
225          unset($rows[$RowIdx]);
226          continue;
227        }
228      }
229    }
230
231    /* reset array keys, keep order (uploadtree_pk) */
232    $rows2 = array();
233    foreach ($rows as $row) {
234      $rows2[] = $row;
235    }
236    unset($rows);
237
238    /* remove duplicate files */
239    $NumRows = count($rows2);
240    $prev = 0;
241    for($RowIdx = 0; $RowIdx < $NumRows; $RowIdx++)
242    {
243      if ($RowIdx > 0)
244      {
245        /* Since rows are ordered by uploadtree_pk,
246         * remove duplicate uploadtree_pk's.  This can happen if there
247         * are multiple same copyrights in one file.
248         */
249        if ($rows2[$RowIdx-1]['uploadtree_pk'] == $rows2[$RowIdx]['uploadtree_pk']) {
250          unset($rows2[$RowIdx-1]);
251        }
252      }
253    }
254
255    /* sort by name so output has some order */
256    usort($rows2, 'copyright_namecmp');
257
258    return $rows2;
259  }
260
261  /**
262   * @copydoc FO_Plugin::OutputOpen()
263   * @see FO_Plugin::OutputOpen()
264   */
265  function OutputOpen()
266  {
267
268    if ($this->State != PLUGIN_STATE_READY) {
269      return(0);
270    }
271
272    return parent::OutputOpen();
273  }
274
275  /**
276   * @copydoc FO_Plugin::Output()
277   * @see FO_Plugin::Output()
278   */
279  function Output()
280  {
281    if ($this->State != PLUGIN_STATE_READY) {
282      return;
283    }
284
285    $OutBuf = "";
286    $Time = microtime(true);
287    $Max = 50;
288
289    /*  Input parameters */
290    $agent_pk = GetParm("agent",PARM_INTEGER);
291    $uploadtree_pk = GetParm("item",PARM_INTEGER);
292    $hash = GetParm("hash",PARM_RAW);
293    $type = GetParm("type",PARM_RAW);
294    $excl = GetParm("excl",PARM_RAW);
295    $filter = GetParm("filter",PARM_RAW);
296    if (empty($uploadtree_pk) || empty($hash) || empty($type) || empty($agent_pk))
297    {
298      $this->vars['pageContent'] = $this->Name . _(" is missing required parameters");
299      return;
300    }
301
302    /* Check item1 and item2 upload permissions */
303    $Row = $this->uploadDao->getUploadEntry($uploadtree_pk);
304    if (!$this->uploadDao->isAccessible($Row['upload_fk'], Auth::getGroupId()))
305    {
306      $this->vars['pageContent'] = "<h2>" . _("Permission Denied") . "</h2>";
307      return;
308    }
309
310    $Page = GetParm("page",PARM_INTEGER);
311    if (empty($Page) || $Page == -1) {
312      $Page=0;
313    }
314
315    list($tableName,$modBack,$viewName) = $this->getTableName($type);
316
317    /* get all rows */
318    $upload_pk = -1;
319    $allRows = $this->GetRows($uploadtree_pk, $agent_pk, $upload_pk, $hash, $type, $tableName, $filter);
320    $uploadtree_tablename = $this->uploadDao->getUploadtreeTableName($upload_pk);
321
322    /* slim down to all rows with this hash and type,  and filter */
323    $NumInstances = 0;
324    $rows = $this->GetRequestedRows($allRows, $excl, $NumInstances, $filter, $hash);
325
326    // micro menus
327    $OutBuf .= menu_to_1html(menu_find($this->Name, $MenuDepth),0);
328
329    $RowCount = count($rows);
330    if ($RowCount)
331    {
332      $TypeStr = "";
333      $Content = htmlentities($rows[0]['content']);
334      $Offset = ($Page < 0) ? 0 : $Page*$Max;
335      $PkgsOnly = false;
336      $text = _("files");
337      $text1 = _("unique");
338      $text3 = _("copyright");
339      $text4 = _("email");
340      $text5 = _("url");
341      switch ($type)
342      {
343        case "statement":
344          $TypeStr = "$text3";
345          break;
346        case "email":
347          $TypeStr = "$text4";
348          break;
349        case "url":
350          $TypeStr = "$text5";
351          break;
352        case "ecc":
353          $TypeStr = _("export restriction");
354          break;
355        case "keyword":
356          $TypeStr = _("Keyword Analysis");
357          break;
358        case "copyFindings":
359          $TypeStr = _("User Findings");
360      }
361      $OutBuf .= "$NumInstances $TypeStr instances found in $RowCount  $text";
362
363      $OutBuf .= ": <b>$Content</b>";
364
365      $text = _("Display excludes files with these extensions");
366      if (!empty($excl)) { $OutBuf .= "<br>$text: $excl";
367      }
368
369      /* Get the page menu */
370      if (($RowCount >= $Max) && ($Page >= 0))
371      {
372        $PagingMenu = "<P />\n" . MenuPage($Page, intval($RowCount / $Max)) . "<P />\n";
373        $OutBuf .= $PagingMenu;
374      }
375      else
376      {
377        $PagingMenu = "";
378      }
379
380      /* Offset is +1 to start numbering from 1 instead of zero */
381      $LinkLast = "$viewName&agent=$agent_pk";
382      $ShowBox = 1;
383      $ShowMicro=NULL;
384
385      $baseURL = "?mod=" . $this->Name . "&agent=$agent_pk&item=$uploadtree_pk&hash=$hash&type=$type&page=-1";
386
387      // display rows
388      $RowNum = 0;
389      foreach($rows as $row)
390      {
391        ++$RowNum;
392        if ($RowNum < $Offset) {
393          continue;
394        }
395        if ($RowNum > $Offset + $Max) {
396          break;
397        }
398
399        // Allow user to exclude files with this extension
400        $FileExt = GetFileExt($row['ufile_name']);
401        if (empty($excl)) {
402          $URL = $baseURL . "&excl=$FileExt";
403        } else {
404          $URL = $baseURL . "&excl=$excl:$FileExt";
405        }
406
407        $text = _("Exclude this file type");
408        $Header = "<a href=$URL>$text.</a>";
409
410        $ok = true;
411        if ($excl)
412        {
413          $ExclArray = explode(":", $excl);
414          if (in_array($FileExt, $ExclArray)) {
415            $ok = false;
416          }
417        }
418
419        if ($ok)
420        {
421          $OutBuf .= Dir2Browse($modBack, $row['uploadtree_pk'], $LinkLast,
422            $ShowBox, $ShowMicro, $RowNum, $Header, '', $uploadtree_tablename);
423        }
424      }
425    }
426    else
427    {
428      $OutBuf .= _("No files found");
429    }
430
431    if (!empty($PagingMenu)) {
432      $OutBuf .= $PagingMenu . "\n";
433    }
434    $OutBuf .= "<hr>\n";
435    $Time = microtime(true) - $Time;
436    $text = _("Elapsed time");
437    $text1 = _("seconds");
438    $OutBuf .= sprintf("<small>$text: %.2f $text1</small>\n", $Time);
439
440    $this->vars['pageContent'] = $OutBuf;
441    return;
442  }
443
444  /**
445   * @copydoc FO_Plugin::getTemplateName()
446   * @see FO_Plugin::getTemplateName()
447   */
448  function getTemplateName()
449  {
450    return 'copyrightlist.html.twig';
451  }
452
453  /**
454   * @brief Get the table name, mod, and view based on type
455   * @param string $type Type of content
456   * @return string[] Table name, mod, and view
457   */
458  private function getTableName($type)
459  {
460
461    switch ($type) {
462      case "ecc" :
463        $tableName = "ecc";
464        $modBack = "ecc-hist";
465        $viewName = "ecc-view";
466        break;
467      case "keyword" :
468        $tableName = "keyword";
469        $modBack = "keyword-hist";
470        $viewName = "keyword-view";
471        break;
472      case "statement" :
473        $tableName = "copyright";
474        $modBack = "copyright-hist";
475        $viewName = "copyright-view";
476        break;
477      case "copyFindings" :
478        $tableName = "copyright_decision";
479        $modBack = "copyright-hist";
480        $viewName = "copyright-view";
481        break;
482      default:
483        $tableName = "author";
484        $modBack = "email-hist";
485        $viewName = "copyright-view";
486    }
487    return array($tableName, $modBack,$viewName);
488  }
489}
490
491$NewPlugin = new copyright_list;
492$NewPlugin->Initialize();
493