Page MenuHomePhabricator

D7413.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -449,6 +449,9 @@
'DiffusionBrowseResultSet' => 'applications/diffusion/data/DiffusionBrowseResultSet.php',
'DiffusionBrowseSearchController' => 'applications/diffusion/controller/DiffusionBrowseSearchController.php',
'DiffusionBrowseTableView' => 'applications/diffusion/view/DiffusionBrowseTableView.php',
+ 'DiffusionCapabilityCreateRepositories' => 'applications/diffusion/capability/DiffusionCapabilityCreateRepositories.php',
+ 'DiffusionCapabilityDefaultEdit' => 'applications/diffusion/capability/DiffusionCapabilityDefaultEdit.php',
+ 'DiffusionCapabilityDefaultView' => 'applications/diffusion/capability/DiffusionCapabilityDefaultView.php',
'DiffusionChangeController' => 'applications/diffusion/controller/DiffusionChangeController.php',
'DiffusionCommentListView' => 'applications/diffusion/view/DiffusionCommentListView.php',
'DiffusionCommentView' => 'applications/diffusion/view/DiffusionCommentView.php',
@@ -2634,6 +2637,9 @@
'DiffusionBrowseMainController' => 'DiffusionBrowseController',
'DiffusionBrowseSearchController' => 'DiffusionBrowseController',
'DiffusionBrowseTableView' => 'DiffusionView',
+ 'DiffusionCapabilityCreateRepositories' => 'PhabricatorPolicyCapability',
+ 'DiffusionCapabilityDefaultEdit' => 'PhabricatorPolicyCapability',
+ 'DiffusionCapabilityDefaultView' => 'PhabricatorPolicyCapability',
'DiffusionChangeController' => 'DiffusionController',
'DiffusionCommentListView' => 'AphrontView',
'DiffusionCommentView' => 'AphrontView',
diff --git a/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php b/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php
--- a/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php
+++ b/src/applications/diffusion/application/PhabricatorApplicationDiffusion.php
@@ -103,4 +103,17 @@
return 0.120;
}
+ protected function getCustomCapabilities() {
+ return array(
+ DiffusionCapabilityDefaultView::CAPABILITY => array(
+ ),
+ DiffusionCapabilityDefaultEdit::CAPABILITY => array(
+ 'default' => PhabricatorPolicies::POLICY_ADMIN,
+ ),
+ DiffusionCapabilityCreateRepositories::CAPABILITY => array(
+ 'default' => PhabricatorPolicies::POLICY_ADMIN,
+ ),
+ );
+ }
+
}
diff --git a/src/applications/diffusion/capability/DiffusionCapabilityCreateRepositories.php b/src/applications/diffusion/capability/DiffusionCapabilityCreateRepositories.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/capability/DiffusionCapabilityCreateRepositories.php
@@ -0,0 +1,20 @@
+<?php
+
+final class DiffusionCapabilityCreateRepositories
+ extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'diffusion.create';
+
+ public function getCapabilityKey() {
+ return self::CAPABILITY;
+ }
+
+ public function getCapabilityName() {
+ return pht('Can Create Repositories');
+ }
+
+ public function describeCapabilityRejection() {
+ return pht('You do not have permission to create new repositories.');
+ }
+
+}
diff --git a/src/applications/diffusion/capability/DiffusionCapabilityDefaultEdit.php b/src/applications/diffusion/capability/DiffusionCapabilityDefaultEdit.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/capability/DiffusionCapabilityDefaultEdit.php
@@ -0,0 +1,16 @@
+<?php
+
+final class DiffusionCapabilityDefaultEdit
+ extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'diffusion.default.edit';
+
+ public function getCapabilityKey() {
+ return self::CAPABILITY;
+ }
+
+ public function getCapabilityName() {
+ return pht('Default Edit Policy');
+ }
+
+}
diff --git a/src/applications/diffusion/capability/DiffusionCapabilityDefaultView.php b/src/applications/diffusion/capability/DiffusionCapabilityDefaultView.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/capability/DiffusionCapabilityDefaultView.php
@@ -0,0 +1,20 @@
+<?php
+
+final class DiffusionCapabilityDefaultView
+ extends PhabricatorPolicyCapability {
+
+ const CAPABILITY = 'diffusion.default.view';
+
+ public function getCapabilityKey() {
+ return self::CAPABILITY;
+ }
+
+ public function getCapabilityName() {
+ return pht('Default View Policy');
+ }
+
+ public function shouldAllowPublicPolicySetting() {
+ return true;
+ }
+
+}
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php b/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php
--- a/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php
@@ -32,6 +32,9 @@
$cancel_uri = $this->getRepositoryControllerURI($repository, 'edit/');
} else {
+ $this->requireApplicationCapability(
+ DiffusionCapabilityCreateRepositories::CAPABILITY);
+
$cancel_uri = $this->getApplicationURI();
}
@@ -60,15 +63,19 @@
if ($request->isFormPost()) {
$form->readFromRequest($request);
if ($form->isComplete()) {
+ $is_create = ($this->edit === null);
- if ($this->edit != 'remote') {
- // TODO: This exception is heartwarming but should probably take more
- // substantive actions.
- throw new Exception("GOOD JOB AT FORM");
+ if ($is_create) {
+ $repository = PhabricatorRepository::initializeNewRepository(
+ $viewer);
}
$template = id(new PhabricatorRepositoryTransaction());
+ $type_name = PhabricatorRepositoryTransaction::TYPE_NAME;
+ $type_vcs = PhabricatorRepositoryTransaction::TYPE_VCS;
+ $type_activate = PhabricatorRepositoryTransaction::TYPE_ACTIVATE;
+ $type_local_path = PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH;
$type_remote_uri = PhabricatorRepositoryTransaction::TYPE_REMOTE_URI;
$type_ssh_login = PhabricatorRepositoryTransaction::TYPE_SSH_LOGIN;
$type_ssh_key = PhabricatorRepositoryTransaction::TYPE_SSH_KEY;
@@ -78,6 +85,44 @@
$xactions = array();
+ // If we're creating a new repository, set all this core stuff.
+ if ($is_create) {
+ $callsign = $form->getPage('name')
+ ->getControl('callsign')->getValue();
+
+ // We must set this to a unique value to save the repository
+ // initially, and it's immutable, so we don't bother using
+ // transactions to apply this change.
+ $repository->setCallsign($callsign);
+
+ $xactions[] = id(clone $template)
+ ->setTransactionType($type_name)
+ ->setNewValue(
+ $form->getPage('name')->getControl('name')->getValue());
+
+ $xactions[] = id(clone $template)
+ ->setTransactionType($type_vcs)
+ ->setNewValue(
+ $form->getPage('vcs')->getControl('vcs')->getValue());
+
+ $activate = $form->getPage('done')
+ ->getControl('activate')->getValue();
+ $xactions[] = id(clone $template)
+ ->setTransactionType($type_activate)
+ ->setNewValue(
+ ($activate == 'start'));
+
+ $default_local_path = PhabricatorEnv::getEnvConfig(
+ 'repository.default-local-path');
+
+ $default_local_path = rtrim($default_local_path, '/');
+ $default_local_path = $default_local_path.'/'.$callsign.'/';
+
+ $xactions[] = id(clone $template)
+ ->setTransactionType($type_local_path)
+ ->setNewValue($default_local_path);
+ }
+
$xactions[] = id(clone $template)
->setTransactionType($type_remote_uri)
->setNewValue(
@@ -619,7 +664,7 @@
pht('Configure More Options First'),
pht(
'Configure more options before beginning the repository '.
- 'import. This will let you fine-tune settings.. You can '.
+ 'import. This will let you fine-tune settings. You can '.
'start the import whenever you are ready.')));
}
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
--- a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
@@ -336,12 +336,12 @@
$view->addProperty(pht('Default Branch'), $default_branch);
$track_only = nonempty(
- $repository->getHumanReadableDetail('branch-filter'),
+ $repository->getHumanReadableDetail('branch-filter', array()),
phutil_tag('em', array(), pht('Track All Branches')));
$view->addProperty(pht('Track Only'), $track_only);
$autoclose_only = nonempty(
- $repository->getHumanReadableDetail('close-commits-filter'),
+ $repository->getHumanReadableDetail('close-commits-filter', array()),
phutil_tag('em', array(), pht('Autoclose On All Branches')));
$view->addProperty(pht('Autoclose Only'), $autoclose_only);
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryListController.php b/src/applications/diffusion/controller/DiffusionRepositoryListController.php
--- a/src/applications/diffusion/controller/DiffusionRepositoryListController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryListController.php
@@ -90,7 +90,6 @@
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
-
id(new PhabricatorRepositorySearchEngine())
->setViewer($viewer)
->addNavigationItems($nav->getMenu());
@@ -100,6 +99,22 @@
return $nav;
}
+ public function buildApplicationCrumbs() {
+ $crumbs = parent::buildApplicationCrumbs();
+
+ $can_create = $this->hasApplicationCapability(
+ DiffusionCapabilityCreateRepositories::CAPABILITY);
+
+ $crumbs->addAction(
+ id(new PHUIListItemView())
+ ->setName(pht('Import Repository'))
+ ->setHref($this->getApplicationURI('/create/'))
+ ->setDisabled(!$can_create)
+ ->setIcon('create'));
+
+ return $crumbs;
+ }
+
private function buildShortcuts() {
$shortcuts = id(new PhabricatorRepositoryShortcut())->loadAll();
if ($shortcuts) {
diff --git a/src/applications/repository/PhabricatorRepositoryConfigOptions.php b/src/applications/repository/PhabricatorRepositoryConfigOptions.php
--- a/src/applications/repository/PhabricatorRepositoryConfigOptions.php
+++ b/src/applications/repository/PhabricatorRepositoryConfigOptions.php
@@ -16,14 +16,14 @@
public function getOptions() {
return array(
- $this->newOption('repository.default-local-path', 'string', null)
+ $this->newOption('repository.default-local-path', 'string', '/var/repo/')
->setSummary(
pht("Default location to store local copies of repositories."))
->setDescription(
pht(
"The default location in which to store local copies of ".
"repositories. Anything stored in this directory will be assumed ".
- "to be under the control of phabricator, which means that ".
+ "to be under the control of Phabricator, which means that ".
"Phabricator will try to do some maintenance on working copies ".
"if there are problems (such as a change to the remote origin ".
"url). This maintenance may include completely removing (and ".
diff --git a/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php b/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php
--- a/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php
+++ b/src/applications/repository/conduit/ConduitAPI_repository_create_Method.php
@@ -62,15 +62,24 @@
}
protected function execute(ConduitAPIRequest $request) {
- if (!$request->getUser()->getIsAdmin()) {
- throw new ConduitException('ERR-PERMISSIONS');
- }
+ $application = id(new PhabricatorApplicationQuery())
+ ->setViewer($request->getUser())
+ ->withClasses(array('PhabricatorApplicationDiffusion'))
+ ->executeOne();
+
+ PhabricatorPolicyFilter::requireCapability(
+ $request->getUser(),
+ $application,
+ DiffusionCapabilityCreateRepositories::CAPABILITY);
// TODO: This has some duplication with (and lacks some of the validation
// of) the web workflow; refactor things so they can share more code as this
- // stabilizes.
+ // stabilizes. Specifically, this should move to transactions since they
+ // work properly now.
+
+ $repository = PhabricatorRepository::initializeNewRepository(
+ $request->getUser());
- $repository = new PhabricatorRepository();
$repository->setName($request->getValue('name'));
$callsign = $request->getValue('callsign');
diff --git a/src/applications/repository/editor/PhabricatorRepositoryEditor.php b/src/applications/repository/editor/PhabricatorRepositoryEditor.php
--- a/src/applications/repository/editor/PhabricatorRepositoryEditor.php
+++ b/src/applications/repository/editor/PhabricatorRepositoryEditor.php
@@ -6,6 +6,7 @@
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
+ $types[] = PhabricatorRepositoryTransaction::TYPE_VCS;
$types[] = PhabricatorRepositoryTransaction::TYPE_ACTIVATE;
$types[] = PhabricatorRepositoryTransaction::TYPE_NAME;
$types[] = PhabricatorRepositoryTransaction::TYPE_DESCRIPTION;
@@ -36,6 +37,8 @@
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
+ case PhabricatorRepositoryTransaction::TYPE_VCS:
+ return $object->getVersionControlSystem();
case PhabricatorRepositoryTransaction::TYPE_ACTIVATE:
return $object->isTracked();
case PhabricatorRepositoryTransaction::TYPE_NAME:
@@ -96,6 +99,7 @@
case PhabricatorRepositoryTransaction::TYPE_HTTP_LOGIN:
case PhabricatorRepositoryTransaction::TYPE_HTTP_PASS:
case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH:
+ case PhabricatorRepositoryTransaction::TYPE_VCS:
return $xaction->getNewValue();
case PhabricatorRepositoryTransaction::TYPE_NOTIFY:
case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE:
@@ -108,6 +112,9 @@
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
+ case PhabricatorRepositoryTransaction::TYPE_VCS:
+ $object->setVersionControlSystem($xaction->getNewValue());
+ break;
case PhabricatorRepositoryTransaction::TYPE_ACTIVATE:
$object->setDetail('tracking-enabled', $xaction->getNewValue());
break;
@@ -219,4 +226,36 @@
return parent::transactionHasEffect($object, $xaction);
}
+ protected function requireCapabilities(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorRepositoryTransaction::TYPE_ACTIVATE:
+ case PhabricatorRepositoryTransaction::TYPE_NAME:
+ case PhabricatorRepositoryTransaction::TYPE_DESCRIPTION:
+ case PhabricatorRepositoryTransaction::TYPE_ENCODING:
+ case PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH:
+ case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY:
+ case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY:
+ case PhabricatorRepositoryTransaction::TYPE_UUID:
+ case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH:
+ case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI:
+ case PhabricatorRepositoryTransaction::TYPE_SSH_LOGIN:
+ case PhabricatorRepositoryTransaction::TYPE_SSH_KEY:
+ case PhabricatorRepositoryTransaction::TYPE_SSH_KEYFILE:
+ case PhabricatorRepositoryTransaction::TYPE_HTTP_LOGIN:
+ case PhabricatorRepositoryTransaction::TYPE_HTTP_PASS:
+ case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH:
+ case PhabricatorRepositoryTransaction::TYPE_VCS:
+ case PhabricatorRepositoryTransaction::TYPE_NOTIFY:
+ case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE:
+ PhabricatorPolicyFilter::requireCapability(
+ $this->requireActor(),
+ $object,
+ PhabricatorPolicyCapability::CAN_EDIT);
+ break;
+ }
+ }
+
}
diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php
--- a/src/applications/repository/storage/PhabricatorRepository.php
+++ b/src/applications/repository/storage/PhabricatorRepository.php
@@ -29,8 +29,8 @@
protected $name;
protected $callsign;
protected $uuid;
- protected $viewPolicy = PhabricatorPolicies::POLICY_USER;
- protected $editPolicy = PhabricatorPolicies::POLICY_ADMIN;
+ protected $viewPolicy;
+ protected $editPolicy;
protected $versionControlSystem;
protected $details = array();
@@ -40,6 +40,20 @@
private $commitCount = self::ATTACHABLE;
private $mostRecentCommit = self::ATTACHABLE;
+ public static function initializeNewRepository(PhabricatorUser $actor) {
+ $app = id(new PhabricatorApplicationQuery())
+ ->setViewer($actor)
+ ->withClasses(array('PhabricatorApplicationDiffusion'))
+ ->executeOne();
+
+ $view_policy = $app->getPolicy(DiffusionCapabilityDefaultView::CAPABILITY);
+ $edit_policy = $app->getPolicy(DiffusionCapabilityDefaultEdit::CAPABILITY);
+
+ return id(new PhabricatorRepository())
+ ->setViewPolicy($view_policy)
+ ->setEditPolicy($edit_policy);
+ }
+
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
diff --git a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php
--- a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php
+++ b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php
@@ -3,6 +3,7 @@
final class PhabricatorRepositoryTransaction
extends PhabricatorApplicationTransaction {
+ const TYPE_VCS = 'repo:vcs';
const TYPE_ACTIVATE = 'repo:activate';
const TYPE_NAME = 'repo:name';
const TYPE_DESCRIPTION = 'repo:description';
@@ -34,13 +35,59 @@
return null;
}
+ public function shouldHide() {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_REMOTE_URI:
+ case self::TYPE_SSH_LOGIN:
+ case self::TYPE_SSH_KEY:
+ case self::TYPE_SSH_KEYFILE:
+ case self::TYPE_HTTP_LOGIN:
+ case self::TYPE_HTTP_PASS:
+ // Hide null vs empty string changes.
+ return (!strlen($old) && !strlen($new));
+ case self::TYPE_LOCAL_PATH:
+ case self::TYPE_NAME:
+ // Hide these on create, they aren't interesting and we have an
+ // explicit "create" transaction.
+ if (!strlen($old)) {
+ return true;
+ }
+ break;
+ }
+
+ return parent::shouldHide();
+ }
+
+ public function getIcon() {
+ switch ($this->getTransactionType()) {
+ case self::TYPE_VCS:
+ return 'create';
+ }
+ return parent::getIcon();
+ }
+
+ public function getColor() {
+ switch ($this->getTransactionType()) {
+ case self::TYPE_VCS:
+ return 'green';
+ }
+ return parent::getIcon();
+ }
+
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
+ case self::TYPE_VCS:
+ return pht(
+ '%s created this repository.',
+ $this->renderHandleLink($author_phid));
case self::TYPE_ACTIVATE:
if ($new) {
return pht(

File Metadata

Mime Type
text/x-diff
Storage Engine
amazon-s3
Storage Format
Raw Data
Storage Handle
phabricator/6h/ut/ktlprv7fxibtf5if
Default Alt Text
D7413.diff (19 KB)

Event Timeline