mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
Make the Files "TTL" API more structured
Summary: Ref T11357. When creating a file, callers can currently specify a `ttl`. However, it isn't unambiguous what you're supposed to pass, and some callers get it wrong. For example, to mean "this file expires in 60 minutes", you might pass either of these: - `time() + phutil_units('60 minutes in seconds')` - `phutil_units('60 minutes in seconds')` The former means "60 minutes from now". The latter means "1 AM, January 1, 1970". In practice, because the GC normally runs only once every four hours (at least, until recently), and all the bad TTLs are cases where files are normally accessed immediately, these 1970 TTLs didn't cause any real problems. Split `ttl` into `ttl.relative` and `ttl.absolute`, and make sure the values are sane. Then correct all callers, and simplify out the `time()` calls where possible to make switching to `PhabricatorTime` easier. Test Plan: - Generated an SSH keypair. - Viewed a changeset. - Viewed a raw diff. - Viewed a commit's file data. - Viewed a temporary file's details, saw expiration date and relative time. - Ran unit tests. - (Didn't really test Phragment.) Reviewers: chad Reviewed By: chad Subscribers: hach-que Maniphest Tasks: T11357 Differential Revision: https://secure.phabricator.com/D17616
This commit is contained in:
parent
2896da384c
commit
45b386596e
13 changed files with 91 additions and 22 deletions
|
@ -28,7 +28,7 @@ final class PhabricatorAuthSSHKeyGenerateController
|
|||
$private_key,
|
||||
array(
|
||||
'name' => $default_name.'.key',
|
||||
'ttl' => time() + (60 * 10),
|
||||
'ttl.relative' => phutil_units('10 minutes in seconds'),
|
||||
'viewPolicy' => $viewer->getPHID(),
|
||||
));
|
||||
|
||||
|
|
|
@ -357,7 +357,7 @@ final class DifferentialChangesetViewController extends DifferentialController {
|
|||
array(
|
||||
'name' => $changeset->getFilename(),
|
||||
'mime-type' => 'text/plain',
|
||||
'ttl' => phutil_units('24 hours in seconds'),
|
||||
'ttl.relative' => phutil_units('24 hours in seconds'),
|
||||
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
|
||||
));
|
||||
|
||||
|
|
|
@ -893,7 +893,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
|||
$raw_diff,
|
||||
array(
|
||||
'name' => $file_name,
|
||||
'ttl' => (60 * 60 * 24),
|
||||
'ttl.relative' => phutil_units('24 hours in seconds'),
|
||||
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
|
||||
));
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ abstract class DiffusionFileFutureQuery
|
|||
$drequest = $this->getRequest();
|
||||
|
||||
$name = basename($drequest->getPath());
|
||||
$ttl = PhabricatorTime::getNow() + phutil_units('48 hours in seconds');
|
||||
$relative_ttl = phutil_units('48 hours in seconds');
|
||||
|
||||
try {
|
||||
$threshold = PhabricatorFileStorageEngine::getChunkThreshold();
|
||||
|
@ -101,7 +101,7 @@ abstract class DiffusionFileFutureQuery
|
|||
|
||||
$source = id(new PhabricatorExecFutureFileUploadSource())
|
||||
->setName($name)
|
||||
->setTTL($ttl)
|
||||
->setRelativeTTL($relative_ttl)
|
||||
->setViewPolicy(PhabricatorPolicies::POLICY_NOONE)
|
||||
->setExecFuture($future);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ final class PhabricatorImageTransformer extends Phobject {
|
|||
$image,
|
||||
array(
|
||||
'name' => 'meme-'.$file->getName(),
|
||||
'ttl' => time() + 60 * 60 * 24,
|
||||
'ttl.relative' => phutil_units('24 hours in seconds'),
|
||||
'canCDN' => true,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ final class FileAllocateConduitAPIMethod
|
|||
|
||||
$ttl = $request->getValue('deleteAfterEpoch');
|
||||
if ($ttl) {
|
||||
$properties['ttl'] = $ttl;
|
||||
$properties['ttl.absolute'] = $ttl;
|
||||
}
|
||||
|
||||
$file = null;
|
||||
|
|
|
@ -212,6 +212,18 @@ final class PhabricatorFileInfoController extends PhabricatorFileController {
|
|||
pht('Mime Type'),
|
||||
$file->getMimeType());
|
||||
|
||||
$ttl = $file->getTtl();
|
||||
if ($ttl) {
|
||||
$delta = $ttl - PhabricatorTime::getNow();
|
||||
|
||||
$finfo->addProperty(
|
||||
pht('Expires'),
|
||||
pht(
|
||||
'%s (%s)',
|
||||
phabricator_datetime($ttl, $viewer),
|
||||
phutil_format_relative_time_detailed($delta)));
|
||||
}
|
||||
|
||||
$width = $file->getImageWidth();
|
||||
if ($width) {
|
||||
$finfo->addProperty(
|
||||
|
|
|
@ -9,10 +9,13 @@
|
|||
*
|
||||
* | name | Human readable filename.
|
||||
* | authorPHID | User PHID of uploader.
|
||||
* | ttl | Temporary file lifetime, in seconds.
|
||||
* | ttl.absolute | Temporary file lifetime as an epoch timestamp.
|
||||
* | ttl.relative | Temporary file lifetime, relative to now, in seconds.
|
||||
* | viewPolicy | File visibility policy.
|
||||
* | isExplicitUpload | Used to show users files they explicitly uploaded.
|
||||
* | canCDN | Allows the file to be cached and delivered over a CDN.
|
||||
* | profile | Marks the file as a profile image.
|
||||
* | format | Internal encoding format.
|
||||
* | mime-type | Optional, explicit file MIME type.
|
||||
* | builtin | Optional filename, identifies this as a builtin.
|
||||
*
|
||||
|
@ -1110,7 +1113,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
|||
|
||||
$params = array(
|
||||
'name' => $builtin->getBuiltinDisplayName(),
|
||||
'ttl' => time() + (60 * 60 * 24 * 7),
|
||||
'ttl.relative' => phutil_units('7 days in seconds'),
|
||||
'canCDN' => true,
|
||||
'builtin' => $key,
|
||||
);
|
||||
|
@ -1280,14 +1283,68 @@ final class PhabricatorFile extends PhabricatorFileDAO
|
|||
* @return this
|
||||
*/
|
||||
private function readPropertiesFromParameters(array $params) {
|
||||
PhutilTypeSpec::checkMap(
|
||||
$params,
|
||||
array(
|
||||
'name' => 'optional string',
|
||||
'authorPHID' => 'optional string',
|
||||
'ttl.relative' => 'optional int',
|
||||
'ttl.absolute' => 'optional int',
|
||||
'viewPolicy' => 'optional string',
|
||||
'isExplicitUpload' => 'optional bool',
|
||||
'canCDN' => 'optional bool',
|
||||
'profile' => 'optional bool',
|
||||
'format' => 'optional string|PhabricatorFileStorageFormat',
|
||||
'mime-type' => 'optional string',
|
||||
'builtin' => 'optional string',
|
||||
'storageEngines' => 'optional list<PhabricatorFileStorageEngine>',
|
||||
));
|
||||
|
||||
$file_name = idx($params, 'name');
|
||||
$this->setName($file_name);
|
||||
|
||||
$author_phid = idx($params, 'authorPHID');
|
||||
$this->setAuthorPHID($author_phid);
|
||||
|
||||
$file_ttl = idx($params, 'ttl');
|
||||
$this->setTtl($file_ttl);
|
||||
$absolute_ttl = idx($params, 'ttl.absolute');
|
||||
$relative_ttl = idx($params, 'ttl.relative');
|
||||
if ($absolute_ttl !== null && $relative_ttl !== null) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Specify an absolute TTL or a relative TTL, but not both.'));
|
||||
} else if ($absolute_ttl !== null) {
|
||||
if ($absolute_ttl < PhabricatorTime::getNow()) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Absolute TTL must be in the present or future, but TTL "%s" '.
|
||||
'is in the past.',
|
||||
$absolute_ttl));
|
||||
}
|
||||
|
||||
$this->setTtl($absolute_ttl);
|
||||
} else if ($relative_ttl !== null) {
|
||||
if ($relative_ttl < 0) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Relative TTL must be zero or more seconds, but "%s" is '.
|
||||
'negative.',
|
||||
$relative_ttl));
|
||||
}
|
||||
|
||||
$max_relative = phutil_units('365 days in seconds');
|
||||
if ($relative_ttl > $max_relative) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Relative TTL must not be more than "%s" seconds, but TTL '.
|
||||
'"%s" was specified.',
|
||||
$max_relative,
|
||||
$relative_ttl));
|
||||
}
|
||||
|
||||
$absolute_ttl = PhabricatorTime::getNow() + $relative_ttl;
|
||||
|
||||
$this->setTtl($absolute_ttl);
|
||||
}
|
||||
|
||||
$view_policy = idx($params, 'viewPolicy');
|
||||
if ($view_policy) {
|
||||
|
|
|
@ -370,11 +370,11 @@ final class PhabricatorFileTestCase extends PhabricatorTestCase {
|
|||
|
||||
$data = Filesystem::readRandomCharacters(64);
|
||||
|
||||
$ttl = (time() + 60 * 60 * 24);
|
||||
$ttl = (PhabricatorTime::getNow() + phutil_units('24 hours in seconds'));
|
||||
|
||||
$params = array(
|
||||
'name' => 'test.dat',
|
||||
'ttl' => ($ttl),
|
||||
'ttl.absolute' => $ttl,
|
||||
'storageEngines' => array(
|
||||
$engine,
|
||||
),
|
||||
|
|
|
@ -4,7 +4,7 @@ abstract class PhabricatorFileUploadSource
|
|||
extends Phobject {
|
||||
|
||||
private $name;
|
||||
private $ttl;
|
||||
private $relativeTTL;
|
||||
private $viewPolicy;
|
||||
|
||||
private $rope;
|
||||
|
@ -22,13 +22,13 @@ abstract class PhabricatorFileUploadSource
|
|||
return $this->name;
|
||||
}
|
||||
|
||||
public function setTTL($ttl) {
|
||||
$this->ttl = $ttl;
|
||||
public function setRelativeTTL($relative_ttl) {
|
||||
$this->relativeTTL = $relative_ttl;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTTL() {
|
||||
return $this->ttl;
|
||||
public function getRelativeTTL() {
|
||||
return $this->relativeTTL;
|
||||
}
|
||||
|
||||
public function setViewPolicy($view_policy) {
|
||||
|
@ -214,7 +214,7 @@ abstract class PhabricatorFileUploadSource
|
|||
private function getNewFileParameters() {
|
||||
return array(
|
||||
'name' => $this->getName(),
|
||||
'ttl' => $this->getTTL(),
|
||||
'ttl.relative' => $this->getRelativeTTL(),
|
||||
'viewPolicy' => $this->getViewPolicy(),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ final class PhragmentGetPatchConduitAPIMethod
|
|||
$data,
|
||||
array(
|
||||
'name' => 'patch.dmp',
|
||||
'ttl' => time() + 60 * 60 * 24,
|
||||
'ttl.relative' => phutil_units('24 hours in seconds'),
|
||||
));
|
||||
$patches[$key]['patchURI'] = $file->getDownloadURI();
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ final class PhragmentPatchController extends PhragmentController {
|
|||
array(
|
||||
'name' => $name,
|
||||
'mime-type' => 'text/plain',
|
||||
'ttl' => time() + 60 * 60 * 24,
|
||||
'ttl.relative' => phutil_units('24 hours in seconds'),
|
||||
));
|
||||
|
||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
|
|
|
@ -104,7 +104,7 @@ final class PhragmentZIPController extends PhragmentController {
|
|||
$data,
|
||||
array(
|
||||
'name' => $zip_name,
|
||||
'ttl' => time() + 60 * 60 * 24,
|
||||
'ttl.relative' => phutil_units('24 hours in seconds'),
|
||||
));
|
||||
|
||||
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
|
|
Loading…
Reference in a new issue