public function updateTransactionMailBody(PhabricatorMetaMTAMailBody $body, PhabricatorApplicationTransactionEditor $editor, array $xactions)
 {
     $status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED;
     // Show the "BRANCH" section only if there's a new diff or the revision
     // is "Accepted".
     if (!$editor->getDiffUpdateTransaction($xactions) && $this->getObject()->getStatus() != $status_accepted) {
         return;
     }
     $branch = $this->getBranchDescription($this->getObject()->getActiveDiff());
     if ($branch === null) {
         return;
     }
     $body->addTextSection(pht('BRANCH'), $branch);
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case AlmanacBindingTransaction::TYPE_INTERFACE:
             $missing = $this->validateIsEmptyTextField($object->getInterfacePHID(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('Bindings must specify an interface.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             } else {
                 if ($xactions) {
                     foreach ($xactions as $xaction) {
                         $interfaces = id(new AlmanacInterfaceQuery())->setViewer($this->requireActor())->withPHIDs(array($xaction->getNewValue()))->execute();
                         if (!$interfaces) {
                             $error = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), pht('You can not bind a service to an invalid or restricted ' . 'interface.'), $xaction);
                             $errors[] = $error;
                         }
                     }
                     $final_value = last($xactions)->getNewValue();
                     $binding = id(new AlmanacBindingQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withServicePHIDs(array($object->getServicePHID()))->withInterfacePHIDs(array($final_value))->executeOne();
                     if ($binding && $binding->getID() != $object->getID()) {
                         $error = new PhabricatorApplicationTransactionValidationError($type, pht('Already Bound'), pht('You can not bind a service to the same interface multiple ' . 'times.'), last($xactions));
                         $errors[] = $error;
                     }
                 }
             }
             break;
     }
     return $errors;
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case PhamePostTransaction::TYPE_TITLE:
             $missing = $this->validateIsEmptyTextField($object->getTitle(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('Title is required.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             break;
         case PhamePostTransaction::TYPE_PHAME_TITLE:
             $missing = $this->validateIsEmptyTextField($object->getPhameTitle(), $xactions);
             $phame_title = last($xactions)->getNewValue();
             if ($missing || $phame_title == '/') {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('Phame title is required.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             $duplicate_post = id(new PhamePostQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPhameTitles(array($phame_title))->executeOne();
             if ($duplicate_post && $duplicate_post->getID() != $object->getID()) {
                 $error_text = pht('Phame title must be unique; another post already has this phame ' . 'title.');
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Not Unique'), $error_text, nonempty(last($xactions), null));
                 $errors[] = $error;
             }
             break;
     }
     return $errors;
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case PhabricatorMetaMTAApplicationEmailTransaction::TYPE_ADDRESS:
             foreach ($xactions as $xaction) {
                 $email = $xaction->getNewValue();
                 if (!strlen($email)) {
                     // We'll deal with this below.
                     continue;
                 }
                 if (!PhabricatorUserEmail::isValidAddress($email)) {
                     $errors[] = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), pht('Email address is not formatted properly.'));
                 }
             }
             $missing = $this->validateIsEmptyTextField($object->getAddress(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('You must provide an email address.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             break;
     }
     return $errors;
 }
 public function getTransactionTypes()
 {
     $types = parent::getTransactionTypes();
     $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
     $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
     return $types;
 }
 /**
  * We run Herald as part of transaction validation because Herald can
  * block diff creation for Differential diffs. Its important to do this
  * separately so no Herald logs are saved; these logs could expose
  * information the Herald rules are inteneded to block.
  */
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     foreach ($xactions as $xaction) {
         switch ($type) {
             case DifferentialDiffTransaction::TYPE_DIFF_CREATE:
                 $diff = clone $object;
                 $diff = $this->updateDiffFromDict($diff, $xaction->getNewValue());
                 $adapter = $this->buildHeraldAdapter($diff, $xactions);
                 $adapter->setContentSource($this->getContentSource());
                 $adapter->setIsNewObject($this->getIsNewObject());
                 $engine = new HeraldEngine();
                 $rules = $engine->loadRulesForAdapter($adapter);
                 $rules = mpull($rules, null, 'getID');
                 $effects = $engine->applyRules($rules, $adapter);
                 $blocking_effect = null;
                 foreach ($effects as $effect) {
                     if ($effect->getAction() == HeraldAdapter::ACTION_BLOCK) {
                         $blocking_effect = $effect;
                         break;
                     }
                 }
                 if ($blocking_effect) {
                     $rule = $blocking_effect->getRule();
                     $message = $effect->getTarget();
                     if (!strlen($message)) {
                         $message = pht('(None.)');
                     }
                     $errors[] = new PhabricatorApplicationTransactionValidationError($type, pht('Rejected by Herald'), pht("Creation of this diff was rejected by Herald rule %s.\n" . "  Rule: %s\n" . "Reason: %s", $rule->getMonogram(), $rule->getName(), $message));
                 }
                 break;
         }
     }
     return $errors;
 }
Example #7
0
 public function getTransactionTypes()
 {
     $types = parent::getTransactionTypes();
     $types[] = PhabricatorTransactions::TYPE_COMMENT;
     $types[] = HeraldRuleTransaction::TYPE_DISABLE;
     return $types;
 }
 protected function buildMailBody(PhabricatorLiskDAO $object, array $xactions)
 {
     $body = parent::buildMailBody($object, $xactions);
     $detail_uri = PhabricatorEnv::getProductionURI($object->getURI());
     $body->addLinkSection(pht('PACKAGE DETAIL'), $detail_uri);
     return $body;
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case PhortuneAccountTransaction::TYPE_NAME:
             $missing = $this->validateIsEmptyTextField($object->getName(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('Account name is required.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             break;
         case PhabricatorTransactions::TYPE_EDGE:
             foreach ($xactions as $xaction) {
                 switch ($xaction->getMetadataValue('edge:type')) {
                     case PhortuneAccountHasMemberEdgeType::EDGECONST:
                         // TODO: This is a bit cumbersome, but validation happens before
                         // transaction normalization. Maybe provide a cleaner attack on
                         // this eventually? There's no way to generate "+" or "-"
                         // transactions right now.
                         $new = $xaction->getNewValue();
                         $set = idx($new, '=', array());
                         if (empty($set[$this->requireActor()->getPHID()])) {
                             $error = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), pht('You can not remove yourself as an account member.'), $xaction);
                             $errors[] = $error;
                         }
                         break;
                 }
             }
             break;
     }
     return $errors;
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case PhabricatorOAuthServerTransaction::TYPE_NAME:
             $missing = $this->validateIsEmptyTextField($object->getName(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('OAuth applications must have a name.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             break;
         case PhabricatorOAuthServerTransaction::TYPE_REDIRECT_URI:
             $missing = $this->validateIsEmptyTextField($object->getRedirectURI(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('OAuth applications must have a valid redirect URI.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             } else {
                 foreach ($xactions as $xaction) {
                     $redirect_uri = $xaction->getNewValue();
                     try {
                         $server = new PhabricatorOAuthServer();
                         $server->assertValidRedirectURI($redirect_uri);
                     } catch (Exception $ex) {
                         $errors[] = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), $ex->getMessage(), $xaction);
                     }
                 }
             }
             break;
     }
     return $errors;
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case NuanceRequestorTransaction::TYPE_PROPERTY:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
Example #12
0
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case FundBackerTransaction::TYPE_STATUS:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
 public function getTransactionTypes()
 {
     $types = parent::getTransactionTypes();
     $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
     $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
     $types[] = DrydockBlueprintTransaction::TYPE_NAME;
     return $types;
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case DrydockBlueprintTransaction::TYPE_NAME:
         case DrydockBlueprintTransaction::TYPE_DISABLED:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case HarbormasterBuildTransaction::TYPE_CREATE:
         case HarbormasterBuildTransaction::TYPE_COMMAND:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhluxTransaction::TYPE_EDIT_KEY:
         case PhluxTransaction::TYPE_EDIT_VALUE:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhabricatorProfilePanelConfigurationTransaction::TYPE_PROPERTY:
         case PhabricatorProfilePanelConfigurationTransaction::TYPE_ORDER:
         case PhabricatorProfilePanelConfigurationTransaction::TYPE_VISIBILITY:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
Example #19
0
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case NuanceItemTransaction::TYPE_REQUESTOR:
         case NuanceItemTransaction::TYPE_SOURCE:
         case NuanceItemTransaction::TYPE_OWNER:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhortunePaymentProviderConfigTransaction::TYPE_CREATE:
         case PhortunePaymentProviderConfigTransaction::TYPE_PROPERTY:
         case PhortunePaymentProviderConfigTransaction::TYPE_ENABLE:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhortuneProductTransaction::TYPE_NAME:
         case PhortuneProductTransaction::TYPE_TYPE:
         case PhortuneProductTransaction::TYPE_PRICE:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case HarbormasterBuildStepTransaction::TYPE_CREATE:
         case HarbormasterBuildStepTransaction::TYPE_NAME:
         case HarbormasterBuildStepTransaction::TYPE_DEPENDS_ON:
         case HarbormasterBuildStepTransaction::TYPE_DESCRIPTION:
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }
 public function updateTransactionMailBody(PhabricatorMetaMTAMailBody $body, PhabricatorApplicationTransactionEditor $editor, array $xactions)
 {
     if ($editor->getIsNewObject()) {
         return;
     }
     if ($editor->getIsCloseByCommit()) {
         return;
     }
     $xaction = $editor->getDiffUpdateTransaction($xactions);
     if (!$xaction) {
         return;
     }
     $original = id(new DifferentialDiffQuery())->setViewer($this->getViewer())->withPHIDs(array($xaction->getOldValue()))->executeOne();
     if (!$original) {
         return;
     }
     $revision = $this->getObject();
     $current = $revision->getActiveDiff();
     $old_id = $original->getID();
     $new_id = $current->getID();
     $uri = '/' . $revision->getMonogram() . '?vs=' . $old_id . '&id=' . $new_id;
     $uri = PhabricatorEnv::getProductionURI($uri);
     $body->addTextSection(pht('CHANGES SINCE LAST UPDATE'), $uri);
 }
 protected function transactionHasEffect(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     $old = $xaction->getOldValue();
     $new = $xaction->getNewValue();
     $type = $xaction->getTransactionType();
     switch ($type) {
         case PhabricatorConfigTransaction::TYPE_EDIT:
             // If an edit deletes an already-deleted entry, no-op it.
             if (idx($old, 'deleted') && idx($new, 'deleted')) {
                 return false;
             }
             break;
     }
     return parent::transactionHasEffect($object, $xaction);
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case HarbormasterBuildPlanTransaction::TYPE_NAME:
             $missing = $this->validateIsEmptyTextField($object->getName(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('You must choose a name for your build plan.'), last($xactions));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             break;
     }
     return $errors;
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case FundInitiativeTransaction::TYPE_NAME:
             $missing = $this->validateIsEmptyTextField($object->getName(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('Initiative name is required.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             }
             break;
     }
     return $errors;
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case DrydockBlueprintTransaction::TYPE_NAME:
             $missing = $this->validateIsEmptyTextField($object->getBlueprintName(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('You must choose a name for this blueprint.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
                 continue;
             }
             break;
     }
     return $errors;
 }
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case AlmanacNamespaceTransaction::TYPE_NAME:
             $missing = $this->validateIsEmptyTextField($object->getName(), $xactions);
             if ($missing) {
                 $error = new PhabricatorApplicationTransactionValidationError($type, pht('Required'), pht('Namespace name is required.'), nonempty(last($xactions), null));
                 $error->setIsMissingFieldError(true);
                 $errors[] = $error;
             } else {
                 foreach ($xactions as $xaction) {
                     $name = $xaction->getNewValue();
                     $message = null;
                     try {
                         AlmanacNames::validateName($name);
                     } catch (Exception $ex) {
                         $message = $ex->getMessage();
                     }
                     if ($message !== null) {
                         $error = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), $message, $xaction);
                         $errors[] = $error;
                         continue;
                     }
                     $other = id(new AlmanacNamespaceQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withNames(array($name))->executeOne();
                     if ($other && $other->getID() != $object->getID()) {
                         $error = new PhabricatorApplicationTransactionValidationError($type, pht('Not Unique'), pht('The namespace name "%s" is already in use by another ' . 'namespace. Each namespace must have a unique name.', $name), $xaction);
                         $errors[] = $error;
                         continue;
                     }
                     if ($name === $object->getName()) {
                         continue;
                     }
                     $namespace = AlmanacNamespace::loadRestrictedNamespace($this->getActor(), $name);
                     if ($namespace) {
                         $error = new PhabricatorApplicationTransactionValidationError($type, pht('Restricted'), pht('You do not have permission to create Almanac namespaces ' . 'within the "%s" namespace.', $namespace->getName()), $xaction);
                         $errors[] = $error;
                         continue;
                     }
                 }
             }
             break;
     }
     return $errors;
 }
 protected function transactionHasEffect(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     $old = $xaction->getOldValue();
     $new = $xaction->getNewValue();
     switch ($xaction->getTransactionType()) {
         case PhabricatorSlowvoteTransaction::TYPE_RESPONSES:
             if ($old === null) {
                 return true;
             }
             return (int) $old !== (int) $new;
         case PhabricatorSlowvoteTransaction::TYPE_SHUFFLE:
             if ($old === null) {
                 return true;
             }
             return (bool) $old !== (bool) $new;
     }
     return parent::transactionHasEffect($object, $xaction);
 }
Example #30
0
 protected function validateTransaction(PhabricatorLiskDAO $object, $type, array $xactions)
 {
     $errors = parent::validateTransaction($object, $type, $xactions);
     switch ($type) {
         case AlmanacTransaction::TYPE_PROPERTY_UPDATE:
             foreach ($xactions as $xaction) {
                 $property_key = $xaction->getMetadataValue('almanac.property');
                 $message = null;
                 try {
                     AlmanacNames::validateName($property_key);
                 } catch (Exception $ex) {
                     $message = $ex->getMessage();
                 }
                 if ($message !== null) {
                     $error = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), $message, $xaction);
                     $errors[] = $error;
                     continue;
                 }
                 $new_value = $xaction->getNewValue();
                 try {
                     phutil_json_encode($new_value);
                 } catch (Exception $ex) {
                     $message = pht('Almanac property values must be representable in JSON. %s', $ex->getMessage());
                 }
                 if ($message !== null) {
                     $error = new PhabricatorApplicationTransactionValidationError($type, pht('Invalid'), $message, $xaction);
                     $errors[] = $error;
                     continue;
                 }
             }
             break;
         case AlmanacTransaction::TYPE_PROPERTY_REMOVE:
             // NOTE: No name validation on removals since it's OK to delete
             // an invalid property that somehow came into existence.
             break;
     }
     return $errors;
 }