FOSSology  4.7.1
Open Source License Compliance by Open Source Software
AjaxSHDetailsBrowser.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2019 Sandip Kumar Bhuyan <sandipbhuyan@gmail.com>
4  Author: Sandip Kumar Bhuyan<sandipbhyan@gmail.com>
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
18 use Symfony\Component\HttpFoundation\JsonResponse;
19 use Symfony\Component\HttpFoundation\Request;
20 use Symfony\Component\HttpFoundation\Response;
21 
23 {
24  const NAME = "ajax_sh_browser";
25 
26  private $uploadtree_tablename = "";
28  private $uploadDao;
30  private $licenseDao;
32  private $agentDao;
37  private $shDao;
42  private $configuration;
43 
44  protected $agentNames = array('softwareHeritage' => 'SH');
45 
46  public function __construct()
47  {
48  parent::__construct(self::NAME, array(
49  self::TITLE => _("Ajax: File Browser"),
50  self::DEPENDENCIES => array("fileBrowse"),
51  self::PERMISSION => Auth::PERM_READ,
52  self::REQUIRES_LOGIN => false
53  ));
54 
55  $this->uploadDao = $this->getObject('dao.upload');
56  $this->licenseDao = $this->getObject('dao.license');
57  $this->agentDao = $this->getObject('dao.agent');
58  $this->shDao = $this->container->get('dao.softwareHeritage');
59  $sysconfig = $GLOBALS['SysConf']['SYSCONFIG'];
60  $this->configuration = [
61  'url' => trim($sysconfig['SwhURL']),
62  'uri' => trim($sysconfig['SwhBaseURL']),
63  'content' => trim($sysconfig['SwhContent']),
64  'maxtime' => intval($sysconfig['SwhSleep']),
65  'token' => trim($sysconfig['SwhToken'])
66  ];
67  }
68 
73  public function handle(Request $request)
74  {
75  $upload = intval($request->get("upload"));
76  $groupId = Auth::getGroupId();
77  if (!$this->uploadDao->isAccessible($upload, $groupId)) {
78  throw new \Exception("Permission Denied");
79  }
80 
81  $item = intval($request->get("item"));
82  $this->uploadtree_tablename = $this->uploadDao->getUploadtreeTableName($upload);
83  $itemTreeBounds = $this->uploadDao->getItemTreeBounds($item, $this->uploadtree_tablename);
84  $left = $itemTreeBounds->getLeft();
85  if (empty($left)) {
86  throw new \Exception("Job unpack/adj2nest hasn't completed.");
87  }
88 
89  $scannerAgents = array_keys($this->agentNames);
90  $scanJobProxy = new ScanJobProxy($this->agentDao, $upload);
91  $scanJobProxy->createAgentStatus($scannerAgents);
92  $selectedAgentId = intval($request->get('agentId'));
93  $tag_pk = intval($request->get('tag'));
94 
95  $UniqueTagArray = array();
96  $this->licenseProjector = new LicenseMap($this->getObject('db.manager'),$groupId,LicenseMap::CONCLUSION,true);
97  $vars = $this->createFileListing($tag_pk, $itemTreeBounds, $UniqueTagArray, $selectedAgentId, $groupId, $scanJobProxy, $request);
98 
99  return new JsonResponse(array(
100  'sEcho' => intval($request->get('sEcho')),
101  'aaData' => $vars['fileData'],
102  'iTotalRecords' => $vars['iTotalDisplayRecords'],
103  'iTotalDisplayRecords' => $vars['iTotalDisplayRecords']
104  ));
105  }
106 
116  private function createFileListing($tagId, ItemTreeBounds $itemTreeBounds, &$UniqueTagArray, $selectedAgentId, $groupId, $scanJobProxy, $request)
117  {
118  if (!empty($selectedAgentId)) {
119  $agentName = $this->agentDao->getAgentName($selectedAgentId);
120  $selectedScanners = array($agentName=>$selectedAgentId);
121  } else {
122  $selectedScanners = $scanJobProxy->getLatestSuccessfulAgentIds();
123  }
124 
126  $uploadId = $itemTreeBounds->getUploadId();
127  $isFlat = isset($_GET['flatten']);
128 
129  if ($isFlat) {
130  $options = array(UploadTreeProxy::OPT_RANGE => $itemTreeBounds);
131  } else {
132  $options = array(
133  UploadTreeProxy::OPT_ITEM_FILTER => "AND ut.ufile_mode & (1<<28) = 0 AND ut.realparent=" . $itemTreeBounds->getItemId()
134  );
135  }
136 
137  $searchMap = array();
138  foreach (explode(' ',$request->get('sSearch')) as $pair) {
139  $a = explode(':',$pair);
140  if (count($a) == 1) {
141  $searchMap['head'] = $pair;
142  } else {
143  $searchMap[$a[0]] = $a[1];
144  }
145  }
146 
147  if (array_key_exists('ext', $searchMap) && strlen($searchMap['ext'])>=1) {
148  $options[UploadTreeProxy::OPT_EXT] = $searchMap['ext'];
149  }
150  if (array_key_exists('head', $searchMap) && strlen($searchMap['head'])>=1) {
151  $options[UploadTreeProxy::OPT_HEAD] = $searchMap['head'];
152  }
153 
154  $descendantView = new UploadTreeProxy($uploadId, $options, $itemTreeBounds->getUploadTreeTableName(), 'uberItems');
155 
156  $vars['iTotalDisplayRecords'] = $descendantView->count();
157 
158  $columnNamesInDatabase = array($isFlat?'ufile_name':'lft');
159  $defaultOrder = array(array(0, "asc"));
160  $orderString = $this->getObject('utils.data_tables_utility')->getSortingString($_GET, $columnNamesInDatabase, $defaultOrder);
161 
162  $offset = GetParm('iDisplayStart', PARM_INTEGER);
163  $limit = GetParm('iDisplayLength', PARM_INTEGER);
164  if ($offset) {
165  $orderString .= " OFFSET $offset";
166  }
167  if ($limit) {
168  $orderString .= " LIMIT $limit";
169  }
170 
171  /* Get ALL the items under this Uploadtree_pk */
172  $sql = $descendantView->getDbViewQuery()." $orderString";
173  $dbManager = $this->getObject('db.manager');
174 
175  $dbManager->prepare($stmt=__METHOD__.$orderString,$sql);
176  $res = $dbManager->execute($stmt,$descendantView->getParams());
177  $descendants = $dbManager->fetchAll($res);
178  $dbManager->freeResult($res);
179 
180  /* Filter out Children that don't have tag */
181  if (!empty($tagId)) {
182  TagFilter($descendants, $tagId, $itemTreeBounds->getUploadTreeTableName());
183  }
184  if (empty($descendants)) {
185  $vars['fileData'] = array();
186  return $vars;
187  }
188 
189  if ($isFlat) {
190  $firstChild = reset($descendants);
191  $lastChild = end($descendants);
192  $nameRange = array($firstChild['ufile_name'],$lastChild['ufile_name']);
193  } else {
194  $nameRange = array();
195  }
196 
197  /******* File Listing ************/
198  $pfileLicenses = array();
199  foreach ($selectedScanners as $agentName=>$agentId) {
200  $licensePerPfile = $this->licenseDao->getLicenseIdPerPfileForAgentId($itemTreeBounds, $agentId, $isFlat, $nameRange);
201  foreach ($licensePerPfile as $pfile => $licenseRow) {
202  foreach ($licenseRow as $licId => $row) {
203  $lic = $this->licenseProjector->getProjectedShortname($licId);
204  $pfileLicenses[$pfile][$lic][$agentName] = $row;
205  }
206  }
207  }
208 
209  $baseUri = Traceback_uri().'?mod=sh-agent'.Traceback_parm_keep(array('upload','folder','show'));
210 
211  $tableData = array();
212  $latestSuccessfulAgentIds = $scanJobProxy->getLatestSuccessfulAgentIds();
213  foreach ($descendants as $child) {
214  if (empty($child)) {
215  continue;
216  }
217  $tableData[] = $this->createFileDataRow($child, $uploadId, $selectedAgentId,
218  $baseUri, $UniqueTagArray, $isFlat);
219  }
220 
221  $vars['fileData'] = $tableData;
222  return $vars;
223  }
224 
234  private function createFileDataRow($child, $uploadId, $selectedAgentId, $uri, &$UniqueTagArray, $isFlat)
235  {
236  $fileId = $child['pfile_fk'];
237  $childUploadTreeId = $child['uploadtree_pk'];
238  $linkUri = '';
239  if (!empty($fileId)) {
240  $linkUri = Traceback_uri();
241  $linkUri .= "?mod=view-license&upload=$uploadId&item=$childUploadTreeId";
242  if ($selectedAgentId) {
243  $linkUri .= "&agentId=$selectedAgentId";
244  }
245  }
246 
247  /* Determine link for containers */
248  $isContainer = Iscontainer($child['ufile_mode']);
249  if ($isContainer && !$isFlat) {
250  $uploadtree_pk = $child['uploadtree_pk'];
251  $linkUri = "$uri&item=" . $uploadtree_pk;
252  if ($selectedAgentId) {
253  $linkUri .= "&agentId=$selectedAgentId";
254  }
255  } else if ($isContainer) {
256  $uploadtree_pk = Isartifact($child['ufile_mode']) ? DirGetNonArtifact($childUploadTreeId, $this->uploadtree_tablename) : $childUploadTreeId;
257  $linkUri = "$uri&item=" . $uploadtree_pk;
258  if ($selectedAgentId) {
259  $linkUri .= "&agentId=$selectedAgentId";
260  }
261  }
262 
263  /* Populate the output ($VF) - file list */
264  /* id of each element is its uploadtree_pk */
265  $fileName = htmlspecialchars($child['ufile_name']);
266  if ($isContainer) {
267  $fileName = "<a href='$linkUri'><span style='color: darkblue'> <b>$fileName</b> </span></a>";
268  } else if (! empty($linkUri)) {
269  $fileName = "<a href='$linkUri'>$fileName</a>";
270  }
271 
272  $fileListLinks = FileListLinks($uploadId, $childUploadTreeId, 0, $fileId, true, $UniqueTagArray, $this->uploadtree_tablename, !$isFlat);
273 
274  if ($isContainer) {
275  $childBounds = new ItemTreeBounds(
276  $child['uploadtree_pk'],
277  $this->uploadtree_tablename,
278  $uploadId,
279  $child['lft'],
280  $child['rgt']
281  );
282  $shRecord = $this->shDao->getAggregatedSWHRecord($childBounds);
283  return [$fileName, "", $shRecord["license"], $shRecord["img"], $fileListLinks];
284  }
285 
286  $pfileHash = $this->uploadDao->getUploadHashesFromPfileId($fileId);
287  $shRecord = $this->shDao->getSoftwareHetiageRecord($fileId);
288 
289  $text = _("Software Heritage");
290  $shLink = $this->configuration['url'] .
291  $this->configuration['uri'] . strtolower($pfileHash["sha256"]) .
292  $this->configuration['content'];
293  $fileListLinks .= "[<a href='".$shLink."' target=\"_blank\">$text</a>]";
294 
295  return [$fileName, $pfileHash["sha256"], $shRecord["license"], $shRecord["img"], $fileListLinks];
296  }
297 }
298 
299 register_plugin(new AjaxSHDetailsBrowser());
char * uploadtree_tablename
upload.uploadtree_tablename
Definition: adj2nest.c:100
createFileDataRow($child, $uploadId, $selectedAgentId, $uri, &$UniqueTagArray, $isFlat)
handle(Request $request)
createFileListing($tagId, ItemTreeBounds $itemTreeBounds, &$UniqueTagArray, $selectedAgentId, $groupId, $scanJobProxy, $request)
Contains the constants and helpers for authentication of user.
Definition: Auth.php:24
Wrapper class for license map.
Definition: LicenseMap.php:19
Isartifact($mode)
Definition: common-dir.php:29
DirGetNonArtifact($UploadtreePk, $uploadtree_tablename='uploadtree')
Given an artifact directory (uploadtree_pk), return the first non-artifact directory (uploadtree_pk).
Definition: common-dir.php:158
Iscontainer($mode)
Definition: common-dir.php:38
FileListLinks($upload_fk, $uploadtree_pk, $napk, $pfile_pk, $Recurse=True, &$UniqueTagArray=array(), $uploadtree_tablename="uploadtree", $wantTags=true)
Get list of links: [View][Info][Download]
Traceback_uri()
Get the URI without query to this location.
Definition: common-parm.php:97
const PARM_INTEGER
Definition: common-parm.php:14
GetParm($parameterName, $parameterType)
This function will retrieve the variables and check data types.
Definition: common-parm.php:46
Traceback_parm_keep($List)
Create a new URI, keeping only these items.
TagFilter(&$UploadtreeRows, $tag_pk, $uploadtree_tablename)
Given a list of uploadtree recs, remove recs that do not have $tag_pk.
char * trim(char *ptext)
Trimming whitespace.
Definition: fossconfig.c:690
#define PERM_READ
Read-only permission.
Definition: libfossology.h:32