Summary: we used to need this function for security purposes, but no longer need it. remove it so that some call sites can be optimized via smarter data fetching, and so the whole codebase can have one less thing in it. Test Plan: verified the images displayed properly for each of the following - viewed a diff with added images. - viewed a user feed - viewed a user profile - viewed all image macros - viewed a paste and clicked through "raw link" weakness in testing around proxy files and transformed files. not sure what these are. changes here are very programmatic however. Reviewers: epriestley Reviewed By: epriestley CC: aran, btrahan, epriestley Maniphest Tasks: T672 Differential Revision: https://secure.phabricator.com/D1354
224 lines
6.5 KiB
PHP
224 lines
6.5 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright 2012 Facebook, Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
class PhabricatorFileViewController extends PhabricatorFileController {
|
|
|
|
private $phid;
|
|
private $view;
|
|
|
|
public function willProcessRequest(array $data) {
|
|
$this->phid = $data['phid'];
|
|
$this->view = $data['view'];
|
|
}
|
|
|
|
public function processRequest() {
|
|
|
|
$request = $this->getRequest();
|
|
$user = $request->getUser();
|
|
|
|
$file = id(new PhabricatorFile())->loadOneWhere(
|
|
'phid = %s',
|
|
$this->phid);
|
|
if (!$file) {
|
|
return new Aphront404Response();
|
|
}
|
|
|
|
switch ($this->view) {
|
|
case 'download':
|
|
case 'view':
|
|
$data = $file->loadFileData();
|
|
$response = new AphrontFileResponse();
|
|
$response->setContent($data);
|
|
$response->setCacheDurationInSeconds(60 * 60 * 24 * 30);
|
|
|
|
if ($this->view == 'view') {
|
|
if (!$file->isViewableInBrowser()) {
|
|
return new Aphront400Response();
|
|
}
|
|
$download = false;
|
|
} else {
|
|
$download = true;
|
|
}
|
|
|
|
if ($download) {
|
|
if (!$request->isFormPost()) {
|
|
// Require a POST to download files to hinder attacks where you
|
|
// <applet src="http://phabricator.example.com/file/..." /> on some
|
|
// other domain.
|
|
return id(new AphrontRedirectResponse())
|
|
->setURI($file->getInfoURI());
|
|
}
|
|
}
|
|
|
|
if ($download) {
|
|
$mime_type = $file->getMimeType();
|
|
} else {
|
|
$mime_type = $file->getViewableMimeType();
|
|
}
|
|
|
|
// If an alternate file domain is configured, forbid all views which
|
|
// don't originate from it.
|
|
if (!$download) {
|
|
$alt = PhabricatorEnv::getEnvConfig('security.alternate-file-domain');
|
|
if ($alt) {
|
|
$domain = id(new PhutilURI($alt))->getDomain();
|
|
if ($domain != $request->getHost()) {
|
|
return new Aphront400Response();
|
|
}
|
|
}
|
|
}
|
|
|
|
$response->setMimeType($mime_type);
|
|
|
|
if ($download) {
|
|
$response->setDownload($file->getName());
|
|
}
|
|
return $response;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
$author_child = null;
|
|
if ($file->getAuthorPHID()) {
|
|
$author = id(new PhabricatorUser())->loadOneWhere(
|
|
'phid = %s',
|
|
$file->getAuthorPHID());
|
|
|
|
if ($author) {
|
|
$author_child = id(new AphrontFormStaticControl())
|
|
->setLabel('Author')
|
|
->setName('author')
|
|
->setValue($author->getUserName());
|
|
}
|
|
}
|
|
|
|
$form = new AphrontFormView();
|
|
|
|
if ($file->isViewableInBrowser()) {
|
|
$form->setAction($file->getViewURI());
|
|
$button_name = 'View File';
|
|
} else {
|
|
$form->setAction('/file/download/'.$file->getPHID().'/');
|
|
$button_name = 'Download File';
|
|
}
|
|
|
|
$file_id = 'F'.$file->getID();
|
|
|
|
$form->setUser($user);
|
|
$form
|
|
->appendChild(
|
|
id(new AphrontFormStaticControl())
|
|
->setLabel('Name')
|
|
->setName('name')
|
|
->setValue($file->getName()))
|
|
->appendChild(
|
|
id(new AphrontFormStaticControl())
|
|
->setLabel('ID')
|
|
->setName('id')
|
|
->setValue($file_id)
|
|
->setCaption(
|
|
'Download this file with: <tt>arc download '.
|
|
phutil_escape_html($file_id).'</tt>'))
|
|
->appendChild(
|
|
id(new AphrontFormStaticControl())
|
|
->setLabel('PHID')
|
|
->setName('phid')
|
|
->setValue($file->getPHID()))
|
|
->appendChild($author_child)
|
|
->appendChild(
|
|
id(new AphrontFormStaticControl())
|
|
->setLabel('Created')
|
|
->setName('created')
|
|
->setValue(phabricator_datetime($file->getDateCreated(), $user)))
|
|
->appendChild(
|
|
id(new AphrontFormStaticControl())
|
|
->setLabel('Mime Type')
|
|
->setName('mime')
|
|
->setValue($file->getMimeType()))
|
|
->appendChild(
|
|
id(new AphrontFormStaticControl())
|
|
->setLabel('Size')
|
|
->setName('size')
|
|
->setValue($file->getByteSize().' bytes'))
|
|
->appendChild(
|
|
id(new AphrontFormStaticControl())
|
|
->setLabel('Engine')
|
|
->setName('storageEngine')
|
|
->setValue($file->getStorageEngine()))
|
|
->appendChild(
|
|
id(new AphrontFormStaticControl())
|
|
->setLabel('Format')
|
|
->setName('storageFormat')
|
|
->setValue($file->getStorageFormat()))
|
|
->appendChild(
|
|
id(new AphrontFormStaticControl())
|
|
->setLabel('Handle')
|
|
->setName('storageHandle')
|
|
->setValue($file->getStorageHandle()))
|
|
->appendChild(
|
|
id(new AphrontFormSubmitControl())
|
|
->setValue($button_name));
|
|
|
|
$panel = new AphrontPanelView();
|
|
$panel->setHeader('File Info - '.$file->getName());
|
|
|
|
$panel->appendChild($form);
|
|
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
|
|
|
|
|
$transformations = id(new PhabricatorTransformedFile())->loadAllWhere(
|
|
'originalPHID = %s',
|
|
$file->getPHID());
|
|
$transformed_phids = mpull($transformations, 'getTransformedPHID');
|
|
$transformed_files = id(new PhabricatorFile())->loadAllWhere(
|
|
'phid in (%Ls)',
|
|
$transformed_phids);
|
|
$transformed_map = mpull($transformed_files, null, 'getPHID');
|
|
$rows = array();
|
|
foreach ($transformations as $transformed) {
|
|
$phid = $transformed->getTransformedPHID();
|
|
$rows[] = array(
|
|
phutil_escape_html($transformed->getTransform()),
|
|
phutil_render_tag(
|
|
'a',
|
|
array(
|
|
'href' => $transformed_map[$phid]->getBestURI(),
|
|
),
|
|
$phid));
|
|
}
|
|
|
|
$table = new AphrontTableView($rows);
|
|
$table->setHeaders(
|
|
array(
|
|
'Transform',
|
|
'File',
|
|
));
|
|
|
|
$xform_panel = new AphrontPanelView();
|
|
$xform_panel->appendChild($table);
|
|
$xform_panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
|
$xform_panel->setHeader('Transformations');
|
|
|
|
return $this->buildStandardPageResponse(
|
|
array($panel, $xform_panel),
|
|
array(
|
|
'title' => 'File Info - '.$file->getName(),
|
|
));
|
|
}
|
|
}
|