Changeset View
Changeset View
Standalone View
Standalone View
src/applications/files/storage/PhabricatorFile.php
| Show First 20 Lines • Show All 691 Lines • ▼ Show 20 Lines | final class PhabricatorFile extends PhabricatorFileDAO | ||||
| public function getViewURI() { | public function getViewURI() { | ||||
| if (!$this->getPHID()) { | if (!$this->getPHID()) { | ||||
| throw new Exception( | throw new Exception( | ||||
| pht('You must save a file before you can generate a view URI.')); | pht('You must save a file before you can generate a view URI.')); | ||||
| } | } | ||||
| return $this->getCDNURI(null); | return $this->getCDNURI(); | ||||
| } | } | ||||
| private function getCDNURI($token) { | public function getCDNURI() { | ||||
| $name = self::normalizeFileName($this->getName()); | $name = self::normalizeFileName($this->getName()); | ||||
| $name = phutil_escape_uri($name); | $name = phutil_escape_uri($name); | ||||
| $parts = array(); | $parts = array(); | ||||
| $parts[] = 'file'; | $parts[] = 'file'; | ||||
| $parts[] = 'data'; | $parts[] = 'data'; | ||||
| // If this is an instanced install, add the instance identifier to the URI. | // If this is an instanced install, add the instance identifier to the URI. | ||||
| // Instanced configurations behind a CDN may not be able to control the | // Instanced configurations behind a CDN may not be able to control the | ||||
| // request domain used by the CDN (as with AWS CloudFront). Embedding the | // request domain used by the CDN (as with AWS CloudFront). Embedding the | ||||
| // instance identity in the path allows us to distinguish between requests | // instance identity in the path allows us to distinguish between requests | ||||
| // originating from different instances but served through the same CDN. | // originating from different instances but served through the same CDN. | ||||
| $instance = PhabricatorEnv::getEnvConfig('cluster.instance'); | $instance = PhabricatorEnv::getEnvConfig('cluster.instance'); | ||||
| if (strlen($instance)) { | if (strlen($instance)) { | ||||
| $parts[] = '@'.$instance; | $parts[] = '@'.$instance; | ||||
| } | } | ||||
| $parts[] = $this->getSecretKey(); | $parts[] = $this->getSecretKey(); | ||||
| $parts[] = $this->getPHID(); | $parts[] = $this->getPHID(); | ||||
| if ($token) { | |||||
| $parts[] = $token; | |||||
| } | |||||
| $parts[] = $name; | $parts[] = $name; | ||||
| $path = '/'.implode('/', $parts); | $path = '/'.implode('/', $parts); | ||||
| // If this file is only partially uploaded, we're just going to return a | // If this file is only partially uploaded, we're just going to return a | ||||
| // local URI to make sure that Ajax works, since the page is inevitably | // local URI to make sure that Ajax works, since the page is inevitably | ||||
| // going to give us an error back. | // going to give us an error back. | ||||
| if ($this->getIsPartial()) { | if ($this->getIsPartial()) { | ||||
| return PhabricatorEnv::getURI($path); | return PhabricatorEnv::getURI($path); | ||||
| } else { | } else { | ||||
| return PhabricatorEnv::getCDNURI($path); | return PhabricatorEnv::getCDNURI($path); | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Get the CDN URI for this file, including a one-time-use security token. | |||||
| * | |||||
| */ | |||||
| public function getCDNURIWithToken() { | |||||
| if (!$this->getPHID()) { | |||||
| throw new Exception( | |||||
| pht('You must save a file before you can generate a CDN URI.')); | |||||
| } | |||||
| return $this->getCDNURI($this->generateOneTimeToken()); | |||||
| } | |||||
| public function getInfoURI() { | public function getInfoURI() { | ||||
| return '/'.$this->getMonogram(); | return '/'.$this->getMonogram(); | ||||
| } | } | ||||
| public function getBestURI() { | public function getBestURI() { | ||||
| if ($this->isViewableInBrowser()) { | if ($this->isViewableInBrowser()) { | ||||
| return $this->getViewURI(); | return $this->getViewURI(); | ||||
| ▲ Show 20 Lines • Show All 354 Lines • ▼ Show 20 Lines | public function getIsProfileImage() { | ||||
| return idx($this->metadata, self::METADATA_PROFILE); | return idx($this->metadata, self::METADATA_PROFILE); | ||||
| } | } | ||||
| public function setIsProfileImage($value) { | public function setIsProfileImage($value) { | ||||
| $this->metadata[self::METADATA_PROFILE] = $value; | $this->metadata[self::METADATA_PROFILE] = $value; | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| protected function generateOneTimeToken() { | |||||
| $key = Filesystem::readRandomCharacters(16); | |||||
| $token_type = PhabricatorFileAccessTemporaryTokenType::TOKENTYPE; | |||||
| // Save the new secret. | |||||
| $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); | |||||
| $token = id(new PhabricatorAuthTemporaryToken()) | |||||
| ->setTokenResource($this->getPHID()) | |||||
| ->setTokenType($token_type) | |||||
| ->setTokenExpires(time() + phutil_units('1 hour in seconds')) | |||||
| ->setTokenCode(PhabricatorHash::digest($key)) | |||||
| ->save(); | |||||
| unset($unguarded); | |||||
| return $key; | |||||
| } | |||||
| public function validateOneTimeToken($token_code) { | |||||
| $token_type = PhabricatorFileAccessTemporaryTokenType::TOKENTYPE; | |||||
| $token = id(new PhabricatorAuthTemporaryTokenQuery()) | |||||
| ->setViewer(PhabricatorUser::getOmnipotentUser()) | |||||
| ->withTokenResources(array($this->getPHID())) | |||||
| ->withTokenTypes(array($token_type)) | |||||
| ->withExpired(false) | |||||
| ->withTokenCodes(array(PhabricatorHash::digest($token_code))) | |||||
| ->executeOne(); | |||||
| return $token; | |||||
| } | |||||
| /** | /** | ||||
| * Write the policy edge between this file and some object. | * Write the policy edge between this file and some object. | ||||
| * | * | ||||
| * @param phid Object PHID to attach to. | * @param phid Object PHID to attach to. | ||||
| * @return this | * @return this | ||||
| */ | */ | ||||
| public function attachToObject($phid) { | public function attachToObject($phid) { | ||||
| $edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST; | $edge_type = PhabricatorObjectHasFileEdgeType::EDGECONST; | ||||
| ▲ Show 20 Lines • Show All 217 Lines • Show Last 20 Lines | |||||