Page MenuHomePhabricator

D18894.id45308.diff
No OneTemporary

D18894.id45308.diff

diff --git a/resources/sql/autopatches/20180120.auth.01.password.sql b/resources/sql/autopatches/20180120.auth.01.password.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20180120.auth.01.password.sql
@@ -0,0 +1,10 @@
+CREATE TABLE {$NAMESPACE}_auth.auth_password (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ objectPHID VARBINARY(64) NOT NULL,
+ passwordType VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT},
+ passwordHash VARCHAR(128) NOT NULL COLLATE {$COLLATE_TEXT},
+ isRevoked BOOL NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/resources/sql/autopatches/20180120.auth.02.passwordxaction.sql b/resources/sql/autopatches/20180120.auth.02.passwordxaction.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20180120.auth.02.passwordxaction.sql
@@ -0,0 +1,19 @@
+CREATE TABLE {$NAMESPACE}_auth.auth_passwordtransaction (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ authorPHID VARBINARY(64) NOT NULL,
+ objectPHID VARBINARY(64) NOT NULL,
+ viewPolicy VARBINARY(64) NOT NULL,
+ editPolicy VARBINARY(64) NOT NULL,
+ commentPHID VARBINARY(64) DEFAULT NULL,
+ commentVersion INT UNSIGNED NOT NULL,
+ transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL,
+ oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ UNIQUE KEY `key_phid` (`phid`),
+ KEY `key_object` (`objectPHID`)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2088,7 +2088,16 @@
'PhabricatorAuthOldOAuthRedirectController' => 'applications/auth/controller/PhabricatorAuthOldOAuthRedirectController.php',
'PhabricatorAuthOneTimeLoginController' => 'applications/auth/controller/PhabricatorAuthOneTimeLoginController.php',
'PhabricatorAuthOneTimeLoginTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthOneTimeLoginTemporaryTokenType.php',
+ 'PhabricatorAuthPassword' => 'applications/auth/storage/PhabricatorAuthPassword.php',
+ 'PhabricatorAuthPasswordEditor' => 'applications/auth/editor/PhabricatorAuthPasswordEditor.php',
+ 'PhabricatorAuthPasswordPHIDType' => 'applications/auth/phid/PhabricatorAuthPasswordPHIDType.php',
+ 'PhabricatorAuthPasswordQuery' => 'applications/auth/query/PhabricatorAuthPasswordQuery.php',
'PhabricatorAuthPasswordResetTemporaryTokenType' => 'applications/auth/tokentype/PhabricatorAuthPasswordResetTemporaryTokenType.php',
+ 'PhabricatorAuthPasswordRevokeTransaction' => 'applications/auth/xaction/PhabricatorAuthPasswordRevokeTransaction.php',
+ 'PhabricatorAuthPasswordRevoker' => 'applications/auth/revoker/PhabricatorAuthPasswordRevoker.php',
+ 'PhabricatorAuthPasswordTestCase' => 'applications/auth/__tests__/PhabricatorAuthPasswordTestCase.php',
+ 'PhabricatorAuthPasswordTransaction' => 'applications/auth/storage/PhabricatorAuthPasswordTransaction.php',
+ 'PhabricatorAuthPasswordTransactionType' => 'applications/auth/xaction/PhabricatorAuthPasswordTransactionType.php',
'PhabricatorAuthProvider' => 'applications/auth/provider/PhabricatorAuthProvider.php',
'PhabricatorAuthProviderConfig' => 'applications/auth/storage/PhabricatorAuthProviderConfig.php',
'PhabricatorAuthProviderConfigController' => 'applications/auth/controller/config/PhabricatorAuthProviderConfigController.php',
@@ -3479,6 +3488,7 @@
'PhabricatorPagerUIExample' => 'applications/uiexample/examples/PhabricatorPagerUIExample.php',
'PhabricatorPassphraseApplication' => 'applications/passphrase/application/PhabricatorPassphraseApplication.php',
'PhabricatorPasswordAuthProvider' => 'applications/auth/provider/PhabricatorPasswordAuthProvider.php',
+ 'PhabricatorPasswordDestructionEngineExtension' => 'applications/auth/extension/PhabricatorPasswordDestructionEngineExtension.php',
'PhabricatorPasswordHasher' => 'infrastructure/util/password/PhabricatorPasswordHasher.php',
'PhabricatorPasswordHasherTestCase' => 'infrastructure/util/password/__tests__/PhabricatorPasswordHasherTestCase.php',
'PhabricatorPasswordHasherUnavailableException' => 'infrastructure/util/password/PhabricatorPasswordHasherUnavailableException.php',
@@ -7363,7 +7373,21 @@
'PhabricatorAuthOldOAuthRedirectController' => 'PhabricatorAuthController',
'PhabricatorAuthOneTimeLoginController' => 'PhabricatorAuthController',
'PhabricatorAuthOneTimeLoginTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
+ 'PhabricatorAuthPassword' => array(
+ 'PhabricatorAuthDAO',
+ 'PhabricatorPolicyInterface',
+ 'PhabricatorDestructibleInterface',
+ 'PhabricatorApplicationTransactionInterface',
+ ),
+ 'PhabricatorAuthPasswordEditor' => 'PhabricatorApplicationTransactionEditor',
+ 'PhabricatorAuthPasswordPHIDType' => 'PhabricatorPHIDType',
+ 'PhabricatorAuthPasswordQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorAuthPasswordResetTemporaryTokenType' => 'PhabricatorAuthTemporaryTokenType',
+ 'PhabricatorAuthPasswordRevokeTransaction' => 'PhabricatorAuthPasswordTransactionType',
+ 'PhabricatorAuthPasswordRevoker' => 'PhabricatorAuthRevoker',
+ 'PhabricatorAuthPasswordTestCase' => 'PhabricatorTestCase',
+ 'PhabricatorAuthPasswordTransaction' => 'PhabricatorApplicationTransaction',
+ 'PhabricatorAuthPasswordTransactionType' => 'PhabricatorModularTransactionType',
'PhabricatorAuthProvider' => 'Phobject',
'PhabricatorAuthProviderConfig' => array(
'PhabricatorAuthDAO',
@@ -8980,6 +9004,7 @@
'PhabricatorPagerUIExample' => 'PhabricatorUIExample',
'PhabricatorPassphraseApplication' => 'PhabricatorApplication',
'PhabricatorPasswordAuthProvider' => 'PhabricatorAuthProvider',
+ 'PhabricatorPasswordDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
'PhabricatorPasswordHasher' => 'Phobject',
'PhabricatorPasswordHasherTestCase' => 'PhabricatorTestCase',
'PhabricatorPasswordHasherUnavailableException' => 'Exception',
diff --git a/src/applications/auth/__tests__/PhabricatorAuthPasswordTestCase.php b/src/applications/auth/__tests__/PhabricatorAuthPasswordTestCase.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/__tests__/PhabricatorAuthPasswordTestCase.php
@@ -0,0 +1,31 @@
+<?php
+
+final class PhabricatorAuthPasswordTestCase extends PhabricatorTestCase {
+
+ protected function getPhabricatorTestCaseConfiguration() {
+ return array(
+ self::PHABRICATOR_TESTCONFIG_BUILD_STORAGE_FIXTURES => true,
+ );
+ }
+
+ public function testCompare() {
+ $password1 = new PhutilOpaqueEnvelope('hunter2');
+ $password2 = new PhutilOpaqueEnvelope('hunter3');
+
+ $user = $this->generateNewTestUser();
+ $type = PhabricatorAuthPassword::PASSWORD_TYPE_TEST;
+
+ $pass = PhabricatorAuthPassword::initializeNewPassword($user, $type)
+ ->setPassword($password1, $user)
+ ->save();
+
+ $this->assertTrue(
+ $pass->comparePassword($password1, $user),
+ pht('Good password should match.'));
+
+ $this->assertFalse(
+ $pass->comparePassword($password2, $user),
+ pht('Bad password should not match.'));
+ }
+
+}
diff --git a/src/applications/auth/editor/PhabricatorAuthPasswordEditor.php b/src/applications/auth/editor/PhabricatorAuthPasswordEditor.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/editor/PhabricatorAuthPasswordEditor.php
@@ -0,0 +1,22 @@
+<?php
+
+final class PhabricatorAuthPasswordEditor
+ extends PhabricatorApplicationTransactionEditor {
+
+ public function getEditorApplicationClass() {
+ return 'PhabricatorAuthApplication';
+ }
+
+ public function getEditorObjectsDescription() {
+ return pht('Passwords');
+ }
+
+ public function getCreateObjectTitle($author, $object) {
+ return pht('%s created this password.', $author);
+ }
+
+ public function getCreateObjectTitleForFeed($author, $object) {
+ return pht('%s created %s.', $author, $object);
+ }
+
+}
diff --git a/src/applications/auth/extension/PhabricatorPasswordDestructionEngineExtension.php b/src/applications/auth/extension/PhabricatorPasswordDestructionEngineExtension.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/extension/PhabricatorPasswordDestructionEngineExtension.php
@@ -0,0 +1,29 @@
+<?php
+
+final class PhabricatorPasswordDestructionEngineExtension
+ extends PhabricatorDestructionEngineExtension {
+
+ const EXTENSIONKEY = 'passwords';
+
+ public function getExtensionName() {
+ return pht('Passwords');
+ }
+
+ public function destroyObject(
+ PhabricatorDestructionEngine $engine,
+ $object) {
+
+ $viewer = $engine->getViewer();
+ $object_phid = $object->getPHID();
+
+ $passwords = id(new PhabricatorAuthPasswordQuery())
+ ->setViewer($viewer)
+ ->withObjectPHIDs(array($object_phid))
+ ->execute();
+
+ foreach ($passwords as $password) {
+ $engine->destroyObject($password);
+ }
+ }
+
+}
diff --git a/src/applications/auth/phid/PhabricatorAuthPasswordPHIDType.php b/src/applications/auth/phid/PhabricatorAuthPasswordPHIDType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/phid/PhabricatorAuthPasswordPHIDType.php
@@ -0,0 +1,36 @@
+<?php
+
+final class PhabricatorAuthPasswordPHIDType extends PhabricatorPHIDType {
+
+ const TYPECONST = 'APAS';
+
+ public function getTypeName() {
+ return pht('Auth Password');
+ }
+
+ public function newObject() {
+ return new PhabricatorAuthPassword();
+ }
+
+ public function getPHIDTypeApplicationClass() {
+ return 'PhabricatorAuthApplication';
+ }
+
+ protected function buildQueryForObjects(
+ PhabricatorObjectQuery $query,
+ array $phids) {
+ return id(new PhabricatorAuthPasswordQuery())
+ ->withPHIDs($phids);
+ }
+
+ public function loadHandles(
+ PhabricatorHandleQuery $query,
+ array $handles,
+ array $objects) {
+
+ foreach ($handles as $phid => $handle) {
+ $password = $objects[$phid];
+ }
+ }
+
+}
diff --git a/src/applications/auth/query/PhabricatorAuthPasswordQuery.php b/src/applications/auth/query/PhabricatorAuthPasswordQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/query/PhabricatorAuthPasswordQuery.php
@@ -0,0 +1,114 @@
+<?php
+
+final class PhabricatorAuthPasswordQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $ids;
+ private $phids;
+ private $objectPHIDs;
+ private $passwordTypes;
+ private $isRevoked;
+
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
+ public function withPHIDs(array $phids) {
+ $this->phids = $phids;
+ return $this;
+ }
+
+ public function withObjectPHIDs(array $object_phids) {
+ $this->objectPHIDs = $object_phids;
+ return $this;
+ }
+
+ public function withPasswordTypes(array $types) {
+ $this->passwordTypes = $types;
+ return $this;
+ }
+
+ public function withIsRevoked($is_revoked) {
+ $this->isRevoked = $is_revoked;
+ return $this;
+ }
+
+ public function newResultObject() {
+ return new PhabricatorAuthPassword();
+ }
+
+ protected function loadPage() {
+ return $this->loadStandardPage($this->newResultObject());
+ }
+
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
+
+ if ($this->ids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'id IN (%Ld)',
+ $this->ids);
+ }
+
+ if ($this->phids !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'phid IN (%Ls)',
+ $this->phids);
+ }
+
+ if ($this->objectPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'objectPHID IN (%Ls)',
+ $this->objectPHIDs);
+ }
+
+ if ($this->passwordTypes !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'passwordType IN (%Ls)',
+ $this->passwordTypes);
+ }
+
+ if ($this->isRevoked !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'isRevoked = %d',
+ (int)$this->isRevoked);
+ }
+
+ return $where;
+ }
+
+ protected function willFilterPage(array $passwords) {
+ $object_phids = mpull($passwords, 'getObjectPHID');
+
+ $objects = id(new PhabricatorObjectQuery())
+ ->setViewer($this->getViewer())
+ ->setParentQuery($this)
+ ->withPHIDs($object_phids)
+ ->execute();
+ $objects = mpull($objects, null, 'getPHID');
+
+ foreach ($passwords as $key => $password) {
+ $object = idx($objects, $password->getObjectPHID());
+ if (!$object) {
+ unset($passwords[$key]);
+ $this->didRejectResult($password);
+ continue;
+ }
+
+ $password->attachObject($object);
+ }
+
+ return $passwords;
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorAuthApplication';
+ }
+
+}
diff --git a/src/applications/auth/revoker/PhabricatorAuthSSHRevoker.php b/src/applications/auth/revoker/PhabricatorAuthPasswordRevoker.php
copy from src/applications/auth/revoker/PhabricatorAuthSSHRevoker.php
copy to src/applications/auth/revoker/PhabricatorAuthPasswordRevoker.php
--- a/src/applications/auth/revoker/PhabricatorAuthSSHRevoker.php
+++ b/src/applications/auth/revoker/PhabricatorAuthPasswordRevoker.php
@@ -1,52 +1,52 @@
<?php
-final class PhabricatorAuthSSHRevoker
+final class PhabricatorAuthPasswordRevoker
extends PhabricatorAuthRevoker {
- const REVOKERKEY = 'ssh';
+ const REVOKERKEY = 'password';
public function revokeAllCredentials() {
- $query = new PhabricatorAuthSSHKeyQuery();
+ $query = new PhabricatorAuthPasswordQuery();
return $this->revokeWithQuery($query);
}
public function revokeCredentialsFrom($object) {
- $query = id(new PhabricatorAuthSSHKeyQuery())
+ $query = id(new PhabricatorAuthPasswordQuery())
->withObjectPHIDs(array($object->getPHID()));
-
return $this->revokeWithQuery($query);
}
private function revokeWithQuery(PhabricatorAuthSSHKeyQuery $query) {
$viewer = $this->getViewer();
- // We're only going to revoke keys which have not already been revoked.
-
- $ssh_keys = $query
+ $passwords = $query
->setViewer($viewer)
- ->withIsActive(true)
+ ->withIsRevoked(false)
->execute();
$content_source = PhabricatorContentSource::newForSource(
PhabricatorDaemonContentSource::SOURCECONST);
+ $revoke_type = PhabricatorAuthPasswordRevokeTransaction::TRANSACTIONTYPE;
+
$auth_phid = id(new PhabricatorAuthApplication())->getPHID();
- foreach ($ssh_keys as $ssh_key) {
+ foreach ($passwords as $password) {
$xactions = array();
- $xactions[] = $ssh_key->getApplicationTransactionTemplate()
- ->setTransactionType(PhabricatorAuthSSHKeyTransaction::TYPE_DEACTIVATE)
- ->setNewValue(1);
- $editor = id(new PhabricatorAuthSSHKeyEditor())
+ $xactions[] = $password->getApplicationTransactionTemplate()
+ ->setTransactionType($revoke_type)
+ ->setNewValue(true);
+
+ $editor = $password->getApplicationTransactionEditor()
->setActor($viewer)
->setActingAsPHID($auth_phid)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true)
->setContentSource($content_source)
- ->applyTransactions($ssh_key, $xactions);
+ ->applyTransactions($password, $xactions);
}
- return count($ssh_keys);
+ return count($passwords);
}
}
diff --git a/src/applications/auth/revoker/PhabricatorAuthSSHRevoker.php b/src/applications/auth/revoker/PhabricatorAuthSSHRevoker.php
--- a/src/applications/auth/revoker/PhabricatorAuthSSHRevoker.php
+++ b/src/applications/auth/revoker/PhabricatorAuthSSHRevoker.php
@@ -37,7 +37,7 @@
->setTransactionType(PhabricatorAuthSSHKeyTransaction::TYPE_DEACTIVATE)
->setNewValue(1);
- $editor = id(new PhabricatorAuthSSHKeyEditor())
+ $editor = $ssh_key->getApplicationTransactionEditor()
->setActor($viewer)
->setActingAsPHID($auth_phid)
->setContinueOnNoEffect(true)
diff --git a/src/applications/auth/storage/PhabricatorAuthPassword.php b/src/applications/auth/storage/PhabricatorAuthPassword.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/storage/PhabricatorAuthPassword.php
@@ -0,0 +1,167 @@
+<?php
+
+final class PhabricatorAuthPassword
+ extends PhabricatorAuthDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorDestructibleInterface,
+ PhabricatorApplicationTransactionInterface {
+
+ protected $objectPHID;
+ protected $passwordType;
+ protected $passwordHash;
+ protected $isRevoked;
+
+ private $object = self::ATTACHABLE;
+
+ const PASSWORD_TYPE_ACCOUNT = 'account';
+ const PASSWORD_TYPE_VCS = 'vcs';
+ const PASSWORD_TYPE_TEST = 'test';
+
+ public static function initializeNewPassword(
+ PhabricatorUser $object,
+ $type) {
+
+ return id(new self())
+ ->setObjectPHID($object->getPHID())
+ ->attachObject($object)
+ ->setPasswordType($type)
+ ->setIsRevoked(0);
+ }
+
+ protected function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ self::CONFIG_COLUMN_SCHEMA => array(
+ 'passwordType' => 'text64',
+ 'passwordHash' => 'text128',
+ 'isRevoked' => 'bool',
+ ),
+ self::CONFIG_KEY_SCHEMA => array(
+ 'key_role' => array(
+ 'columns' => array('objectPHID', 'passwordType'),
+ ),
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function getPHIDType() {
+ return PhabricatorAuthPasswordPHIDType::TYPECONST;
+ }
+
+ public function getObject() {
+ return $this->assertAttached($this->object);
+ }
+
+ public function attachObject($object) {
+ $this->object = $object;
+ return $this;
+ }
+
+ public function setPassword(
+ PhutilOpaqueEnvelope $password,
+ PhabricatorUser $object) {
+
+ $hasher = PhabricatorPasswordHasher::getBestHasher();
+
+ $digest = $this->digestPassword($password, $object);
+ $hash = $hasher->getPasswordHashForStorage($digest);
+ $raw_hash = $hash->openEnvelope();
+
+ return $this->setPasswordHash($raw_hash);
+ }
+
+ public function comparePassword(
+ PhutilOpaqueEnvelope $password,
+ PhabricatorUser $object) {
+
+ $digest = $this->digestPassword($password, $object);
+ $raw_hash = $this->getPasswordHash();
+ $hash = new PhutilOpaqueEnvelope($raw_hash);
+
+ return PhabricatorPasswordHasher::comparePassword($digest, $hash);
+ }
+
+ private function digestPassword(
+ PhutilOpaqueEnvelope $password,
+ PhabricatorUser $object) {
+
+ $object_phid = $object->getPHID();
+
+ if ($this->getObjectPHID() !== $object->getPHID()) {
+ throw new Exception(
+ pht(
+ 'This password is associated with a an object PHID ("%s") for '.
+ 'a different object than the provided one ("%s").',
+ $this->getObjectPHID(),
+ $object->getPHID()));
+ }
+
+ $raw_input = PhabricatorHash::digestPassword($password, $object_phid);
+
+ return new PhutilOpaqueEnvelope($raw_input);
+ }
+
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ );
+ }
+
+ public function getPolicy($capability) {
+ return PhabricatorPolicies::getMostOpenPolicy();
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+
+/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
+
+
+ public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
+ return array(
+ array($this->getObject(), PhabricatorPolicyCapability::CAN_VIEW),
+ );
+ }
+
+
+/* -( PhabricatorDestructibleInterface )----------------------------------- */
+
+
+ public function destroyObjectPermanently(
+ PhabricatorDestructionEngine $engine) {
+ $this->delete();
+ }
+
+
+/* -( PhabricatorApplicationTransactionInterface )------------------------- */
+
+
+ public function getApplicationTransactionEditor() {
+ return new PhabricatorAuthPasswordEditor();
+ }
+
+ public function getApplicationTransactionObject() {
+ return $this;
+ }
+
+ public function getApplicationTransactionTemplate() {
+ return new PhabricatorAuthPasswordTransaction();
+ }
+
+ public function willRenderTimeline(
+ PhabricatorApplicationTransactionView $timeline,
+ AphrontRequest $request) {
+
+ return $timeline;
+ }
+
+
+}
diff --git a/src/applications/auth/storage/PhabricatorAuthPasswordTransaction.php b/src/applications/auth/storage/PhabricatorAuthPasswordTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/storage/PhabricatorAuthPasswordTransaction.php
@@ -0,0 +1,21 @@
+<?php
+
+final class PhabricatorAuthPasswordTransaction
+ extends PhabricatorApplicationTransaction {
+
+ public function getApplicationName() {
+ return 'auth';
+ }
+
+ public function getApplicationTransactionType() {
+ return PhabricatorAuthPasswordPHIDType::TYPECONST;
+ }
+
+ public function getApplicationTransactionCommentObject() {
+ return null;
+ }
+
+ public function getBaseTransactionClass() {
+ return 'PhabricatorAuthPasswordTransactionType';
+ }
+}
diff --git a/src/applications/auth/xaction/PhabricatorAuthPasswordRevokeTransaction.php b/src/applications/auth/xaction/PhabricatorAuthPasswordRevokeTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/xaction/PhabricatorAuthPasswordRevokeTransaction.php
@@ -0,0 +1,32 @@
+<?php
+
+final class PhabricatorAuthPasswordRevokeTransaction
+ extends PhabricatorAuthPasswordTransactionType {
+
+ const TRANSACTIONTYPE = 'password.revoke';
+
+ public function generateOldValue($object) {
+ return (bool)$object->getIsRevoked();
+ }
+
+ public function generateNewValue($object, $value) {
+ return (bool)$value;
+ }
+
+ public function applyInternalEffects($object, $value) {
+ $object->setIsRevoked((int)$value);
+ }
+
+ public function getTitle() {
+ if ($this->getNewValue()) {
+ return pht(
+ '%s revoked this password.',
+ $this->renderAuthor());
+ } else {
+ return pht(
+ '%s reinstated this password.',
+ $this->renderAuthor());
+ }
+ }
+
+}
diff --git a/src/applications/auth/xaction/PhabricatorAuthPasswordTransactionType.php b/src/applications/auth/xaction/PhabricatorAuthPasswordTransactionType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/auth/xaction/PhabricatorAuthPasswordTransactionType.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class PhabricatorAuthPasswordTransactionType
+ extends PhabricatorModularTransactionType {}

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 23, 6:35 PM (18 h, 30 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6779224
Default Alt Text
D18894.id45308.diff (22 KB)

Event Timeline