mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-22 11:39:03 +01:00
Always serve "{meme ...}" from the CDN domain, never from the primary domain
Summary: Ref T13101. This is a minimal change to make "{meme ...}" work with the new Content-Security-Policy by using an Ajax request to generate the image and then swapping the source on the client. This could be much cleaner (see T5258, etc). Test Plan: Used `{meme, src=cat6, above=i am, below=cat}`, chuckled completely unironically. Maniphest Tasks: T13101 Differential Revision: https://secure.phabricator.com/D19196
This commit is contained in:
parent
6095d88998
commit
98cac2cc29
3 changed files with 99 additions and 42 deletions
|
@ -13,18 +13,25 @@ final class PhabricatorMacroMemeController
|
|||
$lower_text = $request->getStr('lowertext');
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$uri = self::generateMacro($viewer, $macro_name,
|
||||
$upper_text, $lower_text);
|
||||
if ($uri === false) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setIsExternal(true)
|
||||
->setURI($uri);
|
||||
$uri = self::generateMacro(
|
||||
$viewer,
|
||||
$macro_name,
|
||||
$upper_text,
|
||||
$lower_text);
|
||||
|
||||
$content = array(
|
||||
'imageURI' => $uri,
|
||||
);
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent($content);
|
||||
}
|
||||
|
||||
public static function generateMacro($viewer, $macro_name, $upper_text,
|
||||
$lower_text) {
|
||||
public static function generateMacro(
|
||||
PhabricatorUser $viewer,
|
||||
$macro_name,
|
||||
$upper_text,
|
||||
$lower_text) {
|
||||
|
||||
$macro = id(new PhabricatorMacroQuery())
|
||||
->setViewer($viewer)
|
||||
->withNames(array($macro_name))
|
||||
|
@ -35,34 +42,75 @@ final class PhabricatorMacroMemeController
|
|||
}
|
||||
$file = $macro->getFile();
|
||||
|
||||
$upper_text = strtoupper($upper_text);
|
||||
$lower_text = strtoupper($lower_text);
|
||||
$mixed_text = md5($upper_text).':'.md5($lower_text);
|
||||
$hash = 'meme'.hash('sha256', $mixed_text);
|
||||
$xform = id(new PhabricatorTransformedFile())
|
||||
->loadOneWhere('originalphid=%s and transform=%s',
|
||||
$file->getPHID(), $hash);
|
||||
$upper_text = phutil_utf8_strtoupper($upper_text);
|
||||
$lower_text = phutil_utf8_strtoupper($lower_text);
|
||||
|
||||
if ($xform) {
|
||||
$memefile = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($xform->getTransformedPHID()))
|
||||
->executeOne();
|
||||
if ($memefile) {
|
||||
return $memefile->getBestURI();
|
||||
}
|
||||
$hash = PhabricatorHash::digestForIndex(
|
||||
phutil_json_encode(
|
||||
array(
|
||||
'kind' => 'meme',
|
||||
'upper' => $upper_text,
|
||||
'lower' => $lower_text,
|
||||
)));
|
||||
|
||||
$xfile = self::loadTransformedFile($viewer, $file->getPHID(), $hash);
|
||||
if ($xfile) {
|
||||
return $xfile->getViewURI();
|
||||
}
|
||||
|
||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
$transformers = (new PhabricatorImageTransformer());
|
||||
$newfile = $transformers
|
||||
->executeMemeTransform($file, $upper_text, $lower_text);
|
||||
$xfile = new PhabricatorTransformedFile();
|
||||
$xfile->setOriginalPHID($file->getPHID());
|
||||
$xfile->setTransformedPHID($newfile->getPHID());
|
||||
$xfile->setTransform($hash);
|
||||
$xfile->save();
|
||||
$transformer = new PhabricatorImageTransformer();
|
||||
|
||||
return $newfile->getBestURI();
|
||||
$new_file = $transformer->executeMemeTransform(
|
||||
$file,
|
||||
$upper_text,
|
||||
$lower_text);
|
||||
|
||||
$xfile = id(new PhabricatorTransformedFile())
|
||||
->setOriginalPHID($file->getPHID())
|
||||
->setTransformedPHID($new_file->getPHID())
|
||||
->setTransform($hash);
|
||||
|
||||
try {
|
||||
$caught = null;
|
||||
|
||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
try {
|
||||
$xfile->save();
|
||||
} catch (Exception $ex) {
|
||||
$caught = $ex;
|
||||
}
|
||||
unset($unguarded);
|
||||
|
||||
if ($caught) {
|
||||
throw $caught;
|
||||
}
|
||||
|
||||
return $new_file->getViewURI();
|
||||
} catch (AphrontDuplicateKeyQueryException $ex) {
|
||||
$xfile = self::loadTransformedFile($viewer, $file->getPHID(), $hash);
|
||||
if (!$xfile) {
|
||||
throw $ex;
|
||||
}
|
||||
return $xfile->getViewURI();
|
||||
}
|
||||
}
|
||||
|
||||
private static function loadTransformedFile(
|
||||
PhabricatorUser $viewer,
|
||||
$file_phid,
|
||||
$hash) {
|
||||
|
||||
$xform = id(new PhabricatorTransformedFile())->loadOneWhere(
|
||||
'originalPHID = %s AND transform = %s',
|
||||
$file_phid,
|
||||
$hash);
|
||||
if (!$xform) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($xform->getTransformedPHID()))
|
||||
->executeOne();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,13 +50,10 @@ final class PhabricatorMemeRemarkupRule extends PhutilRemarkupRule {
|
|||
$options['above'],
|
||||
$options['below']);
|
||||
|
||||
$img = $this->newTag(
|
||||
'img',
|
||||
array(
|
||||
'src' => $uri,
|
||||
'alt' => $alt_text,
|
||||
'class' => 'phabricator-remarkup-macro',
|
||||
));
|
||||
$img = id(new PHUIRemarkupImageView())
|
||||
->setURI($uri)
|
||||
->addClass('phabricator-remarkup-macro')
|
||||
->setAlt($alt_text);
|
||||
}
|
||||
|
||||
return $this->getEngine()->storeText($img);
|
||||
|
|
|
@ -7,6 +7,7 @@ final class PHUIRemarkupImageView
|
|||
private $width;
|
||||
private $height;
|
||||
private $alt;
|
||||
private $classes = array();
|
||||
|
||||
public function setURI($uri) {
|
||||
$this->uri = $uri;
|
||||
|
@ -44,6 +45,11 @@ final class PHUIRemarkupImageView
|
|||
return $this->alt;
|
||||
}
|
||||
|
||||
public function addClass($class) {
|
||||
$this->classes[] = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$id = celerity_generate_unique_node_id();
|
||||
|
||||
|
@ -54,6 +60,11 @@ final class PHUIRemarkupImageView
|
|||
'imageID' => $id,
|
||||
));
|
||||
|
||||
$classes = null;
|
||||
if ($this->classes) {
|
||||
$classes = implode(' ', $this->classes);
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
'img',
|
||||
array(
|
||||
|
@ -61,6 +72,7 @@ final class PHUIRemarkupImageView
|
|||
'width' => $this->getWidth(),
|
||||
'height' => $this->getHeight(),
|
||||
'alt' => $this->getAlt(),
|
||||
'class' => $classes,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue