コード例 #1
0
 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);
     }
 }
コード例 #2
0
 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));
 }
コード例 #3
0
 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)));
 }
コード例 #6
0
 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);
 }
コード例 #7
0
 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();
 }
コード例 #8
0
 /**
  * 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();
 }
コード例 #9
0
 private function loadFileForData($path, $data)
 {
     return PhabricatorFile::buildFromFileDataOrHash($data, array('name' => basename($path)));
 }
コード例 #10
0
 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;
 }
コード例 #11
0
 /**
  * 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());
 }
コード例 #12
0
 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));
 }
コード例 #13
0
 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());
 }
コード例 #14
0
 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;
 }
コード例 #15
0
 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);
 }