public function processRequest() { if (!PhabricatorEnv::getEnvConfig('files.enable-proxy')) { return new Aphront400Response(); } $request = $this->getRequest(); $uri = $request->getStr('uri'); $proxy = id(new PhabricatorFileProxyImage())->loadOneWhere('uri = %s', $uri); if (!$proxy) { // This write is fine to skip CSRF checks for, we're just building a // cache of some remote image. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $file = PhabricatorFile::newFromFileDownload($uri, nonempty(basename($uri), 'proxied-file')); if ($file) { $proxy = new PhabricatorFileProxyImage(); $proxy->setURI($uri); $proxy->setFilePHID($file->getPHID()); $proxy->save(); } unset($unguarded); } if ($proxy) { $file = id(new PhabricatorFile())->loadOneWhere('phid = %s', $proxy->getFilePHID()); if ($file) { $view_uri = $file->getBestURI(); } else { $bad_phid = $proxy->getFilePHID(); throw new Exception("Unable to load file with phid {$bad_phid}."); } return id(new AphrontRedirectResponse())->setURI($view_uri); } return new Aphront400Response(); }
public static function newFromImageURI($uri, $file_name, $image_macro_name) { $file = PhabricatorFile::newFromFileDownload($uri, $file_name); if (!$file) { return null; } $image_macro = new PhabricatorFileImageMacro(); $image_macro->setName($image_macro_name); $image_macro->setFilePHID($file->getPHID()); $image_macro->save(); return $image_macro; }
public function importEventsFromSource(PhabricatorUser $viewer, PhabricatorCalendarImport $import, $should_queue) { $uri_key = PhabricatorCalendarImportICSURITransaction::PARAMKEY_URI; $uri = $import->getParameter($uri_key); PhabricatorSystemActionEngine::willTakeAction(array($viewer->getPHID()), new PhabricatorFilesOutboundRequestAction(), 1); $file = PhabricatorFile::newFromFileDownload($uri, array('viewPolicy' => PhabricatorPolicies::POLICY_NOONE, 'authorPHID' => $import->getAuthorPHID(), 'canCDN' => true)); $import->newLogMessage(PhabricatorCalendarImportFetchLogType::LOGTYPE, array('file.phid' => $file->getPHID())); $data = $file->loadFileData(); if ($should_queue && $this->shouldQueueDataImport($data)) { return $this->queueDataImport($import, $data); } return $this->importICSData($viewer, $import, $data); }
public function handleRequest(AphrontRequest $request) { $show_prototypes = PhabricatorEnv::getEnvConfig('phabricator.show-prototypes'); if (!$show_prototypes) { throw new Exception(pht('Show prototypes is disabled. Set `phabricator.show-prototypes` to `true` to use the image proxy')); } $viewer = $request->getViewer(); $img_uri = $request->getStr('uri'); // Validate the URI before doing anything PhabricatorEnv::requireValidRemoteURIForLink($img_uri); $uri = new PhutilURI($img_uri); $proto = $uri->getProtocol(); if (!in_array($proto, array('http', 'https'))) { throw new Exception(pht('The provided image URI must be either http or https')); } // Check if we already have the specified image URI downloaded $cached_request = id(new PhabricatorFileExternalRequest())->loadOneWhere('uriIndex = %s', PhabricatorHash::digestForIndex($img_uri)); if ($cached_request) { return $this->getExternalResponse($cached_request); } $ttl = PhabricatorTime::getNow() + phutil_units('7 days in seconds'); $external_request = id(new PhabricatorFileExternalRequest())->setURI($img_uri)->setTTL($ttl); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); // Cache missed so we'll need to validate and download the image try { // Rate limit outbound fetches to make this mechanism less useful for // scanning networks and ports. PhabricatorSystemActionEngine::willTakeAction(array($viewer->getPHID()), new PhabricatorFilesOutboundRequestAction(), 1); $file = PhabricatorFile::newFromFileDownload($uri, array('viewPolicy' => PhabricatorPolicies::POLICY_NOONE, 'canCDN' => true)); if (!$file->isViewableImage()) { $mime_type = $file->getMimeType(); $engine = new PhabricatorDestructionEngine(); $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->save(); } $external_request->setIsSuccessful(true)->setFilePHID($file->getPHID())->save(); unset($unguarded); return $this->getExternalResponse($external_request); } catch (HTTPFutureHTTPResponseStatus $status) { $external_request->setIsSuccessful(false)->setResponseMessage($status->getMessage())->save(); return $this->getExternalResponse($external_request); } catch (Exception $ex) { // Not actually saving the request in this case $external_request->setResponseMessage($ex->getMessage()); return $this->getExternalResponse($external_request); } }
public function processRequest() { if (!PhabricatorEnv::getEnvConfig('files.enable-proxy')) { return new Aphront400Response(); } $request = $this->getRequest(); $uri = $request->getStr('uri'); $proxy = id(new PhabricatorFileProxyImage())->loadOneWhere('uri = %s', $uri); if (!$proxy) { $file = PhabricatorFile::newFromFileDownload($uri, nonempty(basename($uri), 'proxied-file')); if ($file) { $proxy = new PhabricatorFileProxyImage(); $proxy->setURI($uri); $proxy->setFilePHID($file->getPHID()); $proxy->save(); } } if ($proxy) { $view_uri = PhabricatorFileURI::getViewURIForPHID($proxy->getFilePHID()); return id(new AphrontRedirectResponse())->setURI($view_uri); } return new Aphront400Response(); }
protected function loadOrCreateAccount($account_id) { if (!strlen($account_id)) { throw new Exception(pht('Empty account ID!')); } $adapter = $this->getAdapter(); $adapter_class = get_class($adapter); if (!strlen($adapter->getAdapterType())) { throw new Exception(pht("AuthAdapter (of class '%s') has an invalid implementation: " . "no adapter type.", $adapter_class)); } if (!strlen($adapter->getAdapterDomain())) { throw new Exception(pht("AuthAdapter (of class '%s') has an invalid implementation: " . "no adapter domain.", $adapter_class)); } $account = id(new PhabricatorExternalAccount())->loadOneWhere('accountType = %s AND accountDomain = %s AND accountID = %s', $adapter->getAdapterType(), $adapter->getAdapterDomain(), $account_id); if (!$account) { $account = id(new PhabricatorExternalAccount())->setAccountType($adapter->getAdapterType())->setAccountDomain($adapter->getAdapterDomain())->setAccountID($account_id); } $account->setUsername($adapter->getAccountName()); $account->setRealName($adapter->getAccountRealName()); $account->setEmail($adapter->getAccountEmail()); $account->setAccountURI($adapter->getAccountURI()); $account->setProfileImagePHID(null); $image_uri = $adapter->getAccountImageURI(); if ($image_uri) { try { $name = PhabricatorSlug::normalize($this->getProviderName()); $name = $name . '-profile.jpg'; // TODO: If the image has not changed, we do not need to make a new // file entry for it, but there's no convenient way to do this with // PhabricatorFile right now. The storage will get shared, so the impact // here is negligible. $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $image_file = PhabricatorFile::newFromFileDownload($image_uri, array('name' => $name, 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE)); if ($image_file->isViewableImage()) { $image_file->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())->setCanCDN(true)->save(); $account->setProfileImagePHID($image_file->getPHID()); } else { $image_file->delete(); } unset($unguarded); } catch (Exception $ex) { // Log this but proceed, it's not especially important that we // be able to pull profile images. phlog($ex); } } $this->willSaveAccount($account); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $account->save(); unset($unguarded); return $account; }
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; $can_fetch = PhabricatorEnv::getEnvConfig('security.allow-outbound-http'); 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; } } } $file = null; if ($request->getFileExists('file')) { $file = PhabricatorFile::newFromPHPUpload($_FILES['file'], array('name' => $request->getStr('name'), 'authorPHID' => $user->getPHID(), 'isExplicitUpload' => true, 'canCDN' => true)); } else { if ($request->getStr('url')) { try { $file = PhabricatorFile::newFromFileDownload($request->getStr('url'), array('name' => $request->getStr('name'), 'authorPHID' => $user->getPHID(), 'isExplicitUpload' => true, 'canCDN' => true)); } catch (Exception $ex) { $errors[] = pht('Could not fetch URL: %s', $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)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request); $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'); } if ($can_fetch) { $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()); if ($can_fetch) { $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)); }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $id = $request->getURIData('id'); $this->requireApplicationCapability(PhabricatorMacroManageCapability::CAPABILITY); if ($id) { $macro = id(new PhabricatorMacroQuery())->setViewer($viewer)->withIDs(array($id))->needFiles(true)->executeOne(); if (!$macro) { return new Aphront404Response(); } } else { $macro = new PhabricatorFileImageMacro(); $macro->setAuthorPHID($viewer->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; } } } $uri = $request->getStr('url'); $engine = new PhabricatorDestructionEngine(); $file = null; if ($request->getFileExists('file')) { $file = PhabricatorFile::newFromPHPUpload($_FILES['file'], array('name' => $request->getStr('name'), 'authorPHID' => $viewer->getPHID(), 'isExplicitUpload' => true, 'canCDN' => true)); } else { if ($uri) { try { // Rate limit outbound fetches to make this mechanism less useful for // scanning networks and ports. PhabricatorSystemActionEngine::willTakeAction(array($viewer->getPHID()), new PhabricatorFilesOutboundRequestAction(), 1); $file = PhabricatorFile::newFromFileDownload($uri, array('name' => $request->getStr('name'), 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE, 'isExplicitUpload' => true, 'canCDN' => true)); 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($viewer->getPHID())->save(); } } catch (HTTPFutureHTTPResponseStatus $status) { $errors[] = pht('The URI "%s" could not be loaded, got %s error.', $uri, $status->getStatusCode()); } catch (Exception $ex) { $errors[] = $ex->getMessage(); } } else { if ($request->getStr('phid')) { $file = id(new PhabricatorFileQuery())->setViewer($viewer)->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(PhabricatorMacroTransaction::TYPE_NAME)->setNewValue($new_name); } if ($file) { $xactions[] = id(new PhabricatorMacroTransaction())->setTransactionType(PhabricatorMacroTransaction::TYPE_FILE)->setNewValue($file->getPHID()); } $editor = id(new PhabricatorMacroEditor())->setActor($viewer)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request); $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'); } $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()); $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)); }