mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-23 15:22:41 +01:00
Add diffusion.uri.edit
for creating and editing repository URIs
Summary: Ref T10748. Brings the rest of the transactions to EditEngine, supports creating via API. Test Plan: - Created a URI via API. - Created a URI via web. - Tried to apply sneaky transactions, got rejected with good error messages. <_< >_> Reviewers: chad Reviewed By: chad Maniphest Tasks: T10748 Differential Revision: https://secure.phabricator.com/D15821
This commit is contained in:
parent
128995f1ac
commit
da599386f6
7 changed files with 188 additions and 6 deletions
|
@ -816,6 +816,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionTagListController' => 'applications/diffusion/controller/DiffusionTagListController.php',
|
'DiffusionTagListController' => 'applications/diffusion/controller/DiffusionTagListController.php',
|
||||||
'DiffusionTagListView' => 'applications/diffusion/view/DiffusionTagListView.php',
|
'DiffusionTagListView' => 'applications/diffusion/view/DiffusionTagListView.php',
|
||||||
'DiffusionTagsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionTagsQueryConduitAPIMethod.php',
|
'DiffusionTagsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionTagsQueryConduitAPIMethod.php',
|
||||||
|
'DiffusionURIEditConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionURIEditConduitAPIMethod.php',
|
||||||
'DiffusionURIEditEngine' => 'applications/diffusion/editor/DiffusionURIEditEngine.php',
|
'DiffusionURIEditEngine' => 'applications/diffusion/editor/DiffusionURIEditEngine.php',
|
||||||
'DiffusionURIEditor' => 'applications/diffusion/editor/DiffusionURIEditor.php',
|
'DiffusionURIEditor' => 'applications/diffusion/editor/DiffusionURIEditor.php',
|
||||||
'DiffusionURITestCase' => 'applications/diffusion/request/__tests__/DiffusionURITestCase.php',
|
'DiffusionURITestCase' => 'applications/diffusion/request/__tests__/DiffusionURITestCase.php',
|
||||||
|
@ -5044,6 +5045,7 @@ phutil_register_library_map(array(
|
||||||
'DiffusionTagListController' => 'DiffusionController',
|
'DiffusionTagListController' => 'DiffusionController',
|
||||||
'DiffusionTagListView' => 'DiffusionView',
|
'DiffusionTagListView' => 'DiffusionView',
|
||||||
'DiffusionTagsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
'DiffusionTagsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
|
||||||
|
'DiffusionURIEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||||
'DiffusionURIEditEngine' => 'PhabricatorEditEngine',
|
'DiffusionURIEditEngine' => 'PhabricatorEditEngine',
|
||||||
'DiffusionURIEditor' => 'PhabricatorApplicationTransactionEditor',
|
'DiffusionURIEditor' => 'PhabricatorApplicationTransactionEditor',
|
||||||
'DiffusionURITestCase' => 'PhutilTestCase',
|
'DiffusionURITestCase' => 'PhutilTestCase',
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class DiffusionURIEditConduitAPIMethod
|
||||||
|
extends PhabricatorEditEngineAPIMethod {
|
||||||
|
|
||||||
|
public function getAPIMethodName() {
|
||||||
|
return 'diffusion.uri.edit';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newEditEngine() {
|
||||||
|
return new DiffusionURIEditEngine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMethodSummary() {
|
||||||
|
return pht(
|
||||||
|
'Apply transactions to create a new repository URI or edit an existing '.
|
||||||
|
'one.');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,8 +37,15 @@ final class DiffusionURIEditEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function newEditableObject() {
|
protected function newEditableObject() {
|
||||||
|
$uri = PhabricatorRepositoryURI::initializeNewURI();
|
||||||
|
|
||||||
$repository = $this->getRepository();
|
$repository = $this->getRepository();
|
||||||
return PhabricatorRepositoryURI::initializeNewURI($repository);
|
if ($repository) {
|
||||||
|
$uri->setRepositoryPHID($repository->getPHID());
|
||||||
|
$uri->attachRepository($repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function newObjectQuery() {
|
protected function newObjectQuery() {
|
||||||
|
@ -77,6 +84,23 @@ final class DiffusionURIEditEngine
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
id(new PhabricatorHandlesEditField())
|
||||||
|
->setKey('repository')
|
||||||
|
->setAliases(array('repositoryPHID'))
|
||||||
|
->setLabel(pht('Repository'))
|
||||||
|
->setIsRequired(true)
|
||||||
|
->setIsConduitOnly(true)
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorRepositoryURITransaction::TYPE_REPOSITORY)
|
||||||
|
->setDescription(pht('The repository this URI is associated with.'))
|
||||||
|
->setConduitDescription(
|
||||||
|
pht(
|
||||||
|
'Create a URI in a given repository. This transaction type '.
|
||||||
|
'must be present when creating a new URI and must not be '.
|
||||||
|
'present when editing an existing URI.'))
|
||||||
|
->setConduitTypeDescription(
|
||||||
|
pht('Repository PHID to create a new URI for.'))
|
||||||
|
->setSingleValue($object->getRepositoryPHID()),
|
||||||
id(new PhabricatorTextEditField())
|
id(new PhabricatorTextEditField())
|
||||||
->setKey('uri')
|
->setKey('uri')
|
||||||
->setLabel(pht('URI'))
|
->setLabel(pht('URI'))
|
||||||
|
@ -104,6 +128,28 @@ final class DiffusionURIEditEngine
|
||||||
->setConduitTypeDescription(pht('New display behavior.'))
|
->setConduitTypeDescription(pht('New display behavior.'))
|
||||||
->setValue($object->getDisplayType())
|
->setValue($object->getDisplayType())
|
||||||
->setOptions($object->getAvailableDisplayTypeOptions()),
|
->setOptions($object->getAvailableDisplayTypeOptions()),
|
||||||
|
id(new PhabricatorHandlesEditField())
|
||||||
|
->setKey('credential')
|
||||||
|
->setAliases(array('credentialPHID'))
|
||||||
|
->setLabel(pht('Credential'))
|
||||||
|
->setIsConduitOnly(true)
|
||||||
|
->setTransactionType(
|
||||||
|
PhabricatorRepositoryURITransaction::TYPE_CREDENTIAL)
|
||||||
|
->setDescription(
|
||||||
|
pht('The credential to use when interacting with this URI.'))
|
||||||
|
->setConduitDescription(pht('Change the credential for this URI.'))
|
||||||
|
->setConduitTypeDescription(pht('New credential PHID, or null.'))
|
||||||
|
->setSingleValue($object->getCredentialPHID()),
|
||||||
|
id(new PhabricatorBoolEditField())
|
||||||
|
->setKey('disable')
|
||||||
|
->setLabel(pht('Disabled'))
|
||||||
|
->setIsConduitOnly(true)
|
||||||
|
->setTransactionType(PhabricatorRepositoryURITransaction::TYPE_DISABLE)
|
||||||
|
->setDescription(pht('Active status of the URI.'))
|
||||||
|
->setConduitDescription(pht('Disable or activate the URI.'))
|
||||||
|
->setConduitTypeDescription(pht('True to disable the URI.'))
|
||||||
|
->setOptions(pht('Enable'), pht('Disable'))
|
||||||
|
->setValue($object->getIsDisabled()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,12 @@ final class DiffusionURIEditor
|
||||||
public function getTransactionTypes() {
|
public function getTransactionTypes() {
|
||||||
$types = parent::getTransactionTypes();
|
$types = parent::getTransactionTypes();
|
||||||
|
|
||||||
|
$types[] = PhabricatorRepositoryURITransaction::TYPE_REPOSITORY;
|
||||||
$types[] = PhabricatorRepositoryURITransaction::TYPE_URI;
|
$types[] = PhabricatorRepositoryURITransaction::TYPE_URI;
|
||||||
$types[] = PhabricatorRepositoryURITransaction::TYPE_IO;
|
$types[] = PhabricatorRepositoryURITransaction::TYPE_IO;
|
||||||
$types[] = PhabricatorRepositoryURITransaction::TYPE_DISPLAY;
|
$types[] = PhabricatorRepositoryURITransaction::TYPE_DISPLAY;
|
||||||
|
$types[] = PhabricatorRepositoryURITransaction::TYPE_CREDENTIAL;
|
||||||
|
$types[] = PhabricatorRepositoryURITransaction::TYPE_DISABLE;
|
||||||
|
|
||||||
return $types;
|
return $types;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +35,12 @@ final class DiffusionURIEditor
|
||||||
return $object->getIOType();
|
return $object->getIOType();
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
||||||
return $object->getDisplayType();
|
return $object->getDisplayType();
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_REPOSITORY:
|
||||||
|
return $object->getRepositoryPHID();
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_CREDENTIAL:
|
||||||
|
return $object->getCredentialPHID();
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_DISABLE:
|
||||||
|
return (int)$object->getIsDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getCustomTransactionOldValue($object, $xaction);
|
return parent::getCustomTransactionOldValue($object, $xaction);
|
||||||
|
@ -45,7 +54,11 @@ final class DiffusionURIEditor
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_IO:
|
case PhabricatorRepositoryURITransaction::TYPE_IO:
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_REPOSITORY:
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_CREDENTIAL:
|
||||||
return $xaction->getNewValue();
|
return $xaction->getNewValue();
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_DISABLE:
|
||||||
|
return (int)$xaction->getNewValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::getCustomTransactionNewValue($object, $xaction);
|
return parent::getCustomTransactionNewValue($object, $xaction);
|
||||||
|
@ -65,6 +78,15 @@ final class DiffusionURIEditor
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
||||||
$object->setDisplayType($xaction->getNewValue());
|
$object->setDisplayType($xaction->getNewValue());
|
||||||
break;
|
break;
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_REPOSITORY:
|
||||||
|
$object->setRepositoryPHID($xaction->getNewValue());
|
||||||
|
break;
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_CREDENTIAL:
|
||||||
|
$object->setCredentialPHID($xaction->getNewValue());
|
||||||
|
break;
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_DISABLE:
|
||||||
|
$object->setIsDisabled($xaction->getNewValue());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +98,9 @@ final class DiffusionURIEditor
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_IO:
|
case PhabricatorRepositoryURITransaction::TYPE_IO:
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
case PhabricatorRepositoryURITransaction::TYPE_DISPLAY:
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_REPOSITORY:
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_CREDENTIAL:
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_DISABLE:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +115,92 @@ final class DiffusionURIEditor
|
||||||
$errors = parent::validateTransaction($object, $type, $xactions);
|
$errors = parent::validateTransaction($object, $type, $xactions);
|
||||||
|
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_REPOSITORY:
|
||||||
|
$missing = $this->validateIsEmptyTextField(
|
||||||
|
$object->getRepositoryPHID(),
|
||||||
|
$xactions);
|
||||||
|
if ($missing) {
|
||||||
|
// NOTE: This isn't being marked as a missing field error because
|
||||||
|
// it's a fundamental, required property of the URI.
|
||||||
|
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
pht('Required'),
|
||||||
|
pht(
|
||||||
|
'When creating a repository URI, you must specify which '.
|
||||||
|
'repository the URI will belong to.'),
|
||||||
|
nonempty(last($xactions), null));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$viewer = $this->getActor();
|
||||||
|
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$repository_phid = $xaction->getNewValue();
|
||||||
|
|
||||||
|
// If this isn't changing anything, let it through as-is.
|
||||||
|
if ($repository_phid == $object->getRepositoryPHID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->getIsNewObject()) {
|
||||||
|
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
pht('Invalid'),
|
||||||
|
pht(
|
||||||
|
'The repository a URI is associated with is immutable, and '.
|
||||||
|
'can not be changed after the URI is created.'),
|
||||||
|
$xaction);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$repository = id(new PhabricatorRepositoryQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($repository_phid))
|
||||||
|
->requireCapabilities(
|
||||||
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
|
->executeOne();
|
||||||
|
if (!$repository) {
|
||||||
|
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
pht('Invalid'),
|
||||||
|
pht(
|
||||||
|
'To create a URI for a repository ("%s"), it must exist and '.
|
||||||
|
'you must have permission to edit it.',
|
||||||
|
$repository_phid),
|
||||||
|
$xaction);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PhabricatorRepositoryURITransaction::TYPE_CREDENTIAL:
|
||||||
|
$viewer = $this->getActor();
|
||||||
|
foreach ($xactions as $xaction) {
|
||||||
|
$credential_phid = $xaction->getNewValue();
|
||||||
|
|
||||||
|
if ($credential_phid == $object->getCredentialPHID()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$credential = id(new PassphraseCredentialQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($credential_phid))
|
||||||
|
->executeOne();
|
||||||
|
if (!$credential) {
|
||||||
|
$errors[] = new PhabricatorApplicationTransactionValidationError(
|
||||||
|
$type,
|
||||||
|
pht('Invalid'),
|
||||||
|
pht(
|
||||||
|
'You can only associate a credential ("%s") with a repository '.
|
||||||
|
'URI if it exists and you have permission to see it.',
|
||||||
|
$credential_phid),
|
||||||
|
$xaction);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
case PhabricatorRepositoryURITransaction::TYPE_URI:
|
||||||
$missing = $this->validateIsEmptyTextField(
|
$missing = $this->validateIsEmptyTextField(
|
||||||
$object->getURI(),
|
$object->getURI(),
|
||||||
|
@ -99,7 +210,7 @@ final class DiffusionURIEditor
|
||||||
$error = new PhabricatorApplicationTransactionValidationError(
|
$error = new PhabricatorApplicationTransactionValidationError(
|
||||||
$type,
|
$type,
|
||||||
pht('Required'),
|
pht('Required'),
|
||||||
pht('Repository URI is required.'),
|
pht('A repository URI must have a nonempty URI.'),
|
||||||
nonempty(last($xactions), null));
|
nonempty(last($xactions), null));
|
||||||
|
|
||||||
$error->setIsMissingFieldError(true);
|
$error->setIsMissingFieldError(true);
|
||||||
|
|
|
@ -2179,7 +2179,9 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO
|
||||||
$uris = array();
|
$uris = array();
|
||||||
foreach ($protocol_map as $protocol => $proto_supported) {
|
foreach ($protocol_map as $protocol => $proto_supported) {
|
||||||
foreach ($identifier_map as $identifier => $id_supported) {
|
foreach ($identifier_map as $identifier => $id_supported) {
|
||||||
$uris[] = PhabricatorRepositoryURI::initializeNewURI($this)
|
$uris[] = PhabricatorRepositoryURI::initializeNewURI()
|
||||||
|
->setRepositoryPHID($this->getPHID())
|
||||||
|
->attachRepository($this)
|
||||||
->setBuiltinProtocol($protocol)
|
->setBuiltinProtocol($protocol)
|
||||||
->setBuiltinIdentifier($identifier)
|
->setBuiltinIdentifier($identifier)
|
||||||
->setIsDisabled(!$proto_supported || !$id_supported);
|
->setIsDisabled(!$proto_supported || !$id_supported);
|
||||||
|
|
|
@ -62,10 +62,8 @@ final class PhabricatorRepositoryURI
|
||||||
) + parent::getConfiguration();
|
) + parent::getConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function initializeNewURI(PhabricatorRepository $repository) {
|
public static function initializeNewURI() {
|
||||||
return id(new self())
|
return id(new self())
|
||||||
->attachRepository($repository)
|
|
||||||
->setRepositoryPHID($repository->getPHID())
|
|
||||||
->setIoType(self::IO_DEFAULT)
|
->setIoType(self::IO_DEFAULT)
|
||||||
->setDisplayType(self::DISPLAY_DEFAULT)
|
->setDisplayType(self::DISPLAY_DEFAULT)
|
||||||
->setIsDisabled(0);
|
->setIsDisabled(0);
|
||||||
|
|
|
@ -3,9 +3,12 @@
|
||||||
final class PhabricatorRepositoryURITransaction
|
final class PhabricatorRepositoryURITransaction
|
||||||
extends PhabricatorApplicationTransaction {
|
extends PhabricatorApplicationTransaction {
|
||||||
|
|
||||||
|
const TYPE_REPOSITORY = 'diffusion.uri.repository';
|
||||||
const TYPE_URI = 'diffusion.uri.uri';
|
const TYPE_URI = 'diffusion.uri.uri';
|
||||||
const TYPE_IO = 'diffusion.uri.io';
|
const TYPE_IO = 'diffusion.uri.io';
|
||||||
const TYPE_DISPLAY = 'diffusion.uri.display';
|
const TYPE_DISPLAY = 'diffusion.uri.display';
|
||||||
|
const TYPE_CREDENTIAL = 'diffusion.uri.credential';
|
||||||
|
const TYPE_DISABLE = 'diffusion.uri.disable';
|
||||||
|
|
||||||
public function getApplicationName() {
|
public function getApplicationName() {
|
||||||
return 'repository';
|
return 'repository';
|
||||||
|
|
Loading…
Reference in a new issue