1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-19 03:50:54 +01:00
phorge-phorge/src/applications/macro/controller/PhabricatorMacroEditController.php

289 lines
8.3 KiB
PHP
Raw Normal View History

<?php
final class PhabricatorMacroEditController extends PhabricatorMacroController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, 'id');
}
public function processRequest() {
$this->requireApplicationCapability(
PhabricatorMacroManageCapability::CAPABILITY);
$request = $this->getRequest();
$user = $request->getUser();
if ($this->id) {
$macro = id(new PhabricatorMacroQuery())
->setViewer($user)
->withIDs(array($this->id))
->needFiles(true)
->executeOne();
if (!$macro) {
return new Aphront404Response();
}
} else {
$macro = new PhabricatorFileImageMacro();
$macro->setAuthorPHID($user->getPHID());
}
$errors = array();
$e_name = true;
$e_file = null;
$file = null;
if ($request->isFormPost()) {
$original = clone $macro;
$new_name = null;
if ($request->getBool('name_form') || !$macro->getID()) {
$new_name = $request->getStr('name');
$macro->setName($new_name);
if (!strlen($macro->getName())) {
$errors[] = pht('Macro name is required.');
$e_name = pht('Required');
} else if (!preg_match('/^[a-z0-9:_-]{3,}\z/', $macro->getName())) {
$errors[] = pht(
'Macro must be at least three characters long and contain only '.
'lowercase letters, digits, hyphens, colons and underscores.');
$e_name = pht('Invalid');
} else {
$e_name = null;
}
}
Improve granluarity and defaults of `security.allow-outbound-http` Summary: Ref T6755. This is a partial fix, but: - Allow netblocks to be blacklisted instead of making the feature all-or-nothing. - Default to disallow requests to all reserved private/local/special IP blocks. This should generally be a "safe" setting. - Explain the risks better. - Improve the errors rasied by Macro when failing. - Removed `security.allow-outbound-http`, as it is superseded by this setting and is somewhat misleading. - We still make outbound HTTP requests to OAuth. - We still make outbound HTTP requests for repositories. From a technical perspective: - Separate URIs that are safe to link to or redirect to (basically, not "javascript://") from URIs that are safe to fetch (nothing in a private block). - Add the default blacklist. - Be more careful with response data in Macro fetching, and don't let the user see it if it isn't ultimately valid. Additionally: - I want to do this check before pulling repositories, but that's enough of a mess that it should go in a separate diff. - The future implementation of T4190 needs to perform the fetch check. Test Plan: - Fetched a valid macro. - Fetched a non-image, verified it didn't result in a viewable file. - Fetched a private-ip-space image, got an error. - Fetched a 404, got a useful-enough error without additional revealing response content (which is usually HTML anyway and not useful). - Fetched a bad protocol, got an error. - Linked to a local resource, a phriction page, a valid remote site, all worked. - Linked to private IP space, which worked fine (we want to let you link and redierect to other private services, just not fetch them). - Added and executed unit tests. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6755 Differential Revision: https://secure.phabricator.com/D12136
2015-03-23 18:44:03 +01:00
$uri = $request->getStr('url');
$engine = new PhabricatorDestructionEngine();
$file = null;
if ($request->getFileExists('file')) {
$file = PhabricatorFile::newFromPHPUpload(
$_FILES['file'],
array(
'name' => $request->getStr('name'),
'authorPHID' => $user->getPHID(),
'isExplicitUpload' => true,
'canCDN' => true,
));
Improve granluarity and defaults of `security.allow-outbound-http` Summary: Ref T6755. This is a partial fix, but: - Allow netblocks to be blacklisted instead of making the feature all-or-nothing. - Default to disallow requests to all reserved private/local/special IP blocks. This should generally be a "safe" setting. - Explain the risks better. - Improve the errors rasied by Macro when failing. - Removed `security.allow-outbound-http`, as it is superseded by this setting and is somewhat misleading. - We still make outbound HTTP requests to OAuth. - We still make outbound HTTP requests for repositories. From a technical perspective: - Separate URIs that are safe to link to or redirect to (basically, not "javascript://") from URIs that are safe to fetch (nothing in a private block). - Add the default blacklist. - Be more careful with response data in Macro fetching, and don't let the user see it if it isn't ultimately valid. Additionally: - I want to do this check before pulling repositories, but that's enough of a mess that it should go in a separate diff. - The future implementation of T4190 needs to perform the fetch check. Test Plan: - Fetched a valid macro. - Fetched a non-image, verified it didn't result in a viewable file. - Fetched a private-ip-space image, got an error. - Fetched a 404, got a useful-enough error without additional revealing response content (which is usually HTML anyway and not useful). - Fetched a bad protocol, got an error. - Linked to a local resource, a phriction page, a valid remote site, all worked. - Linked to private IP space, which worked fine (we want to let you link and redierect to other private services, just not fetch them). - Added and executed unit tests. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6755 Differential Revision: https://secure.phabricator.com/D12136
2015-03-23 18:44:03 +01:00
} else if ($uri) {
try {
$file = PhabricatorFile::newFromFileDownload(
Improve granluarity and defaults of `security.allow-outbound-http` Summary: Ref T6755. This is a partial fix, but: - Allow netblocks to be blacklisted instead of making the feature all-or-nothing. - Default to disallow requests to all reserved private/local/special IP blocks. This should generally be a "safe" setting. - Explain the risks better. - Improve the errors rasied by Macro when failing. - Removed `security.allow-outbound-http`, as it is superseded by this setting and is somewhat misleading. - We still make outbound HTTP requests to OAuth. - We still make outbound HTTP requests for repositories. From a technical perspective: - Separate URIs that are safe to link to or redirect to (basically, not "javascript://") from URIs that are safe to fetch (nothing in a private block). - Add the default blacklist. - Be more careful with response data in Macro fetching, and don't let the user see it if it isn't ultimately valid. Additionally: - I want to do this check before pulling repositories, but that's enough of a mess that it should go in a separate diff. - The future implementation of T4190 needs to perform the fetch check. Test Plan: - Fetched a valid macro. - Fetched a non-image, verified it didn't result in a viewable file. - Fetched a private-ip-space image, got an error. - Fetched a 404, got a useful-enough error without additional revealing response content (which is usually HTML anyway and not useful). - Fetched a bad protocol, got an error. - Linked to a local resource, a phriction page, a valid remote site, all worked. - Linked to private IP space, which worked fine (we want to let you link and redierect to other private services, just not fetch them). - Added and executed unit tests. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6755 Differential Revision: https://secure.phabricator.com/D12136
2015-03-23 18:44:03 +01:00
$uri,
array(
'name' => $request->getStr('name'),
Improve granluarity and defaults of `security.allow-outbound-http` Summary: Ref T6755. This is a partial fix, but: - Allow netblocks to be blacklisted instead of making the feature all-or-nothing. - Default to disallow requests to all reserved private/local/special IP blocks. This should generally be a "safe" setting. - Explain the risks better. - Improve the errors rasied by Macro when failing. - Removed `security.allow-outbound-http`, as it is superseded by this setting and is somewhat misleading. - We still make outbound HTTP requests to OAuth. - We still make outbound HTTP requests for repositories. From a technical perspective: - Separate URIs that are safe to link to or redirect to (basically, not "javascript://") from URIs that are safe to fetch (nothing in a private block). - Add the default blacklist. - Be more careful with response data in Macro fetching, and don't let the user see it if it isn't ultimately valid. Additionally: - I want to do this check before pulling repositories, but that's enough of a mess that it should go in a separate diff. - The future implementation of T4190 needs to perform the fetch check. Test Plan: - Fetched a valid macro. - Fetched a non-image, verified it didn't result in a viewable file. - Fetched a private-ip-space image, got an error. - Fetched a 404, got a useful-enough error without additional revealing response content (which is usually HTML anyway and not useful). - Fetched a bad protocol, got an error. - Linked to a local resource, a phriction page, a valid remote site, all worked. - Linked to private IP space, which worked fine (we want to let you link and redierect to other private services, just not fetch them). - Added and executed unit tests. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6755 Differential Revision: https://secure.phabricator.com/D12136
2015-03-23 18:44:03 +01:00
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
'isExplicitUpload' => true,
'canCDN' => true,
));
Improve granluarity and defaults of `security.allow-outbound-http` Summary: Ref T6755. This is a partial fix, but: - Allow netblocks to be blacklisted instead of making the feature all-or-nothing. - Default to disallow requests to all reserved private/local/special IP blocks. This should generally be a "safe" setting. - Explain the risks better. - Improve the errors rasied by Macro when failing. - Removed `security.allow-outbound-http`, as it is superseded by this setting and is somewhat misleading. - We still make outbound HTTP requests to OAuth. - We still make outbound HTTP requests for repositories. From a technical perspective: - Separate URIs that are safe to link to or redirect to (basically, not "javascript://") from URIs that are safe to fetch (nothing in a private block). - Add the default blacklist. - Be more careful with response data in Macro fetching, and don't let the user see it if it isn't ultimately valid. Additionally: - I want to do this check before pulling repositories, but that's enough of a mess that it should go in a separate diff. - The future implementation of T4190 needs to perform the fetch check. Test Plan: - Fetched a valid macro. - Fetched a non-image, verified it didn't result in a viewable file. - Fetched a private-ip-space image, got an error. - Fetched a 404, got a useful-enough error without additional revealing response content (which is usually HTML anyway and not useful). - Fetched a bad protocol, got an error. - Linked to a local resource, a phriction page, a valid remote site, all worked. - Linked to private IP space, which worked fine (we want to let you link and redierect to other private services, just not fetch them). - Added and executed unit tests. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6755 Differential Revision: https://secure.phabricator.com/D12136
2015-03-23 18:44:03 +01:00
if (!$file->isViewableInBrowser()) {
$mime_type = $file->getMimeType();
$engine->destroyObject($file);
$file = null;
throw new Exception(
pht(
'The URI "%s" does not correspond to a valid image file, got '.
'a file with MIME type "%s". You must specify the URI of a '.
'valid image file.',
$uri,
$mime_type));
} else {
$file
->setAuthorPHID($user->getPHID())
->save();
}
} catch (HTTPFutureHTTPResponseStatus $status) {
$errors[] = pht(
'The URI "%s" could not be loaded, got %s error.',
$uri,
$status->getStatusCode());
} catch (Exception $ex) {
Improve granluarity and defaults of `security.allow-outbound-http` Summary: Ref T6755. This is a partial fix, but: - Allow netblocks to be blacklisted instead of making the feature all-or-nothing. - Default to disallow requests to all reserved private/local/special IP blocks. This should generally be a "safe" setting. - Explain the risks better. - Improve the errors rasied by Macro when failing. - Removed `security.allow-outbound-http`, as it is superseded by this setting and is somewhat misleading. - We still make outbound HTTP requests to OAuth. - We still make outbound HTTP requests for repositories. From a technical perspective: - Separate URIs that are safe to link to or redirect to (basically, not "javascript://") from URIs that are safe to fetch (nothing in a private block). - Add the default blacklist. - Be more careful with response data in Macro fetching, and don't let the user see it if it isn't ultimately valid. Additionally: - I want to do this check before pulling repositories, but that's enough of a mess that it should go in a separate diff. - The future implementation of T4190 needs to perform the fetch check. Test Plan: - Fetched a valid macro. - Fetched a non-image, verified it didn't result in a viewable file. - Fetched a private-ip-space image, got an error. - Fetched a 404, got a useful-enough error without additional revealing response content (which is usually HTML anyway and not useful). - Fetched a bad protocol, got an error. - Linked to a local resource, a phriction page, a valid remote site, all worked. - Linked to private IP space, which worked fine (we want to let you link and redierect to other private services, just not fetch them). - Added and executed unit tests. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6755 Differential Revision: https://secure.phabricator.com/D12136
2015-03-23 18:44:03 +01:00
$errors[] = $ex->getMessage();
}
} else if ($request->getStr('phid')) {
$file = id(new PhabricatorFileQuery())
->setViewer($user)
->withPHIDs(array($request->getStr('phid')))
->executeOne();
}
if ($file) {
if (!$file->isViewableInBrowser()) {
$errors[] = pht('You must upload an image.');
$e_file = pht('Invalid');
} else {
$macro->setFilePHID($file->getPHID());
$macro->attachFile($file);
$e_file = null;
}
}
if (!$macro->getID() && !$file) {
$errors[] = pht('You must upload an image to create a macro.');
$e_file = pht('Required');
}
if (!$errors) {
try {
$xactions = array();
if ($new_name !== null) {
$xactions[] = id(new PhabricatorMacroTransaction())
->setTransactionType(PhabricatorMacroTransactionType::TYPE_NAME)
->setNewValue($new_name);
}
if ($file) {
$xactions[] = id(new PhabricatorMacroTransaction())
->setTransactionType(PhabricatorMacroTransactionType::TYPE_FILE)
->setNewValue($file->getPHID());
}
$editor = id(new PhabricatorMacroEditor())
->setActor($user)
Add ApplicationTransaction handling for transactions with no effect Summary: When a user submits an action with no effect (like an empty comment, an "abandon" on an already-accepted revision, or a "close, resolved" on a closed task) we want to alert them that their action isn't effective. These warnings fall into two general buckets: - User is submitting two or more actions, and some aren't effective but some are. Prompt them to apply the effective actions only. - A special case of this is where the only effective action is a comment. We provide tailored text ("Post Comment") in this case. - User is submitting one action, which isn't effective. Tell them they're out of luck. - A special case of this is an empty comment. We provide tailored text in this case. By default, the transaction editor throws when transactions have no effect. The caller can then deal with this, or use `PhabricatorApplicationTransactionNoEffectResponse` to provide a standard dialog that gives the user information as above. For cases where we expect transactions to have no effect (notably, "edit" forms) we just continue on no-effect unconditionally. Also fix an issue where new, combined or filtered transactions would not be represented properly in the Ajax response (i.e., return final transactions from `applyTransactions()`), and translate some strings. Test Plan: - Submitted empty and nonempy comments in Macro and Pholio. - Submitted comments with new and existing "@mentions". - Submitted edits in both applications. Reviewers: btrahan, vrana Reviewed By: btrahan CC: aran Maniphest Tasks: T912, T2104 Differential Revision: https://secure.phabricator.com/D4160
2012-12-12 02:27:40 +01:00
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request);
Add ApplicationTransaction handling for transactions with no effect Summary: When a user submits an action with no effect (like an empty comment, an "abandon" on an already-accepted revision, or a "close, resolved" on a closed task) we want to alert them that their action isn't effective. These warnings fall into two general buckets: - User is submitting two or more actions, and some aren't effective but some are. Prompt them to apply the effective actions only. - A special case of this is where the only effective action is a comment. We provide tailored text ("Post Comment") in this case. - User is submitting one action, which isn't effective. Tell them they're out of luck. - A special case of this is an empty comment. We provide tailored text in this case. By default, the transaction editor throws when transactions have no effect. The caller can then deal with this, or use `PhabricatorApplicationTransactionNoEffectResponse` to provide a standard dialog that gives the user information as above. For cases where we expect transactions to have no effect (notably, "edit" forms) we just continue on no-effect unconditionally. Also fix an issue where new, combined or filtered transactions would not be represented properly in the Ajax response (i.e., return final transactions from `applyTransactions()`), and translate some strings. Test Plan: - Submitted empty and nonempy comments in Macro and Pholio. - Submitted comments with new and existing "@mentions". - Submitted edits in both applications. Reviewers: btrahan, vrana Reviewed By: btrahan CC: aran Maniphest Tasks: T912, T2104 Differential Revision: https://secure.phabricator.com/D4160
2012-12-12 02:27:40 +01:00
$xactions = $editor->applyTransactions($original, $xactions);
$view_uri = $this->getApplicationURI('/view/'.$original->getID().'/');
return id(new AphrontRedirectResponse())->setURI($view_uri);
} catch (AphrontDuplicateKeyQueryException $ex) {
throw $ex;
$errors[] = pht('Macro name is not unique!');
$e_name = pht('Duplicate');
}
}
}
$current_file = null;
if ($macro->getFilePHID()) {
$current_file = $macro->getFile();
}
$form = new AphrontFormView();
$form->addHiddenInput('name_form', 1);
$form->setUser($request->getUser());
$form
->setEncType('multipart/form-data')
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setName('name')
->setValue($macro->getName())
->setCaption(
pht('This word or phrase will be replaced with the image.'))
->setError($e_name));
if (!$macro->getID()) {
if ($current_file) {
$current_file_view = id(new PhabricatorFileLinkView())
->setFilePHID($current_file->getPHID())
->setFileName($current_file->getName())
->setFileViewable(true)
->setFileViewURI($current_file->getBestURI())
->render();
$form->addHiddenInput('phid', $current_file->getPHID());
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Selected File'))
->setValue($current_file_view));
$other_label = pht('Change File');
} else {
$other_label = pht('File');
}
Improve granluarity and defaults of `security.allow-outbound-http` Summary: Ref T6755. This is a partial fix, but: - Allow netblocks to be blacklisted instead of making the feature all-or-nothing. - Default to disallow requests to all reserved private/local/special IP blocks. This should generally be a "safe" setting. - Explain the risks better. - Improve the errors rasied by Macro when failing. - Removed `security.allow-outbound-http`, as it is superseded by this setting and is somewhat misleading. - We still make outbound HTTP requests to OAuth. - We still make outbound HTTP requests for repositories. From a technical perspective: - Separate URIs that are safe to link to or redirect to (basically, not "javascript://") from URIs that are safe to fetch (nothing in a private block). - Add the default blacklist. - Be more careful with response data in Macro fetching, and don't let the user see it if it isn't ultimately valid. Additionally: - I want to do this check before pulling repositories, but that's enough of a mess that it should go in a separate diff. - The future implementation of T4190 needs to perform the fetch check. Test Plan: - Fetched a valid macro. - Fetched a non-image, verified it didn't result in a viewable file. - Fetched a private-ip-space image, got an error. - Fetched a 404, got a useful-enough error without additional revealing response content (which is usually HTML anyway and not useful). - Fetched a bad protocol, got an error. - Linked to a local resource, a phriction page, a valid remote site, all worked. - Linked to private IP space, which worked fine (we want to let you link and redierect to other private services, just not fetch them). - Added and executed unit tests. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6755 Differential Revision: https://secure.phabricator.com/D12136
2015-03-23 18:44:03 +01:00
$form->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('URL'))
->setName('url')
->setValue($request->getStr('url'))
->setError($request->getFileExists('file') ? false : $e_file));
$form->appendChild(
id(new AphrontFormFileControl())
->setLabel($other_label)
->setName('file')
->setError($request->getStr('url') ? false : $e_file));
}
$view_uri = $this->getApplicationURI('/view/'.$macro->getID().'/');
if ($macro->getID()) {
$cancel_uri = $view_uri;
} else {
$cancel_uri = $this->getApplicationURI();
}
$form
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Save Image Macro'))
->addCancelButton($cancel_uri));
$crumbs = $this->buildApplicationCrumbs();
if ($macro->getID()) {
$title = pht('Edit Image Macro');
$crumb = pht('Edit Macro');
$crumbs->addTextCrumb(pht('Macro "%s"', $macro->getName()), $view_uri);
} else {
$title = pht('Create Image Macro');
$crumb = pht('Create Macro');
}
$crumbs->addTextCrumb($crumb, $request->getRequestURI());
$upload = null;
if ($macro->getID()) {
$upload_form = id(new AphrontFormView())
->setEncType('multipart/form-data')
->setUser($request->getUser());
Improve granluarity and defaults of `security.allow-outbound-http` Summary: Ref T6755. This is a partial fix, but: - Allow netblocks to be blacklisted instead of making the feature all-or-nothing. - Default to disallow requests to all reserved private/local/special IP blocks. This should generally be a "safe" setting. - Explain the risks better. - Improve the errors rasied by Macro when failing. - Removed `security.allow-outbound-http`, as it is superseded by this setting and is somewhat misleading. - We still make outbound HTTP requests to OAuth. - We still make outbound HTTP requests for repositories. From a technical perspective: - Separate URIs that are safe to link to or redirect to (basically, not "javascript://") from URIs that are safe to fetch (nothing in a private block). - Add the default blacklist. - Be more careful with response data in Macro fetching, and don't let the user see it if it isn't ultimately valid. Additionally: - I want to do this check before pulling repositories, but that's enough of a mess that it should go in a separate diff. - The future implementation of T4190 needs to perform the fetch check. Test Plan: - Fetched a valid macro. - Fetched a non-image, verified it didn't result in a viewable file. - Fetched a private-ip-space image, got an error. - Fetched a 404, got a useful-enough error without additional revealing response content (which is usually HTML anyway and not useful). - Fetched a bad protocol, got an error. - Linked to a local resource, a phriction page, a valid remote site, all worked. - Linked to private IP space, which worked fine (we want to let you link and redierect to other private services, just not fetch them). - Added and executed unit tests. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6755 Differential Revision: https://secure.phabricator.com/D12136
2015-03-23 18:44:03 +01:00
$upload_form->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('URL'))
->setName('url')
->setValue($request->getStr('url')));
$upload_form
->appendChild(
id(new AphrontFormFileControl())
->setLabel(pht('File'))
->setName('file'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Upload File')));
$upload = id(new PHUIObjectBoxView())
->setHeaderText(pht('Upload New File'))
->setForm($upload_form);
}
$form_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setFormErrors($errors)
->setForm($form);
return $this->buildApplicationPage(
array(
$crumbs,
$form_box,
$upload,
),
array(
'title' => $title,
));
}
}