diff --git a/src/applications/auth/storage/PhabricatorAuthMessage.php b/src/applications/auth/storage/PhabricatorAuthMessage.php index a1aa928684..00f5fbfbaa 100644 --- a/src/applications/auth/storage/PhabricatorAuthMessage.php +++ b/src/applications/auth/storage/PhabricatorAuthMessage.php @@ -1,132 +1,138 @@ setMessageKey($type->getMessageTypeKey()) ->attachMessageType($type); } protected function getConfiguration() { return array( self::CONFIG_AUX_PHID => true, self::CONFIG_COLUMN_SCHEMA => array( 'messageKey' => 'text64', 'messageText' => 'text', ), self::CONFIG_KEY_SCHEMA => array( 'key_type' => array( 'columns' => array('messageKey'), 'unique' => true, ), ), ) + parent::getConfiguration(); } public function getPHIDType() { return PhabricatorAuthMessagePHIDType::TYPECONST; } public function getObjectName() { return pht('Auth Message %d', $this->getID()); } public function getURI() { return urisprintf('/auth/message/%s', $this->getID()); } public function attachMessageType(PhabricatorAuthMessageType $type) { $this->messageType = $type; return $this; } public function getMessageType() { return $this->assertAttached($this->messageType); } public function getMessageTypeDisplayName() { return $this->getMessageType()->getDisplayName(); } - public static function loadMessageText( + public static function loadMessage( PhabricatorUser $viewer, $message_key) { - - $message = id(new PhabricatorAuthMessageQuery()) + return id(new PhabricatorAuthMessageQuery()) ->setViewer($viewer) ->withMessageKeys(array($message_key)) ->executeOne(); + } + + public static function loadMessageText( + PhabricatorUser $viewer, + $message_key) { + + $message = self::loadMessage($viewer, $message_key); if (!$message) { return null; } return $message->getMessageText(); } /* -( PhabricatorPolicyInterface )----------------------------------------- */ public function getCapabilities() { return array( PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT, ); } public function getPolicy($capability) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: return PhabricatorPolicies::getMostOpenPolicy(); default: return false; } } public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { switch ($capability) { case PhabricatorPolicyCapability::CAN_VIEW: // Even if an install doesn't allow public users, you can still view // auth messages: otherwise, we can't do things like show you // guidance on the login screen. return true; default: return false; } } /* -( PhabricatorApplicationTransactionInterface )------------------------- */ public function getApplicationTransactionEditor() { return new PhabricatorAuthMessageEditor(); } public function getApplicationTransactionTemplate() { return new PhabricatorAuthMessageTransaction(); } /* -( PhabricatorDestructibleInterface )----------------------------------- */ public function destroyObjectPermanently( PhabricatorDestructionEngine $engine) { $this->delete(); } } diff --git a/src/applications/people/controller/PhabricatorPeopleWelcomeController.php b/src/applications/people/controller/PhabricatorPeopleWelcomeController.php index 5ea4437d8a..3fb75265ff 100644 --- a/src/applications/people/controller/PhabricatorPeopleWelcomeController.php +++ b/src/applications/people/controller/PhabricatorPeopleWelcomeController.php @@ -1,83 +1,95 @@ getViewer(); $user = id(new PhabricatorPeopleQuery()) ->setViewer($admin) ->withIDs(array($request->getURIData('id'))) ->executeOne(); if (!$user) { return new Aphront404Response(); } $id = $user->getID(); $profile_uri = "/people/manage/{$id}/"; $welcome_engine = id(new PhabricatorPeopleWelcomeMailEngine()) ->setSender($admin) ->setRecipient($user); try { $welcome_engine->validateMail(); } catch (PhabricatorPeopleMailEngineException $ex) { return $this->newDialog() ->setTitle($ex->getTitle()) ->appendParagraph($ex->getBody()) ->addCancelButton($profile_uri, pht('Done')); } $v_message = $request->getStr('message'); if ($request->isFormPost()) { if (strlen($v_message)) { $welcome_engine->setWelcomeMessage($v_message); } $welcome_engine->sendMail(); return id(new AphrontRedirectResponse())->setURI($profile_uri); } + $default_message = PhabricatorAuthMessage::loadMessage( + $admin, + PhabricatorAuthWelcomeMailMessageType::MESSAGEKEY); + if (strlen($default_message->getMessageText())) { + $message_instructions = pht( + 'The email will identify you as the sender. You may optionally '. + 'replace the [[ %s | default custom mail body ]] with different text '. + 'by providing a message below.', + $default_message->getURI()); + } else { + $message_instructions = pht( + 'The email will identify you as the sender. You may optionally '. + 'include additional text in the mail body by specifying it below.'); + } + $form = id(new AphrontFormView()) ->setViewer($admin) - ->appendInstructions( + ->appendRemarkupInstructions( pht( 'This workflow will send this user ("%s") a copy of the "Welcome to '. 'Phabricator" email that users normally receive when their '. 'accounts are created by an administrator.', $user->getUsername())) - ->appendInstructions( + ->appendRemarkupInstructions( pht( 'The email will contain a link that the user may use to log in '. 'to their account. This link bypasses authentication requirements '. 'and allows them to log in without credentials. Sending a copy of '. 'this email can be useful if the original was lost or never sent.')) - ->appendInstructions( - pht( - 'The email will identify you as the sender. You may optionally '. - 'include additional text in the mail body by specifying it below.')) + ->appendRemarkupInstructions($message_instructions) ->appendControl( - id(new AphrontFormTextAreaControl()) + id(new PhabricatorRemarkupControl()) ->setName('message') ->setLabel(pht('Custom Message')) ->setValue($v_message)); return $this->newDialog() ->setTitle(pht('Send Welcome Email')) ->setWidth(AphrontDialogView::WIDTH_FORM) ->appendForm($form) ->addSubmitButton(pht('Send Email')) ->addCancelButton($profile_uri); } } diff --git a/src/applications/people/mail/PhabricatorPeopleMailEngine.php b/src/applications/people/mail/PhabricatorPeopleMailEngine.php index 8f8a22b12e..281009341d 100644 --- a/src/applications/people/mail/PhabricatorPeopleMailEngine.php +++ b/src/applications/people/mail/PhabricatorPeopleMailEngine.php @@ -1,61 +1,72 @@ sender = $sender; return $this; } final public function getSender() { if (!$this->sender) { throw new PhutilInvalidStateException('setSender'); } return $this->sender; } final public function setRecipient(PhabricatorUser $recipient) { $this->recipient = $recipient; return $this; } final public function getRecipient() { if (!$this->recipient) { throw new PhutilInvalidStateException('setRecipient'); } return $this->recipient; } final public function canSendMail() { try { $this->validateMail(); return true; } catch (PhabricatorPeopleMailEngineException $ex) { return false; } } final public function sendMail() { $this->validateMail(); $mail = $this->newMail(); $mail ->setForceDelivery(true) ->save(); return $mail; } abstract public function validateMail(); abstract protected function newMail(); final protected function throwValidationException($title, $body) { throw new PhabricatorPeopleMailEngineException($title, $body); } + final protected function newRemarkupText($text) { + $recipient = $this->getRecipient(); + + $engine = PhabricatorMarkupEngine::newMarkupEngine(array()) + ->setConfig('viewer', $recipient) + ->setConfig('uri.base', PhabricatorEnv::getProductionURI('/')) + ->setMode(PhutilRemarkupEngine::MODE_TEXT); + + return $engine->markupText($text); + } + } diff --git a/src/applications/people/mail/PhabricatorPeopleWelcomeMailEngine.php b/src/applications/people/mail/PhabricatorPeopleWelcomeMailEngine.php index 761703e1b5..ff7ee71272 100644 --- a/src/applications/people/mail/PhabricatorPeopleWelcomeMailEngine.php +++ b/src/applications/people/mail/PhabricatorPeopleWelcomeMailEngine.php @@ -1,119 +1,135 @@ welcomeMessage = $welcome_message; return $this; } public function getWelcomeMessage() { return $this->welcomeMessage; } public function validateMail() { $sender = $this->getSender(); $recipient = $this->getRecipient(); if (!$sender->getIsAdmin()) { $this->throwValidationException( pht('Not an Administrator'), pht( 'You can not send welcome mail because you are not an '. 'administrator. Only administrators may send welcome mail.')); } if ($recipient->getIsDisabled()) { $this->throwValidationException( pht('User is Disabled'), pht( 'You can not send welcome mail to this user because their account '. 'is disabled.')); } if (!$recipient->canEstablishWebSessions()) { $this->throwValidationException( pht('Not a Normal User'), pht( 'You can not send this user welcome mail because they are not '. 'a normal user and can not log in to the web interface. Special '. 'users (like bots and mailing lists) are unable to establish '. 'web sessions.')); } } protected function newMail() { $sender = $this->getSender(); $recipient = $this->getRecipient(); - $recipient_username = $recipient->getUserName(); - $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); - $base_uri = PhabricatorEnv::getProductionURI('/'); $engine = new PhabricatorAuthSessionEngine(); $uri = $engine->getOneTimeLoginURI( $recipient, $recipient->loadPrimaryEmail(), PhabricatorAuthSessionEngine::ONETIME_WELCOME); $message = array(); $message[] = pht('Welcome to Phabricator!'); $message[] = pht( '%s (%s) has created an account for you.', $sender->getUsername(), $sender->getRealName()); $message[] = pht( ' Username: %s', $recipient->getUsername()); // If password auth is enabled, give the user specific instructions about // how to add a credential to their account. // If we aren't sure what they're supposed to be doing and passwords are // not enabled, just give them generic instructions. $use_passwords = PhabricatorPasswordAuthProvider::getPasswordProvider(); if ($use_passwords) { $message[] = pht( 'To log in to Phabricator, follow this link and set a password:'); $message[] = pht(' %s', $uri); $message[] = pht( 'After you have set a password, you can log in to Phabricator in '. 'the future by going here:'); $message[] = pht(' %s', $base_uri); } else { $message[] = pht( 'To log in to your account for the first time, follow this link:'); $message[] = pht(' %s', $uri); $message[] = pht( 'After you set up your account, you can log in to Phabricator in '. 'the future by going here:'); $message[] = pht(' %s', $base_uri); } - $custom_body = $this->getWelcomeMessage(); - if (strlen($custom_body)) { - $message[] = $custom_body; - } else { - if (!$is_serious) { - $message[] = pht("Love,\nPhabricator"); - } + $message_body = $this->newBody(); + if ($message_body !== null) { + $message[] = $message_body; } $message = implode("\n\n", $message); return id(new PhabricatorMetaMTAMail()) ->addTos(array($recipient->getPHID())) ->setSubject(pht('[Phabricator] Welcome to Phabricator')) ->setBody($message); } + private function newBody() { + $recipient = $this->getRecipient(); + + $custom_body = $this->getWelcomeMessage(); + if (strlen($custom_body)) { + return $this->newRemarkupText($custom_body); + } + + $default_body = PhabricatorAuthMessage::loadMessageText( + $recipient, + PhabricatorAuthWelcomeMailMessageType::MESSAGEKEY); + if (strlen($default_body)) { + return $this->newRemarkupText($default_body); + } + + $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business'); + if (!$is_serious) { + return pht("Love,\nPhabricator"); + } + + return null; + } + }