@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PhabricatorAuthSSHKeyGenerateController
4 extends PhabricatorAuthSSHKeyController {
5
6 public function handleRequest(AphrontRequest $request) {
7 $viewer = $this->getViewer();
8
9 $key = $this->newKeyForObjectPHID($request->getStr('objectPHID'));
10 if (!$key) {
11 return new Aphront404Response();
12 }
13
14 $cancel_uri = $key->getObject()->getSSHPublicKeyManagementURI($viewer);
15
16 $token = id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
17 $viewer,
18 $request,
19 $cancel_uri);
20
21 if ($request->isFormPost()) {
22 $default_name = $key->getObject()->getSSHKeyDefaultName();
23
24 $keys = PhabricatorSSHKeyGenerator::generateKeypair();
25 list($public_key, $private_key) = $keys;
26
27 $key_name = $default_name.'.key';
28
29 $file = PhabricatorFile::newFromFileData(
30 $private_key,
31 array(
32 'name' => $key_name,
33 'ttl.relative' => phutil_units('10 minutes in seconds'),
34 'viewPolicy' => $viewer->getPHID(),
35 ));
36
37 $public_key = PhabricatorAuthSSHPublicKey::newFromRawKey($public_key);
38
39 $type = $public_key->getType();
40 $body = $public_key->getBody();
41 $comment = pht('Generated');
42
43 $entire_key = "{$type} {$body} {$comment}";
44
45 $type_create = PhabricatorTransactions::TYPE_CREATE;
46 $type_name = PhabricatorAuthSSHKeyTransaction::TYPE_NAME;
47 $type_key = PhabricatorAuthSSHKeyTransaction::TYPE_KEY;
48
49 $xactions = array();
50
51 $xactions[] = id(new PhabricatorAuthSSHKeyTransaction())
52 ->setTransactionType(PhabricatorTransactions::TYPE_CREATE);
53
54 $xactions[] = id(new PhabricatorAuthSSHKeyTransaction())
55 ->setTransactionType($type_name)
56 ->setNewValue($default_name);
57
58 $xactions[] = id(new PhabricatorAuthSSHKeyTransaction())
59 ->setTransactionType($type_key)
60 ->setNewValue($entire_key);
61
62 $editor = id(new PhabricatorAuthSSHKeyEditor())
63 ->setActor($viewer)
64 ->setContentSourceFromRequest($request)
65 ->applyTransactions($key, $xactions);
66
67 $download_link = phutil_tag(
68 'a',
69 array(
70 'href' => $file->getDownloadURI(),
71 ),
72 array(
73 id(new PHUIIconView())->setIcon('fa-download'),
74 ' ',
75 pht('Download Private Key (%s)', $key_name),
76 ));
77 $download_link = phutil_tag('strong', array(), $download_link);
78
79 // NOTE: We're disabling workflow on cancel so the page reloads, showing
80 // the new key.
81
82 return $this->newDialog()
83 ->setTitle(pht('Download Private Key'))
84 ->appendParagraph(
85 pht(
86 'A keypair has been generated, and the public key has been '.
87 'added as a recognized key.'))
88 ->appendParagraph($download_link)
89 ->appendParagraph(
90 pht(
91 'After you download the private key, it will be destroyed. '.
92 'You will not be able to retrieve it if you lose your copy.'))
93 ->setDisableWorkflowOnCancel(true)
94 ->addCancelButton($cancel_uri, pht('Done'));
95 }
96
97 try {
98 PhabricatorSSHKeyGenerator::assertCanGenerateKeypair();
99
100 return $this->newDialog()
101 ->setTitle(pht('Generate New Keypair'))
102 ->addHiddenInput('objectPHID', $key->getObject()->getPHID())
103 ->appendParagraph(
104 pht(
105 'This workflow will generate a new SSH keypair, add the public '.
106 'key, and let you download the private key.'))
107 ->appendParagraph(
108 pht('The private key will not be retained.'))
109 ->addSubmitButton(pht('Generate New Keypair'))
110 ->addCancelButton($cancel_uri);
111 } catch (Exception $ex) {
112 return $this->newDialog()
113 ->setTitle(pht('Unable to Generate Keys'))
114 ->appendParagraph($ex->getMessage())
115 ->addCancelButton($cancel_uri);
116 }
117 }
118
119}