mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +01:00
Make "Subscribe/Unsubscribe" require only "CAN_VIEW", not "CAN_INTERACT"
Summary: Ref T13249. See PHI1059. Currently, Subscribe/Unsubscribe require CAN_INTERACT via the web UI and no permissions (i.e., effectively CAN_VIEW) via the API. Weaken the requirements from the web UI so that you do not need "CAN_INTERACT". This is a product change to the effect that it's okay to subscribe/unsubscribe from anything you can see, even hard-locked tasks. This generally seems reasonable. Increase the requirements for the actual transaction, which mostly applies to API changes: - To remove subscribers other than yourself, require CAN_EDIT. - To add subscribers other than yourself, require CAN_EDIT or CAN_INTERACT. You may have CAN_EDIT but not CAN_INTERACT on "soft locked" tasks. It's okay to click "Edit" on these, click "Yes, override lock", then remove subscribers other than yourself. This technically plugs some weird, mostly theoretical holes in the API where "attackers" could sometimes make more subscription changes than they should have been able to. Now that we send you email when you're unsubscribed this could only really be used to be mildly mischievous, but no harm in making the policy enforcement more correct. Test Plan: Against normal, soft-locked, and hard-locked tasks: subscribed, unsubscribed, added and removed subscribers, overrode locks, edited via API. Everything worked like it should and I couldn't find any combination of lock state, policy state, and edit pathway that did anything suspicious. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13249 Differential Revision: https://secure.phabricator.com/D20174
This commit is contained in:
parent
8cf6c68c95
commit
e44b40ca4d
3 changed files with 44 additions and 18 deletions
|
@ -47,15 +47,6 @@ final class PhabricatorSubscriptionsEditController
|
||||||
$handle->getURI());
|
$handle->getURI());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PhabricatorPolicyFilter::canInteract($viewer, $object)) {
|
|
||||||
$lock = PhabricatorEditEngineLock::newForObject($viewer, $object);
|
|
||||||
|
|
||||||
$dialog = $this->newDialog()
|
|
||||||
->addCancelButton($handle->getURI());
|
|
||||||
|
|
||||||
return $lock->willBlockUserInteractionWithDialog($dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($object instanceof PhabricatorApplicationTransactionInterface) {
|
if ($object instanceof PhabricatorApplicationTransactionInterface) {
|
||||||
if ($is_add) {
|
if ($is_add) {
|
||||||
$xaction_value = array(
|
$xaction_value = array(
|
||||||
|
|
|
@ -73,24 +73,20 @@ final class PhabricatorSubscriptionsUIEventListener
|
||||||
->setName(pht('Automatically Subscribed'))
|
->setName(pht('Automatically Subscribed'))
|
||||||
->setIcon('fa-check-circle lightgreytext');
|
->setIcon('fa-check-circle lightgreytext');
|
||||||
} else {
|
} else {
|
||||||
$can_interact = PhabricatorPolicyFilter::canInteract($user, $object);
|
|
||||||
|
|
||||||
if ($is_subscribed) {
|
if ($is_subscribed) {
|
||||||
$sub_action = id(new PhabricatorActionView())
|
$sub_action = id(new PhabricatorActionView())
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setRenderAsForm(true)
|
->setRenderAsForm(true)
|
||||||
->setHref('/subscriptions/delete/'.$object->getPHID().'/')
|
->setHref('/subscriptions/delete/'.$object->getPHID().'/')
|
||||||
->setName(pht('Unsubscribe'))
|
->setName(pht('Unsubscribe'))
|
||||||
->setIcon('fa-minus-circle')
|
->setIcon('fa-minus-circle');
|
||||||
->setDisabled(!$can_interact);
|
|
||||||
} else {
|
} else {
|
||||||
$sub_action = id(new PhabricatorActionView())
|
$sub_action = id(new PhabricatorActionView())
|
||||||
->setWorkflow(true)
|
->setWorkflow(true)
|
||||||
->setRenderAsForm(true)
|
->setRenderAsForm(true)
|
||||||
->setHref('/subscriptions/add/'.$object->getPHID().'/')
|
->setHref('/subscriptions/add/'.$object->getPHID().'/')
|
||||||
->setName(pht('Subscribe'))
|
->setName(pht('Subscribe'))
|
||||||
->setIcon('fa-plus-circle')
|
->setIcon('fa-plus-circle');
|
||||||
->setDisabled(!$can_interact);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$user->isLoggedIn()) {
|
if (!$user->isLoggedIn()) {
|
||||||
|
|
|
@ -1648,9 +1648,48 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
// don't enforce it here.
|
// don't enforce it here.
|
||||||
return null;
|
return null;
|
||||||
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
case PhabricatorTransactions::TYPE_SUBSCRIBERS:
|
||||||
// TODO: Removing subscribers other than yourself should probably
|
// Anyone can subscribe to or unsubscribe from anything they can view,
|
||||||
// require CAN_EDIT permission. You can do this via the API but
|
// with no other permissions.
|
||||||
// generally can not via the web interface.
|
|
||||||
|
$old = array_fuse($xaction->getOldValue());
|
||||||
|
$new = array_fuse($xaction->getNewValue());
|
||||||
|
|
||||||
|
// To remove users other than yourself, you must be able to edit the
|
||||||
|
// object.
|
||||||
|
$rem = array_diff_key($old, $new);
|
||||||
|
foreach ($rem as $phid) {
|
||||||
|
if ($phid !== $this->getActingAsPHID()) {
|
||||||
|
return PhabricatorPolicyCapability::CAN_EDIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// To add users other than yourself, you must be able to interact.
|
||||||
|
// This allows "@mentioning" users to work as long as you can comment
|
||||||
|
// on objects.
|
||||||
|
|
||||||
|
// If you can edit, we return that policy instead so that you can
|
||||||
|
// override a soft lock and still make edits.
|
||||||
|
|
||||||
|
// TODO: This is a little bit hacky. We really want to be able to say
|
||||||
|
// "this requires either interact or edit", but there's currently no
|
||||||
|
// way to specify this kind of requirement.
|
||||||
|
|
||||||
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$this->getActor(),
|
||||||
|
$this->object,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
|
$add = array_diff_key($new, $old);
|
||||||
|
foreach ($add as $phid) {
|
||||||
|
if ($phid !== $this->getActingAsPHID()) {
|
||||||
|
if ($can_edit) {
|
||||||
|
return PhabricatorPolicyCapability::CAN_EDIT;
|
||||||
|
} else {
|
||||||
|
return PhabricatorPolicyCapability::CAN_INTERACT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
case PhabricatorTransactions::TYPE_TOKEN:
|
case PhabricatorTransactions::TYPE_TOKEN:
|
||||||
// TODO: This technically requires CAN_INTERACT, like comments.
|
// TODO: This technically requires CAN_INTERACT, like comments.
|
||||||
|
|
Loading…
Reference in a new issue