1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 10:12:41 +01:00

Fix member edit transaction validation so it works for both implicit and explicit account creation

Summary:
Ref T12451. Ref T12484. This should deal with all the `+` / `-` / `=` cases correctly, I think.

Also makes sure that members are real users, not commits or tokens or whatever. And expands the creation test case to make some other basic sanity checks.

Test Plan:
  - Went through implicit first-time creation flow.
  - Went through explicit second-time creation flow.
  - Unit test now passes.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T12484, T12451

Differential Revision: https://secure.phabricator.com/D17692
This commit is contained in:
epriestley 2017-04-14 09:54:01 -07:00
parent 71d933d496
commit 505b1d8379
2 changed files with 44 additions and 26 deletions

View file

@ -21,6 +21,23 @@ final class PhabricatorPhortuneTestCase
1, 1,
count($accounts), count($accounts),
pht('Creation of default account for users with no accounts.')); pht('Creation of default account for users with no accounts.'));
// Reload the account. The user should be able to view and edit it, and
// should be a member.
$account = head($accounts);
$account = id(new PhortuneAccountQuery())
->setViewer($user)
->withPHIDs(array($account->getPHID()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
$this->assertEqual(true, ($account instanceof PhortuneAccount));
$this->assertEqual(array($user->getPHID()), $account->getMemberPHIDs());
} }
} }

View file

@ -28,47 +28,48 @@ final class PhortuneAccountEditor
$errors = parent::validateTransaction($object, $type, $xactions); $errors = parent::validateTransaction($object, $type, $xactions);
$viewer = $this->requireActor();
switch ($type) { switch ($type) {
case PhabricatorTransactions::TYPE_EDGE: case PhabricatorTransactions::TYPE_EDGE:
foreach ($xactions as $xaction) { foreach ($xactions as $xaction) {
switch ($xaction->getMetadataValue('edge:type')) { switch ($xaction->getMetadataValue('edge:type')) {
case PhortuneAccountHasMemberEdgeType::EDGECONST: case PhortuneAccountHasMemberEdgeType::EDGECONST:
$actor_phid = $this->requireActor()->getPHID();
$new = $xaction->getNewValue();
$old = $object->getMemberPHIDs(); $old = $object->getMemberPHIDs();
$new = $this->getPHIDTransactionNewValue($xaction, $old);
// Check if user is trying to not set themselves on creation $old = array_fuse($old);
if (!$old) { $new = array_fuse($new);
$set = idx($new, '+', array());
$actor_set = false; foreach ($new as $new_phid) {
foreach ($set as $phid) { if (isset($old[$new_phid])) {
if ($actor_phid == $phid) { continue;
$actor_set = true;
}
} }
if (!$actor_set) {
$user = id(new PhabricatorPeopleQuery())
->setViewer($viewer)
->withPHIDs(array($new_phid))
->executeOne();
if (!$user) {
$error = new PhabricatorApplicationTransactionValidationError( $error = new PhabricatorApplicationTransactionValidationError(
$type, $type,
pht('Invalid'), pht('Invalid'),
pht('You can not remove yourself as an account manager.'), pht(
$xaction); 'Account managers must be valid users, "%s" is not.',
$new_phid));
$errors[] = $error; $errors[] = $error;
continue;
} }
} }
// Check if user is trying to remove themselves on edit $actor_phid = $this->getActingAsPHID();
$set = idx($new, '-', array()); if (!isset($new[$actor_phid])) {
foreach ($set as $phid) { $error = new PhabricatorApplicationTransactionValidationError(
if ($actor_phid == $phid) { $type,
$error = new PhabricatorApplicationTransactionValidationError( pht('Invalid'),
$type, pht('You can not remove yourself as an account manager.'),
pht('Invalid'), $xaction);
pht('You can not remove yourself as an account manager.'), $errors[] = $error;
$xaction);
$errors[] = $error;
}
} }
break; break;
} }