public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); $key = $this->newKeyForObjectPHID($request->getStr('objectPHID')); if (!$key) { return new Aphront404Response(); } $cancel_uri = $key->getObject()->getSSHPublicKeyManagementURI($viewer); $token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession($viewer, $request, $cancel_uri); if ($request->isFormPost()) { $default_name = $key->getObject()->getSSHKeyDefaultName(); $keys = PhabricatorSSHKeyGenerator::generateKeypair(); list($public_key, $private_key) = $keys; $file = PhabricatorFile::buildFromFileDataOrHash($private_key, array('name' => $default_name . '.key', 'ttl' => time() + 60 * 10, 'viewPolicy' => $viewer->getPHID())); $public_key = PhabricatorAuthSSHPublicKey::newFromRawKey($public_key); $type = $public_key->getType(); $body = $public_key->getBody(); $key->setName($default_name)->setKeyType($type)->setKeyBody($body)->setKeyComment(pht('Generated'))->save(); // NOTE: We're disabling workflow on submit so the download works. We're // disabling workflow on cancel so the page reloads, showing the new // key. return $this->newDialog()->setTitle(pht('Download Private Key'))->setDisableWorkflowOnCancel(true)->setDisableWorkflowOnSubmit(true)->setSubmitURI($file->getDownloadURI())->appendParagraph(pht('A keypair has been generated, and the public key has been ' . 'added as a recognized key. Use the button below to download ' . 'the private key.'))->appendParagraph(pht('After you download the private key, it will be destroyed. ' . 'You will not be able to retrieve it if you lose your copy.'))->addSubmitButton(pht('Download Private Key'))->addCancelButton($cancel_uri, pht('Done')); } try { PhabricatorSSHKeyGenerator::assertCanGenerateKeypair(); return $this->newDialog()->setTitle(pht('Generate New Keypair'))->addHiddenInput('objectPHID', $key->getObject()->getPHID())->appendParagraph(pht('This workflow will generate a new SSH keypair, add the public ' . 'key, and let you download the private key.'))->appendParagraph(pht('Phabricator will not retain a copy of the private key.'))->addSubmitButton(pht('Generate New Keypair'))->addCancelButton($cancel_uri); } catch (Exception $ex) { return $this->newDialog()->setTitle(pht('Unable to Generate Keys'))->appendParagraph($ex->getMessage())->addCancelButton($cancel_uri); } }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $aid = $request->getURIData('aid'); $bid = $request->getURIData('bid'); // If "aid" is "x", then it means the user wants to generate // a patch of an empty file to the version specified by "bid". $ids = array($aid, $bid); if ($aid === 'x') { $ids = array($bid); } $versions = id(new PhragmentFragmentVersionQuery())->setViewer($viewer)->withIDs($ids)->execute(); $version_a = null; if ($aid !== 'x') { $version_a = idx($versions, $aid, null); if ($version_a === null) { return new Aphront404Response(); } } $version_b = idx($versions, $bid, null); if ($version_b === null) { return new Aphront404Response(); } $file_phids = array(); if ($version_a !== null) { $file_phids[] = $version_a->getFilePHID(); } $file_phids[] = $version_b->getFilePHID(); $files = id(new PhabricatorFileQuery())->setViewer($viewer)->withPHIDs($file_phids)->execute(); $files = mpull($files, null, 'getPHID'); $file_a = null; if ($version_a != null) { $file_a = idx($files, $version_a->getFilePHID(), null); } $file_b = idx($files, $version_b->getFilePHID(), null); $patch = PhragmentPatchUtil::calculatePatch($file_a, $file_b); if ($patch === null) { // There are no differences between the two files, so we output // an empty patch. $patch = ''; } $a_sequence = 'x'; if ($version_a !== null) { $a_sequence = $version_a->getSequence(); } $name = $version_b->getFragment()->getName() . '.' . $a_sequence . '.' . $version_b->getSequence() . '.patch'; $return = $version_b->getURI(); if ($request->getExists('return')) { $return = $request->getStr('return'); } $result = PhabricatorFile::buildFromFileDataOrHash($patch, array('name' => $name, 'mime-type' => 'text/plain', 'ttl' => time() + 60 * 60 * 24)); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $result->attachToObject($version_b->getFragmentPHID()); unset($unguarded); return id(new AphrontRedirectResponse())->setURI($result->getDownloadURI($return)); }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $color_map = PhabricatorFilesComposeIconBuiltinFile::getAllColors(); $icon_map = $this->getIconMap(); if ($request->isFormPost()) { $project_phid = $request->getStr('projectPHID'); if ($project_phid) { $project = id(new PhabricatorProjectQuery())->setViewer($viewer)->withPHIDs(array($project_phid))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne(); if (!$project) { return new Aphront404Response(); } } $icon = $request->getStr('icon'); $color = $request->getStr('color'); $composer = id(new PhabricatorFilesComposeIconBuiltinFile())->setIcon($icon)->setColor($color); $data = $composer->loadBuiltinFileData(); $file = PhabricatorFile::buildFromFileDataOrHash($data, array('name' => $composer->getBuiltinDisplayName(), 'profile' => true, 'canCDN' => true)); if ($project_phid) { $edit_uri = '/project/history/' . $project->getID() . '/'; $xactions = array(); $xactions[] = id(new PhabricatorProjectTransaction())->setTransactionType(PhabricatorProjectTransaction::TYPE_IMAGE)->setNewValue($file->getPHID()); $editor = id(new PhabricatorProjectTransactionEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnMissingFields(true)->setContinueOnNoEffect(true); $editor->applyTransactions($project, $xactions); return id(new AphrontRedirectResponse())->setURI($edit_uri); } else { $content = array('phid' => $file->getPHID()); return id(new AphrontAjaxResponse())->setContent($content); } } $value_color = head_key($color_map); $value_icon = head_key($icon_map); require_celerity_resource('people-profile-css'); $buttons = array(); foreach ($color_map as $color => $info) { $quip = idx($info, 'quip'); $buttons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-color', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('color' => $color, 'tip' => $quip)), id(new PHUIIconView())->addClass('compose-background-' . $color)); } $icons = array(); foreach ($icon_map as $icon => $spec) { $quip = idx($spec, 'quip'); $icons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-icon', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('icon' => $icon, 'tip' => $quip)), id(new PHUIIconView())->setIconFont($icon)->addClass('compose-icon-bg')); } $dialog_id = celerity_generate_unique_node_id(); $color_input_id = celerity_generate_unique_node_id(); $icon_input_id = celerity_generate_unique_node_id(); $preview_id = celerity_generate_unique_node_id(); $preview = id(new PHUIIconView())->setID($preview_id)->addClass('compose-background-' . $value_color)->setIconFont($value_icon)->addClass('compose-icon-bg'); $color_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'color', 'value' => $value_color, 'id' => $color_input_id)); $icon_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'icon', 'value' => $value_icon, 'id' => $icon_input_id)); Javelin::initBehavior('phabricator-tooltips'); Javelin::initBehavior('icon-composer', array('dialogID' => $dialog_id, 'colorInputID' => $color_input_id, 'iconInputID' => $icon_input_id, 'previewID' => $preview_id, 'defaultColor' => $value_color, 'defaultIcon' => $value_icon)); $dialog = id(new AphrontDialogView())->setUser($viewer)->setFormID($dialog_id)->setClass('compose-dialog')->setTitle(pht('Compose Image'))->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Background Color')))->appendChild($buttons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Icon')))->appendChild($icons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Preview')))->appendChild($preview)->appendChild($color_input)->appendChild($icon_input)->addCancelButton('/')->addSubmitButton(pht('Save Image')); return id(new AphrontDialogResponse())->setDialog($dialog); }
private function newFile(DiffusionRequest $drequest, $content) { $path = $drequest->getPath(); $name = basename($path); $repository = $drequest->getRepository(); $repository_phid = $repository->getPHID(); $file = PhabricatorFile::buildFromFileDataOrHash($content, array('name' => $name, 'ttl' => time() + phutil_units('48 hours in seconds'), 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE)); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $file->attachToObject($repository_phid); unset($unguarded); return $file; }
public function markupContent($content, array $argv) { if (!Filesystem::binaryExists('dot')) { return $this->markupError(pht('Unable to locate the `%s` binary. Install Graphviz.', 'dot')); } $width = $this->parseDimension(idx($argv, 'width')); $future = id(new ExecFuture('dot -T%s', 'png'))->setTimeout(15)->write(trim($content)); list($err, $stdout, $stderr) = $future->resolve(); if ($err) { return $this->markupError(pht('Execution of `%s` failed (#%d), check your syntax: %s', 'dot', $err, $stderr)); } $file = PhabricatorFile::buildFromFileDataOrHash($stdout, array('name' => 'graphviz.png')); if ($this->getEngine()->isTextMode()) { return '<' . $file->getBestURI() . '>'; } return phutil_tag('img', array('src' => $file->getBestURI(), 'width' => nonempty($width, null))); }
public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $colors = array('red' => pht('Verbillion'), 'orange' => pht('Navel Orange'), 'yellow' => pht('Prim Goldenrod'), 'green' => pht('Lustrous Verdant'), 'blue' => pht('Tropical Deep'), 'sky' => pht('Wide Open Sky'), 'indigo' => pht('Pleated Khaki'), 'violet' => pht('Aged Merlot'), 'charcoal' => pht('Gemstone'), 'backdrop' => pht('Driven Snow')); $manifest = PHUIIconView::getSheetManifest(PHUIIconView::SPRITE_PROJECTS); if ($request->isFormPost()) { $icon = $request->getStr('icon'); $color = $request->getStr('color'); if (isset($colors[$color]) && isset($manifest['projects-' . $icon])) { $root = dirname(phutil_get_library_root('phabricator')); $icon_file = $root . '/resources/sprite/projects_1x/' . $icon . '.png'; $icon_data = Filesystem::readFile($icon_file); $data = $this->composeImage($color, $icon_data); $file = PhabricatorFile::buildFromFileDataOrHash($data, array('name' => 'project.png', 'canCDN' => true)); $content = array('phid' => $file->getPHID()); return id(new AphrontAjaxResponse())->setContent($content); } } $value_color = head_key($colors); $value_icon = head_key($manifest); $value_icon = substr($value_icon, strlen('projects-')); require_celerity_resource('people-profile-css'); $buttons = array(); foreach ($colors as $color => $name) { $buttons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-color', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('color' => $color, 'tip' => $name)), id(new PHUIIconView())->addClass('compose-background-' . $color)); } $icons = array(); $icon_quips = array('8ball' => pht('Take a Risk'), 'alien' => pht('Foreign Interface'), 'announce' => pht('Louder is Better'), 'art' => pht('Unique Snowflake'), 'award' => pht('Shooting Star'), 'bacon' => pht('Healthy Vegetables'), 'bandaid' => pht('Durable Infrastructure'), 'beer' => pht('Healthy Vegetable Juice'), 'bomb' => pht('Imminent Success'), 'briefcase' => pht('Adventure Pack'), 'bug' => pht('Costumed Egg'), 'calendar' => pht('Everyone Loves Meetings'), 'cloud' => pht('Water Cycle'), 'coffee' => pht('Half-Whip Nonfat Soy Latte'), 'creditcard' => pht('Expense It'), 'death' => pht('Calcium Promotes Bone Health'), 'desktop' => pht('Magical Portal'), 'dropbox' => pht('Cardboard Box'), 'education' => pht('Debt'), 'experimental' => pht('CAUTION: Dangerous Chemicals'), 'facebook' => pht('Popular Social Network'), 'facility' => pht('Pollution Solves Problems'), 'film' => pht('Actual Physical Film'), 'forked' => pht('You Can\'t Eat Soup'), 'games' => pht('Serious Business'), 'ghost' => pht('Haunted'), 'gift' => pht('Surprise!'), 'globe' => pht('Scanner Sweep'), 'golf' => pht('Business Meeting'), 'heart' => pht('Undergoing a Major Surgery'), 'intergalactic' => pht('Jupiter'), 'lock' => pht('Extremely Secret'), 'mail' => pht('Oragami'), 'martini' => pht('Healthy Olive Drink'), 'medical' => pht('Medic!'), 'mobile' => pht('Cellular Telephone'), 'music' => pht("♫"), 'news' => pht('Actual Physical Newspaper'), 'orgchart' => pht('It\'s Good to be King'), 'peoples' => pht('Angel and Devil'), 'piechart' => pht('Actual Physical Pie'), 'poison' => pht('Healthy Bone Juice'), 'putabirdonit' => pht('Put a Bird On It'), 'radiate' => pht('Radiant Beauty'), 'savings' => pht('Oink Oink'), 'search' => pht('Sleuthing'), 'shield' => pht('Royal Crest'), 'speed' => pht('Slow and Steady'), 'sprint' => pht('Fire Exit'), 'star' => pht('The More You Know'), 'storage' => pht('Stack of Pancakes'), 'tablet' => pht('Cellular Telephone For Giants'), 'travel' => pht('Pretty Clearly an Airplane'), 'twitter' => pht('Bird Stencil'), 'warning' => pht('No Caution Required, Everything Looks Safe'), 'whale' => pht('Friendly Walrus')); foreach ($manifest as $icon => $spec) { $icon = substr($icon, strlen('projects-')); $icons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-icon', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('icon' => $icon, 'tip' => idx($icon_quips, $icon, $icon))), id(new PHUIIconView())->setSpriteIcon($icon)->setSpriteSheet(PHUIIconView::SPRITE_PROJECTS)); } $dialog_id = celerity_generate_unique_node_id(); $color_input_id = celerity_generate_unique_node_id(); $icon_input_id = celerity_generate_unique_node_id(); $preview_id = celerity_generate_unique_node_id(); $preview = id(new PHUIIconView())->setID($preview_id)->addClass('compose-background-' . $value_color)->setSpriteIcon($value_icon)->setSpriteSheet(PHUIIconView::SPRITE_PROJECTS); $color_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'color', 'value' => $value_color, 'id' => $color_input_id)); $icon_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'icon', 'value' => $value_icon, 'id' => $icon_input_id)); Javelin::initBehavior('phabricator-tooltips'); Javelin::initBehavior('icon-composer', array('dialogID' => $dialog_id, 'colorInputID' => $color_input_id, 'iconInputID' => $icon_input_id, 'previewID' => $preview_id, 'defaultColor' => $value_color, 'defaultIcon' => $value_icon)); $dialog = id(new AphrontDialogView())->setUser($viewer)->setFormID($dialog_id)->setClass('compose-dialog')->setTitle(pht('Compose Image'))->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Background Color')))->appendChild($buttons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Icon')))->appendChild($icons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Preview')))->appendChild($preview)->appendChild($color_input)->appendChild($icon_input)->addCancelButton('/')->addSubmitButton(pht('Save Image')); return id(new AphrontDialogResponse())->setDialog($dialog); }
private function buildRawDiffResponse(DiffusionRequest $drequest) { $raw_diff = $this->callConduitWithDiffusionRequest('diffusion.rawdiffquery', array('commit' => $drequest->getCommit(), 'path' => $drequest->getPath())); $file = PhabricatorFile::buildFromFileDataOrHash($raw_diff, array('name' => $drequest->getCommit() . '.diff', 'ttl' => 60 * 60 * 24, 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE)); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $file->attachToObject($drequest->getRepository()->getPHID()); unset($unguarded); return $file->getRedirectResponse(); }
/** * Note this code is somewhat similar to the buildPatch method in * @{class:DifferentialReviewRequestMail}. * * @return @{class:AphrontRedirectResponse} */ private function buildRawDiffResponse(DifferentialRevision $revision, array $changesets, array $vs_changesets, array $vs_map, PhabricatorRepository $repository = null) { assert_instances_of($changesets, 'DifferentialChangeset'); assert_instances_of($vs_changesets, 'DifferentialChangeset'); $viewer = $this->getRequest()->getUser(); id(new DifferentialHunkQuery())->setViewer($viewer)->withChangesets($changesets)->needAttachToChangesets(true)->execute(); $diff = new DifferentialDiff(); $diff->attachChangesets($changesets); $raw_changes = $diff->buildChangesList(); $changes = array(); foreach ($raw_changes as $changedict) { $changes[] = ArcanistDiffChange::newFromDictionary($changedict); } $loader = id(new PhabricatorFileBundleLoader())->setViewer($viewer); $bundle = ArcanistBundle::newFromChanges($changes); $bundle->setLoadFileDataCallback(array($loader, 'loadFileData')); $vcs = $repository ? $repository->getVersionControlSystem() : null; switch ($vcs) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $raw_diff = $bundle->toGitPatch(); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: default: $raw_diff = $bundle->toUnifiedDiff(); break; } $request_uri = $this->getRequest()->getRequestURI(); // this ends up being something like // D123.diff // or the verbose // D123.vs123.id123.whitespaceignore-all.diff // lame but nice to include these options $file_name = ltrim($request_uri->getPath(), '/') . '.'; foreach ($request_uri->getQueryParams() as $key => $value) { if ($key == 'download') { continue; } $file_name .= $key . $value . '.'; } $file_name .= 'diff'; $file = PhabricatorFile::buildFromFileDataOrHash($raw_diff, array('name' => $file_name, 'ttl' => 60 * 60 * 24, 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE)); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $file->attachToObject($revision->getPHID()); unset($unguarded); return $file->getRedirectResponse(); }
private function loadFileForData($path, $data) { return PhabricatorFile::buildFromFileDataOrHash($data, array('name' => basename($path))); }
private function loadFileForData($path, $data) { $file = PhabricatorFile::buildFromFileDataOrHash($data, array('name' => basename($path), 'ttl' => time() + 60 * 60 * 24, 'viewPolicy' => PhabricatorPolicies::POLICY_NOONE)); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $file->attachToObject($this->getDiffusionRequest()->getRepository()->getPHID()); unset($unguarded); return $file; }
/** * Note this code is somewhat similar to the buildPatch method in * @{class:DifferentialReviewRequestMail}. * * @return @{class:AphrontRedirectResponse} */ private function buildRawDiffResponse(array $changesets, array $vs_changesets, array $vs_map, PhabricatorRepository $repository = null) { assert_instances_of($changesets, 'DifferentialChangeset'); assert_instances_of($vs_changesets, 'DifferentialChangeset'); $engine = new PhabricatorDifferenceEngine(); $generated_changesets = array(); foreach ($changesets as $changeset) { $changeset->attachHunks($changeset->loadHunks()); $right = $changeset->makeNewFile(); $choice = $changeset; $vs = idx($vs_map, $changeset->getID()); if ($vs == -1) { $left = $right; $right = $changeset->makeOldFile(); } else { if ($vs) { $choice = $vs_changeset = $vs_changesets[$vs]; $vs_changeset->attachHunks($vs_changeset->loadHunks()); $left = $vs_changeset->makeNewFile(); } else { $left = $changeset->makeOldFile(); } } $synthetic = $engine->generateChangesetFromFileContent($left, $right); if (!$synthetic->getAffectedLineCount()) { $filetype = $choice->getFileType(); if ($filetype == DifferentialChangeType::FILE_TEXT || $filetype == DifferentialChangeType::FILE_SYMLINK) { continue; } } $choice->attachHunks($synthetic->getHunks()); $generated_changesets[] = $choice; } $diff = new DifferentialDiff(); $diff->attachChangesets($generated_changesets); $diff_dict = $diff->getDiffDict(); $changes = array(); foreach ($diff_dict['changes'] as $changedict) { $changes[] = ArcanistDiffChange::newFromDictionary($changedict); } $bundle = ArcanistBundle::newFromChanges($changes); $bundle->setLoadFileDataCallback(array($this, 'loadFileByPHID')); $vcs = $repository ? $repository->getVersionControlSystem() : null; switch ($vcs) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: $raw_diff = $bundle->toGitPatch(); break; case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: default: $raw_diff = $bundle->toUnifiedDiff(); break; } $request_uri = $this->getRequest()->getRequestURI(); // this ends up being something like // D123.diff // or the verbose // D123.vs123.id123.whitespaceignore-all.diff // lame but nice to include these options $file_name = ltrim($request_uri->getPath(), '/') . '.'; foreach ($request_uri->getQueryParams() as $key => $value) { if ($key == 'download') { continue; } $file_name .= $key . $value . '.'; } $file_name .= 'diff'; $file = PhabricatorFile::buildFromFileDataOrHash($raw_diff, array('name' => $file_name)); return id(new AphrontRedirectResponse())->setURI($file->getBestURI()); }
public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $parents = $this->loadParentFragments($this->dblob); if ($parents === null) { return new Aphront404Response(); } $fragment = idx($parents, count($parents) - 1, null); if ($this->snapshot !== null) { $snapshot = id(new PhragmentSnapshotQuery())->setViewer($viewer)->withPrimaryFragmentPHIDs(array($fragment->getPHID()))->withNames(array($this->snapshot))->executeOne(); if ($snapshot === null) { return new Aphront404Response(); } $cache = id(new PhragmentSnapshotChildQuery())->setViewer($viewer)->needFragmentVersions(true)->withSnapshotPHIDs(array($snapshot->getPHID()))->execute(); $this->snapshotCache = mpull($cache, 'getFragmentVersion', 'getFragmentPHID'); } $temp = new TempFile(); $zip = null; try { $zip = new ZipArchive(); } catch (Exception $e) { $dialog = new AphrontDialogView(); $dialog->setUser($viewer); $inst = pht('This system does not have the ZIP PHP extension installed. This ' . 'is required to download ZIPs from Phragment.'); $dialog->setTitle(pht('ZIP Extension Not Installed')); $dialog->appendParagraph($inst); $dialog->addCancelButton('/phragment/browse/' . $this->dblob); return id(new AphrontDialogResponse())->setDialog($dialog); } if (!$zip->open((string) $temp, ZipArchive::CREATE)) { throw new Exception('Unable to create ZIP archive!'); } $mappings = $this->getFragmentMappings($fragment, $fragment->getPath()); $phids = array(); foreach ($mappings as $path => $file_phid) { $phids[] = $file_phid; } $files = id(new PhabricatorFileQuery())->setViewer($viewer)->withPHIDs($phids)->execute(); $files = mpull($files, null, 'getPHID'); foreach ($mappings as $path => $file_phid) { if (!isset($files[$file_phid])) { // The path is most likely pointing to a deleted fragment, which // hence no longer has a file associated with it. unset($mappings[$path]); continue; } $mappings[$path] = $files[$file_phid]; } foreach ($mappings as $path => $file) { if ($file !== null) { $zip->addFromString($path, $file->loadFileData()); } } $zip->close(); $zip_name = $fragment->getName(); if (substr($zip_name, -4) !== '.zip') { $zip_name .= '.zip'; } $data = Filesystem::readFile((string) $temp); $file = PhabricatorFile::buildFromFileDataOrHash($data, array('name' => $zip_name, 'ttl' => time() + 60 * 60 * 24)); $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); $file->attachToObject($fragment->getPHID()); unset($unguarded); $return = $fragment->getURI(); if ($request->getExists('return')) { $return = $request->getStr('return'); } return id(new AphrontRedirectResponse())->setIsExternal(true)->setURI($file->getDownloadURI($return)); }
private function buildRawDiffResponse(DiffusionRequest $drequest) { $raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest); $raw_diff = $raw_query->loadRawDiff(); $file = PhabricatorFile::buildFromFileDataOrHash($raw_diff, array('name' => $drequest->getCommit() . '.diff')); return id(new AphrontRedirectResponse())->setURI($file->getBestURI()); }
protected function execute(ConduitAPIRequest $request) { $path = $request->getValue('path'); $state = $request->getValue('state'); // The state is an array mapping file paths to hashes. $patches = array(); // We need to get all of the mappings (like phragment.getstate) first // so that we can detect deletions and creations of files. $fragment = id(new PhragmentFragmentQuery())->setViewer($request->getUser())->withPaths(array($path))->executeOne(); if ($fragment === null) { throw new ConduitException('ERR_BAD_FRAGMENT'); } $mappings = $fragment->getFragmentMappings($request->getUser(), $fragment->getPath()); $file_phids = mpull(mpull($mappings, 'getLatestVersion'), 'getFilePHID'); $files = id(new PhabricatorFileQuery())->setViewer($request->getUser())->withPHIDs($file_phids)->execute(); $files = mpull($files, null, 'getPHID'); // Scan all of the files that the caller currently has and iterate // over that. foreach ($state as $path => $hash) { // If $mappings[$path] exists, then the user has the file and it's // also a fragment. if (array_key_exists($path, $mappings)) { $file_phid = $mappings[$path]->getLatestVersion()->getFilePHID(); if ($file_phid !== null) { // If the file PHID is present, then we need to check the // hashes to see if they are the same. $hash_caller = strtolower($state[$path]); $hash_current = $files[$file_phid]->getContentHash(); if ($hash_caller === $hash_current) { // The user's version is identical to our version, so // there is no update needed. } else { // The hash differs, and the user needs to update. $patches[] = array('path' => $path, 'fileOld' => null, 'fileNew' => $files[$file_phid], 'hashOld' => $hash_caller, 'hashNew' => $hash_current, 'patchURI' => null); } } else { // We have a record of this as a file, but there is no file // attached to the latest version, so we consider this to be // a deletion. $patches[] = array('path' => $path, 'fileOld' => null, 'fileNew' => null, 'hashOld' => $hash_caller, 'hashNew' => PhragmentPatchUtil::EMPTY_HASH, 'patchURI' => null); } } else { // If $mappings[$path] does not exist, then the user has a file, // and we have absolutely no record of it what-so-ever (we haven't // even recorded a deletion). Assuming most applications will store // some form of data near their own files, this is probably a data // file relevant for the application that is not versioned, so we // don't tell the client to do anything with it. } } // Check the remaining files that we know about but the caller has // not reported. foreach ($mappings as $path => $child) { if (array_key_exists($path, $state)) { // We have already evaluated this above. } else { $file_phid = $mappings[$path]->getLatestVersion()->getFilePHID(); if ($file_phid !== null) { // If the file PHID is present, then this is a new file that // we know about, but the caller does not. We need to tell // the caller to create the file. $hash_current = $files[$file_phid]->getContentHash(); $patches[] = array('path' => $path, 'fileOld' => null, 'fileNew' => $files[$file_phid], 'hashOld' => PhragmentPatchUtil::EMPTY_HASH, 'hashNew' => $hash_current, 'patchURI' => null); } else { // We have a record of deleting this file, and the caller hasn't // reported it, so they've probably deleted it in a previous // update. } } } // Before we can calculate patches, we need to resolve the old versions // of files so we can draw diffs on them. $hashes = array(); foreach ($patches as $patch) { if ($patch['hashOld'] !== PhragmentPatchUtil::EMPTY_HASH) { $hashes[] = $patch['hashOld']; } } $old_files = array(); if (count($hashes) !== 0) { $old_files = id(new PhabricatorFileQuery())->setViewer($request->getUser())->withContentHashes($hashes)->execute(); } $old_files = mpull($old_files, null, 'getContentHash'); foreach ($patches as $key => $patch) { if ($patch['hashOld'] !== PhragmentPatchUtil::EMPTY_HASH) { if (array_key_exists($patch['hashOld'], $old_files)) { $patches[$key]['fileOld'] = $old_files[$patch['hashOld']]; } else { // We either can't see or can't read the old file. $patches[$key]['hashOld'] = PhragmentPatchUtil::EMPTY_HASH; $patches[$key]['fileOld'] = null; } } } // Now run through all of the patch entries, calculate the patches // and return the results. foreach ($patches as $key => $patch) { $data = PhragmentPatchUtil::calculatePatch($patches[$key]['fileOld'], $patches[$key]['fileNew']); unset($patches[$key]['fileOld']); unset($patches[$key]['fileNew']); $file = PhabricatorFile::buildFromFileDataOrHash($data, array('name' => 'patch.dmp', 'ttl' => time() + 60 * 60 * 24)); $patches[$key]['patchURI'] = $file->getDownloadURI(); } return $patches; }
private function processGenerate(AphrontRequest $request) { $user = $this->getUser(); $viewer = $request->getUser(); $token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession($viewer, $request, $this->getPanelURI()); $is_self = $user->getPHID() == $viewer->getPHID(); if ($request->isFormPost()) { $keys = PhabricatorSSHKeyGenerator::generateKeypair(); list($public_key, $private_key) = $keys; $file = PhabricatorFile::buildFromFileDataOrHash($private_key, array('name' => 'id_rsa_phabricator.key', 'ttl' => time() + 60 * 10, 'viewPolicy' => $viewer->getPHID())); list($type, $body, $comment) = self::parsePublicKey($public_key); $key = id(new PhabricatorUserSSHKey())->setUserPHID($user->getPHID())->setName('id_rsa_phabricator')->setKeyType($type)->setKeyBody($body)->setKeyHash(md5($body))->setKeyComment(pht('Generated'))->save(); // NOTE: We're disabling workflow on submit so the download works. We're // disabling workflow on cancel so the page reloads, showing the new // key. if ($is_self) { $what_happened = pht('The public key has been associated with your Phabricator ' . 'account. Use the button below to download the private key.'); } else { $what_happened = pht('The public key has been associated with the %s account. ' . 'Use the button below to download the private key.', phutil_tag('strong', array(), $user->getUsername())); } $dialog = id(new AphrontDialogView())->setTitle(pht('Download Private Key'))->setUser($viewer)->setDisableWorkflowOnCancel(true)->setDisableWorkflowOnSubmit(true)->setSubmitURI($file->getDownloadURI())->appendParagraph(pht('Successfully generated a new keypair.'))->appendParagraph($what_happened)->appendParagraph(pht('After you download the private key, it will be destroyed. ' . 'You will not be able to retrieve it if you lose your copy.'))->addSubmitButton(pht('Download Private Key'))->addCancelButton($this->getPanelURI(), pht('Done')); return id(new AphrontDialogResponse())->setDialog($dialog); } $dialog = id(new AphrontDialogView())->setUser($viewer)->addCancelButton($this->getPanelURI()); try { PhabricatorSSHKeyGenerator::assertCanGenerateKeypair(); if ($is_self) { $explain = pht('This will generate an SSH keypair, associate the public key ' . 'with your account, and let you download the private key.'); } else { $explain = pht('This will generate an SSH keypair, associate the public key with ' . 'the %s account, and let you download the private key.', phutil_tag('strong', array(), $user->getUsername())); } $dialog->addHiddenInput('generate', true)->setTitle(pht('Generate New Keypair'))->appendParagraph($explain)->appendParagraph(pht('Phabricator will not retain a copy of the private key.'))->addSubmitButton(pht('Generate Keypair')); } catch (Exception $ex) { $dialog->setTitle(pht('Unable to Generate Keys'))->appendParagraph($ex->getMessage()); } return id(new AphrontDialogResponse())->setDialog($dialog); }