public static function loadForRevision($revision) { $app_legalpad = 'PhabricatorLegalpadApplication'; if (!PhabricatorApplication::isClassInstalled($app_legalpad)) { return array(); } if (!$revision->getPHID()) { return array(); } $phids = PhabricatorEdgeQuery::loadDestinationPHIDs($revision->getPHID(), LegalpadObjectNeedsSignatureEdgeType::EDGECONST); if ($phids) { // NOTE: We're bypassing permissions to pull these. We have to expose // some information about signature status in order to implement this // field meaningfully (otherwise, we could not tell reviewers that they // can't accept the revision yet), but that's OK because the only way to // require signatures is with a "Global" Herald rule, which requires a // high level of access. $signatures = id(new LegalpadDocumentSignatureQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withDocumentPHIDs($phids)->withSignerPHIDs(array($revision->getAuthorPHID()))->execute(); $signatures = mpull($signatures, null, 'getDocumentPHID'); $phids = array_fuse($phids); foreach ($phids as $phid) { $phids[$phid] = isset($signatures[$phid]); } } return $phids; }
public function testDetectSlowCopiedCode() { // This tests that the detector has a reasonable runtime when a diff // contains a very large number of identical lines. See T5041. $parser = new ArcanistDiffParser(); $line = str_repeat('x', 60); $oline = '-' . $line . "\n"; $nline = '+' . $line . "\n"; $n = 1000; $oblock = str_repeat($oline, $n); $nblock = str_repeat($nline, $n); $raw_diff = <<<EODIFF diff --git a/dst b/dst new file mode 100644 index 0000000..1234567 --- /dev/null +++ b/dst @@ -0,0 +1,{$n} @@ {$nblock} diff --git a/src b/src deleted file mode 100644 index 123457..0000000 --- a/src +++ /dev/null @@ -1,{$n} +0,0 @@ {$oblock} EODIFF; $diff = DifferentialDiff::newFromRawChanges(PhabricatorUser::getOmnipotentUser(), $parser->parseDiff($raw_diff)); $this->assertTrue(true); }
protected function doWork() { $viewer = PhabricatorUser::getOmnipotentUser(); $task_data = $this->getTaskData(); $email_phids = idx($task_data, 'emailPHIDs'); if (!$email_phids) { // If we don't have any email targets, don't send any email. return; } $event_phid = idx($task_data, 'eventPHID'); $event = id(new PhabricatorRepositoryPushEventQuery())->setViewer($viewer)->withPHIDs(array($event_phid))->needLogs(true)->executeOne(); $repository = $event->getRepository(); if (!$repository->shouldPublish()) { // If the repository is still importing, don't send email. return; } $targets = id(new PhabricatorRepositoryPushReplyHandler())->setMailReceiver($repository)->getMailTargets($email_phids, array()); $messages = array(); foreach ($targets as $target) { $messages[] = $this->sendMail($target, $repository, $event); } foreach ($messages as $message) { $message->save(); } }
private function getBlockers(PhabricatorRepositoryCommit $commit, HarbormasterBuildPlan $plan, HarbormasterBuild $source) { $call = new ConduitCall('diffusion.commitparentsquery', array('commit' => $commit->getCommitIdentifier(), 'repository' => $commit->getRepository()->getPHID())); $call->setUser(PhabricatorUser::getOmnipotentUser()); $parents = $call->execute(); $parents = id(new DiffusionCommitQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withRepository($commit->getRepository())->withIdentifiers($parents)->execute(); $blockers = array(); $build_objects = array(); foreach ($parents as $parent) { if (!$parent->isImported()) { $blockers[] = pht('Commit %s', $parent->getCommitIdentifier()); } else { $build_objects[] = $parent->getPHID(); } } if ($build_objects) { $buildables = id(new HarbormasterBuildableQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withBuildablePHIDs($build_objects)->withManualBuildables(false)->execute(); $buildable_phids = mpull($buildables, 'getPHID'); if ($buildable_phids) { $builds = id(new HarbormasterBuildQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withBuildablePHIDs($buildable_phids)->withBuildPlanPHIDs(array($plan->getPHID()))->execute(); foreach ($builds as $build) { if (!$build->isComplete()) { $blockers[] = pht('Build %d', $build->getID()); } } } } return $blockers; }
private function updateBranchStates(PhabricatorRepository $repository, array $branches) { assert_instances_of($branches, 'DiffusionRepositoryRef'); $all_cursors = id(new PhabricatorRepositoryRefCursorQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withRepositoryPHIDs(array($repository->getPHID()))->execute(); $state_map = array(); $type_branch = PhabricatorRepositoryRefCursor::TYPE_BRANCH; foreach ($all_cursors as $cursor) { if ($cursor->getRefType() !== $type_branch) { continue; } $raw_name = $cursor->getRefNameRaw(); $hash = $cursor->getCommitIdentifier(); $state_map[$raw_name][$hash] = $cursor; } foreach ($branches as $branch) { $cursor = idx($state_map, $branch->getShortName(), array()); $cursor = idx($cursor, $branch->getCommitIdentifier()); if (!$cursor) { continue; } $fields = $branch->getRawFields(); $cursor_state = (bool) $cursor->getIsClosed(); $branch_state = (bool) idx($fields, 'closed'); if ($cursor_state != $branch_state) { $cursor->setIsClosed((int) $branch_state)->save(); } } }
public function render() { $viewer = $this->getUser(); $blueprint_phids = $this->getBlueprintPHIDs(); $object_phid = $this->getObjectPHID(); // NOTE: We're intentionally letting you see the authorization state on // blueprints you can't see because this has a tremendous potential to // be extremely confusing otherwise. You still can't see the blueprints // themselves, but you can know if the object is authorized on something. if ($blueprint_phids) { $handles = $viewer->loadHandles($blueprint_phids); $authorizations = id(new DrydockAuthorizationQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withObjectPHIDs(array($object_phid))->withBlueprintPHIDs($blueprint_phids)->execute(); $authorizations = mpull($authorizations, null, 'getBlueprintPHID'); } else { $handles = array(); $authorizations = array(); } $items = array(); foreach ($blueprint_phids as $phid) { $authorization = idx($authorizations, $phid); if (!$authorization) { continue; } $handle = $handles[$phid]; $item = id(new PHUIStatusItemView())->setTarget($handle->renderLink()); $state = $authorization->getBlueprintAuthorizationState(); $item->setIcon(DrydockAuthorization::getBlueprintStateIcon($state), null, DrydockAuthorization::getBlueprintStateName($state)); $items[] = $item; } $status = new PHUIStatusListView(); foreach ($items as $item) { $status->addItem($item); } return $status; }
protected function executeAllocateResource(DrydockLease $lease) { $repository_id = $lease->getAttribute('repositoryID'); if (!$repository_id) { throw new Exception(pht("Lease is missing required '%s' attribute.", 'repositoryID')); } $repository = id(new PhabricatorRepositoryQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withIDs(array($repository_id))->executeOne(); if (!$repository) { throw new Exception(pht("Repository '%s' does not exist!", $repository_id)); } switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: break; default: throw new Exception(pht('Unsupported VCS!')); } // TODO: Policy stuff here too. $host_lease = id(new DrydockLease())->setResourceType('host')->waitUntilActive(); $path = $host_lease->getAttribute('path') . $repository->getCallsign(); $this->log(pht('Cloning %s into %s....', $repository->getCallsign(), $path)); $cmd = $host_lease->getInterface('command'); $cmd->execx('git clone --origin origin %P %s', $repository->getRemoteURIEnvelope(), $path); $this->log(pht('Complete.')); $resource = $this->newResourceTemplate(pht('Working Copy (%s)', $repository->getCallsign())); $resource->setStatus(DrydockResourceStatus::STATUS_OPEN); $resource->setAttribute('lease.host', $host_lease->getID()); $resource->setAttribute('path', $path); $resource->setAttribute('repositoryID', $repository->getID()); $resource->save(); return $resource; }
protected function willFilterPage(array $items) { $source_phids = mpull($items, 'getSourcePHID'); // NOTE: We always load sources, even if the viewer can't formally see // them. If they can see the item, they're allowed to be aware of the // source in some sense. $sources = id(new NuanceSourceQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs($source_phids)->execute(); $sources = mpull($sources, null, 'getPHID'); foreach ($items as $key => $item) { $source = idx($sources, $item->getSourcePHID()); if (!$source) { $this->didRejectResult($items[$key]); unset($items[$key]); continue; } $item->attachSource($source); } $type_map = NuanceItemType::getAllItemTypes(); foreach ($items as $key => $item) { $type = idx($type_map, $item->getItemType()); if (!$type) { $this->didRejectResult($items[$key]); unset($items[$key]); continue; } $item->attachImplementation($type); } return $items; }
public static function loadAffiliatedUserPHIDs(array $package_ids) { if (!$package_ids) { return array(); } $owners = id(new PhabricatorOwnersOwner())->loadAllWhere('packageID IN (%Ls)', $package_ids); $type_user = PhabricatorPeopleUserPHIDType::TYPECONST; $type_project = PhabricatorProjectProjectPHIDType::TYPECONST; $user_phids = array(); $project_phids = array(); foreach ($owners as $owner) { $owner_phid = $owner->getUserPHID(); switch (phid_get_type($owner_phid)) { case PhabricatorPeopleUserPHIDType::TYPECONST: $user_phids[] = $owner_phid; break; case PhabricatorProjectProjectPHIDType::TYPECONST: $project_phids[] = $owner_phid; break; } } if ($project_phids) { $projects = id(new PhabricatorProjectQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs($project_phids)->needMembers(true)->execute(); foreach ($projects as $project) { foreach ($project->getMemberPHIDs() as $member_phid) { $user_phids[] = $member_phid; } } } $user_phids = array_fuse($user_phids); return array_values($user_phids); }
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 applyRequire(array $phids) { $adapter = $this->getAdapter(); $edgetype_legal = LegalpadObjectNeedsSignatureEdgeType::EDGECONST; $current = $adapter->loadEdgePHIDs($edgetype_legal); $allowed_types = array(PhabricatorLegalpadDocumentPHIDType::TYPECONST); $targets = $this->loadStandardTargets($phids, $allowed_types, $current); if (!$targets) { return; } $phids = array_fuse(array_keys($targets)); $object = $adapter->getObject(); $author_phid = $object->getAuthorPHID(); $signatures = id(new LegalpadDocumentSignatureQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withDocumentPHIDs($phids)->withSignerPHIDs(array($author_phid))->execute(); $signatures = mpull($signatures, null, 'getDocumentPHID'); $signed = array(); foreach ($phids as $phid) { if (isset($signatures[$phid])) { $signed[] = $phid; unset($phids[$phid]); } } if ($signed) { $this->logEffect(self::DO_SIGNED, $phids); } if (!$phids) { return; } $xaction = $adapter->newTransaction()->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', $edgetype_legal)->setNewValue(array('+' => $phids)); $adapter->queueTransaction($xaction); $this->logEffect(self::DO_REQUIRED, $phids); }
public function updateRefs() { $this->newRefs = array(); $this->deadRefs = array(); $this->closeCommits = array(); $repository = $this->getRepository(); $vcs = $repository->getVersionControlSystem(); switch ($vcs) { case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: // No meaningful refs of any type in Subversion. $branches = array(); $bookmarks = array(); $tags = array(); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $branches = $this->loadMercurialBranchPositions($repository); $bookmarks = $this->loadMercurialBookmarkPositions($repository); $tags = array(); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $branches = $this->loadGitBranchPositions($repository); $bookmarks = array(); $tags = $this->loadGitTagPositions($repository); break; default: throw new Exception(pht('Unknown VCS "%s"!', $vcs)); } $maps = array(PhabricatorRepositoryRefCursor::TYPE_BRANCH => $branches, PhabricatorRepositoryRefCursor::TYPE_TAG => $tags, PhabricatorRepositoryRefCursor::TYPE_BOOKMARK => $bookmarks); $all_cursors = id(new PhabricatorRepositoryRefCursorQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withRepositoryPHIDs(array($repository->getPHID()))->execute(); $cursor_groups = mgroup($all_cursors, 'getRefType'); $this->hasNoCursors = !$all_cursors; // Find all the heads of closing refs. $all_closing_heads = array(); foreach ($all_cursors as $cursor) { if ($this->shouldCloseRef($cursor->getRefType(), $cursor->getRefName())) { $all_closing_heads[] = $cursor->getCommitIdentifier(); } } $all_closing_heads = array_unique($all_closing_heads); $all_closing_heads = $this->removeMissingCommits($all_closing_heads); foreach ($maps as $type => $refs) { $cursor_group = idx($cursor_groups, $type, array()); $this->updateCursors($cursor_group, $refs, $type, $all_closing_heads); } if ($this->closeCommits) { $this->setCloseFlagOnCommits($this->closeCommits); } if ($this->newRefs || $this->deadRefs) { $repository->openTransaction(); foreach ($this->newRefs as $ref) { $ref->save(); } foreach ($this->deadRefs as $ref) { $ref->delete(); } $repository->saveTransaction(); $this->newRefs = array(); $this->deadRefs = array(); } }
protected function newEditableObject() { $viewer = $this->getViewer(); $repository = PhabricatorRepository::initializeNewRepository($viewer); $repository->setDetail('newly-initialized', true); $vcs = $this->getVersionControlSystem(); if ($vcs) { $repository->setVersionControlSystem($vcs); } // Pick a random open service to allocate this repository on, if any exist. // If there are no services, we aren't in cluster mode and will allocate // locally. If there are services but none permit allocations, we fail. // Eventually we can make this more flexible, but this rule is a reasonable // starting point as we begin to deploy cluster services. $services = id(new AlmanacServiceQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withServiceTypes(array(AlmanacClusterRepositoryServiceType::SERVICETYPE))->needProperties(true)->execute(); if ($services) { // Filter out services which do not permit new allocations. foreach ($services as $key => $possible_service) { if ($possible_service->getAlmanacPropertyValue('closed')) { unset($services[$key]); } } if (!$services) { throw new Exception(pht('This install is configured in cluster mode, but all available ' . 'repository cluster services are closed to new allocations. ' . 'At least one service must be open to allow new allocations to ' . 'take place.')); } shuffle($services); $service = head($services); $repository->setAlmanacServicePHID($service->getPHID()); } return $repository; }
public function getViewer() { // Some day, we might provide a more general viewer mechanism to scripts. // For now, workflows can call this method for convenience and future // flexibility. return PhabricatorUser::getOmnipotentUser(); }
public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target) { $viewer = PhabricatorUser::getOmnipotentUser(); $settings = $this->getSettings(); $variables = $build_target->getVariables(); $uri = $settings['uri'] . '/httpAuth/app/rest/buildQueue'; $method = 'POST'; $contentType = 'application/xml'; $xmlBuilder = new TeamCityXmlBuildBuilder(); $payload = $xmlBuilder->addBuildId($settings['buildId'])->addBranchName(implode(array("D", $variables['buildable.diff'])))->addDiffId(implode(array("D", $variables['buildable.diff'])))->addHarbormasterPHID($variables['target.phid'])->addRevisionId($variables['buildable.revision'])->build(); $future = id(new HTTPFuture($uri, $payload))->setMethod($method)->addHeader('Content-Type', $contentType)->setTimeout(60); $credential_phid = $this->getSetting('credential'); if ($credential_phid) { $key = PassphrasePasswordKey::loadFromPHID($credential_phid, $viewer); $future->setHTTPBasicAuthCredentials($key->getUsernameEnvelope()->openEnvelope(), $key->getPasswordEnvelope()); } $this->resolveFutures($build, $build_target, array($future)); list($status, $body, $headers) = $future->resolve(); $header_lines = array(); // TODO: We don't currently preserve the entire "HTTP" response header, but // should. Once we do, reproduce it here faithfully. $status_code = $status->getStatusCode(); $header_lines[] = "HTTP {$status_code}"; foreach ($headers as $header) { list($head, $tail) = $header; $header_lines[] = "{$head}: {$tail}"; } $header_lines = implode("\n", $header_lines); $build_target->newLog($uri, 'http.head')->append($header_lines); $build_target->newLog($uri, 'http.body')->append($body); if ($status->isError()) { throw new HarbormasterBuildFailureException(); } }
protected function buildBareRepository($callsign) { $existing_repository = id(new PhabricatorRepositoryQuery())->withCallsigns(array($callsign))->setViewer(PhabricatorUser::getOmnipotentUser())->executeOne(); if ($existing_repository) { $existing_repository->delete(); } $data_dir = dirname(__FILE__) . '/data/'; $types = array('svn' => PhabricatorRepositoryType::REPOSITORY_TYPE_SVN, 'hg' => PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL, 'git' => PhabricatorRepositoryType::REPOSITORY_TYPE_GIT); $hits = array(); foreach ($types as $type => $const) { $path = $data_dir . $callsign . '.' . $type . '.tgz'; if (Filesystem::pathExists($path)) { $hits[$const] = $path; } } if (!$hits) { throw new Exception("No test data for callsign '{$callsign}'. Expected an archive " . "like '{$callsign}.git.tgz' in '{$data_dir}'."); } if (count($hits) > 1) { throw new Exception("Expected exactly one archive matching callsign '{$callsign}', " . "found too many: " . implode(', ', $hits)); } $path = head($hits); $vcs_type = head_key($hits); $dir = PhutilDirectoryFixture::newFromArchive($path); $local = new TempFile('.ignore'); $user = $this->generateNewTestUser(); $repo = PhabricatorRepository::initializeNewRepository($user)->setCallsign($callsign)->setName(pht('Test Repo "%s"', $callsign))->setVersionControlSystem($vcs_type)->setDetail('local-path', dirname($local) . '/' . $callsign)->setDetail('remote-uri', 'file://' . $dir->getPath() . '/'); $this->didConstructRepository($repo); $repo->save(); $repo->makeEphemeral(); // Keep the disk resources around until we exit. $this->dirs[] = $dir; $this->dirs[] = $local; return $repo; }
protected function willFilterPage(array $accounts) { if ($this->needImages) { $file_phids = mpull($accounts, 'getProfileImagePHID'); $file_phids = array_filter($file_phids); if ($file_phids) { // NOTE: We use the omnipotent viewer here because these files are // usually created during registration and can't be associated with // the correct policies, since the relevant user account does not exist // yet. In effect, if you can see an ExternalAccount, you can see its // profile image. $files = id(new PhabricatorFileQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs($file_phids)->execute(); $files = mpull($files, null, 'getPHID'); } else { $files = array(); } $default_file = null; foreach ($accounts as $account) { $image_phid = $account->getProfileImagePHID(); if ($image_phid && isset($files[$image_phid])) { $account->attachProfileImageFile($files[$image_phid]); } else { if ($default_file === null) { $default_file = PhabricatorFile::loadBuiltin($this->getViewer(), 'profile.png'); } $account->attachProfileImageFile($default_file); } } } return $accounts; }
private function buildChangesetParsers($type, $data, $file) { $parser = new ArcanistDiffParser(); $changes = $parser->parseDiff($data); $diff = DifferentialDiff::newFromRawChanges(PhabricatorUser::getOmnipotentUser(), $changes); $changesets = $diff->getChangesets(); $engine = new PhabricatorMarkupEngine(); $engine->setViewer(new PhabricatorUser()); $parsers = array(); foreach ($changesets as $changeset) { $cparser = new DifferentialChangesetParser(); $cparser->setUser(new PhabricatorUser()); $cparser->setDisableCache(true); $cparser->setChangeset($changeset); $cparser->setMarkupEngine($engine); if ($type == 'one') { $cparser->setRenderer(new DifferentialChangesetOneUpTestRenderer()); } else { if ($type == 'two') { $cparser->setRenderer(new DifferentialChangesetTwoUpTestRenderer()); } else { throw new Exception(pht('Unknown renderer type "%s"!', $type)); } } $parsers[] = $cparser; } return $parsers; }
private function checkAuditReasons(PhabricatorRepositoryCommit $commit, PhabricatorOwnersPackage $package) { $data = id(new PhabricatorRepositoryCommitData())->loadOneWhere('commitID = %d', $commit->getID()); $reasons = array(); if ($data->getCommitDetail('vsDiff')) { $reasons[] = pht('Changed After Revision Was Accepted'); } $commit_author_phid = $data->getCommitDetail('authorPHID'); if (!$commit_author_phid) { $reasons[] = pht('Commit Author Not Recognized'); } $revision_id = $data->getCommitDetail('differential.revisionID'); $revision_author_phid = null; $commit_reviewedby_phid = null; if ($revision_id) { $revision = id(new DifferentialRevisionQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withIDs(array($revision_id))->executeOne(); if ($revision) { $revision_author_phid = $revision->getAuthorPHID(); $commit_reviewedby_phid = $data->getCommitDetail('reviewerPHID'); if ($revision_author_phid !== $commit_author_phid) { $reasons[] = pht('Author Not Matching with Revision'); } } else { $reasons[] = pht('Revision Not Found'); } } else { $reasons[] = pht('No Revision Specified'); } $owners_phids = PhabricatorOwnersOwner::loadAffiliatedUserPHIDs(array($package->getID())); if (!($commit_author_phid && in_array($commit_author_phid, $owners_phids) || $commit_reviewedby_phid && in_array($commit_reviewedby_phid, $owners_phids))) { $reasons[] = pht('Owners Not Involved'); } return $reasons; }
protected function buildAbstractDocumentByPHID($phid) { $task = $this->loadDocumentByPHID($phid); $doc = new PhabricatorSearchAbstractDocument(); $doc->setPHID($task->getPHID()); $doc->setDocumentType(ManiphestTaskPHIDType::TYPECONST); $doc->setDocumentTitle($task->getTitle()); $doc->setDocumentCreated($task->getDateCreated()); $doc->setDocumentModified($task->getDateModified()); $doc->addField(PhabricatorSearchField::FIELD_BODY, $task->getDescription()); $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR, $task->getAuthorPHID(), PhabricatorPeopleUserPHIDType::TYPECONST, $task->getDateCreated()); $doc->addRelationship($task->isClosed() ? PhabricatorSearchRelationship::RELATIONSHIP_CLOSED : PhabricatorSearchRelationship::RELATIONSHIP_OPEN, $task->getPHID(), ManiphestTaskPHIDType::TYPECONST, time()); $this->indexTransactions($doc, new ManiphestTransactionQuery(), array($phid)); foreach ($task->getProjectPHIDs() as $phid) { $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_PROJECT, $phid, PhabricatorProjectProjectPHIDType::TYPECONST, $task->getDateModified()); // Bogus. } $owner = $task->getOwnerPHID(); if ($owner) { $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_OWNER, $owner, PhabricatorPeopleUserPHIDType::TYPECONST, time()); } else { $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_UNOWNED, $task->getPHID(), PhabricatorPHIDConstants::PHID_TYPE_VOID, $task->getDateCreated()); } // We need to load handles here since non-users may subscribe (mailing // lists, e.g.) $ccs = $task->getCCPHIDs(); $handles = id(new PhabricatorHandleQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withPHIDs($ccs)->execute(); foreach ($ccs as $cc) { $doc->addRelationship(PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER, $handles[$cc]->getPHID(), $handles[$cc]->getType(), time()); } return $doc; }
public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target) { $viewer = PhabricatorUser::getOmnipotentUser(); $settings = $this->getSettings(); $variables = $build_target->getVariables(); $uri = $this->mergeVariables('vurisprintf', $settings['uri'], $variables); $method = nonempty(idx($settings, 'method'), 'POST'); $future = id(new HTTPSFuture($uri))->setMethod($method)->setTimeout(60); $credential_phid = $this->getSetting('credential'); if ($credential_phid) { $key = PassphrasePasswordKey::loadFromPHID($credential_phid, $viewer); $future->setHTTPBasicAuthCredentials($key->getUsernameEnvelope()->openEnvelope(), $key->getPasswordEnvelope()); } $this->resolveFutures($build, $build_target, array($future)); list($status, $body, $headers) = $future->resolve(); $header_lines = array(); // TODO: We don't currently preserve the entire "HTTP" response header, but // should. Once we do, reproduce it here faithfully. $status_code = $status->getStatusCode(); $header_lines[] = "HTTP {$status_code}"; foreach ($headers as $header) { list($head, $tail) = $header; $header_lines[] = "{$head}: {$tail}"; } $header_lines = implode("\n", $header_lines); $build_target->newLog($uri, 'http.head')->append($header_lines); $build_target->newLog($uri, 'http.body')->append($body); if ($status->isError()) { throw new HarbormasterBuildFailureException(); } }
public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target) { $viewer = PhabricatorUser::getOmnipotentUser(); $settings = $this->getSettings(); // TODO: We should probably have a separate temporary storage area for // execution stuff that doesn't step on configuration state? $lease_phid = $build_target->getDetail('exec.leasePHID'); if ($lease_phid) { $lease = id(new DrydockLeaseQuery())->setViewer($viewer)->withPHIDs(array($lease_phid))->executeOne(); if (!$lease) { throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" could not be loaded.', $lease_phid)); } } else { $working_copy_type = id(new DrydockWorkingCopyBlueprintImplementation())->getType(); $lease = id(new DrydockLease())->setResourceType($working_copy_type)->setOwnerPHID($build_target->getPHID()); $variables = $build_target->getVariables(); $repository_phid = idx($variables, 'repository.phid'); $commit = idx($variables, 'repository.commit'); $lease->setAttribute('repositoryPHID', $repository_phid)->setAttribute('commit', $commit); $lease->queueForActivation(); $build_target->setDetail('exec.leasePHID', $lease->getPHID())->save(); } if ($lease->isActivating()) { // TODO: Smart backoff? throw new PhabricatorWorkerYieldException(15); } if (!$lease->isActive()) { // TODO: We could just forget about this lease and retry? throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" never activated.', $lease->getPHID())); } $artifact = $build_target->createArtifact($viewer, $settings['name'], HarbormasterWorkingCopyArtifact::ARTIFACTCONST, array('drydockLeasePHID' => $lease->getPHID())); }
protected function doWork() { $data = $this->getTaskData(); $viewer = PhabricatorUser::getOmnipotentUser(); $address = idx($data, 'address'); $author_phid = idx($data, 'authorPHID'); $author = id(new PhabricatorPeopleQuery())->setViewer($viewer)->withPHIDs(array($author_phid))->executeOne(); if (!$author) { throw new PhabricatorWorkerPermanentFailureException(pht('Invite has invalid author PHID ("%s").', $author_phid)); } $invite = id(new PhabricatorAuthInviteQuery())->setViewer($viewer)->withEmailAddresses(array($address))->executeOne(); if ($invite) { // If we're inviting a user who has already been invited, we just // regenerate their invite code. $invite->regenerateVerificationCode(); } else { // Otherwise, we're creating a new invite. $invite = id(new PhabricatorAuthInvite())->setEmailAddress($address); } // Whether this is a new invite or not, tag this most recent author as // the invite author. $invite->setAuthorPHID($author_phid); $code = $invite->getVerificationCode(); $invite_uri = '/auth/invite/' . $code . '/'; $invite_uri = PhabricatorEnv::getProductionURI($invite_uri); $template = idx($data, 'template'); $template = str_replace('{$INVITE_URI}', $invite_uri, $template); $invite->save(); $mail = id(new PhabricatorMetaMTAMail())->addRawTos(array($invite->getEmailAddress()))->setForceDelivery(true)->setSubject(pht('[Phabricator] %s has invited you to join Phabricator', $author->getFullName()))->setBody($template)->saveAndSend(); }
/** * Load the namespace which prevents use of an Almanac name, if one exists. */ public static function loadRestrictedNamespace(PhabricatorUser $viewer, $name) { // For a name like "x.y.z", produce a list of controlling namespaces like // ("z", "y.x", "x.y.z"). $names = array(); $parts = explode('.', $name); for ($ii = 0; $ii < count($parts); $ii++) { $names[] = implode('.', array_slice($parts, -($ii + 1))); } // Load all the possible controlling namespaces. $namespaces = id(new AlmanacNamespaceQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withNames($names)->execute(); if (!$namespaces) { return null; } // Find the "nearest" (longest) namespace that exists. If both // "sub.domain.com" and "domain.com" exist, we only care about the policy // on the former. $namespaces = msort($namespaces, 'getNameLength'); $namespace = last($namespaces); $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $namespace, PhabricatorPolicyCapability::CAN_EDIT); if ($can_edit) { return null; } return $namespace; }
public function getURI() { if ($this->isExternal) { return $this->externalURI; } $request = DiffusionRequest::newFromDictionary(array('user' => PhabricatorUser::getOmnipotentUser(), 'repository' => $this->getRepository())); return $request->generateURI(array('action' => 'browse', 'path' => $this->getPath(), 'line' => $this->getLineNumber())); }
public static function initializeNewProject(PhabricatorUser $actor) { $app = id(new PhabricatorApplicationQuery())->setViewer(PhabricatorUser::getOmnipotentUser())->withClasses(array('PhabricatorProjectApplication'))->executeOne(); $view_policy = $app->getPolicy(ProjectDefaultViewCapability::CAPABILITY); $edit_policy = $app->getPolicy(ProjectDefaultEditCapability::CAPABILITY); $join_policy = $app->getPolicy(ProjectDefaultJoinCapability::CAPABILITY); return id(new PhabricatorProject())->setAuthorPHID($actor->getPHID())->setIcon(self::DEFAULT_ICON)->setColor(self::DEFAULT_COLOR)->setViewPolicy($view_policy)->setEditPolicy($edit_policy)->setJoinPolicy($join_policy)->setIsMembershipLocked(0)->attachMemberPHIDs(array())->attachSlugs(array()); }
private function loadCredential() { if ($this->credential === null) { $credential_phid = $this->getConfig('credentialPHID'); $this->credential = PassphraseSSHKey::loadFromPHID($credential_phid, PhabricatorUser::getOmnipotentUser()); } return $this->credential; }
private static function loadDiffusionChangesForCommit($commit) { $repository = id(new PhabricatorRepository())->load($commit->getRepositoryID()); $data = array('user' => PhabricatorUser::getOmnipotentUser(), 'initFromConduit' => false, 'repository' => $repository, 'commit' => $commit->getCommitIdentifier()); $drequest = DiffusionRequest::newFromDictionary($data); $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest($drequest); return $change_query->loadChanges(); }
public function releaseArtifact() { $impl = $this->getArtifactImplementation(); if ($impl) { $impl->releaseArtifact(PhabricatorUser::getOmnipotentUser()); } return null; }
public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target) { $viewer = PhabricatorUser::getOmnipotentUser(); $settings = $this->getSettings(); $variables = $build_target->getVariables(); $artifact = $build_target->loadArtifact($settings['hostartifact']); $impl = $artifact->getArtifactImplementation(); $lease = $impl->loadArtifactLease($viewer); $this->platform = $lease->getAttribute('platform'); $command = $this->mergeVariables(array($this, 'escapeCommand'), $settings['command'], $variables); $this->platform = null; $interface = $lease->getInterface('command'); $future = $interface->getExecFuture('%C', $command); $log_stdout = $build->createLog($build_target, 'remote', 'stdout'); $log_stderr = $build->createLog($build_target, 'remote', 'stderr'); $start_stdout = $log_stdout->start(); $start_stderr = $log_stderr->start(); $build_update = 5; // Read the next amount of available output every second. $futures = new FutureIterator(array($future)); foreach ($futures->setUpdateInterval(1) as $key => $future_iter) { if ($future_iter === null) { // Check to see if we should abort. if ($build_update <= 0) { $build->reload(); if ($this->shouldAbort($build, $build_target)) { $future->resolveKill(); throw new HarbormasterBuildAbortedException(); } else { $build_update = 5; } } else { $build_update -= 1; } // Command is still executing. // Read more data as it is available. list($stdout, $stderr) = $future->read(); $log_stdout->append($stdout); $log_stderr->append($stderr); $future->discardBuffers(); } else { // Command execution is complete. // Get the return value so we can log that as well. list($err) = $future->resolve(); // Retrieve the last few bits of information. list($stdout, $stderr) = $future->read(); $log_stdout->append($stdout); $log_stderr->append($stderr); $future->discardBuffers(); break; } } $log_stdout->finalize($start_stdout); $log_stderr->finalize($start_stderr); if ($err) { throw new HarbormasterBuildFailureException(); } }