Changeset View
Changeset View
Standalone View
Standalone View
src/applications/people/storage/PhabricatorUser.php
| Show All 24 Lines | final class PhabricatorUser | ||||
| const NAMETOKEN_TABLE = 'user_nametoken'; | const NAMETOKEN_TABLE = 'user_nametoken'; | ||||
| const MAXIMUM_USERNAME_LENGTH = 64; | const MAXIMUM_USERNAME_LENGTH = 64; | ||||
| protected $userName; | protected $userName; | ||||
| protected $realName; | protected $realName; | ||||
| protected $passwordSalt; | protected $passwordSalt; | ||||
| protected $passwordHash; | protected $passwordHash; | ||||
| protected $profileImagePHID; | protected $profileImagePHID; | ||||
| protected $profileImageCache; | |||||
| protected $availabilityCache; | protected $availabilityCache; | ||||
| protected $availabilityCacheTTL; | protected $availabilityCacheTTL; | ||||
| protected $conduitCertificate; | protected $conduitCertificate; | ||||
| protected $isSystemAgent = 0; | protected $isSystemAgent = 0; | ||||
| protected $isMailingList = 0; | protected $isMailingList = 0; | ||||
| protected $isAdmin = 0; | protected $isAdmin = 0; | ||||
| protected $isDisabled = 0; | protected $isDisabled = 0; | ||||
| protected $isEmailVerified = 0; | protected $isEmailVerified = 0; | ||||
| protected $isApproved = 0; | protected $isApproved = 0; | ||||
| protected $isEnrolledInMultiFactor = 0; | protected $isEnrolledInMultiFactor = 0; | ||||
| protected $accountSecret; | protected $accountSecret; | ||||
| private $profileImage = self::ATTACHABLE; | |||||
| private $profile = null; | private $profile = null; | ||||
| private $availability = self::ATTACHABLE; | private $availability = self::ATTACHABLE; | ||||
| private $preferences = null; | private $preferences = null; | ||||
| private $omnipotent = false; | private $omnipotent = false; | ||||
| private $customFields = self::ATTACHABLE; | private $customFields = self::ATTACHABLE; | ||||
| private $badgePHIDs = self::ATTACHABLE; | private $badgePHIDs = self::ATTACHABLE; | ||||
| private $alternateCSRFString = self::ATTACHABLE; | private $alternateCSRFString = self::ATTACHABLE; | ||||
| ▲ Show 20 Lines • Show All 133 Lines • ▼ Show 20 Lines | return array( | ||||
| 'isSystemAgent' => 'bool', | 'isSystemAgent' => 'bool', | ||||
| 'isMailingList' => 'bool', | 'isMailingList' => 'bool', | ||||
| 'isDisabled' => 'bool', | 'isDisabled' => 'bool', | ||||
| 'isAdmin' => 'bool', | 'isAdmin' => 'bool', | ||||
| 'isEmailVerified' => 'uint32', | 'isEmailVerified' => 'uint32', | ||||
| 'isApproved' => 'uint32', | 'isApproved' => 'uint32', | ||||
| 'accountSecret' => 'bytes64', | 'accountSecret' => 'bytes64', | ||||
| 'isEnrolledInMultiFactor' => 'bool', | 'isEnrolledInMultiFactor' => 'bool', | ||||
| 'profileImageCache' => 'text255?', | |||||
| 'availabilityCache' => 'text255?', | 'availabilityCache' => 'text255?', | ||||
| 'availabilityCacheTTL' => 'uint32?', | 'availabilityCacheTTL' => 'uint32?', | ||||
| ), | ), | ||||
| self::CONFIG_KEY_SCHEMA => array( | self::CONFIG_KEY_SCHEMA => array( | ||||
| 'key_phid' => null, | 'key_phid' => null, | ||||
| 'phid' => array( | 'phid' => array( | ||||
| 'columns' => array('phid'), | 'columns' => array('phid'), | ||||
| 'unique' => true, | 'unique' => true, | ||||
| ), | ), | ||||
| 'userName' => array( | 'userName' => array( | ||||
| 'columns' => array('userName'), | 'columns' => array('userName'), | ||||
| 'unique' => true, | 'unique' => true, | ||||
| ), | ), | ||||
| 'realName' => array( | 'realName' => array( | ||||
| 'columns' => array('realName'), | 'columns' => array('realName'), | ||||
| ), | ), | ||||
| 'key_approved' => array( | 'key_approved' => array( | ||||
| 'columns' => array('isApproved'), | 'columns' => array('isApproved'), | ||||
| ), | ), | ||||
| ), | ), | ||||
| self::CONFIG_NO_MUTATE => array( | self::CONFIG_NO_MUTATE => array( | ||||
| 'profileImageCache' => true, | |||||
| 'availabilityCache' => true, | 'availabilityCache' => true, | ||||
| 'availabilityCacheTTL' => true, | 'availabilityCacheTTL' => true, | ||||
| ), | ), | ||||
| ) + parent::getConfiguration(); | ) + parent::getConfiguration(); | ||||
| } | } | ||||
| public function generatePHID() { | public function generatePHID() { | ||||
| return PhabricatorPHID::generateNewPHID( | return PhabricatorPHID::generateNewPHID( | ||||
| ▲ Show 20 Lines • Show All 556 Lines • ▼ Show 20 Lines | public static function validateUsername($username) { | ||||
| return (bool)preg_match('/^[a-zA-Z0-9._-]*[a-zA-Z0-9_-]\z/', $username); | return (bool)preg_match('/^[a-zA-Z0-9._-]*[a-zA-Z0-9_-]\z/', $username); | ||||
| } | } | ||||
| public static function getDefaultProfileImageURI() { | public static function getDefaultProfileImageURI() { | ||||
| return celerity_get_resource_uri('/rsrc/image/avatar.png'); | return celerity_get_resource_uri('/rsrc/image/avatar.png'); | ||||
| } | } | ||||
| public function attachProfileImageURI($uri) { | |||||
| $this->profileImage = $uri; | |||||
| return $this; | |||||
| } | |||||
| public function getProfileImageURI() { | public function getProfileImageURI() { | ||||
| return $this->assertAttached($this->profileImage); | $uri_key = PhabricatorUserProfileImageCacheType::KEY_URI; | ||||
| return $this->requireCacheData($uri_key); | |||||
| } | } | ||||
| public function getFullName() { | public function getFullName() { | ||||
| if (strlen($this->getRealName())) { | if (strlen($this->getRealName())) { | ||||
| return $this->getUsername().' ('.$this->getRealName().')'; | return $this->getUsername().' ('.$this->getRealName().')'; | ||||
| } else { | } else { | ||||
| return $this->getUsername(); | return $this->getUsername(); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 194 Lines • ▼ Show 20 Lines | queryfx( | ||||
| $ttl, | $ttl, | ||||
| $this->getID()); | $this->getID()); | ||||
| unset($unguarded); | unset($unguarded); | ||||
| return $this; | return $this; | ||||
| } | } | ||||
| /* -( Profile Image Cache )------------------------------------------------ */ | |||||
| /** | |||||
| * Get this user's cached profile image URI. | |||||
| * | |||||
| * @return string|null Cached URI, if a URI is cached. | |||||
| * @task image-cache | |||||
| */ | |||||
| public function getProfileImageCache() { | |||||
| $version = $this->getProfileImageVersion(); | |||||
| $parts = explode(',', $this->profileImageCache, 2); | |||||
| if (count($parts) !== 2) { | |||||
| return null; | |||||
| } | |||||
| if ($parts[0] !== $version) { | |||||
| return null; | |||||
| } | |||||
| return $parts[1]; | |||||
| } | |||||
| /** | |||||
| * Generate a new cache value for this user's profile image. | |||||
| * | |||||
| * @return string New cache value. | |||||
| * @task image-cache | |||||
| */ | |||||
| public function writeProfileImageCache($uri) { | |||||
| $version = $this->getProfileImageVersion(); | |||||
| $cache = "{$version},{$uri}"; | |||||
| $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); | |||||
| queryfx( | |||||
| $this->establishConnection('w'), | |||||
| 'UPDATE %T SET profileImageCache = %s WHERE id = %d', | |||||
| $this->getTableName(), | |||||
| $cache, | |||||
| $this->getID()); | |||||
| unset($unguarded); | |||||
| } | |||||
| /** | |||||
| * Get a version identifier for a user's profile image. | |||||
| * | |||||
| * This version will change if the image changes, or if any of the | |||||
| * environment configuration which goes into generating a URI changes. | |||||
| * | |||||
| * @return string Cache version. | |||||
| * @task image-cache | |||||
| */ | |||||
| private function getProfileImageVersion() { | |||||
| $parts = array( | |||||
| PhabricatorEnv::getCDNURI('/'), | |||||
| PhabricatorEnv::getEnvConfig('cluster.instance'), | |||||
| $this->getProfileImagePHID(), | |||||
| ); | |||||
| $parts = serialize($parts); | |||||
| return PhabricatorHash::digestForIndex($parts); | |||||
| } | |||||
| /* -( Multi-Factor Authentication )---------------------------------------- */ | /* -( Multi-Factor Authentication )---------------------------------------- */ | ||||
| /** | /** | ||||
| * Update the flag storing this user's enrollment in multi-factor auth. | * Update the flag storing this user's enrollment in multi-factor auth. | ||||
| * | * | ||||
| * With certain settings, we need to check if a user has MFA on every page, | * With certain settings, we need to check if a user has MFA on every page, | ||||
| * so we cache MFA enrollment on the user object for performance. Calling this | * so we cache MFA enrollment on the user object for performance. Calling this | ||||
| ▲ Show 20 Lines • Show All 439 Lines • ▼ Show 20 Lines | protected function requireCacheData($key) { | ||||
| $usable_value = $type->getDefaultValue(); | $usable_value = $type->getDefaultValue(); | ||||
| $user_phid = $this->getPHID(); | $user_phid = $this->getPHID(); | ||||
| if ($user_phid) { | if ($user_phid) { | ||||
| $map = $type->newValueForUsers($key, array($this)); | $map = $type->newValueForUsers($key, array($this)); | ||||
| if (array_key_exists($user_phid, $map)) { | if (array_key_exists($user_phid, $map)) { | ||||
| $usable_value = $map[$user_phid]; | $usable_value = $map[$user_phid]; | ||||
| $raw_value = $type->getValueForStorage($usable_value); | $raw_value = $type->getValueForStorage($usable_value); | ||||
| $usable_value = $type->getValueFromStorage($raw_value); | |||||
| $this->rawCacheData[$key] = $raw_value; | $this->rawCacheData[$key] = $raw_value; | ||||
| PhabricatorUserCache::writeCache( | PhabricatorUserCache::writeCache( | ||||
| $type, | $type, | ||||
| $key, | $key, | ||||
| $user_phid, | $user_phid, | ||||
| $raw_value); | $raw_value); | ||||
| } | } | ||||
| Show All 18 Lines | |||||