Changeset View
Changeset View
Standalone View
Standalone View
src/applications/auth/storage/PhabricatorAuthPassword.php
Show All 15 Lines | final class PhabricatorAuthPassword | ||||
private $object = self::ATTACHABLE; | private $object = self::ATTACHABLE; | ||||
const PASSWORD_TYPE_ACCOUNT = 'account'; | const PASSWORD_TYPE_ACCOUNT = 'account'; | ||||
const PASSWORD_TYPE_VCS = 'vcs'; | const PASSWORD_TYPE_VCS = 'vcs'; | ||||
const PASSWORD_TYPE_TEST = 'test'; | const PASSWORD_TYPE_TEST = 'test'; | ||||
public static function initializeNewPassword( | public static function initializeNewPassword( | ||||
PhabricatorPasswordHashInterface $object, | PhabricatorAuthPasswordHashInterface $object, | ||||
$type) { | $type) { | ||||
return id(new self()) | return id(new self()) | ||||
->setObjectPHID($object->getPHID()) | ->setObjectPHID($object->getPHID()) | ||||
->attachObject($object) | ->attachObject($object) | ||||
->setPasswordType($type) | ->setPasswordType($type) | ||||
->setIsRevoked(0); | ->setIsRevoked(0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | public function canUpgrade() { | ||||
} | } | ||||
$hash = $this->newPasswordEnvelope(); | $hash = $this->newPasswordEnvelope(); | ||||
return PhabricatorPasswordHasher::canUpgradeHash($hash); | return PhabricatorPasswordHasher::canUpgradeHash($hash); | ||||
} | } | ||||
public function upgradePasswordHasher( | public function upgradePasswordHasher( | ||||
PhutilOpaqueEnvelope $envelope, | PhutilOpaqueEnvelope $envelope, | ||||
PhabricatorPasswordHashInterface $object) { | PhabricatorAuthPasswordHashInterface $object) { | ||||
// Before we make changes, double check that this is really the correct | // Before we make changes, double check that this is really the correct | ||||
// password. It could be really bad if we "upgraded" a password and changed | // password. It could be really bad if we "upgraded" a password and changed | ||||
// the secret! | // the secret! | ||||
if (!$this->comparePassword($envelope, $object)) { | if (!$this->comparePassword($envelope, $object)) { | ||||
throw new Exception( | throw new Exception( | ||||
pht( | pht( | ||||
'Attempting to upgrade password hasher, but the password for the '. | 'Attempting to upgrade password hasher, but the password for the '. | ||||
'upgrade is not the stored credential!')); | 'upgrade is not the stored credential!')); | ||||
} | } | ||||
return $this->setPassword($envelope, $object); | return $this->setPassword($envelope, $object); | ||||
} | } | ||||
public function setPassword( | public function setPassword( | ||||
PhutilOpaqueEnvelope $password, | PhutilOpaqueEnvelope $password, | ||||
PhabricatorPasswordHashInterface $object) { | PhabricatorAuthPasswordHashInterface $object) { | ||||
$hasher = PhabricatorPasswordHasher::getBestHasher(); | $hasher = PhabricatorPasswordHasher::getBestHasher(); | ||||
return $this->setPasswordWithHasher($password, $object, $hasher); | return $this->setPasswordWithHasher($password, $object, $hasher); | ||||
} | } | ||||
public function setPasswordWithHasher( | public function setPasswordWithHasher( | ||||
PhutilOpaqueEnvelope $password, | PhutilOpaqueEnvelope $password, | ||||
PhabricatorPasswordHashInterface $object, | PhabricatorAuthPasswordHashInterface $object, | ||||
PhabricatorPasswordHasher $hasher) { | PhabricatorPasswordHasher $hasher) { | ||||
if (!strlen($password->openEnvelope())) { | if (!strlen($password->openEnvelope())) { | ||||
throw new Exception( | throw new Exception( | ||||
pht('Attempting to set an empty password!')); | pht('Attempting to set an empty password!')); | ||||
} | } | ||||
// Generate (or regenerate) the salt first. | // Generate (or regenerate) the salt first. | ||||
$new_salt = Filesystem::readRandomCharacters(64); | $new_salt = Filesystem::readRandomCharacters(64); | ||||
$this->setPasswordSalt($new_salt); | $this->setPasswordSalt($new_salt); | ||||
// Clear any legacy digest format to force a modern digest. | // Clear any legacy digest format to force a modern digest. | ||||
$this->setLegacyDigestFormat(null); | $this->setLegacyDigestFormat(null); | ||||
$digest = $this->digestPassword($password, $object); | $digest = $this->digestPassword($password, $object); | ||||
$hash = $hasher->getPasswordHashForStorage($digest); | $hash = $hasher->getPasswordHashForStorage($digest); | ||||
$raw_hash = $hash->openEnvelope(); | $raw_hash = $hash->openEnvelope(); | ||||
return $this->setPasswordHash($raw_hash); | return $this->setPasswordHash($raw_hash); | ||||
} | } | ||||
public function comparePassword( | public function comparePassword( | ||||
PhutilOpaqueEnvelope $password, | PhutilOpaqueEnvelope $password, | ||||
PhabricatorPasswordHashInterface $object) { | PhabricatorAuthPasswordHashInterface $object) { | ||||
$digest = $this->digestPassword($password, $object); | $digest = $this->digestPassword($password, $object); | ||||
$hash = $this->newPasswordEnvelope(); | $hash = $this->newPasswordEnvelope(); | ||||
return PhabricatorPasswordHasher::comparePassword($digest, $hash); | return PhabricatorPasswordHasher::comparePassword($digest, $hash); | ||||
} | } | ||||
public function newPasswordEnvelope() { | public function newPasswordEnvelope() { | ||||
return new PhutilOpaqueEnvelope($this->getPasswordHash()); | return new PhutilOpaqueEnvelope($this->getPasswordHash()); | ||||
} | } | ||||
private function digestPassword( | private function digestPassword( | ||||
PhutilOpaqueEnvelope $password, | PhutilOpaqueEnvelope $password, | ||||
PhabricatorPasswordHashInterface $object) { | PhabricatorAuthPasswordHashInterface $object) { | ||||
$object_phid = $object->getPHID(); | $object_phid = $object->getPHID(); | ||||
if ($this->getObjectPHID() !== $object->getPHID()) { | if ($this->getObjectPHID() !== $object->getPHID()) { | ||||
throw new Exception( | throw new Exception( | ||||
pht( | pht( | ||||
'This password is associated with an object PHID ("%s") for '. | 'This password is associated with an object PHID ("%s") for '. | ||||
'a different object than the provided one ("%s").', | 'a different object than the provided one ("%s").', | ||||
▲ Show 20 Lines • Show All 80 Lines • Show Last 20 Lines |