diff --git a/src/applications/auth/controller/PhabricatorAuthRegisterController.php b/src/applications/auth/controller/PhabricatorAuthRegisterController.php --- a/src/applications/auth/controller/PhabricatorAuthRegisterController.php +++ b/src/applications/auth/controller/PhabricatorAuthRegisterController.php @@ -62,6 +62,16 @@ if (!PhabricatorUserEmail::isValidAddress($default_email)) { $default_email = null; } + if ($default_email !== null) { + // We shoud bypass policy here becase e.g. limiting an application use + // to a subset of users should not allow the others to overwrite + // configured application emails + $application_email = id(new PhabricatorMetaMTAApplicationEmail()) + ->loadOneWhere('address = %s', $default_email); + if ($application_email) { + $default_email = null; + } + } if ($default_email !== null) { // If the account source provided an email, but it's not allowed by @@ -86,7 +96,6 @@ // If the account source provided an email, but another account already // has that email, just pretend we didn't get an email. - // TODO: See T3340. // TODO: See T3472. if ($default_email !== null) { diff --git a/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php b/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php --- a/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php +++ b/src/applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php @@ -61,6 +61,27 @@ return idx($this->configData, $key, $default); } + + public function getInUseMessage() { + $applications = PhabricatorApplication::getAllApplications(); + $applications = mpull($applications, null, 'getPHID'); + $application = idx( + $applications, + $this->getApplicationPHID()); + if ($application) { + $message = pht( + 'The address %s is configured to be used by the %s Application.', + $this->getAddress(), + $application->getName()); + } else { + $message = pht( + 'The address %s is configured to be used by an application.', + $this->getAddress()); + } + + return $message; + } + /* -( PhabricatorPolicyInterface )----------------------------------------- */ diff --git a/src/applications/people/editor/PhabricatorUserEditor.php b/src/applications/people/editor/PhabricatorUserEditor.php --- a/src/applications/people/editor/PhabricatorUserEditor.php +++ b/src/applications/people/editor/PhabricatorUserEditor.php @@ -578,6 +578,12 @@ if (!PhabricatorUserEmail::isAllowedAddress($email->getAddress())) { throw new Exception(PhabricatorUserEmail::describeAllowedAddresses()); } + + $application_email = id(new PhabricatorMetaMTAApplicationEmail()) + ->loadOneWhere('address = %s', $email->getAddress()); + if ($application_email) { + throw new Exception($application_email->getInUseMessage()); + } } private function revokePasswordResetLinks(PhabricatorUser $user) { diff --git a/src/applications/people/editor/__tests__/PhabricatorUserEditorTestCase.php b/src/applications/people/editor/__tests__/PhabricatorUserEditorTestCase.php --- a/src/applications/people/editor/__tests__/PhabricatorUserEditorTestCase.php +++ b/src/applications/people/editor/__tests__/PhabricatorUserEditorTestCase.php @@ -53,6 +53,26 @@ $this->assertTrue($caught instanceof Exception); } + public function testRegistrationEmailApplicationEmailCollide() { + $app_email = 'bugs@whitehouse.gov'; + $app_email_object = + PhabricatorMetaMTAApplicationEmail::initializeNewAppEmail( + $this->generateNewTestUser()); + $app_email_object->setAddress($app_email); + $app_email_object->setApplicationPHID('test'); + $app_email_object->save(); + + $caught = null; + try { + $this->registerUser( + 'PhabricatorUserEditorTestCaseDomain', + $app_email); + } catch (Exception $ex) { + $caught = $ex; + } + $this->assertTrue($caught instanceof Exception); + } + private function registerUser($username, $email) { $user = id(new PhabricatorUser()) ->setUsername($username) diff --git a/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php b/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php --- a/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php +++ b/src/applications/settings/panel/PhabricatorEmailAddressesSettingsPanel.php @@ -185,6 +185,14 @@ $e_email = pht('Disallowed'); $errors[] = PhabricatorUserEmail::describeAllowedAddresses(); } + if ($e_email === true) { + $application_email = id(new PhabricatorMetaMTAApplicationEmail()) + ->loadOneWhere('address = %s', $email); + if ($application_email) { + $e_email = pht('In Use'); + $errors[] = $application_email->getInUseMessage(); + } + } if (!$errors) { $object = id(new PhabricatorUserEmail())