Skip to content

Commit 4350858

Browse files
committed
Differential - allow setting viewPolicy from web ui during diff creation process
Summary: Fixes T6152, T6237. This introduces a viewPolicy column to the DifferentialDiff, and re-jiggers the DifferentialDiff policy implementation such that things behave as before once associated with a revision, else use the DifferentialDiff policy column value. Test Plan: made a diff with a non-standard view policy and noted that policy was still selected in the revision step. arc lint. Reviewers: epriestley Reviewed By: epriestley Subscribers: Korvin, epriestley Maniphest Tasks: T6237, T6152 Differential Revision: https://secure.phabricator.com/D10875
1 parent 7ef236c commit 4350858

19 files changed

+107
-25
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE {$NAMESPACE}_differential.differential_diff
2+
ADD viewPolicy VARBINARY(64) NOT NULL;
3+
4+
UPDATE {$NAMESPACE}_differential.differential_diff
5+
SET viewPolicy = 'users' WHERE viewPolicy = '';

src/applications/differential/__tests__/DifferentialParseRenderTestCase.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ private function buildChangesetParser($type, $data, $file) {
3535
$parser = new ArcanistDiffParser();
3636
$changes = $parser->parseDiff($data);
3737

38-
$diff = DifferentialDiff::newFromRawChanges($changes);
38+
$diff = DifferentialDiff::newFromRawChanges(
39+
PhabricatorUser::getOmnipotentUser(),
40+
$changes);
3941
if (count($diff->getChangesets()) !== 1) {
4042
throw new Exception("Expected one changeset: {$file}");
4143
}

src/applications/differential/conduit/DifferentialCreateDiffConduitAPIMethod.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ protected function execute(ConduitAPIRequest $request) {
6969
$changes[] = ArcanistDiffChange::newFromDictionary($dict);
7070
}
7171

72-
$diff = DifferentialDiff::newFromRawChanges($changes);
72+
$diff = DifferentialDiff::newFromRawChanges($viewer, $changes);
7373

7474
// TODO: Remove repository UUID eventually; for now continue writing
7575
// the UUID. Note that we'll overwrite it below if we identify a

src/applications/differential/conduit/DifferentialCreateRawDiffConduitAPIMethod.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public function defineParamTypes() {
1515
return array(
1616
'diff' => 'required string',
1717
'repositoryPHID' => 'optional string',
18+
'viewPolicy' => 'optional string',
1819
);
1920
}
2021

@@ -45,7 +46,7 @@ protected function execute(ConduitAPIRequest $request) {
4546

4647
$parser = new ArcanistDiffParser();
4748
$changes = $parser->parseDiff($raw_diff);
48-
$diff = DifferentialDiff::newFromRawChanges($changes);
49+
$diff = DifferentialDiff::newFromRawChanges($viewer, $changes);
4950

5051
$diff_data_dict = array(
5152
'creationMethod' => 'web',
@@ -58,6 +59,12 @@ protected function execute(ConduitAPIRequest $request) {
5859
->setTransactionType(DifferentialDiffTransaction::TYPE_DIFF_CREATE)
5960
->setNewValue($diff_data_dict),);
6061

62+
if ($request->getValue('viewPolicy')) {
63+
$xactions[] = id(new DifferentialTransaction())
64+
->setTransactionType(PhabricatorTransactions::TYPE_VIEW_POLICY)
65+
->setNewValue($request->getValue('viewPolicy'));
66+
}
67+
6168
id(new DifferentialDiffEditor())
6269
->setActor($viewer)
6370
->setContentSourceFromConduitRequest($request)

src/applications/differential/controller/DifferentialDiffCreateController.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ final class DifferentialDiffCreateController extends DifferentialController {
55
public function processRequest() {
66

77
$request = $this->getRequest();
8+
$viewer = $request->getUser();
89

910
$diff = null;
11+
// This object is just for policy stuff
12+
$diff_object = DifferentialDiff::initializeNewDiff($viewer);
1013
$repository_phid = null;
1114
$repository_value = array();
1215
$errors = array();
@@ -41,8 +44,9 @@ public function processRequest() {
4144
'differential.createrawdiff',
4245
array(
4346
'diff' => $diff,
44-
'repositoryPHID' => $repository_phid,));
45-
$call->setUser($request->getUser());
47+
'repositoryPHID' => $repository_phid,
48+
'viewPolicy' => $request->getStr('viewPolicy'),));
49+
$call->setUser($viewer);
4650
$result = $call->execute();
4751
$path = id(new PhutilURI($result['uri']))->getPath();
4852
return id(new AphrontRedirectResponse())->setURI($path);
@@ -68,10 +72,15 @@ public function processRequest() {
6872
$repository_value = $this->loadViewerHandles(array($repository_phid));
6973
}
7074

75+
$policies = id(new PhabricatorPolicyQuery())
76+
->setViewer($viewer)
77+
->setObject($diff_object)
78+
->execute();
79+
7180
$form
7281
->setAction('/differential/diff/create/')
7382
->setEncType('multipart/form-data')
74-
->setUser($request->getUser())
83+
->setUser($viewer)
7584
->appendInstructions(
7685
pht(
7786
'The best way to create a Differential diff is by using %s, but you '.
@@ -100,6 +109,13 @@ public function processRequest() {
100109
->setDatasource(new DiffusionRepositoryDatasource())
101110
->setValue($repository_value)
102111
->setLimit(1))
112+
->appendChild(
113+
id(new AphrontFormPolicyControl())
114+
->setUser($viewer)
115+
->setName('viewPolicy')
116+
->setPolicyObject($diff_object)
117+
->setPolicies($policies)
118+
->setCapability(PhabricatorPolicyCapability::CAN_VIEW))
103119
->appendChild(
104120
id(new AphrontFormSubmitControl())
105121
->addCancelButton($cancel_uri)

src/applications/differential/controller/DifferentialRevisionEditController.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ public function processRequest() {
7979
if ($repository_field) {
8080
$repository_field->setValue($request->getStr($repo_key));
8181
}
82+
$view_policy_key = id(new DifferentialViewPolicyField())->getFieldKey();
83+
$view_policy_field = idx(
84+
$field_list->getFields(),
85+
$view_policy_key);
86+
if ($view_policy_field) {
87+
$view_policy_field->setValue($diff->getViewPolicy());
88+
}
8289
}
8390

8491
$validation_exception = null;

src/applications/differential/editor/DifferentialDiffEditor.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public function getEditorObjectsDescription() {
2222
public function getTransactionTypes() {
2323
$types = parent::getTransactionTypes();
2424

25+
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
2526
$types[] = DifferentialDiffTransaction::TYPE_DIFF_CREATE;
2627

2728
return $types;
@@ -61,6 +62,9 @@ protected function applyCustomInternalTransaction(
6162
$dict = $this->diffDataDict;
6263
$this->updateDiffFromDict($object, $dict);
6364
return;
65+
case PhabricatorTransactions::TYPE_VIEW_POLICY:
66+
$object->setViewPolicy($xaction->getNewValue());
67+
return;
6468
}
6569

6670
return parent::applyCustomInternalTransaction($object, $xaction);
@@ -72,6 +76,7 @@ protected function applyCustomExternalTransaction(
7276

7377
switch ($xaction->getTransactionType()) {
7478
case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
79+
case PhabricatorTransactions::TYPE_VIEW_POLICY:
7580
return;
7681
}
7782

src/applications/differential/parser/__tests__/DifferentialHunkParserTestCase.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ private function createHunksFromFile($name) {
4040
throw new Exception("Expected 1 changeset for '{$name}'!");
4141
}
4242

43-
$diff = DifferentialDiff::newFromRawChanges($changes);
43+
$diff = DifferentialDiff::newFromRawChanges(
44+
PhabricatorUser::getOmnipotentUser(),
45+
$changes);
4446
return head($diff->getChangesets())->getHunks();
4547
}
4648

src/applications/differential/query/DifferentialDiffQuery.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ public function willFilterPage(array $diffs) {
6262

6363
foreach ($diffs as $key => $diff) {
6464
if (!$diff->getRevisionID()) {
65-
$diff->attachRevision(null);
6665
continue;
6766
}
6867

src/applications/differential/storage/DifferentialDiff.php

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ final class DifferentialDiff
3333

3434
protected $description;
3535

36+
protected $viewPolicy;
37+
3638
private $unsavedChangesets = array();
3739
private $changesets = self::ATTACHABLE;
3840
private $arcanistProject = self::ATTACHABLE;
@@ -136,10 +138,27 @@ public function save() {
136138
return $ret;
137139
}
138140

139-
public static function newFromRawChanges(array $changes) {
141+
public static function initializeNewDiff(PhabricatorUser $actor) {
142+
$app = id(new PhabricatorApplicationQuery())
143+
->setViewer($actor)
144+
->withClasses(array('PhabricatorDifferentialApplication'))
145+
->executeOne();
146+
$view_policy = $app->getPolicy(
147+
DifferentialDefaultViewCapability::CAPABILITY);
148+
149+
$diff = id(new DifferentialDiff())
150+
->setViewPolicy($view_policy);
151+
152+
return $diff;
153+
}
154+
155+
public static function newFromRawChanges(
156+
PhabricatorUser $actor,
157+
array $changes) {
158+
140159
assert_instances_of($changes, 'ArcanistDiffChange');
141-
$diff = new DifferentialDiff();
142160

161+
$diff = self::initializeNewDiff($actor);
143162
// There may not be any changes; initialize the changesets list so that
144163
// we don't throw later when accessing it.
145164
$diff->attachChangesets(array());
@@ -289,6 +308,10 @@ public function buildChangesList() {
289308
return $changes;
290309
}
291310

311+
public function hasRevision() {
312+
return $this->revision !== self::ATTACHABLE;
313+
}
314+
292315
public function getRevision() {
293316
return $this->assertAttached($this->revision);
294317
}
@@ -318,27 +341,27 @@ public function getCapabilities() {
318341
}
319342

320343
public function getPolicy($capability) {
321-
if ($this->getRevision()) {
344+
if ($this->hasRevision()) {
322345
return $this->getRevision()->getPolicy($capability);
323346
}
324347

325-
return PhabricatorPolicies::POLICY_USER;
348+
return $this->viewPolicy;
326349
}
327350

328351
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
329-
if ($this->getRevision()) {
352+
if ($this->hasRevision()) {
330353
return $this->getRevision()->hasAutomaticCapability($capability, $viewer);
331354
}
332355

333-
return false;
356+
return ($this->getAuthorPHID() == $viewer->getPhid());
334357
}
335358

336359
public function describeAutomaticCapability($capability) {
337-
if ($this->getRevision()) {
360+
if ($this->hasRevision()) {
338361
return pht(
339362
'This diff is attached to a revision, and inherits its policies.');
340363
}
341-
return null;
364+
return pht('The author of a diff can see it.');
342365
}
343366

344367

0 commit comments

Comments
 (0)