1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 17:02:41 +01:00
phorge-phorge/resources/sql/autopatches/20160503.repo.03.lpathmigrate.php
epriestley dd2b10b8f8 Guarantee repositories have unique local paths
Summary:
Ref T4039. Long ago these were more freely editable and there were some security concerns around creating a repository, then setting its local path to point somewhere it shouldn't.

Local paths are no longer editable so there's no real reason we need to provide a uniqueness guarantee anymore, but you could still make a mistake with `bin/repository move-paths` by accident, and it's a little cleaner to pull them out into their own column with a key.

(We still don't -- and, largely can't -- guarantee that two paths aren't //equivalent// since one might be symlinked to the other, or symlinked only on some hosts, or whatever, but the primary value here is as a sanity check that you aren't goofing things up and pointing a bunch of repositories at the same working copy by mistake.)

Test Plan:
  - Ran migrations.
  - Grepped for `local-path`.
  - Listed and moved paths with `bin/repository`.
  - Created a new repository, verified its local path populated correctly.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4039

Differential Revision: https://secure.phabricator.com/D15837
2016-05-04 16:09:52 -07:00

57 lines
1.5 KiB
PHP

<?php
$table = new PhabricatorRepository();
$conn_w = $table->establishConnection('w');
$default_path = PhabricatorEnv::getEnvConfig('repository.default-local-path');
$default_path = rtrim($default_path, '/');
foreach (new LiskMigrationIterator($table) as $repository) {
$local_path = $repository->getLocalPath();
if (strlen($local_path)) {
// Repository already has a modern, unique local path.
continue;
}
$local_path = $repository->getDetail('local-path');
if (!strlen($local_path)) {
// Repository does not have a local path using the older format.
continue;
}
$random = Filesystem::readRandomCharacters(8);
// Try the configured path first, then a default path, then a path with some
// random noise.
$paths = array(
$local_path,
$default_path.'/'.$repository->getID().'/',
$default_path.'/'.$repository->getID().'-'.$random.'/',
);
foreach ($paths as $path) {
// Set, then get the path to normalize it.
$repository->setLocalPath($path);
$path = $repository->getLocalPath();
try {
queryfx(
$conn_w,
'UPDATE %T SET localPath = %s WHERE id = %d',
$table->getTableName(),
$path,
$repository->getID());
echo tsprintf(
"%s\n",
pht(
'Assigned repository "%s" to local path "%s".',
$repository->getDisplayName(),
$path));
break;
} catch (AphrontDuplicateKeyQueryException $ex) {
// Ignore, try the next one.
}
}
}