diff --git a/resources/sql/autopatches/20141107.phriction.policy.1.sql b/resources/sql/autopatches/20141107.phriction.policy.1.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20141107.phriction.policy.1.sql @@ -0,0 +1,5 @@ +ALTER TABLE {$NAMESPACE}_phriction.phriction_document + ADD viewPolicy VARBINARY(64) NOT NULL; + +ALTER TABLE {$NAMESPACE}_phriction.phriction_document + ADD editPolicy VARBINARY(64) NOT NULL; diff --git a/resources/sql/autopatches/20141107.phriction.policy.2.php b/resources/sql/autopatches/20141107.phriction.policy.2.php new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20141107.phriction.policy.2.php @@ -0,0 +1,47 @@ +establishConnection('w'); + +echo "Populating Phriction policies.\n"; + +$default_view_policy = PhabricatorPolicies::getMostOpenPolicy(); +$default_edit_policy = PhabricatorPolicies::POLICY_USER; + +foreach (new LiskMigrationIterator($table) as $doc) { + $id = $doc->getID(); + + if ($doc->getViewPolicy() && $doc->getEditPolicy()) { + echo "Skipping doc $id; already has policy set.\n"; + continue; + } + + // project documents get the project policy + if (PhrictionDocument::isProjectSlug($doc->getSlug())) { + + $project_slug = + PhrictionDocument::getProjectSlugIdentifier($doc->getSlug()); + $project_slugs = array($project_slug); + $project = id(new PhabricatorProjectQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withPhrictionSlugs($project_slugs) + ->executeOne(); + + $project_name = $project->getName(); + echo "Migrating doc $id to project policy $project_name...\n"; + $doc->setViewPolicy($project->getViewPolicy()); + $doc->setEditPolicy($project->getEditPolicy()); + $doc->save(); + + // non-project documents get the most open policy possible + } else { + + echo "Migrating doc $id to default install policy...\n"; + $doc->setViewPolicy($default_view_policy); + $doc->setEditPolicy($default_edit_policy); + $doc->save(); + + } +} + +echo "Done.\n"; 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 @@ -2756,7 +2756,6 @@ 'PhrequentUserTime' => 'applications/phrequent/storage/PhrequentUserTime.php', 'PhrequentUserTimeQuery' => 'applications/phrequent/query/PhrequentUserTimeQuery.php', 'PhrictionActionConstants' => 'applications/phriction/constants/PhrictionActionConstants.php', - 'PhrictionActionMenuEventListener' => 'applications/phriction/event/PhrictionActionMenuEventListener.php', 'PhrictionChangeType' => 'applications/phriction/constants/PhrictionChangeType.php', 'PhrictionConduitAPIMethod' => 'applications/phriction/conduit/PhrictionConduitAPIMethod.php', 'PhrictionConstants' => 'applications/phriction/constants/PhrictionConstants.php', @@ -5959,7 +5958,6 @@ ), 'PhrequentUserTimeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhrictionActionConstants' => 'PhrictionConstants', - 'PhrictionActionMenuEventListener' => 'PhabricatorEventListener', 'PhrictionChangeType' => 'PhrictionConstants', 'PhrictionConduitAPIMethod' => 'ConduitAPIMethod', 'PhrictionContent' => array( diff --git a/src/applications/phriction/application/PhabricatorPhrictionApplication.php b/src/applications/phriction/application/PhabricatorPhrictionApplication.php --- a/src/applications/phriction/application/PhabricatorPhrictionApplication.php +++ b/src/applications/phriction/application/PhabricatorPhrictionApplication.php @@ -36,12 +36,6 @@ ); } - public function getEventListeners() { - return array( - new PhrictionActionMenuEventListener(), - ); - } - public function getRoutes() { return array( // Match "/w/" with slug "/". diff --git a/src/applications/phriction/controller/PhrictionDiffController.php b/src/applications/phriction/controller/PhrictionDiffController.php --- a/src/applications/phriction/controller/PhrictionDiffController.php +++ b/src/applications/phriction/controller/PhrictionDiffController.php @@ -4,6 +4,10 @@ private $id; + public function shouldAllowPublic() { + return true; + } + public function willProcessRequest(array $data) { $this->id = $data['id']; } diff --git a/src/applications/phriction/controller/PhrictionDocumentController.php b/src/applications/phriction/controller/PhrictionDocumentController.php --- a/src/applications/phriction/controller/PhrictionDocumentController.php +++ b/src/applications/phriction/controller/PhrictionDocumentController.php @@ -5,6 +5,10 @@ private $slug; + public function shouldAllowPublic() { + return true; + } + public function willProcessRequest(array $data) { $this->slug = $data['slug']; } @@ -199,6 +203,8 @@ } $header = id(new PHUIHeaderView()) + ->setUser($user) + ->setPolicyObject($document) ->setHeader($page_title); $prop_list = null; diff --git a/src/applications/phriction/controller/PhrictionEditController.php b/src/applications/phriction/controller/PhrictionEditController.php --- a/src/applications/phriction/controller/PhrictionEditController.php +++ b/src/applications/phriction/controller/PhrictionEditController.php @@ -131,6 +131,8 @@ $content_text = $request->getStr('content'); $notes = $request->getStr('description'); $current_version = $request->getInt('contentVersion'); + $v_view = $request->getStr('viewPolicy'); + $v_edit = $request->getStr('editPolicy'); $xactions = array(); $xactions[] = id(new PhrictionTransaction()) @@ -139,6 +141,12 @@ $xactions[] = id(new PhrictionTransaction()) ->setTransactionType(PhrictionTransaction::TYPE_CONTENT) ->setNewValue($content_text); + $xactions[] = id(new PhrictionTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) + ->setNewValue($v_view); + $xactions[] = id(new PhrictionTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) + ->setNewValue($v_edit); $editor = id(new PhrictionTransactionEditor()) ->setActor($user) @@ -170,7 +178,8 @@ $overwrite = true; } - // TODO - remember to set policy to what the user tried to set it to + $document->setViewPolicy($v_view); + $document->setEditPolicy($v_edit); } } @@ -194,6 +203,13 @@ $cancel_uri = PhrictionDocument::getSlugURI($document->getSlug()); + $policies = id(new PhabricatorPolicyQuery()) + ->setViewer($user) + ->setObject($document) + ->execute(); + $view_capability = PhabricatorPolicyCapability::CAN_VIEW; + $edit_capability = PhabricatorPolicyCapability::CAN_EDIT; + $form = id(new AphrontFormView()) ->setUser($user) ->addHiddenInput('slug', $document->getSlug()) @@ -220,6 +236,22 @@ ->setID('document-textarea') ->setUser($user)) ->appendChild( + id(new AphrontFormPolicyControl()) + ->setName('viewPolicy') + ->setPolicyObject($document) + ->setCapability($view_capability) + ->setPolicies($policies) + ->setCaption( + $document->describeAutomaticCapability($view_capability))) + ->appendChild( + id(new AphrontFormPolicyControl()) + ->setName('editPolicy') + ->setPolicyObject($document) + ->setCapability($edit_capability) + ->setPolicies($policies) + ->setCaption( + $document->describeAutomaticCapability($edit_capability))) + ->appendChild( id(new AphrontFormTextControl()) ->setLabel(pht('Edit Notes')) ->setValue($notes) diff --git a/src/applications/phriction/controller/PhrictionHistoryController.php b/src/applications/phriction/controller/PhrictionHistoryController.php --- a/src/applications/phriction/controller/PhrictionHistoryController.php +++ b/src/applications/phriction/controller/PhrictionHistoryController.php @@ -5,6 +5,10 @@ private $slug; + public function shouldAllowPublic() { + return true; + } + public function willProcessRequest(array $data) { $this->slug = $data['slug']; } diff --git a/src/applications/phriction/editor/PhrictionTransactionEditor.php b/src/applications/phriction/editor/PhrictionTransactionEditor.php --- a/src/applications/phriction/editor/PhrictionTransactionEditor.php +++ b/src/applications/phriction/editor/PhrictionTransactionEditor.php @@ -83,10 +83,8 @@ $types[] = PhrictionTransaction::TYPE_MOVE_TO; $types[] = PhrictionTransaction::TYPE_MOVE_AWAY; - /* TODO $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; - */ return $types; } @@ -202,8 +200,18 @@ ->setNewValue(true); } break; + case PhrictionTransaction::TYPE_MOVE_TO: + $document = $xaction->getNewValue(); + $xactions[] = id(new PhrictionTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) + ->setNewValue($document->getViewPolicy()); + $xactions[] = id(new PhrictionTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) + ->setNewValue($document->getEditPolicy()); + break; default: break; + } return $xactions; @@ -300,6 +308,12 @@ ->setTransactionType(PhrictionTransaction::TYPE_CONTENT) ->setNewValue('') ->setMetadataValue('stub:create:phid', $object->getPHID()); + $stub_xactions[] = id(new PhrictionTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY) + ->setNewValue($object->getViewPolicy()); + $stub_xactions[] = id(new PhrictionTransaction()) + ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) + ->setNewValue($object->getEditPolicy()); $sub_editor = id(new PhrictionTransactionEditor()) ->setActor($this->getActor()) ->setContentSource($this->getContentSource()) diff --git a/src/applications/phriction/event/PhrictionActionMenuEventListener.php b/src/applications/phriction/event/PhrictionActionMenuEventListener.php deleted file mode 100644 --- a/src/applications/phriction/event/PhrictionActionMenuEventListener.php +++ /dev/null @@ -1,43 +0,0 @@ -listen(PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS); - } - - public function handleEvent(PhutilEvent $event) { - switch ($event->getType()) { - case PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS: - $this->handleActionsEvent($event); - break; - } - } - - private function handleActionsEvent(PhutilEvent $event) { - $object = $event->getValue('object'); - - $actions = null; - if ($object instanceof PhabricatorProject) { - $actions = $this->buildProjectActions($event); - } - - $this->addActionMenuItems($event, $actions); - } - - private function buildProjectActions(PhutilEvent $event) { - if (!$this->canUseApplication($event->getUser())) { - return null; - } - - $project = $event->getValue('object'); - $slug = PhabricatorSlug::normalize($project->getPhrictionSlug()); - $href = '/w/projects/'.$slug; - - return id(new PhabricatorActionView()) - ->setIcon('fa-book') - ->setName(pht('View Wiki')) - ->setHref($href); - } - -} diff --git a/src/applications/phriction/storage/PhrictionDocument.php b/src/applications/phriction/storage/PhrictionDocument.php --- a/src/applications/phriction/storage/PhrictionDocument.php +++ b/src/applications/phriction/storage/PhrictionDocument.php @@ -13,13 +13,12 @@ protected $contentID; protected $status; protected $mailKey; + protected $viewPolicy; + protected $editPolicy; private $contentObject = self::ATTACHABLE; private $ancestors = array(); - - // TODO: This should be `self::ATTACHABLE`, but there are still a lot of call - // sites which load PhrictionDocuments directly. - private $project = null; + private $project = self::ATTACHABLE; public function getConfiguration() { return array( @@ -66,6 +65,25 @@ $content->setTitle($default_title); $document->attachContent($content); + $parent_doc = null; + $ancestral_slugs = PhabricatorSlug::getAncestry($slug); + if ($ancestral_slugs) { + $parent = end($ancestral_slugs); + $parent_doc = id(new PhrictionDocumentQuery()) + ->setViewer($actor) + ->withSlugs(array($parent)) + ->executeOne(); + } + + if ($parent_doc) { + $document->setViewPolicy($parent_doc->getViewPolicy()); + $document->setEditPolicy($parent_doc->getEditPolicy()); + } else { + $default_view_policy = PhabricatorPolicies::getMostOpenPolicy(); + $document->setViewPolicy($default_view_policy); + $document->setEditPolicy(PhabricatorPolicies::POLICY_USER); + } + return $document; } @@ -172,31 +190,29 @@ } public function getPolicy($capability) { - if ($this->hasProject()) { - return $this->getProject()->getPolicy($capability); + switch ($capability) { + case PhabricatorPolicyCapability::CAN_VIEW: + return $this->getViewPolicy(); + case PhabricatorPolicyCapability::CAN_EDIT: + return $this->getEditPolicy(); } - - return PhabricatorPolicies::POLICY_USER; } public function hasAutomaticCapability($capability, PhabricatorUser $user) { - if ($this->hasProject()) { - return $this->getProject()->hasAutomaticCapability($capability, $user); - } return false; } public function describeAutomaticCapability($capability) { - if ($this->hasProject()) { - return pht( - "This is a project wiki page, and inherits the project's policies."); - } switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: return pht( 'To view a wiki document, you must also be able to view all '. 'of its parents.'); + case PhabricatorPolicyCapability::CAN_EDIT: + return pht( + 'To edit a wiki document, you must also be able to view all '. + 'of its parents.'); } return null;