FOSSology  4.6.0-rc1
Open Source License Compliance by Open Source Software
UploadFilePage.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2008-2013 Hewlett-Packard Development Company, L.P.
4  SPDX-FileCopyrightText: © 2014-2017 Siemens AG
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
9 namespace Fossology\UI\Page;
10 
15 use Symfony\Component\HttpFoundation\File\Exception\FileException;
16 use Symfony\Component\HttpFoundation\File\UploadedFile;
17 use Symfony\Component\HttpFoundation\Request;
18 use Symfony\Component\HttpFoundation\Response;
19 
24 {
25  const FILE_INPUT_NAME = 'fileInput';
26 
27 
28  public function __construct()
29  {
30  parent::__construct(self::NAME, array(
31  self::TITLE => _("Upload a New File"),
32  self::MENU_LIST => "Upload::From File",
33  self::DEPENDENCIES => array("agent_unpack", "showjobs"),
34  self::PERMISSION => Auth::PERM_WRITE
35  ));
36  }
37 
38 
44  protected function handleView(Request $request, $vars)
45  {
46  // Recalculate views for reuse agent to support multi file uploads
47  $parmAgentList = MenuHook::getAgentPluginNames("ParmAgents");
48  $vars['parmAgentContents'] = array();
49  $vars['parmAgentFoots'] = array();
50  $vars['hiddenAgentContents'] = array();
51  foreach ($parmAgentList as $parmAgent) {
52  $agent = plugin_find($parmAgent);
53  if ($parmAgent == "agent_reuser") {
54  $vars['parmAgentContents'][] = sprintf("<li>
55  <div class='form-group'>
56  <label for='reuse'>
57  (%s) %s
58  </label>
59  <img src='images/info_16.png' data-toggle='tooltip' title='%s' alt='' class='info-bullet'/><br/>
60  <button type='button' class='btn btn-default btn-sm' data-toggle='modal' data-target='#reuseModal'>%s</button>
61  <img src='images/info_16.png' data-toggle='tooltip' title='%s' alt='' class='info-bullet'/><br/>
62 </li>", _("Optional"), _("Reuse"),
63  _("Copy clearing decisions if there is the same file hash between two files"),
64  _("Set the reuse information"),
65  _("Open the pop-up to setup the reuse information for uploads"));
66  $vars['hiddenAgentContents'][] = $agent->renderContent($vars);
67  } else {
68  $vars['parmAgentContents'][] = $agent->renderContent($vars);
69  }
70  $vars['parmAgentFoots'][] = $agent->renderFoot($vars);
71  }
72  $vars['fileInputName'] = self::FILE_INPUT_NAME;
73  return $this->render("upload_file.html.twig", $this->mergeWithDefault($vars));
74  }
75 
79  protected function handleUpload(Request $request)
80  {
81  global $MODDIR;
82  global $SYSCONFDIR;
83  define("UPLOAD_ERR_EMPTY", 5);
84  define("UPLOAD_ERR_INVALID_FOLDER_PK", 100);
85  define("UPLOAD_ERR_RESEND", 200);
86  $uploadErrors = array(
87  UPLOAD_ERR_OK => _("No errors."),
88  UPLOAD_ERR_INI_SIZE => _("Larger than upload_max_filesize ") . ini_get('upload_max_filesize'),
89  UPLOAD_ERR_FORM_SIZE => _("Larger than form MAX_FILE_SIZE."),
90  UPLOAD_ERR_PARTIAL => _("Partial upload."),
91  UPLOAD_ERR_NO_FILE => _("No file selected."),
92  UPLOAD_ERR_NO_TMP_DIR => _("No temporary directory."),
93  UPLOAD_ERR_CANT_WRITE => _("Can't write to disk."),
94  UPLOAD_ERR_EXTENSION => _("File upload stopped by extension."),
95  UPLOAD_ERR_EMPTY => _("File is empty or you don't have permission to read the file."),
96  UPLOAD_ERR_INVALID_FOLDER_PK => _("Invalid Folder."),
97  UPLOAD_ERR_RESEND => _("This seems to be a resent file.")
98  );
99 
100  $folderId = intval($request->get(self::FOLDER_PARAMETER_NAME));
101  $descriptions = $request->get(self::DESCRIPTION_INPUT_NAME, []);
102  for ($i = 0; $i < count($descriptions); $i++) {
103  $descriptions[$i] = stripslashes($descriptions[$i]);
104  $descriptions[$i] = $this->basicShEscaping($descriptions[$i]);
105  }
106  $uploadedFiles = $request->files->get(self::FILE_INPUT_NAME, []);
107  $uploadFiles = [];
108  for ($i = 0; $i < count($uploadedFiles); $i++) {
109  $uploadFiles[] = [
110  'file' => $uploadedFiles[$i],
111  'description' => $descriptions[$i]
112  ];
113  }
114 
115  if (empty($uploadedFiles)) {
116  return array(false, $uploadErrors[UPLOAD_ERR_NO_FILE], "");
117  }
118 
119  if (
120  $request->getSession()->get(self::UPLOAD_FORM_BUILD_PARAMETER_NAME)
121  != $request->get(self::UPLOAD_FORM_BUILD_PARAMETER_NAME)
122  ) {
123  return array(false, $uploadErrors[UPLOAD_ERR_RESEND], "");
124  }
125 
126  foreach ($uploadFiles as $uploadedFile) {
127  if (
128  $uploadedFile['file']->getSize() == 0 &&
129  $uploadedFile['file']->getError() == 0
130  ) {
131  return array(false, $uploadErrors[UPLOAD_ERR_EMPTY], "");
132  } else if ($uploadedFile['file']->getSize() >= UploadedFile::getMaxFilesize()) {
133  return array(false, $uploadErrors[UPLOAD_ERR_INI_SIZE] .
134  _(" is really ") . $uploadedFile['file']->getSize() . " bytes.", "");
135  }
136  if (!$uploadedFile['file']->isValid()) {
137  return array(false, $uploadedFile['file']->getErrorMessage(), "");
138  }
139  }
140 
141  if (empty($folderId)) {
142  return array(false, $uploadErrors[UPLOAD_ERR_INVALID_FOLDER_PK], "");
143  }
144 
145  $setGlobal = ($request->get('globalDecisions')) ? 1 : 0;
146 
147  $public = $request->get('public');
148  $publicPermission = ($public == self::PUBLIC_ALL) ? Auth::PERM_READ : Auth::PERM_NONE;
149 
150  $uploadMode = (1 << 3); // code for "it came from web upload"
151  $userId = Auth::getUserId();
152  $groupId = Auth::getGroupId();
153  $projectGroup = $GLOBALS['SysConf']['DIRECTORIES']['PROJECTGROUP'] ?: 'fossy';
154 
155  $errors = [];
156  $success = [];
157  foreach ($uploadFiles as $uploadedFile) {
158  $originalFileName = $uploadedFile['file']->getClientOriginalName();
159  $originalFileName = $this->basicShEscaping($originalFileName);
160  /* Create an upload record. */
161  $uploadId = JobAddUpload($userId, $groupId, $originalFileName,
162  $originalFileName, $uploadedFile['description'], $uploadMode,
163  $folderId, $publicPermission, $setGlobal);
164  if (empty($uploadId)) {
165  $errors[] = _("Failed to insert upload record: ") .
166  $originalFileName;
167  continue;
168  }
169 
170  try {
171  $uploadedTempFile = $uploadedFile['file']->move(
172  $uploadedFile['file']->getPath(),
173  $uploadedFile['file']->getFilename() . '-uploaded'
174  )->getPathname();
175  } catch (FileException $e) {
176  $errors[] = _("Could not save uploaded file: ") . $originalFileName;
177  continue;
178  }
179  $success[] = [
180  "tempfile" => $uploadedTempFile,
181  "orignalfile" => $originalFileName,
182  "uploadid" => $uploadId
183  ];
184  }
185 
186  if (!empty($errors)) {
187  return [false, implode(" ; ", $errors), ""];
188  }
189 
190  $messages = [];
191  foreach ($success as $row) {
192  $uploadedTempFile = $row["tempfile"];
193  $originalFileName = $row["orignalfile"];
194  $uploadId = $row["uploadid"];
195 
196  $wgetAgentCall = "$MODDIR/wget_agent/agent/wget_agent -C -g " .
197  "$projectGroup -k $uploadId '$uploadedTempFile' -c '$SYSCONFDIR'";
198  $wgetOutput = array();
199  exec($wgetAgentCall, $wgetOutput, $wgetReturnValue);
200  unlink($uploadedTempFile);
201 
202  if ($wgetReturnValue != 0) {
203  $message = implode(' ', $wgetOutput);
204  if (empty($message)) {
205  $message = _("File upload failed. Error:") . $wgetReturnValue;
206  }
207  $errors[] = $message;
208  } else {
209  $reuseRequest = $this->getRequestForReuse($request, $originalFileName);
210  $messages[] = $this->postUploadAddJobs($reuseRequest, $originalFileName,
211  $uploadId);
212  }
213  }
214 
215  if (!empty($errors)) {
216  return [false, implode(" ; ", $errors), ""];
217  }
218 
219  return array(true, implode("", $messages), "",
220  array_column($success, "uploadid"));
221  }
227  private function getRequestForReuse(Request $request, string $originalFileName)
228  {
229  $reuseRequest = clone $request;
230 
231  $reuseSourceRaw = $request->get('reuseSource', 'local');
232  $reuseSource = is_array($reuseSourceRaw) ? reset($reuseSourceRaw) : $reuseSourceRaw;
233 
234  $osselotPackageRaw = $request->get('osselotPackage');
235  $osselotPackage = is_array($osselotPackageRaw) ? reset($osselotPackageRaw) : $osselotPackageRaw;
236 
237  if ($reuseSource === 'osselot') {
238  $reuseRequest->request->set('osselotPackage', $osselotPackage);
239 
240  $versionRadio = $request->get('osselotVersionRadio', []);
241  $selectedVersion = '';
242 
243  if (is_array($versionRadio)) {
244  $selectedVersion = reset($versionRadio);
245  } elseif (is_string($versionRadio)) {
246  $selectedVersion = $versionRadio;
247  }
248 
249  if (empty($selectedVersion)) {
250  $hiddenVersions = $request->get('osselotVersions', '');
251  if (!empty($hiddenVersions)) {
252  $selectedVersion = is_array($hiddenVersions) ? reset($hiddenVersions) : $hiddenVersions;
253  }
254  }
255 
256  $reuseRequest->request->set('osselotVersions', $selectedVersion);
257 
258  $osselotScalarFields = [
259  'osselotAddNewLicensesAs',
260  'osselotLicenseMatch'
261  ];
262 
263  foreach ($osselotScalarFields as $field) {
264  $value = $request->get($field);
265  $finalValue = is_array($value) ? reset($value) : $value;
266  $reuseRequest->request->set($field, $finalValue);
267  }
268 
269  $osselotCheckboxFields = [
270  'osselotAddLicenseInfoFromInfoInFile',
271  'osselotAddLicenseInfoFromConcluded',
272  'osselotAddConcludedAsDecisions',
273  'osselotAddConcludedAsDecisionsOverwrite',
274  'osselotAddConcludedAsDecisionsTBD',
275  'osselotAddCopyrights'
276  ];
277 
278  foreach ($osselotCheckboxFields as $field) {
279  $value = $request->get($field);
280  $finalValue = null;
281 
282  if (is_array($value)) {
283  $firstValue = reset($value);
284  $finalValue = ($firstValue === 'true' || $firstValue === true) ? 'true' : null;
285  } else {
286  $finalValue = ($value === 'true' || $value === true) ? 'true' : null;
287  }
288 
289  $reuseRequest->request->set($field, $finalValue);
290  }
291 
292  $reuseRequest->request->set('reuseSource', 'osselot');
293 
294  return $reuseRequest;
295  }
296 
297  $reuseSelector = $reuseRequest->get(ReuserAgentPlugin::UPLOAD_TO_REUSE_SELECTOR_NAME);
298  $reuseMode = $reuseRequest->get(ReuserAgentPlugin::REUSE_MODE);
299 
300  if (is_array($reuseSelector) && array_key_exists($originalFileName, $reuseSelector)) {
301  $reuseRequest->request->set(
303  $reuseSelector[$originalFileName]
304  );
305  }
306  if (is_array($reuseMode) && array_key_exists($originalFileName, $reuseMode)) {
307  $reuseRequest->request->set(
309  $reuseMode[$originalFileName]
310  );
311  }
312  return $reuseRequest;
313  }
314 }
315 
316 register_plugin(new UploadFilePage());
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 getGroupId()
Get the current user's group id.
Definition: Auth.php:80
render($templateName, $vars=null, $headers=null)
static getAgentPluginNames($hook='Agents')
Definition: MenuHook.php:16
UI element for reuser during Uploading new package.
const REUSE_MODE
Form element name for main license to reuse.
const UPLOAD_TO_REUSE_SELECTOR_NAME
Form element name for main license to reuse.
Upload a file from the users computer using the UI.
handleView(Request $request, $vars)
getRequestForReuse(Request $request, string $originalFileName)
Check if parameters exits for the request Create a new request object and update parameter expected v...
handleUpload(Request $request)
Process the upload request.
JobAddUpload($userId, $groupId, $job_name, $filename, $desc, $UploadMode, $folder_pk, $public_perm=Auth::PERM_NONE, $setGlobal=0)
Insert a new upload record, and update the foldercontents table.
Definition: common-job.php:56
plugin_find($pluginName)
Given the official name of a plugin, return the $Plugins object.