diff --git a/resources/sql/autopatches/20200220.xaccount.01.sql b/resources/sql/autopatches/20200220.xaccount.01.sql new file mode 100644 --- /dev/null +++ b/resources/sql/autopatches/20200220.xaccount.01.sql @@ -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}; 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 @@ -3318,6 +3318,8 @@ '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 @@ '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 @@ 'PhabricatorUserDAO', 'PhabricatorPolicyInterface', ), + 'PhabricatorExternalAccountIdentifier' => array( + 'PhabricatorUserDAO', + 'PhabricatorPolicyInterface', + ), + 'PhabricatorExternalAccountIdentifierQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorExternalAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorExternalAccountsSettingsPanel' => 'PhabricatorSettingsPanel', 'PhabricatorExtraConfigSetupCheck' => 'PhabricatorSetupCheck', @@ -10681,6 +10689,7 @@ 'PhabricatorPeopleDisableController' => 'PhabricatorPeopleController', 'PhabricatorPeopleEmailLoginMailEngine' => 'PhabricatorPeopleMailEngine', 'PhabricatorPeopleEmpowerController' => 'PhabricatorPeopleController', + 'PhabricatorPeopleExternalIdentifierPHIDType' => 'PhabricatorPHIDType', 'PhabricatorPeopleExternalPHIDType' => 'PhabricatorPHIDType', 'PhabricatorPeopleIconSet' => 'PhabricatorIconSet', 'PhabricatorPeopleInviteController' => 'PhabricatorPeopleController', diff --git a/src/applications/auth/query/PhabricatorExternalAccountIdentifierQuery.php b/src/applications/auth/query/PhabricatorExternalAccountIdentifierQuery.php new file mode 100644 --- /dev/null +++ b/src/applications/auth/query/PhabricatorExternalAccountIdentifierQuery.php @@ -0,0 +1,94 @@ +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'; + } + +} diff --git a/src/applications/people/phid/PhabricatorPeopleExternalIdentifierPHIDType.php b/src/applications/people/phid/PhabricatorPeopleExternalIdentifierPHIDType.php new file mode 100644 --- /dev/null +++ b/src/applications/people/phid/PhabricatorPeopleExternalIdentifierPHIDType.php @@ -0,0 +1,38 @@ +withPHIDs($phids); + } + + public function loadHandles( + PhabricatorHandleQuery $query, + array $handles, + array $objects) { + + foreach ($handles as $phid => $handle) { + $identifier = $objects[$phid]; + } + } + +} diff --git a/src/applications/people/storage/PhabricatorExternalAccountIdentifier.php b/src/applications/people/storage/PhabricatorExternalAccountIdentifier.php new file mode 100644 --- /dev/null +++ b/src/applications/people/storage/PhabricatorExternalAccountIdentifier.php @@ -0,0 +1,67 @@ + 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; + } + +}