1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-09 16:32:39 +01:00

Add an "ExternalAccountIdentifier" table

Summary:
Depends on D21010. Ref T13493. External accounts may have multiple different unique identifiers, most often when v1 of the API makes a questionable choice (and provies a mutable, non-unique, or PII identifier) and v2 of the API uses an immutable, unique, random identifier.

Allow Phabricator to store multiple identifiers per external account.

Test Plan: Storage only, see followup changes.

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13493

Differential Revision: https://secure.phabricator.com/D21011
This commit is contained in:
epriestley 2020-02-20 13:43:54 -08:00
parent fbf050167e
commit 70845a2d13
5 changed files with 218 additions and 0 deletions

View file

@ -0,0 +1,10 @@
CREATE TABLE {$NAMESPACE}_user.user_externalaccountidentifier (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
phid VARBINARY(64) NOT NULL,
externalAccountPHID VARBINARY(64) NOT NULL,
providerConfigPHID VARBINARY(64) NOT NULL,
identifierHash BINARY(12) NOT NULL,
identifierRaw LONGTEXT NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET={$CHARSET} COLLATE {$COLLATE_TEXT};

View file

@ -3318,6 +3318,8 @@ phutil_register_library_map(array(
'PhabricatorExtendingPhabricatorConfigOptions' => 'applications/config/option/PhabricatorExtendingPhabricatorConfigOptions.php',
'PhabricatorExtensionsSetupCheck' => 'applications/config/check/PhabricatorExtensionsSetupCheck.php',
'PhabricatorExternalAccount' => 'applications/people/storage/PhabricatorExternalAccount.php',
'PhabricatorExternalAccountIdentifier' => 'applications/people/storage/PhabricatorExternalAccountIdentifier.php',
'PhabricatorExternalAccountIdentifierQuery' => 'applications/auth/query/PhabricatorExternalAccountIdentifierQuery.php',
'PhabricatorExternalAccountQuery' => 'applications/auth/query/PhabricatorExternalAccountQuery.php',
'PhabricatorExternalAccountsSettingsPanel' => 'applications/settings/panel/PhabricatorExternalAccountsSettingsPanel.php',
'PhabricatorExtraConfigSetupCheck' => 'applications/config/check/PhabricatorExtraConfigSetupCheck.php',
@ -4103,6 +4105,7 @@ phutil_register_library_map(array(
'PhabricatorPeopleDisableController' => 'applications/people/controller/PhabricatorPeopleDisableController.php',
'PhabricatorPeopleEmailLoginMailEngine' => 'applications/people/mail/PhabricatorPeopleEmailLoginMailEngine.php',
'PhabricatorPeopleEmpowerController' => 'applications/people/controller/PhabricatorPeopleEmpowerController.php',
'PhabricatorPeopleExternalIdentifierPHIDType' => 'applications/people/phid/PhabricatorPeopleExternalIdentifierPHIDType.php',
'PhabricatorPeopleExternalPHIDType' => 'applications/people/phid/PhabricatorPeopleExternalPHIDType.php',
'PhabricatorPeopleIconSet' => 'applications/people/icon/PhabricatorPeopleIconSet.php',
'PhabricatorPeopleInviteController' => 'applications/people/controller/PhabricatorPeopleInviteController.php',
@ -9763,6 +9766,11 @@ phutil_register_library_map(array(
'PhabricatorUserDAO',
'PhabricatorPolicyInterface',
),
'PhabricatorExternalAccountIdentifier' => array(
'PhabricatorUserDAO',
'PhabricatorPolicyInterface',
),
'PhabricatorExternalAccountIdentifierQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorExternalAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorExternalAccountsSettingsPanel' => 'PhabricatorSettingsPanel',
'PhabricatorExtraConfigSetupCheck' => 'PhabricatorSetupCheck',
@ -10681,6 +10689,7 @@ phutil_register_library_map(array(
'PhabricatorPeopleDisableController' => 'PhabricatorPeopleController',
'PhabricatorPeopleEmailLoginMailEngine' => 'PhabricatorPeopleMailEngine',
'PhabricatorPeopleEmpowerController' => 'PhabricatorPeopleController',
'PhabricatorPeopleExternalIdentifierPHIDType' => 'PhabricatorPHIDType',
'PhabricatorPeopleExternalPHIDType' => 'PhabricatorPHIDType',
'PhabricatorPeopleIconSet' => 'PhabricatorIconSet',
'PhabricatorPeopleInviteController' => 'PhabricatorPeopleController',

View file

@ -0,0 +1,94 @@
<?php
final class PhabricatorExternalAccountIdentifierQuery
extends PhabricatorCursorPagedPolicyAwareQuery {
private $ids;
private $phids;
private $providerConfigPHIDs;
private $externalAccountPHIDs;
private $rawIdentifiers;
public function withIDs($ids) {
$this->ids = $ids;
return $this;
}
public function withPHIDs(array $phids) {
$this->phids = $phids;
return $this;
}
public function withProviderConfigPHIDs(array $phids) {
$this->providerConfigPHIDs = $phids;
return $this;
}
public function withExternalAccountPHIDs(array $phids) {
$this->externalAccountPHIDs = $phids;
return $this;
}
public function withRawIdentifiers(array $identifiers) {
$this->rawIdentifiers = $identifiers;
return $this;
}
public function newResultObject() {
return new PhabricatorExternalAccountIdentifier();
}
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->providerConfigPHIDs !== null) {
$where[] = qsprintf(
$conn,
'providerConfigPHID IN (%Ls)',
$this->providerConfigPHIDs);
}
if ($this->externalAccountPHIDs !== null) {
$where[] = qsprintf(
$conn,
'externalAccountPHID IN (%Ls)',
$this->externalAccountPHIDs);
}
if ($this->rawIdentifiers !== null) {
$hashes = array();
foreach ($this->rawIdentifiers as $raw_identifier) {
$hashes[] = PhabricatorHash::digestForIndex($raw_identifier);
}
$where[] = qsprintf(
$conn,
'identifierHash IN (%Ls)',
$hashes);
}
return $where;
}
public function getQueryApplicationClass() {
return 'PhabricatorPeopleApplication';
}
}

View file

@ -0,0 +1,38 @@
<?php
final class PhabricatorPeopleExternalIdentifierPHIDType
extends PhabricatorPHIDType {
const TYPECONST = 'XIDT';
public function getTypeName() {
return pht('External Account Identifier');
}
public function newObject() {
return new PhabricatorExternalAccountIdentifier();
}
public function getPHIDTypeApplicationClass() {
return 'PhabricatorPeopleApplication';
}
protected function buildQueryForObjects(
PhabricatorObjectQuery $query,
array $phids) {
return id(new PhabricatorExternalAccountIdentifierQuery())
->withPHIDs($phids);
}
public function loadHandles(
PhabricatorHandleQuery $query,
array $handles,
array $objects) {
foreach ($handles as $phid => $handle) {
$identifier = $objects[$phid];
}
}
}

View file

@ -0,0 +1,67 @@
<?php
final class PhabricatorExternalAccountIdentifier
extends PhabricatorUserDAO
implements PhabricatorPolicyInterface {
protected $externalAccountPHID;
protected $providerConfigPHID;
protected $identifierHash;
protected $identifierRaw;
public function getPHIDType() {
return PhabricatorPeopleExternalIdentifierPHIDType::TYPECONST;
}
protected function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'identifierHash' => 'bytes12',
'identifierRaw' => 'text',
),
self::CONFIG_KEY_SCHEMA => array(
'key_identifier' => array(
'columns' => array('providerConfigPHID', 'identifierHash'),
'unique' => true,
),
'key_account' => array(
'columns' => array('externalAccountPHID'),
),
),
) + parent::getConfiguration();
}
public function save() {
$identifier_raw = $this->getIdentifierRaw();
$this->identiferHash = PhabricatorHash::digestForIndex($identifier_raw);
return parent::save();
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
// TODO: These permissions aren't very good. They should just be the same
// as the associated ExternalAccount. See T13381.
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return PhabricatorPolicies::getMostOpenPolicy();
case PhabricatorPolicyCapability::CAN_EDIT:
return PhabricatorPolicies::POLICY_NOONE;
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
return false;
}
}