Path: blob/master/src/applications/people/storage/PhabricatorExternalAccount.php
12256 views
<?php12final class PhabricatorExternalAccount3extends PhabricatorUserDAO4implements5PhabricatorPolicyInterface,6PhabricatorDestructibleInterface {78protected $userPHID;9protected $accountSecret;10protected $displayName;11protected $username;12protected $realName;13protected $email;14protected $emailVerified = 0;15protected $accountURI;16protected $profileImagePHID;17protected $properties = array();18protected $providerConfigPHID;1920// TODO: Remove these (see T13493). These columns are obsolete and have21// no readers and only trivial writers.22protected $accountType;23protected $accountDomain;24protected $accountID;2526private $profileImageFile = self::ATTACHABLE;27private $providerConfig = self::ATTACHABLE;28private $accountIdentifiers = self::ATTACHABLE;2930public function getProfileImageFile() {31return $this->assertAttached($this->profileImageFile);32}3334public function attachProfileImageFile(PhabricatorFile $file) {35$this->profileImageFile = $file;36return $this;37}3839public function generatePHID() {40return PhabricatorPHID::generateNewPHID(41PhabricatorPeopleExternalPHIDType::TYPECONST);42}4344protected function getConfiguration() {45return array(46self::CONFIG_AUX_PHID => true,47self::CONFIG_SERIALIZATION => array(48'properties' => self::SERIALIZATION_JSON,49),50self::CONFIG_COLUMN_SCHEMA => array(51'userPHID' => 'phid?',52'accountType' => 'text16',53'accountDomain' => 'text64',54'accountSecret' => 'text?',55'accountID' => 'text64',56'displayName' => 'text255?',57'username' => 'text255?',58'realName' => 'text255?',59'email' => 'text255?',60'emailVerified' => 'bool',61'profileImagePHID' => 'phid?',62'accountURI' => 'text255?',63),64self::CONFIG_KEY_SCHEMA => array(65'key_user' => array(66'columns' => array('userPHID'),67),68'key_provider' => array(69'columns' => array('providerConfigPHID', 'userPHID'),70),71),72) + parent::getConfiguration();73}7475public function save() {76if (!$this->getAccountSecret()) {77$this->setAccountSecret(Filesystem::readRandomCharacters(32));78}7980$this->openTransaction();8182$result = parent::save();8384$account_phid = $this->getPHID();85$config_phid = $this->getProviderConfigPHID();8687if ($this->accountIdentifiers !== self::ATTACHABLE) {88foreach ($this->getAccountIdentifiers() as $identifier) {89$identifier90->setExternalAccountPHID($account_phid)91->setProviderConfigPHID($config_phid)92->save();93}94}9596$this->saveTransaction();9798return $result;99}100101public function unlinkAccount() {102103// When unlinking an account, we disassociate it from the user and104// remove all the identifying information. We retain the PHID, the105// object itself, and the "ExternalAccountIdentifier" objects in the106// external table.107108// TODO: This unlinks (but does not destroy) any profile image.109110return $this111->setUserPHID(null)112->setDisplayName(null)113->setUsername(null)114->setRealName(null)115->setEmail(null)116->setEmailVerified(0)117->setProfileImagePHID(null)118->setAccountURI(null)119->setProperties(array())120->save();121}122123public function setProperty($key, $value) {124$this->properties[$key] = $value;125return $this;126}127128public function getProperty($key, $default = null) {129return idx($this->properties, $key, $default);130}131132public function isUsableForLogin() {133$config = $this->getProviderConfig();134if (!$config->getIsEnabled()) {135return false;136}137138$provider = $config->getProvider();139if (!$provider->shouldAllowLogin()) {140return false;141}142143return true;144}145146public function attachProviderConfig(PhabricatorAuthProviderConfig $config) {147$this->providerConfig = $config;148return $this;149}150151public function getProviderConfig() {152return $this->assertAttached($this->providerConfig);153}154155public function getAccountIdentifiers() {156$raw = $this->assertAttached($this->accountIdentifiers);157return array_values($raw);158}159160public function attachAccountIdentifiers(array $identifiers) {161assert_instances_of($identifiers, 'PhabricatorExternalAccountIdentifier');162$this->accountIdentifiers = mpull($identifiers, null, 'getIdentifierRaw');163return $this;164}165166public function appendIdentifier(167PhabricatorExternalAccountIdentifier $identifier) {168169$this->assertAttached($this->accountIdentifiers);170171$map = $this->accountIdentifiers;172$raw = $identifier->getIdentifierRaw();173174$old = idx($map, $raw);175$new = $identifier;176177if ($old === null) {178$result = $new;179} else {180// Here, we already know about an identifier and have rediscovered it.181182// We could copy properties from the new version of the identifier here,183// or merge them in some other way (for example, update a "last seen184// from the provider" timestamp), but no such properties currently exist.185$result = $old;186}187188$this->accountIdentifiers[$raw] = $result;189190return $this;191}192193194/* -( PhabricatorPolicyInterface )----------------------------------------- */195196197public function getCapabilities() {198return array(199PhabricatorPolicyCapability::CAN_VIEW,200PhabricatorPolicyCapability::CAN_EDIT,201);202}203204public function getPolicy($capability) {205switch ($capability) {206case PhabricatorPolicyCapability::CAN_VIEW:207return PhabricatorPolicies::getMostOpenPolicy();208case PhabricatorPolicyCapability::CAN_EDIT:209return PhabricatorPolicies::POLICY_NOONE;210}211}212213public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {214return ($viewer->getPHID() == $this->getUserPHID());215}216217public function describeAutomaticCapability($capability) {218switch ($capability) {219case PhabricatorPolicyCapability::CAN_VIEW:220return null;221case PhabricatorPolicyCapability::CAN_EDIT:222return pht(223'External accounts can only be edited by the account owner.');224}225}226227228/* -( PhabricatorDestructibleInterface )----------------------------------- */229230231public function destroyObjectPermanently(232PhabricatorDestructionEngine $engine) {233234$viewer = $engine->getViewer();235236$identifiers = id(new PhabricatorExternalAccountIdentifierQuery())237->setViewer($viewer)238->withExternalAccountPHIDs(array($this->getPHID()))239->newIterator();240foreach ($identifiers as $identifier) {241$engine->destroyObject($identifier);242}243244// TODO: This may leave a profile image behind.245246$this->delete();247}248249}250251252