2011-01-23 03:33:00 +01:00
|
|
|
<?php
|
|
|
|
|
Move ALL files to serve from the alternate file domain, not just files without
"Content-Disposition: attachment"
Summary:
We currently serve some files off the primary domain (with "Content-Disposition:
attachment" + a CSRF check) and some files off the alternate domain (without
either).
This is not sufficient, because some UAs (like the iPad) ignore
"Content-Disposition: attachment". So there's an attack that goes like this:
- Alice uploads xss.html
- Alice says to Bob "hey download this file on your iPad"
- Bob clicks "Download" on Phabricator on his iPad, gets XSS'd.
NOTE: This removes the CSRF check for downloading files. The check is nice to
have but only raises the barrier to entry slightly. Between iPad / sniffing /
flash bytecode attacks, single-domain installs are simply insecure. We could
restore the check at some point in conjunction with a derived authentication
cookie (i.e., a mini-session-token which is only useful for downloading files),
but that's a lot of complexity to drop all at once.
(Because files are now authenticated only by knowing the PHID and secret key,
this also fixes the "no profile pictures in public feed while logged out"
issue.)
Test Plan: Viewed, info'd, and downloaded files
Reviewers: btrahan, arice, alok
Reviewed By: arice
CC: aran, epriestley
Maniphest Tasks: T843
Differential Revision: https://secure.phabricator.com/D1608
2012-02-14 23:52:27 +01:00
|
|
|
final class PhabricatorFileInfoController extends PhabricatorFileController {
|
2011-01-23 03:33:00 +01:00
|
|
|
|
|
|
|
private $phid;
|
|
|
|
|
|
|
|
public function willProcessRequest(array $data) {
|
|
|
|
$this->phid = $data['phid'];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function processRequest() {
|
Use phabricator_ time functions in more places
Summary:
Replace some more date() calls with locale-aware calls.
Also, at least on my system, the DateTimeZone / DateTime stuff didn't actually
work and always rendered in UTC. Fixed that.
Test Plan:
Viewed daemon console, differential revisions, files, and maniphest timestamps
in multiple timezones.
Reviewed By: toulouse
Reviewers: toulouse, fratrik, jungejason, aran, tuomaspelkonen
CC: aran, toulouse
Differential Revision: 530
2011-06-26 18:22:52 +02:00
|
|
|
$request = $this->getRequest();
|
|
|
|
$user = $request->getUser();
|
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
$file = id(new PhabricatorFileQuery())
|
|
|
|
->setViewer($user)
|
|
|
|
->withPHIDs(array($this->phid))
|
|
|
|
->executeOne();
|
|
|
|
|
2011-01-23 03:33:00 +01:00
|
|
|
if (!$file) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
2011-02-22 18:22:57 +01:00
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
$phid = $file->getPHID();
|
2013-09-05 22:11:02 +02:00
|
|
|
$xactions = id(new PhabricatorFileTransactionQuery())
|
|
|
|
->setViewer($user)
|
|
|
|
->withObjectPHIDs(array($phid))
|
|
|
|
->execute();
|
|
|
|
|
2013-10-01 17:43:34 +02:00
|
|
|
$handle_phids = array_merge(
|
|
|
|
array($file->getAuthorPHID()),
|
|
|
|
$file->getObjectPHIDs());
|
|
|
|
|
|
|
|
$this->loadHandles($handle_phids);
|
2013-09-17 18:12:37 +02:00
|
|
|
$header = id(new PHUIHeaderView())
|
2012-12-17 01:33:24 +01:00
|
|
|
->setHeader($file->getName());
|
|
|
|
|
2013-02-20 22:33:47 +01:00
|
|
|
$ttl = $file->getTTL();
|
|
|
|
if ($ttl !== null) {
|
|
|
|
$ttl_tag = id(new PhabricatorTagView())
|
|
|
|
->setType(PhabricatorTagView::TYPE_OBJECT)
|
|
|
|
->setName(pht("Temporary"));
|
|
|
|
$header->addTag($ttl_tag);
|
|
|
|
}
|
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
$actions = $this->buildActionView($file);
|
|
|
|
$properties = $this->buildPropertyView($file);
|
2013-09-05 22:11:02 +02:00
|
|
|
$timeline = $this->buildTransactionView($file, $xactions);
|
2013-04-10 22:08:36 +02:00
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
|
|
|
$crumbs->setActionList($actions);
|
|
|
|
$crumbs->addCrumb(
|
|
|
|
id(new PhabricatorCrumbView())
|
|
|
|
->setName('F'.$file->getID())
|
|
|
|
->setHref($this->getApplicationURI("/info/{$phid}/")));
|
|
|
|
|
2013-09-29 00:55:38 +02:00
|
|
|
$object_box = id(new PHUIObjectBoxView())
|
|
|
|
->setHeader($header)
|
Provide more structure to PHUIObjectBoxView
Summary:
Three changes here.
- Add `setActionList()`, and use that to set the action list.
- Add `setPropertyList()`, and use that to set the property list.
These will let us add some apropriate CSS so we can fix the border issue, and get rid of a bunch of goofy `.x + .y` selectors.
- Replace `addContent()` with `appendChild()`.
This is just a consistency thing; `AphrontView` already provides `appendChild()`, and `addContent()` did the same thing.
Test Plan:
- Viewed "All Config".
- Viewed a countdown.
- Viewed a revision (add comment, change list, table of contents, comment, local commits, open revisions affecting these files, update history).
- Viewed Diffusion (browse, change, history, repository, lint).
- Viewed Drydock (resource, lease).
- Viewed Files.
- Viewed Herald.
- Viewed Legalpad.
- Viewed macro (edit, edit audio, view).
- Viewed Maniphest.
- Viewed Applications.
- Viewed Paste.
- Viewed People.
- Viewed Phulux.
- Viewed Pholio.
- Viewed Phame (blog, post).
- Viewed Phortune (account, product).
- Viewed Ponder (questions, answers, comments).
- Viewed Releeph.
- Viewed Projects.
- Viewed Slowvote.
NOTE: Images in Files aren't on a black background anymore -- I assume that's on purpose?
NOTE: Some jankiness in Phortune, I'll clean that up when I get back to it. Not related to this diff.
Reviewers: chad
Reviewed By: chad
CC: aran
Differential Revision: https://secure.phabricator.com/D7174
2013-09-30 18:36:04 +02:00
|
|
|
->setActionList($actions)
|
|
|
|
->setPropertyList($properties);
|
2013-09-29 00:55:38 +02:00
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
return $this->buildApplicationPage(
|
|
|
|
array(
|
|
|
|
$crumbs,
|
2013-09-29 00:55:38 +02:00
|
|
|
$object_box,
|
2013-09-05 22:11:02 +02:00
|
|
|
$timeline
|
2012-12-17 01:33:24 +01:00
|
|
|
),
|
|
|
|
array(
|
|
|
|
'title' => $file->getName(),
|
|
|
|
'device' => true,
|
2013-09-05 22:11:02 +02:00
|
|
|
'pageObjects' => array($file->getPHID()),
|
2012-12-17 01:33:24 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2013-09-05 22:11:02 +02:00
|
|
|
private function buildTransactionView(
|
|
|
|
PhabricatorFile $file,
|
|
|
|
array $xactions) {
|
|
|
|
|
|
|
|
$user = $this->getRequest()->getUser();
|
|
|
|
$engine = id(new PhabricatorMarkupEngine())
|
|
|
|
->setViewer($user);
|
|
|
|
foreach ($xactions as $xaction) {
|
|
|
|
if ($xaction->getComment()) {
|
|
|
|
$engine->addObject(
|
|
|
|
$xaction->getComment(),
|
|
|
|
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$engine->process();
|
|
|
|
|
|
|
|
$timeline = id(new PhabricatorApplicationTransactionView())
|
|
|
|
->setUser($user)
|
|
|
|
->setObjectPHID($file->getPHID())
|
|
|
|
->setTransactions($xactions)
|
|
|
|
->setMarkupEngine($engine);
|
|
|
|
|
|
|
|
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
|
|
|
|
2013-09-17 18:12:37 +02:00
|
|
|
$add_comment_header = id(new PHUIHeaderView())
|
2013-09-05 22:11:02 +02:00
|
|
|
->setHeader(
|
|
|
|
$is_serious
|
|
|
|
? pht('Add Comment')
|
|
|
|
: pht('Question File Integrity'));
|
|
|
|
|
|
|
|
$submit_button_name = $is_serious
|
|
|
|
? pht('Add Comment')
|
|
|
|
: pht('Debate the Bits');
|
|
|
|
|
|
|
|
$draft = PhabricatorDraft::newFromUserAndKey($user, $file->getPHID());
|
|
|
|
|
|
|
|
$add_comment_form = id(new PhabricatorApplicationTransactionCommentView())
|
|
|
|
->setUser($user)
|
|
|
|
->setObjectPHID($file->getPHID())
|
|
|
|
->setDraft($draft)
|
|
|
|
->setAction($this->getApplicationURI('/comment/'.$file->getID().'/'))
|
|
|
|
->setSubmitButtonName($submit_button_name);
|
|
|
|
|
2013-09-29 00:55:38 +02:00
|
|
|
$comment_box = id(new PHUIObjectBoxView())
|
|
|
|
->setFlush(true)
|
|
|
|
->setHeader($add_comment_header)
|
Provide more structure to PHUIObjectBoxView
Summary:
Three changes here.
- Add `setActionList()`, and use that to set the action list.
- Add `setPropertyList()`, and use that to set the property list.
These will let us add some apropriate CSS so we can fix the border issue, and get rid of a bunch of goofy `.x + .y` selectors.
- Replace `addContent()` with `appendChild()`.
This is just a consistency thing; `AphrontView` already provides `appendChild()`, and `addContent()` did the same thing.
Test Plan:
- Viewed "All Config".
- Viewed a countdown.
- Viewed a revision (add comment, change list, table of contents, comment, local commits, open revisions affecting these files, update history).
- Viewed Diffusion (browse, change, history, repository, lint).
- Viewed Drydock (resource, lease).
- Viewed Files.
- Viewed Herald.
- Viewed Legalpad.
- Viewed macro (edit, edit audio, view).
- Viewed Maniphest.
- Viewed Applications.
- Viewed Paste.
- Viewed People.
- Viewed Phulux.
- Viewed Pholio.
- Viewed Phame (blog, post).
- Viewed Phortune (account, product).
- Viewed Ponder (questions, answers, comments).
- Viewed Releeph.
- Viewed Projects.
- Viewed Slowvote.
NOTE: Images in Files aren't on a black background anymore -- I assume that's on purpose?
NOTE: Some jankiness in Phortune, I'll clean that up when I get back to it. Not related to this diff.
Reviewers: chad
Reviewed By: chad
CC: aran
Differential Revision: https://secure.phabricator.com/D7174
2013-09-30 18:36:04 +02:00
|
|
|
->appendChild($add_comment_form);
|
2013-09-29 00:55:38 +02:00
|
|
|
|
2013-09-05 22:11:02 +02:00
|
|
|
return array(
|
|
|
|
$timeline,
|
2013-09-29 00:55:38 +02:00
|
|
|
$comment_box);
|
2013-09-05 22:11:02 +02:00
|
|
|
}
|
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
private function buildActionView(PhabricatorFile $file) {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$user = $request->getUser();
|
2011-07-08 06:17:00 +02:00
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
$id = $file->getID();
|
2011-02-22 18:22:57 +01:00
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
$view = id(new PhabricatorActionListView())
|
|
|
|
->setUser($user)
|
2013-07-12 20:39:47 +02:00
|
|
|
->setObjectURI($this->getRequest()->getRequestURI())
|
2012-12-17 01:33:24 +01:00
|
|
|
->setObject($file);
|
2012-01-16 22:26:44 +01:00
|
|
|
|
2011-02-22 18:19:14 +01:00
|
|
|
if ($file->isViewableInBrowser()) {
|
2012-12-17 01:33:24 +01:00
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('View File'))
|
|
|
|
->setIcon('preview')
|
|
|
|
->setHref($file->getViewURI()));
|
2011-02-22 18:19:14 +01:00
|
|
|
} else {
|
2012-12-17 01:33:24 +01:00
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setUser($user)
|
|
|
|
->setRenderAsForm(true)
|
2013-01-29 03:12:09 +01:00
|
|
|
->setDownload(true)
|
2012-12-17 01:33:24 +01:00
|
|
|
->setName(pht('Download File'))
|
|
|
|
->setIcon('download')
|
|
|
|
->setHref($file->getViewURI()));
|
2012-01-16 22:26:44 +01:00
|
|
|
}
|
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
$view->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setName(pht('Delete File'))
|
|
|
|
->setIcon('delete')
|
|
|
|
->setHref($this->getApplicationURI("/delete/{$id}/"))
|
|
|
|
->setWorkflow(true));
|
|
|
|
|
|
|
|
return $view;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildPropertyView(PhabricatorFile $file) {
|
|
|
|
$request = $this->getRequest();
|
|
|
|
$user = $request->getUser();
|
|
|
|
|
|
|
|
$view = id(new PhabricatorPropertyListView());
|
|
|
|
|
|
|
|
if ($file->getAuthorPHID()) {
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Author'),
|
|
|
|
$this->getHandle($file->getAuthorPHID())->renderLink());
|
2011-02-22 18:19:14 +01:00
|
|
|
}
|
2011-07-30 01:01:59 +02:00
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
$view->addProperty(
|
|
|
|
pht('Created'),
|
|
|
|
phabricator_datetime($file->getDateCreated(), $user));
|
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Size'),
|
|
|
|
phabricator_format_bytes($file->getByteSize()));
|
|
|
|
|
|
|
|
$view->addSectionHeader(pht('Technical Details'));
|
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Mime Type'),
|
2013-01-29 20:01:47 +01:00
|
|
|
$file->getMimeType());
|
2012-12-17 01:33:24 +01:00
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Engine'),
|
2013-01-29 20:01:47 +01:00
|
|
|
$file->getStorageEngine());
|
2012-12-17 01:33:24 +01:00
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Format'),
|
2013-01-29 20:01:47 +01:00
|
|
|
$file->getStorageFormat());
|
2012-12-17 01:33:24 +01:00
|
|
|
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Handle'),
|
2013-01-29 20:01:47 +01:00
|
|
|
$file->getStorageHandle());
|
2012-12-17 01:33:24 +01:00
|
|
|
|
2013-01-07 18:43:35 +01:00
|
|
|
$metadata = $file->getMetadata();
|
|
|
|
if (!empty($metadata)) {
|
|
|
|
$view->addSectionHeader(pht('Metadata'));
|
|
|
|
|
|
|
|
foreach ($metadata as $key => $value) {
|
|
|
|
$view->addProperty(
|
|
|
|
PhabricatorFile::getMetadataName($key),
|
2013-01-29 20:01:47 +01:00
|
|
|
$value);
|
2013-01-07 18:43:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-01 17:43:34 +02:00
|
|
|
$phids = $file->getObjectPHIDs();
|
|
|
|
if ($phids) {
|
|
|
|
$view->addSectionHeader(pht('Attached'));
|
|
|
|
$view->addProperty(
|
|
|
|
pht('Attached To'),
|
|
|
|
$this->renderHandlesForPHIDs($phids));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-18 15:19:32 +01:00
|
|
|
if ($file->isViewableImage()) {
|
2012-12-17 01:33:24 +01:00
|
|
|
|
2013-01-18 03:39:02 +01:00
|
|
|
$image = phutil_tag(
|
2012-12-17 01:33:24 +01:00
|
|
|
'img',
|
2012-01-16 15:54:08 +01:00
|
|
|
array(
|
2012-12-17 01:33:24 +01:00
|
|
|
'src' => $file->getViewURI(),
|
|
|
|
'class' => 'phabricator-property-list-image',
|
2012-01-16 15:54:08 +01:00
|
|
|
));
|
|
|
|
|
2013-01-18 09:32:58 +01:00
|
|
|
$linked_image = phutil_tag(
|
2012-12-17 01:33:24 +01:00
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => $file->getViewURI(),
|
|
|
|
),
|
|
|
|
$image);
|
|
|
|
|
2013-02-27 01:37:45 +01:00
|
|
|
$view->addImageContent($linked_image);
|
2013-09-27 19:51:25 +02:00
|
|
|
} else if ($file->isAudio()) {
|
|
|
|
$audio = phutil_tag(
|
|
|
|
'audio',
|
|
|
|
array(
|
|
|
|
'controls' => 'controls',
|
|
|
|
'class' => 'phabricator-property-list-audio',
|
|
|
|
),
|
|
|
|
phutil_tag(
|
|
|
|
'source',
|
|
|
|
array(
|
|
|
|
'src' => $file->getViewURI(),
|
|
|
|
'type' => $file->getMimeType(),
|
|
|
|
)));
|
|
|
|
$view->addImageContent($audio);
|
2012-01-16 15:54:08 +01:00
|
|
|
}
|
2011-05-22 23:40:51 +02:00
|
|
|
|
2012-12-17 01:33:24 +01:00
|
|
|
return $view;
|
2011-01-23 03:33:00 +01:00
|
|
|
}
|
2012-12-17 01:33:24 +01:00
|
|
|
|
2011-01-23 03:33:00 +01:00
|
|
|
}
|