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 |