mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-19 05:12:41 +01:00
Send forced mail on SSH key edits
Summary: Ref T10917. This cheats fairly heavily to generate SSH key mail: - Generate normal transaction mail. - Force it to go to the user. - Use `setForceDelivery()` to force it to actually be delivered. - Add some warning language to the mail body. This doesn't move us much closer to Glorious Infrastructure for this whole class of events, but should do what it needs to for now and doesn't really require anything sketchy. Test Plan: Created and edited SSH keys, got security notice mail. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10917 Differential Revision: https://secure.phabricator.com/D15948
This commit is contained in:
parent
da6b3de65c
commit
6f6ca0102d
9 changed files with 134 additions and 7 deletions
|
@ -1883,6 +1883,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuthSSHKeyListController' => 'applications/auth/controller/PhabricatorAuthSSHKeyListController.php',
|
||||
'PhabricatorAuthSSHKeyPHIDType' => 'applications/auth/phid/PhabricatorAuthSSHKeyPHIDType.php',
|
||||
'PhabricatorAuthSSHKeyQuery' => 'applications/auth/query/PhabricatorAuthSSHKeyQuery.php',
|
||||
'PhabricatorAuthSSHKeyReplyHandler' => 'applications/auth/mail/PhabricatorAuthSSHKeyReplyHandler.php',
|
||||
'PhabricatorAuthSSHKeySearchEngine' => 'applications/auth/query/PhabricatorAuthSSHKeySearchEngine.php',
|
||||
'PhabricatorAuthSSHKeyTableView' => 'applications/auth/view/PhabricatorAuthSSHKeyTableView.php',
|
||||
'PhabricatorAuthSSHKeyTransaction' => 'applications/auth/storage/PhabricatorAuthSSHKeyTransaction.php',
|
||||
|
@ -6318,6 +6319,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAuthSSHKeyListController' => 'PhabricatorAuthSSHKeyController',
|
||||
'PhabricatorAuthSSHKeyPHIDType' => 'PhabricatorPHIDType',
|
||||
'PhabricatorAuthSSHKeyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'PhabricatorAuthSSHKeyReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||
'PhabricatorAuthSSHKeySearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'PhabricatorAuthSSHKeyTableView' => 'AphrontView',
|
||||
'PhabricatorAuthSSHKeyTransaction' => 'PhabricatorApplicationTransaction',
|
||||
|
|
|
@ -227,6 +227,14 @@ final class AlmanacDevice
|
|||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getSSHKeyNotifyPHIDs() {
|
||||
// Devices don't currently have anyone useful to notify about SSH key
|
||||
// edits, and they're usually a difficult vector to attack since you need
|
||||
// access to a cluster host. However, it would be nice to make them
|
||||
// subscribable at some point.
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorDestructibleInterface )----------------------------------- */
|
||||
|
||||
|
|
|
@ -36,13 +36,31 @@ final class PhabricatorAuthSSHKeyGenerateController
|
|||
|
||||
$type = $public_key->getType();
|
||||
$body = $public_key->getBody();
|
||||
$comment = pht('Generated');
|
||||
|
||||
$key
|
||||
->setName($default_name)
|
||||
->setKeyType($type)
|
||||
->setKeyBody($body)
|
||||
->setKeyComment(pht('Generated'))
|
||||
->save();
|
||||
$entire_key = "{$type} {$body} {$comment}";
|
||||
|
||||
$type_create = PhabricatorTransactions::TYPE_CREATE;
|
||||
$type_name = PhabricatorAuthSSHKeyTransaction::TYPE_NAME;
|
||||
$type_key = PhabricatorAuthSSHKeyTransaction::TYPE_KEY;
|
||||
|
||||
$xactions = array();
|
||||
|
||||
$xactions[] = id(new PhabricatorAuthSSHKeyTransaction())
|
||||
->setTransactionType(PhabricatorTransactions::TYPE_CREATE);
|
||||
|
||||
$xactions[] = id(new PhabricatorAuthSSHKeyTransaction())
|
||||
->setTransactionType($type_name)
|
||||
->setNewValue($default_name);
|
||||
|
||||
$xactions[] = id(new PhabricatorAuthSSHKeyTransaction())
|
||||
->setTransactionType($type_key)
|
||||
->setNewValue($entire_key);
|
||||
|
||||
$editor = id(new PhabricatorAuthSSHKeyEditor())
|
||||
->setActor($viewer)
|
||||
->setContentSourceFromRequest($request)
|
||||
->applyTransactions($key, $xactions);
|
||||
|
||||
// NOTE: We're disabling workflow on submit so the download works. We're
|
||||
// disabling workflow on cancel so the page reloads, showing the new
|
||||
|
|
|
@ -177,4 +177,68 @@ final class PhabricatorAuthSSHKeyEditor
|
|||
}
|
||||
|
||||
|
||||
protected function shouldSendMail(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getMailSubjectPrefix() {
|
||||
return pht('[SSH Key]');
|
||||
}
|
||||
|
||||
protected function getMailThreadID(PhabricatorLiskDAO $object) {
|
||||
return 'ssh-key-'.$object->getPHID();
|
||||
}
|
||||
|
||||
protected function getMailTo(PhabricatorLiskDAO $object) {
|
||||
return $object->getObject()->getSSHKeyNotifyPHIDs();
|
||||
}
|
||||
|
||||
protected function getMailCC(PhabricatorLiskDAO $object) {
|
||||
return array();
|
||||
}
|
||||
|
||||
protected function buildReplyHandler(PhabricatorLiskDAO $object) {
|
||||
return id(new PhabricatorAuthSSHKeyReplyHandler())
|
||||
->setMailReceiver($object);
|
||||
}
|
||||
|
||||
protected function buildMailTemplate(PhabricatorLiskDAO $object) {
|
||||
$id = $object->getID();
|
||||
$name = $object->getName();
|
||||
$phid = $object->getPHID();
|
||||
|
||||
$mail = id(new PhabricatorMetaMTAMail())
|
||||
->setSubject(pht('SSH Key %d: %s', $id, $name))
|
||||
->addHeader('Thread-Topic', $phid);
|
||||
|
||||
// The primary value of this mail is alerting users to account compromises,
|
||||
// so force delivery. In particular, this mail should still be delievered
|
||||
// even if "self mail" is disabled.
|
||||
$mail->setForceDelivery(true);
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
protected function buildMailBody(
|
||||
PhabricatorLiskDAO $object,
|
||||
array $xactions) {
|
||||
|
||||
$body = parent::buildMailBody($object, $xactions);
|
||||
|
||||
$body->addLinkSection(
|
||||
pht('SECURITY WARNING'),
|
||||
pht(
|
||||
'If you do not recognize this change, it may indicate your account '.
|
||||
'has been compromised.'));
|
||||
|
||||
$detail_uri = $object->getURI();
|
||||
$detail_uri = PhabricatorEnv::getProductionURI($detail_uri);
|
||||
|
||||
$body->addLinkSection(pht('SSH KEY DETAIL'), $detail_uri);
|
||||
|
||||
return $body;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorAuthSSHKeyReplyHandler
|
||||
extends PhabricatorApplicationTransactionReplyHandler {
|
||||
|
||||
public function validateMailReceiver($mail_receiver) {
|
||||
if (!($mail_receiver instanceof PhabricatorAuthSSHKey)) {
|
||||
throw new Exception(
|
||||
pht('Mail receiver is not a %s!', 'PhabricatorAuthSSHKey'));
|
||||
}
|
||||
}
|
||||
|
||||
public function getObjectPrefix() {
|
||||
return 'SSHKEY';
|
||||
}
|
||||
|
||||
}
|
|
@ -17,4 +17,6 @@ interface PhabricatorSSHPublicKeyInterface {
|
|||
*/
|
||||
public function getSSHKeyDefaultName();
|
||||
|
||||
public function getSSHKeyNotifyPHIDs();
|
||||
|
||||
}
|
||||
|
|
|
@ -70,6 +70,12 @@ final class PhabricatorAuthSSHKey
|
|||
return parent::save();
|
||||
}
|
||||
|
||||
public function getMailKey() {
|
||||
// NOTE: We don't actually receive mail for these objects. It's OK for
|
||||
// the mail key to be predictable until we do.
|
||||
return PhabricatorHash::digestForIndex($this->getPHID());
|
||||
}
|
||||
|
||||
public function toPublicKey() {
|
||||
return PhabricatorAuthSSHPublicKey::newFromStoredKey($this);
|
||||
}
|
||||
|
@ -164,7 +170,7 @@ final class PhabricatorAuthSSHKey
|
|||
}
|
||||
|
||||
public function getApplicationTransactionTemplate() {
|
||||
return new PhabricatorAuthProviderConfigTransaction();
|
||||
return new PhabricatorAuthSSHKeyTransaction();
|
||||
}
|
||||
|
||||
public function willRenderTimeline(
|
||||
|
|
|
@ -26,6 +26,10 @@ final class PhabricatorAuthSSHKeyTransaction
|
|||
$new = $this->getNewValue();
|
||||
|
||||
switch ($this->getTransactionType()) {
|
||||
case PhabricatorTransactions::TYPE_CREATE:
|
||||
return pht(
|
||||
'%s created this key.',
|
||||
$this->renderHandleLink($author_phid));
|
||||
case self::TYPE_NAME:
|
||||
return pht(
|
||||
'%s renamed this key from "%s" to "%s".',
|
||||
|
|
|
@ -1342,6 +1342,12 @@ final class PhabricatorUser
|
|||
return 'id_rsa_phabricator';
|
||||
}
|
||||
|
||||
public function getSSHKeyNotifyPHIDs() {
|
||||
return array(
|
||||
$this->getPHID(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorApplicationTransactionInterface )------------------------- */
|
||||
|
||||
|
|
Loading…
Reference in a new issue