@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Phriction - validateTransactions that need parent ancestry to complete successfully

Summary:
Fixes T6651, T6682. Since policy is defined by ancestry, you can't make things outside the core tree.

An alternative fix would be to automagically stub everything in these cases. This has potential negative policy implications - consider making a public document with several levels of depth that automagically stubs out its ancestry as public - and additionally the PhabricatorApplicationTransactionEditor framework would make this very tricky code (i.e. you are expected to validateTransactions in said hook *and* return an error if things aren't valid and not do some automagic stubbing, etc.)

Test Plan: tried to move a doc from location/that/exists to locationz/thatz/dontz/existz/ and got an error message with links to each missing doc. tried to create a doc at locatonz/thatz/dontz/existsz/ and got an error message with links to each missing doc.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T6682, T6651

Differential Revision: https://secure.phabricator.com/D10978

+77 -2
+77 -2
src/applications/phriction/editor/PhrictionTransactionEditor.php
··· 3 3 final class PhrictionTransactionEditor 4 4 extends PhabricatorApplicationTransactionEditor { 5 5 6 + const VALIDATE_CREATE_ANCESTRY = 'create'; 7 + const VALIDATE_MOVE_ANCESTRY = 'move'; 8 + 6 9 private $description; 7 10 private $oldContent; 8 11 private $newContent; ··· 519 522 $errors[] = $error; 520 523 } 521 524 } 525 + 526 + if ($this->getIsNewObject()) { 527 + $ancestry_errors = $this->validateAncestry( 528 + $object, 529 + $type, 530 + $xaction, 531 + self::VALIDATE_CREATE_ANCESTRY); 532 + if ($ancestry_errors) { 533 + $errors = array_merge($errors, $ancestry_errors); 534 + } 535 + } 536 + 522 537 break; 523 538 524 539 case PhrictionTransaction::TYPE_MOVE_TO: ··· 547 562 $errors[] = $error; 548 563 } 549 564 550 - // NOTE: We use the ominpotent user because we can't let users 551 - // overwrite documents even if they can't see them. 565 + $ancestry_errors = $this->validateAncestry( 566 + $object, 567 + $type, 568 + $xaction, 569 + self::VALIDATE_MOVE_ANCESTRY); 570 + if ($ancestry_errors) { 571 + $errors = array_merge($errors, $ancestry_errors); 572 + } 573 + 552 574 $target_document = id(new PhrictionDocumentQuery()) 553 575 ->setViewer(PhabricatorUser::getOmnipotentUser()) 554 576 ->withSlugs(array($object->getSlug())) ··· 603 625 } 604 626 } 605 627 628 + return $errors; 629 + } 630 + 631 + private function validateAncestry( 632 + PhabricatorLiskDAO $object, 633 + $type, 634 + PhabricatorApplicationTransaction $xaction, 635 + $verb) { 636 + 637 + $errors = array(); 638 + // NOTE: We use the ominpotent user for these checks because policy 639 + // doesn't matter; existence does. 640 + $other_doc_viewer = PhabricatorUser::getOmnipotentUser(); 641 + $ancestral_slugs = PhabricatorSlug::getAncestry($object->getSlug()); 642 + if ($ancestral_slugs) { 643 + $ancestors = id(new PhrictionDocumentQuery()) 644 + ->setViewer($other_doc_viewer) 645 + ->withSlugs($ancestral_slugs) 646 + ->execute(); 647 + $ancestors = mpull($ancestors, null, 'getSlug'); 648 + foreach ($ancestral_slugs as $slug) { 649 + $ancestor_doc = idx($ancestors, $slug); 650 + if (!$ancestor_doc) { 651 + $create_uri = '/phriction/edit/?slug='.$slug; 652 + $create_link = phutil_tag( 653 + 'a', 654 + array( 655 + 'href' => $create_uri, 656 + ), 657 + $slug); 658 + switch ($verb) { 659 + case self::VALIDATE_MOVE_ANCESTRY: 660 + $message = pht( 661 + 'Can not move document because the parent document with '. 662 + 'slug %s does not exist!', 663 + $create_link); 664 + break; 665 + case self::VALIDATE_CREATE_ANCESTRY: 666 + $message = pht( 667 + 'Can not create document because the parent document with '. 668 + 'slug %s does not exist!', 669 + $create_link); 670 + break; 671 + } 672 + $error = new PhabricatorApplicationTransactionValidationError( 673 + $type, 674 + pht('Missing Ancestor'), 675 + $message, 676 + $xaction); 677 + $errors[] = $error; 678 + } 679 + } 680 + } 606 681 return $errors; 607 682 } 608 683