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);
     }
 }
Beispiel #2
0
 public function getExternalParentURI()
 {
     $uri = $this->getParentDomain();
     PhabricatorEnv::requireValidRemoteURIForLink($uri);
     return (string) $uri;
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case PhameBlogTransaction::TYPE_NAME:
             $missing = $this->validateIsEmptyTextField($object->getName(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('Name is required.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             break;
         case PhameBlogTransaction::TYPE_PARENTDOMAIN:
             if (!$xactions) {
                 continue;
             }
             $parent_domain = last($xactions)->getNewValue();
             if (empty($parent_domain)) {
                 continue;
             }
             try {
                 PhabricatorEnv::requireValidRemoteURIForLink($parent_domain);
             } catch (Exception $ex) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid URI'), pht('Parent Domain must be set to a valid Remote URI.'), nonempty(last($xactions), null));
                 $errors[] = $error;
             }
             break;
         case PhameBlogTransaction::TYPE_FULLDOMAIN:
             if (!$xactions) {
                 continue;
             }
             $custom_domain = last($xactions)->getNewValue();
             if (empty($custom_domain)) {
                 continue;
             }
             list($error_label, $error_text) = $object->validateCustomDomain($custom_domain);
             if ($error_label) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, $error_label, $error_text, nonempty(last($xactions), null));
                 $errors[] = $error;
             }
             if ($object->getViewPolicy() != PhabricatorPolicies::POLICY_PUBLIC) {
                 $error_text = pht('For custom domains to work, the blog must have a view policy of ' . 'public.');
                 $error = new PhabricatorApplicationTransactionValidationError(PhabricatorTransactions::TYPE_VIEW_POLICY, pht('Invalid Policy'), $error_text, nonempty(last($xactions), null));
                 $errors[] = $error;
             }
             $domain = new PhutilURI($custom_domain);
             $domain = $domain->getDomain();
             $duplicate_blog = id(new PhameBlogQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withDomain($domain)->executeOne();
             if ($duplicate_blog && $duplicate_blog->getID() != $object->getID()) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Not Unique'), pht('Domain must be unique; another blog already has this domain.'), nonempty(last($xactions), null));
                 $errors[] = $error;
             }
             break;
     }
     return $errors;
 }
 /**
  * See http://tools.ietf.org/html/draft-ietf-oauth-v2-23#section-3.1.2
  * for details on what makes a given redirect URI "valid".
  */
 public function assertValidRedirectURI($raw_uri)
 {
     // This covers basics like reasonable formatting and the existence of a
     // protocol.
     PhabricatorEnv::requireValidRemoteURIForLink($raw_uri);
     $uri = new PhutilURI($raw_uri);
     $fragment = $uri->getFragment();
     if (strlen($fragment)) {
         throw new Exception(pht('OAuth application redirect URIs must not contain URI ' . 'fragments, but the URI "%s" has a fragment ("%s").', $raw_uri, $fragment));
     }
     $protocol = $uri->getProtocol();
     switch ($protocol) {
         case 'http':
         case 'https':
             break;
         default:
             throw new Exception(pht('OAuth application redirect URIs must only use the "http" or ' . '"https" protocols, but the URI "%s" uses the "%s" protocol.', $raw_uri, $protocol));
     }
 }