Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/conduit/controller/token/PhabricatorConduitTokenController.php b/src/applications/conduit/controller/token/PhabricatorConduitTokenController.php
index 7dfe11e0d2..482a4b306f 100644
--- a/src/applications/conduit/controller/token/PhabricatorConduitTokenController.php
+++ b/src/applications/conduit/controller/token/PhabricatorConduitTokenController.php
@@ -1,66 +1,66 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group conduit
*/
class PhabricatorConduitTokenController extends PhabricatorConduitController {
public function processRequest() {
$user = $this->getRequest()->getUser();
// Ideally we'd like to verify this, but it's fine to leave it unguarded
// for now and verifying it would need some Ajax junk or for the user to
// click a button or similar.
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
$old_token = id(new PhabricatorConduitCertificateToken())
->loadOneWhere(
'userPHID = %s',
$user->getPHID());
if ($old_token) {
$old_token->delete();
}
$token = id(new PhabricatorConduitCertificateToken())
->setUserPHID($user->getPHID())
- ->setToken(sha1(Filesystem::readRandomBytes(128)))
+ ->setToken(Filesystem::readRandomCharacters(40))
->save();
$panel = new AphrontPanelView();
$panel->setHeader('Certificate Install Token');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild(
'<p class="aphront-form-instructions">Copy and paste this token into '.
'the prompt given to you by "arc install-certificate":</p>'.
'<p style="padding: 0 0 1em 4em;">'.
'<strong>'.phutil_escape_html($token->getToken()).'</strong>'.
'</p>'.
'<p class="aphront-form-instructions">arc will then complete the '.
'install process for you.</p>');
return $this->buildStandardPageResponse(
$panel,
array(
'title' => 'Certificate Install Token',
));
}
}
diff --git a/src/applications/differential/storage/revision/DifferentialRevision.php b/src/applications/differential/storage/revision/DifferentialRevision.php
index 9ad6e4fb39..e6c12c4ef8 100644
--- a/src/applications/differential/storage/revision/DifferentialRevision.php
+++ b/src/applications/differential/storage/revision/DifferentialRevision.php
@@ -1,189 +1,189 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class DifferentialRevision extends DifferentialDAO {
protected $title;
protected $status;
protected $summary;
protected $testPlan;
protected $phid;
protected $authorPHID;
protected $dateCommitted;
protected $lineCount;
protected $attached = array();
protected $unsubscribed = array();
protected $mailKey;
private $relationships;
private $commits;
const RELATIONSHIP_TABLE = 'differential_relationship';
const TABLE_VIEW_TIME = 'differential_viewtime';
const TABLE_COMMIT = 'differential_commit';
const RELATION_REVIEWER = 'revw';
const RELATION_SUBSCRIBED = 'subd';
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'attached' => self::SERIALIZATION_JSON,
'unsubscribed' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function loadCommitPHIDs() {
if (!$this->getID()) {
return ($this->commits = array());
}
$commits = queryfx_all(
$this->establishConnection('r'),
'SELECT commitPHID FROM %T WHERE revisionID = %d',
self::TABLE_COMMIT,
$this->getID());
$commits = ipull($commits, 'commitPHID');
return ($this->commits = $commits);
}
public function getCommitPHIDs() {
if ($this->commits === null) {
throw new Exception("Must load commits!");
}
return $this->commits;
}
public function getAttachedPHIDs($type) {
return array_keys(idx($this->attached, $type, array()));
}
public function setAttachedPHIDs($type, array $phids) {
$this->attached[$type] = array_fill_keys($phids, array());
return $this;
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_DREV);
}
public function loadDiffs() {
if (!$this->getID()) {
return array();
}
return id(new DifferentialDiff())->loadAllWhere(
'revisionID = %d',
$this->getID());
}
public function loadComments() {
if (!$this->getID()) {
return array();
}
return id(new DifferentialComment())->loadAllWhere(
'revisionID = %d',
$this->getID());
}
public function loadActiveDiff() {
return id(new DifferentialDiff())->loadOneWhere(
'revisionID = %d ORDER BY id DESC LIMIT 1',
$this->getID());
}
public function save() {
if (!$this->getMailKey()) {
- $this->mailKey = sha1(Filesystem::readRandomBytes(20));
+ $this->mailKey = Filesystem::readRandomCharacters(40);
}
return parent::save();
}
public function loadRelationships() {
if (!$this->getID()) {
$this->relationships = array();
return;
}
$data = queryfx_all(
$this->establishConnection('r'),
'SELECT * FROM %T WHERE revisionID = %d ORDER BY sequence',
self::RELATIONSHIP_TABLE,
$this->getID());
return $this->attachRelationships($data);
}
public function attachRelationships(array $relationships) {
$this->relationships = igroup($relationships, 'relation');
return $this;
}
public function getReviewers() {
return $this->getRelatedPHIDs(self::RELATION_REVIEWER);
}
public function getCCPHIDs() {
return $this->getRelatedPHIDs(self::RELATION_SUBSCRIBED);
}
private function getRelatedPHIDs($relation) {
if ($this->relationships === null) {
throw new Exception("Must load relationships!");
}
return ipull($this->getRawRelations($relation), 'objectPHID');
}
public function getRawRelations($relation) {
return idx($this->relationships, $relation, array());
}
public function getUnsubscribedPHIDs() {
return array_keys($this->getUnsubscribed());
}
public function loadReviewedBy() {
$reviewer = null;
if ($this->status == DifferentialRevisionStatus::ACCEPTED ||
$this->status == DifferentialRevisionStatus::COMMITTED) {
$comments = $this->loadComments();
foreach ($comments as $comment) {
$action = $comment->getAction();
if ($action == DifferentialAction::ACTION_ACCEPT) {
$reviewer = $comment->getAuthorPHID();
} else if ($action == DifferentialAction::ACTION_REJECT ||
$action == DifferentialAction::ACTION_ABANDON ||
$action == DifferentialAction::ACTION_RETHINK) {
$reviewer = null;
}
}
}
return $reviewer;
}
}
diff --git a/src/applications/files/engine/s3/PhabricatorS3FileStorageEngine.php b/src/applications/files/engine/s3/PhabricatorS3FileStorageEngine.php
index 41f5fb5abf..d78b50fd19 100644
--- a/src/applications/files/engine/s3/PhabricatorS3FileStorageEngine.php
+++ b/src/applications/files/engine/s3/PhabricatorS3FileStorageEngine.php
@@ -1,134 +1,134 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Amazon S3 file storage engine. This engine scales well but is relatively
* high-latency since data has to be pulled off S3.
*
* @task impl Implementation
* @task internal Internals
* @group filestorage
*/
final class PhabricatorS3FileStorageEngine
extends PhabricatorFileStorageEngine {
/* -( Implementation )----------------------------------------------------- */
/**
* This engine identifies as "amazon-s3".
*
* @task impl
*/
public function getEngineIdentifier() {
return 'amazon-s3';
}
/**
* Write file data into S3.
* @task impl
*/
public function writeFile($data, array $params) {
$s3 = $this->newS3API();
- $name = 'phabricator/'.sha1(Filesystem::readRandomBytes(20));
+ $name = 'phabricator/'.Filesystem::readRandomCharacters(20);
AphrontWriteGuard::willWrite();
$s3->putObject(
$data,
$this->getBucketName(),
$name,
$acl = 'private');
return $name;
}
/**
* Load a stored blob from S3.
* @task impl
*/
public function readFile($handle) {
$result = $this->newS3API()->getObject(
$this->getBucketName(),
$handle);
return $result->body;
}
/**
* Delete a blob from S3.
* @task impl
*/
public function deleteFile($handle) {
AphrontWriteGuard::willWrite();
$this->newS3API()->deleteObject(
$this->getBucketName(),
$handle);
}
/* -( Internals )---------------------------------------------------------- */
/**
* Retrieve the S3 bucket name.
*
* @task internal
*/
private function getBucketName() {
$bucket = PhabricatorEnv::getEnvConfig('storage.s3.bucket');
if (!$bucket) {
throw new Exception("No 'storage.s3.bucket' specified!");
}
return $bucket;
}
/**
* Create a new S3 API object.
*
* @task internal
*/
private function newS3API() {
$libroot = dirname(phutil_get_library_root('phabricator'));
require_once $libroot.'/externals/s3/S3.php';
$access_key = PhabricatorEnv::getEnvConfig('amazon-s3.access-key');
$secret_key = PhabricatorEnv::getEnvConfig('amazon-s3.secret-key');
if (!$access_key || !$secret_key) {
throw new Exception(
"Specify 'amazon-s3.access-key' and 'amazon-s3.secret-key'!");
}
$s3 = newv(
'S3',
array(
$access_key,
$secret_key,
$use_ssl = true,
));
$s3->setExceptions(true);
return $s3;
}
}
diff --git a/src/applications/maniphest/storage/task/ManiphestTask.php b/src/applications/maniphest/storage/task/ManiphestTask.php
index 0064116177..67a110583e 100644
--- a/src/applications/maniphest/storage/task/ManiphestTask.php
+++ b/src/applications/maniphest/storage/task/ManiphestTask.php
@@ -1,148 +1,148 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @group maniphest
*/
class ManiphestTask extends ManiphestDAO {
protected $phid;
protected $authorPHID;
protected $ownerPHID;
protected $ccPHIDs = array();
protected $status;
protected $priority;
protected $title;
protected $description;
protected $originalEmailSource;
protected $mailKey;
protected $attached = array();
protected $projectPHIDs = array();
private $projectsNeedUpdate;
private $subscribersNeedUpdate;
protected $ownerOrdering;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'ccPHIDs' => self::SERIALIZATION_JSON,
'attached' => self::SERIALIZATION_JSON,
'projectPHIDs' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function getAttachedPHIDs($type) {
return array_keys(idx($this->attached, $type, array()));
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_TASK);
}
public function getCCPHIDs() {
return nonempty($this->ccPHIDs, array());
}
public function setProjectPHIDs(array $phids) {
$this->projectPHIDs = $phids;
$this->projectsNeedUpdate = true;
return $this;
}
public function setCCPHIDs(array $phids) {
$this->ccPHIDs = $phids;
$this->subscribersNeedUpdate = true;
return $this;
}
public function setOwnerPHID($phid) {
$this->ownerPHID = $phid;
$this->subscribersNeedUpdate = true;
return $this;
}
public function setAuxiliaryAttribute($key, $val) {
$this->removeAuxiliaryAttribute($key);
$attribute = new ManiphestTaskAuxiliaryStorage();
$attribute->setTaskPHID($this->phid);
$attribute->setName($key);
$attribute->setValue($val);
$attribute->save();
}
public function loadAuxiliaryAttribute($key) {
$attribute = id(new ManiphestTaskAuxiliaryStorage())->loadOneWhere(
'taskPHID = %s AND name = %s',
$this->getPHID(),
$key);
return $attribute;
}
public function removeAuxiliaryAttribute($key) {
$attribute = id(new ManiphestTaskAuxiliaryStorage())->loadOneWhere(
'taskPHID = %s AND name = %s',
$this->getPHID(),
$key);
if ($attribute) {
$attribute->delete();
}
}
public function loadAuxiliaryAttributes() {
$attributes = id(new ManiphestTaskAuxiliaryStorage())->loadAllWhere(
'taskPHID = %s',
$this->getPHID());
return $attributes;
}
public function save() {
if (!$this->mailKey) {
- $this->mailKey = sha1(Filesystem::readRandomBytes(20));
+ $this->mailKey = Filesystem::readRandomCharacters(20);
}
$result = parent::save();
if ($this->projectsNeedUpdate) {
// If we've changed the project PHIDs for this task, update the link
// table.
ManiphestTaskProject::updateTaskProjects($this);
$this->projectsNeedUpdate = false;
}
if ($this->subscribersNeedUpdate) {
// If we've changed the subscriber PHIDs for this task, update the link
// table.
ManiphestTaskSubscriber::updateTaskSubscribers($this);
$this->subscribersNeedUpdate = false;
}
return $result;
}
}
diff --git a/src/applications/people/storage/user/PhabricatorUser.php b/src/applications/people/storage/user/PhabricatorUser.php
index f63690034c..008b2d834c 100644
--- a/src/applications/people/storage/user/PhabricatorUser.php
+++ b/src/applications/people/storage/user/PhabricatorUser.php
@@ -1,356 +1,352 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorUser extends PhabricatorUserDAO {
const SESSION_TABLE = 'phabricator_session';
protected $phid;
protected $userName;
protected $realName;
protected $email;
protected $passwordSalt;
protected $passwordHash;
protected $profileImagePHID;
protected $timezoneIdentifier = '';
protected $consoleEnabled = 0;
protected $consoleVisible = 0;
protected $consoleTab = '';
protected $conduitCertificate;
protected $isSystemAgent = 0;
protected $isAdmin = 0;
protected $isDisabled = 0;
private $preferences = null;
protected function readField($field) {
if ($field === 'profileImagePHID') {
return nonempty(
$this->profileImagePHID,
PhabricatorEnv::getEnvConfig('user.default-profile-image-phid'));
}
if ($field === 'timezoneIdentifier') {
// If the user hasn't set one, guess the server's time.
return nonempty(
$this->timezoneIdentifier,
date_default_timezone_get());
}
return parent::readField($field);
}
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_PARTIAL_OBJECTS => true,
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_USER);
}
public function setPassword($password) {
if (!$this->getPHID()) {
throw new Exception(
"You can not set a password for an unsaved user because their PHID ".
"is a salt component in the password hash.");
}
if (!strlen($password)) {
$this->setPasswordHash('');
} else {
$this->setPasswordSalt(md5(mt_rand()));
$hash = $this->hashPassword($password);
$this->setPasswordHash($hash);
}
return $this;
}
public function save() {
if (!$this->getConduitCertificate()) {
$this->setConduitCertificate($this->generateConduitCertificate());
}
$result = parent::save();
PhabricatorSearchUserIndexer::indexUser($this);
return $result;
}
private function generateConduitCertificate() {
- $entropy = Filesystem::readRandomBytes(256);
- $entropy = base64_encode($entropy);
- $entropy = substr($entropy, 0, 255);
- return $entropy;
+ return Filesystem::readRandomCharacters(255);
}
public function comparePassword($password) {
if (!strlen($password)) {
return false;
}
if (!strlen($this->getPasswordHash())) {
return false;
}
$password = $this->hashPassword($password);
return ($password === $this->getPasswordHash());
}
private function hashPassword($password) {
$password = $this->getUsername().
$password.
$this->getPHID().
$this->getPasswordSalt();
for ($ii = 0; $ii < 1000; $ii++) {
$password = md5($password);
}
return $password;
}
const CSRF_CYCLE_FREQUENCY = 3600;
const CSRF_TOKEN_LENGTH = 16;
const EMAIL_CYCLE_FREQUENCY = 86400;
const EMAIL_TOKEN_LENGTH = 24;
public function getCSRFToken($offset = 0) {
return $this->generateToken(
time() + (self::CSRF_CYCLE_FREQUENCY * $offset),
self::CSRF_CYCLE_FREQUENCY,
PhabricatorEnv::getEnvConfig('phabricator.csrf-key'),
self::CSRF_TOKEN_LENGTH);
}
public function validateCSRFToken($token) {
// When the user posts a form, we check that it contains a valid CSRF token.
// Tokens cycle each hour (every CSRF_CYLCE_FREQUENCY seconds) and we accept
// either the current token, the next token (users can submit a "future"
// token if you have two web frontends that have some clock skew) or any of
// the last 6 tokens. This means that pages are valid for up to 7 hours.
// There is also some Javascript which periodically refreshes the CSRF
// tokens on each page, so theoretically pages should be valid indefinitely.
// However, this code may fail to run (if the user loses their internet
// connection, or there's a JS problem, or they don't have JS enabled).
// Choosing the size of the window in which we accept old CSRF tokens is
// an issue of balancing concerns between security and usability. We could
// choose a very narrow (e.g., 1-hour) window to reduce vulnerability to
// attacks using captured CSRF tokens, but it's also more likely that real
// users will be affected by this, e.g. if they close their laptop for an
// hour, open it back up, and try to submit a form before the CSRF refresh
// can kick in. Since the user experience of submitting a form with expired
// CSRF is often quite bad (you basically lose data, or it's a big pain to
// recover at least) and I believe we gain little additional protection
// by keeping the window very short (the overwhelming value here is in
// preventing blind attacks, and most attacks which can capture CSRF tokens
// can also just capture authentication information [sniffing networks]
// or act as the user [xss]) the 7 hour default seems like a reasonable
// balance. Other major platforms have much longer CSRF token lifetimes,
// like Rails (session duration) and Django (forever), which suggests this
// is a reasonable analysis.
$csrf_window = 6;
for ($ii = -$csrf_window; $ii <= 1; $ii++) {
$valid = $this->getCSRFToken($ii);
if ($token == $valid) {
return true;
}
}
return false;
}
private function generateToken($epoch, $frequency, $key, $len) {
$time_block = floor($epoch / $frequency);
$vec = $this->getPHID().$this->getPasswordHash().$key.$time_block;
return substr(sha1($vec), 0, $len);
}
/**
* Issue a new session key to this user. Phabricator supports different
* types of sessions (like "web" and "conduit") and each session type may
* have multiple concurrent sessions (this allows a user to be logged in on
* multiple browsers at the same time, for instance).
*
* Note that this method is transport-agnostic and does not set cookies or
* issue other types of tokens, it ONLY generates a new session key.
*
* You can configure the maximum number of concurrent sessions for various
* session types in the Phabricator configuration.
*
* @param string Session type, like "web".
* @return string Newly generated session key.
*/
public function establishSession($session_type) {
$conn_w = $this->establishConnection('w');
if (strpos($session_type, '-') !== false) {
throw new Exception("Session type must not contain hyphen ('-')!");
}
// We allow multiple sessions of the same type, so when a caller requests
// a new session of type "web", we give them the first available session in
// "web-1", "web-2", ..., "web-N", up to some configurable limit. If none
// of these sessions is available, we overwrite the oldest session and
// reissue a new one in its place.
$session_limit = 1;
switch ($session_type) {
case 'web':
$session_limit = PhabricatorEnv::getEnvConfig('auth.sessions.web');
break;
case 'conduit':
$session_limit = PhabricatorEnv::getEnvConfig('auth.sessions.conduit');
break;
default:
throw new Exception("Unknown session type '{$session_type}'!");
}
$session_limit = (int)$session_limit;
if ($session_limit <= 0) {
throw new Exception(
"Session limit for '{$session_type}' must be at least 1!");
}
// Load all the currently active sessions.
$sessions = queryfx_all(
$conn_w,
'SELECT type, sessionStart FROM %T WHERE userPHID = %s AND type LIKE %>',
PhabricatorUser::SESSION_TABLE,
$this->getPHID(),
$session_type.'-');
// Choose which 'type' we'll actually establish, i.e. what number we're
// going to append to the basic session type. To do this, just check all
// the numbers sequentially until we find an available session.
$establish_type = null;
$sessions = ipull($sessions, null, 'type');
for ($ii = 1; $ii <= $session_limit; $ii++) {
if (empty($sessions[$session_type.'-'.$ii])) {
$establish_type = $session_type.'-'.$ii;
break;
}
}
// If we didn't find an available session, choose the oldest session and
// overwrite it.
if (!$establish_type) {
$sessions = isort($sessions, 'sessionStart');
$oldest = reset($sessions);
$establish_type = $oldest['type'];
}
// Consume entropy to generate a new session key, forestalling the eventual
// heat death of the universe.
- $entropy = Filesystem::readRandomBytes(20);
- $session_key = sha1($entropy);
+ $session_key = Filesystem::readRandomCharacters(40);
// UNGUARDED WRITES: Logging-in users don't have CSRF stuff yet.
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
queryfx(
$conn_w,
'INSERT INTO %T '.
'(userPHID, type, sessionKey, sessionStart)'.
' VALUES '.
'(%s, %s, %s, UNIX_TIMESTAMP()) '.
'ON DUPLICATE KEY UPDATE '.
'sessionKey = VALUES(sessionKey), '.
'sessionStart = VALUES(sessionStart)',
self::SESSION_TABLE,
$this->getPHID(),
$establish_type,
$session_key);
$log = PhabricatorUserLog::newLog(
$this,
$this,
PhabricatorUserLog::ACTION_LOGIN);
$log->setDetails(
array(
'session_type' => $session_type,
'session_issued' => $establish_type,
));
$log->setSession($session_key);
$log->save();
return $session_key;
}
public function destroySession($session_key) {
$conn_w = $this->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE userPHID = %s AND sessionKey = %s',
self::SESSION_TABLE,
$this->getPHID(),
$session_key);
}
private function generateEmailToken($offset = 0) {
return $this->generateToken(
time() + ($offset * self::EMAIL_CYCLE_FREQUENCY),
self::EMAIL_CYCLE_FREQUENCY,
PhabricatorEnv::getEnvConfig('phabricator.csrf-key').$this->getEmail(),
self::EMAIL_TOKEN_LENGTH);
}
public function validateEmailToken($token) {
for ($ii = -1; $ii <= 1; $ii++) {
$valid = $this->generateEmailToken($ii);
if ($token == $valid) {
return true;
}
}
return false;
}
public function getEmailLoginURI() {
$token = $this->generateEmailToken();
$uri = PhabricatorEnv::getProductionURI('/login/etoken/'.$token.'/');
$uri = new PhutilURI($uri);
return $uri->alter('email', $this->getEmail());
}
public function loadPreferences() {
if ($this->preferences) {
return $this->preferences;
}
$preferences = id(new PhabricatorUserPreferences())->loadOneWhere(
'userPHID = %s',
$this->getPHID());
if (!$preferences) {
$preferences = new PhabricatorUserPreferences();
$preferences->setUserPHID($this->getPHID());
$default_dict = array(
PhabricatorUserPreferences::PREFERENCE_TITLES => 'glyph',
PhabricatorUserPreferences::PREFERENCE_MONOSPACED => '');
$preferences->setPreferences($default_dict);
}
$this->preferences = $preferences;
return $preferences;
}
}
diff --git a/src/applications/phid/storage/phid/PhabricatorPHID.php b/src/applications/phid/storage/phid/PhabricatorPHID.php
index 08053a0d1c..f84e794bcf 100644
--- a/src/applications/phid/storage/phid/PhabricatorPHID.php
+++ b/src/applications/phid/storage/phid/PhabricatorPHID.php
@@ -1,50 +1,47 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorPHID extends PhabricatorPHIDDAO {
protected $phid;
protected $phidType;
protected $ownerPHID;
protected $parentPHID;
public static function generateNewPHID($type, array $config = array()) {
$owner = idx($config, 'owner');
$parent = idx($config, 'parent');
if (!$type) {
throw new Exception("Can not generate PHID with no type.");
}
- $entropy = Filesystem::readRandomBytes(20);
-
- $uniq = sha1($entropy);
- $uniq = substr($uniq, 0, 20);
+ $uniq = Filesystem::readRandomCharacters(20);
$phid = 'PHID-'.$type.'-'.$uniq;
$phid_rec = new PhabricatorPHID();
$phid_rec->setPHIDType($type);
$phid_rec->setOwnerPHID($owner);
$phid_rec->setParentPHID($parent);
$phid_rec->setPHID($phid);
$phid_rec->save();
return $phid;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jul 29, 4:53 AM (2 w, 4 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
188000
Default Alt Text
(29 KB)

Event Timeline