mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-13 10:22:42 +01:00
5ac36e8f77
Summary: Fixes T5915. Occasionally, users derp up and diff private key material. Adding a pre-write Herald phase enables configuration of a partial layer of protection that will reject these changes before they hit disk, provided they can be detected by, e.g., filename. Test Plan: - Added a rule with checks on every field, verified they looked fine in the transcript. - Created some revisions to test those changes (I have a bunch of revision rules locally). - Verified rejects don't write transcripts to the database. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5915 Differential Revision: https://secure.phabricator.com/D10305
196 lines
6 KiB
PHP
196 lines
6 KiB
PHP
<?php
|
|
|
|
final class DifferentialCreateDiffConduitAPIMethod
|
|
extends DifferentialConduitAPIMethod {
|
|
|
|
public function getAPIMethodName() {
|
|
return 'differential.creatediff';
|
|
}
|
|
|
|
public function getMethodDescription() {
|
|
return 'Create a new Differential diff.';
|
|
}
|
|
|
|
public function defineParamTypes() {
|
|
|
|
$vcs_const = $this->formatStringConstants(
|
|
array(
|
|
'svn',
|
|
'git',
|
|
'hg',
|
|
));
|
|
|
|
$status_const = $this->formatStringConstants(
|
|
array(
|
|
'none',
|
|
'skip',
|
|
'okay',
|
|
'warn',
|
|
'fail',
|
|
'postponed',
|
|
));
|
|
|
|
return array(
|
|
'changes' => 'required list<dict>',
|
|
'sourceMachine' => 'required string',
|
|
'sourcePath' => 'required string',
|
|
'branch' => 'required string',
|
|
'bookmark' => 'optional string',
|
|
'sourceControlSystem' => 'required '.$vcs_const,
|
|
'sourceControlPath' => 'required string',
|
|
'sourceControlBaseRevision' => 'required string',
|
|
'creationMethod' => 'optional string',
|
|
'arcanistProject' => 'optional string',
|
|
'lintStatus' => 'required '.$status_const,
|
|
'unitStatus' => 'required '.$status_const,
|
|
'repositoryPHID' => 'optional phid',
|
|
|
|
'parentRevisionID' => 'deprecated',
|
|
'authorPHID' => 'deprecated',
|
|
'repositoryUUID' => 'deprecated',
|
|
);
|
|
}
|
|
|
|
public function defineReturnType() {
|
|
return 'nonempty dict';
|
|
}
|
|
|
|
public function defineErrorTypes() {
|
|
return array(
|
|
);
|
|
}
|
|
|
|
protected function execute(ConduitAPIRequest $request) {
|
|
$viewer = $request->getUser();
|
|
$change_data = $request->getValue('changes');
|
|
|
|
$changes = array();
|
|
foreach ($change_data as $dict) {
|
|
$changes[] = ArcanistDiffChange::newFromDictionary($dict);
|
|
}
|
|
|
|
$diff = DifferentialDiff::newFromRawChanges($changes);
|
|
$diff->setSourcePath($request->getValue('sourcePath'));
|
|
$diff->setSourceMachine($request->getValue('sourceMachine'));
|
|
|
|
$diff->setBranch($request->getValue('branch'));
|
|
$diff->setCreationMethod($request->getValue('creationMethod'));
|
|
$diff->setAuthorPHID($viewer->getPHID());
|
|
$diff->setBookmark($request->getValue('bookmark'));
|
|
|
|
// TODO: Remove this eventually; for now continue writing the UUID. Note
|
|
// that we'll overwrite it below if we identify a repository, and `arc`
|
|
// no longer sends it. This stuff is retained for backward compatibility.
|
|
$diff->setRepositoryUUID($request->getValue('repositoryUUID'));
|
|
|
|
$repository_phid = $request->getValue('repositoryPHID');
|
|
if ($repository_phid) {
|
|
$repository = id(new PhabricatorRepositoryQuery())
|
|
->setViewer($viewer)
|
|
->withPHIDs(array($repository_phid))
|
|
->executeOne();
|
|
if ($repository) {
|
|
$diff->setRepositoryPHID($repository->getPHID());
|
|
$diff->setRepositoryUUID($repository->getUUID());
|
|
}
|
|
}
|
|
|
|
$system = $request->getValue('sourceControlSystem');
|
|
$diff->setSourceControlSystem($system);
|
|
$diff->setSourceControlPath($request->getValue('sourceControlPath'));
|
|
$diff->setSourceControlBaseRevision(
|
|
$request->getValue('sourceControlBaseRevision'));
|
|
|
|
$project_name = $request->getValue('arcanistProject');
|
|
$project_phid = null;
|
|
if ($project_name) {
|
|
$arcanist_project = id(new PhabricatorRepositoryArcanistProject())
|
|
->loadOneWhere(
|
|
'name = %s',
|
|
$project_name);
|
|
if (!$arcanist_project) {
|
|
$arcanist_project = new PhabricatorRepositoryArcanistProject();
|
|
$arcanist_project->setName($project_name);
|
|
$arcanist_project->save();
|
|
}
|
|
$project_phid = $arcanist_project->getPHID();
|
|
}
|
|
|
|
$diff->setArcanistProjectPHID($project_phid);
|
|
|
|
switch ($request->getValue('lintStatus')) {
|
|
case 'skip':
|
|
$diff->setLintStatus(DifferentialLintStatus::LINT_SKIP);
|
|
break;
|
|
case 'okay':
|
|
$diff->setLintStatus(DifferentialLintStatus::LINT_OKAY);
|
|
break;
|
|
case 'warn':
|
|
$diff->setLintStatus(DifferentialLintStatus::LINT_WARN);
|
|
break;
|
|
case 'fail':
|
|
$diff->setLintStatus(DifferentialLintStatus::LINT_FAIL);
|
|
break;
|
|
case 'postponed':
|
|
$diff->setLintStatus(DifferentialLintStatus::LINT_POSTPONED);
|
|
break;
|
|
case 'none':
|
|
default:
|
|
$diff->setLintStatus(DifferentialLintStatus::LINT_NONE);
|
|
break;
|
|
}
|
|
|
|
switch ($request->getValue('unitStatus')) {
|
|
case 'skip':
|
|
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP);
|
|
break;
|
|
case 'okay':
|
|
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_OKAY);
|
|
break;
|
|
case 'warn':
|
|
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_WARN);
|
|
break;
|
|
case 'fail':
|
|
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_FAIL);
|
|
break;
|
|
case 'postponed':
|
|
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_POSTPONED);
|
|
break;
|
|
case 'none':
|
|
default:
|
|
$diff->setUnitStatus(DifferentialUnitStatus::UNIT_NONE);
|
|
break;
|
|
}
|
|
|
|
id(new DifferentialDiffEditor())
|
|
->setActor($viewer)
|
|
->setContentSource(
|
|
PhabricatorContentSource::newFromConduitRequest($request))
|
|
->saveDiff($diff);
|
|
|
|
// If we didn't get an explicit `repositoryPHID` (which means the client is
|
|
// old, or couldn't figure out which repository the working copy belongs
|
|
// to), apply heuristics to try to figure it out.
|
|
|
|
if (!$repository_phid) {
|
|
$repository = id(new DifferentialRepositoryLookup())
|
|
->setDiff($diff)
|
|
->setViewer($viewer)
|
|
->lookupRepository();
|
|
if ($repository) {
|
|
$diff->setRepositoryPHID($repository->getPHID());
|
|
$diff->setRepositoryUUID($repository->getUUID());
|
|
$diff->save();
|
|
}
|
|
}
|
|
|
|
$path = '/differential/diff/'.$diff->getID().'/';
|
|
$uri = PhabricatorEnv::getURI($path);
|
|
|
|
return array(
|
|
'diffid' => $diff->getID(),
|
|
'uri' => $uri,
|
|
);
|
|
}
|
|
|
|
}
|