Conpherence - Implement edit rules for rooms
Summary: Fixes T7586. If you can't edit a room, the pertinent UI is greyed out. One exception is the title of the room in the full viewer; this crumb is not disabled as it would be hard to read. Otherwise though, everything is disabled nicely. Test Plan: tried to add participants when I wasn't allowed to and got an error. added participants otherwise okay. tried to edit title when i wasn't allowed and got an error. otherwise okay. left conpherence threads / rooms successfully. Reviewers: epriestley, chad Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T7586 Differential Revision: https://secure.phabricator.com/D12161
This commit is contained in:
@@ -84,7 +84,12 @@ final class ConpherenceColumnViewController extends
|
||||
'content' => hsprintf('%s', $durable_column),
|
||||
'threadID' => $conpherence_id,
|
||||
'threadPHID' => $conpherence_phid,
|
||||
'latestTransactionID' => $latest_transaction_id,);
|
||||
'latestTransactionID' => $latest_transaction_id,
|
||||
'canEdit' => PhabricatorPolicyFilter::hasCapability(
|
||||
$user,
|
||||
$conpherence,
|
||||
PhabricatorPolicyCapability::CAN_EDIT),
|
||||
);
|
||||
|
||||
return id(new AphrontAjaxResponse())->setContent($response);
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ final class ConpherenceListController extends ConpherenceController {
|
||||
case self::UNSELECTED_MODE:
|
||||
default:
|
||||
$layout = id(new ConpherenceLayoutView())
|
||||
->setUser($user)
|
||||
->setBaseURI($this->getApplicationURI())
|
||||
->setThreadView($thread_view)
|
||||
->setRole('list');
|
||||
|
||||
@@ -3,35 +3,37 @@
|
||||
final class ConpherenceUpdateController
|
||||
extends ConpherenceController {
|
||||
|
||||
private $conpherenceID;
|
||||
|
||||
public function setConpherenceID($conpherence_id) {
|
||||
$this->conpherenceID = $conpherence_id;
|
||||
return $this;
|
||||
}
|
||||
public function getConpherenceID() {
|
||||
return $this->conpherenceID;
|
||||
}
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->setConpherenceID(idx($data, 'id'));
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$user = $request->getUser();
|
||||
$conpherence_id = $this->getConpherenceID();
|
||||
$conpherence_id = $request->getURIData('id');
|
||||
if (!$conpherence_id) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$needed_capabilities = array(PhabricatorPolicyCapability::CAN_VIEW);
|
||||
$action = $request->getStr('action', ConpherenceUpdateActions::METADATA);
|
||||
switch ($action) {
|
||||
case ConpherenceUpdateActions::REMOVE_PERSON:
|
||||
$person_phid = $request->getStr('remove_person');
|
||||
if ($person_phid != $user->getPHID()) {
|
||||
$needed_capabilities[] = PhabricatorPolicyCapability::CAN_EDIT;
|
||||
}
|
||||
break;
|
||||
case ConpherenceUpdateActions::ADD_PERSON:
|
||||
case ConpherenceUpdateActions::METADATA:
|
||||
$needed_capabilities[] = PhabricatorPolicyCapability::CAN_EDIT;
|
||||
break;
|
||||
case ConpherenceUpdateActions::JOIN_ROOM:
|
||||
$needed_capabilities[] = PhabricatorPolicyCapability::CAN_JOIN;
|
||||
break;
|
||||
}
|
||||
$conpherence = id(new ConpherenceThreadQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($conpherence_id))
|
||||
->needFilePHIDs(true)
|
||||
->requireCapabilities($needed_capabilities)
|
||||
->executeOne();
|
||||
|
||||
$action = $request->getStr('action', ConpherenceUpdateActions::METADATA);
|
||||
|
||||
$latest_transaction_id = null;
|
||||
$response_mode = $request->isAjax() ? 'ajax' : 'redirect';
|
||||
$error_view = null;
|
||||
@@ -54,10 +56,6 @@ final class ConpherenceUpdateController
|
||||
$draft->replaceOrDelete();
|
||||
return new AphrontAjaxResponse();
|
||||
case ConpherenceUpdateActions::JOIN_ROOM:
|
||||
PhabricatorPolicyFilter::requireCapability(
|
||||
$user,
|
||||
$conpherence,
|
||||
PhabricatorPolicyCapability::CAN_JOIN);
|
||||
$xactions[] = id(new ConpherenceTransaction())
|
||||
->setTransactionType(
|
||||
ConpherenceTransactionType::TYPE_PARTICIPANTS)
|
||||
@@ -257,14 +255,19 @@ final class ConpherenceUpdateController
|
||||
$user = $request->getUser();
|
||||
$remove_person = $request->getStr('remove_person');
|
||||
$participants = $conpherence->getParticipants();
|
||||
$message = pht(
|
||||
'Are you sure you want to remove yourself from this conpherence? ');
|
||||
if (count($participants) == 1) {
|
||||
$message .= pht(
|
||||
'The conpherence will be inaccessible forever and ever.');
|
||||
if ($conpherence->getIsRoom()) {
|
||||
$message = pht(
|
||||
'Are you sure you want to remove yourself from this room?');
|
||||
} else {
|
||||
$message .= pht(
|
||||
'Someone else in the conpherence can add you back later.');
|
||||
$message = pht(
|
||||
'Are you sure you want to remove yourself from this thread?');
|
||||
if (count($participants) == 1) {
|
||||
$message .= pht(
|
||||
'The thread will be inaccessible forever and ever.');
|
||||
} else {
|
||||
$message .= pht(
|
||||
'Someone else in the thread can add you back later.');
|
||||
}
|
||||
}
|
||||
$body = phutil_tag(
|
||||
'p',
|
||||
|
||||
@@ -63,10 +63,15 @@ final class ConpherenceViewController extends
|
||||
$content['threadID'] = $conpherence->getID();
|
||||
$content['threadPHID'] = $conpherence->getPHID();
|
||||
$content['latestTransactionID'] = $data['latest_transaction_id'];
|
||||
$content['canEdit'] = PhabricatorPolicyFilter::hasCapability(
|
||||
$user,
|
||||
$conpherence,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
return id(new AphrontAjaxResponse())->setContent($content);
|
||||
}
|
||||
|
||||
$layout = id(new ConpherenceLayoutView())
|
||||
->setUser($user)
|
||||
->setBaseURI($this->getApplicationURI())
|
||||
->setThread($conpherence)
|
||||
->setHeader($header)
|
||||
|
||||
@@ -369,6 +369,51 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||
return $xactions;
|
||||
}
|
||||
|
||||
protected function requireCapabilities(
|
||||
PhabricatorLiskDAO $object,
|
||||
PhabricatorApplicationTransaction $xaction) {
|
||||
|
||||
parent::requireCapabilities($object, $xaction);
|
||||
|
||||
switch ($xaction->getTransactionType()) {
|
||||
case ConpherenceTransactionType::TYPE_PARTICIPANTS:
|
||||
$old_map = array_fuse($xaction->getOldValue());
|
||||
$new_map = array_fuse($xaction->getNewValue());
|
||||
|
||||
$add = array_keys(array_diff_key($new_map, $old_map));
|
||||
$rem = array_keys(array_diff_key($old_map, $new_map));
|
||||
|
||||
$actor_phid = $this->requireActor()->getPHID();
|
||||
|
||||
$is_join = (($add === array($actor_phid)) && !$rem);
|
||||
$is_leave = (($rem === array($actor_phid)) && !$add);
|
||||
|
||||
if ($is_join) {
|
||||
// You need CAN_JOIN to join a thread / room.
|
||||
PhabricatorPolicyFilter::requireCapability(
|
||||
$this->requireActor(),
|
||||
$object,
|
||||
PhabricatorPolicyCapability::CAN_JOIN);
|
||||
} else if ($is_leave) {
|
||||
// You don't need any capabilities to leave a conpherence thread.
|
||||
} else {
|
||||
// You need CAN_EDIT to change participants other than yourself.
|
||||
PhabricatorPolicyFilter::requireCapability(
|
||||
$this->requireActor(),
|
||||
$object,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
}
|
||||
break;
|
||||
case ConpherenceTransactionType::TYPE_FILES:
|
||||
case ConpherenceTransactionType::TYPE_TITLE:
|
||||
PhabricatorPolicyFilter::requireCapability(
|
||||
$this->requireActor(),
|
||||
$object,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function mergeTransactions(
|
||||
PhabricatorApplicationTransaction $u,
|
||||
PhabricatorApplicationTransaction $v) {
|
||||
@@ -496,7 +541,7 @@ final class ConpherenceEditor extends PhabricatorApplicationTransactionEditor {
|
||||
|
||||
switch ($type) {
|
||||
case ConpherenceTransactionType::TYPE_TITLE:
|
||||
if (!$object->getIsRoom() && $this->getIsNewObject()) {
|
||||
if (!$object->getIsRoom()) {
|
||||
continue;
|
||||
}
|
||||
$missing = $this->validateIsEmptyTextField(
|
||||
|
||||
@@ -266,7 +266,15 @@ final class ConpherenceThread extends ConpherenceDAO
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return pht('Participants in a thread can always view and edit it.');
|
||||
if ($this->getIsRoom()) {
|
||||
switch ($capability) {
|
||||
case PhabricatorPolicyCapability::CAN_VIEW:
|
||||
return pht('Participants in a room can always view it.');
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return pht('Participants in a thread can always view and edit it.');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -237,6 +237,7 @@ final class ConpherenceDurableColumnView extends AphrontTagView {
|
||||
->setHref($action['href'])
|
||||
->setName($action['name'])
|
||||
->setIcon($action['icon'])
|
||||
->setDisabled($action['disabled'])
|
||||
->addSigil('conpherence-durable-column-header-action')
|
||||
->setMetadata(array(
|
||||
'action' => $action['key'],
|
||||
@@ -303,27 +304,41 @@ final class ConpherenceDurableColumnView extends AphrontTagView {
|
||||
}
|
||||
|
||||
private function getHeaderActionsConfig(ConpherenceThread $conpherence) {
|
||||
if ($conpherence->getIsRoom()) {
|
||||
$rename_label = pht('Rename Room');
|
||||
} else {
|
||||
$rename_label = pht('Rename Thread');
|
||||
}
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$this->getUser(),
|
||||
$conpherence,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
return array(
|
||||
array(
|
||||
'name' => pht('Add Participants'),
|
||||
'disabled' => !$can_edit,
|
||||
'href' => '/conpherence/update/'.$conpherence->getID().'/',
|
||||
'icon' => 'fa-plus',
|
||||
'key' => ConpherenceUpdateActions::ADD_PERSON,
|
||||
),
|
||||
array(
|
||||
'name' => pht('Rename Thread'),
|
||||
'name' => $rename_label,
|
||||
'disabled' => !$can_edit,
|
||||
'href' => '/conpherence/update/'.$conpherence->getID().'/',
|
||||
'icon' => 'fa-pencil',
|
||||
'key' => ConpherenceUpdateActions::METADATA,
|
||||
),
|
||||
array(
|
||||
'name' => pht('View in Conpherence'),
|
||||
'disabled' => false,
|
||||
'href' => '/conpherence/'.$conpherence->getID().'/',
|
||||
'icon' => 'fa-comments',
|
||||
'key' => 'go_conpherence',
|
||||
),
|
||||
array(
|
||||
'name' => pht('Hide Column'),
|
||||
'disabled' => false,
|
||||
'href' => '#',
|
||||
'icon' => 'fa-times',
|
||||
'key' => 'hide_column',
|
||||
|
||||
@@ -68,10 +68,15 @@ final class ConpherenceLayoutView extends AphrontView {
|
||||
$selected_id = null;
|
||||
$selected_thread_id = null;
|
||||
$selected_thread_phid = null;
|
||||
$can_edit_selected = null;
|
||||
if ($this->thread) {
|
||||
$selected_id = $this->thread->getPHID().'-nav-item';
|
||||
$selected_thread_id = $this->thread->getID();
|
||||
$selected_thread_phid = $this->thread->getPHID();
|
||||
$can_edit_selected = PhabricatorPolicyFilter::hasCapability(
|
||||
$this->getUser(),
|
||||
$this->thread,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
}
|
||||
$this->initBehavior('conpherence-menu',
|
||||
array(
|
||||
@@ -80,6 +85,7 @@ final class ConpherenceLayoutView extends AphrontView {
|
||||
'selectedID' => $selected_id,
|
||||
'selectedThreadID' => $selected_thread_id,
|
||||
'selectedThreadPHID' => $selected_thread_phid,
|
||||
'canEditSelectedThread' => $can_edit_selected,
|
||||
'latestTransactionID' => $this->latestTransactionID,
|
||||
'role' => $this->role,
|
||||
'hasThreadList' => (bool)$this->threadView,
|
||||
|
||||
@@ -146,6 +146,10 @@ final class PHUIListItemView extends AphrontTagView {
|
||||
$classes[] = 'phui-list-item-selected';
|
||||
}
|
||||
|
||||
if ($this->disabled) {
|
||||
$classes[] = 'phui-list-item-disabled';
|
||||
}
|
||||
|
||||
if ($this->statusColor) {
|
||||
$classes[] = $this->statusColor;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user