Page MenuHomePhorge

No OneTemporary

diff --git a/conf/default.conf.php b/conf/default.conf.php
index a5bb05d2fa..cf02b03b6a 100644
--- a/conf/default.conf.php
+++ b/conf/default.conf.php
@@ -1,46 +1,48 @@
<?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.
*/
return array(
// The root URI which Phabricator is installed on.
// Example: "http://phabricator.example.com/"
'phabricator.base-uri' => null,
//
'phabricator.csrf-key' => '0b7ec0592e0a2829d8b71df2fa269b2c6172eca3',
// -- Facebook ---------------------------------------------------------------
// Can users use Facebook credentials to login to Phabricator?
'facebook.auth-enabled' => false,
// The Facebook "Application ID" to use for Facebook API access.
'facebook.application-id' => null,
// The Facebook "Application Secret" to use for Facebook API access.
'facebook.application-secret' => null,
'recaptcha.public-key' => null,
'recaptcha.private-key' => null,
+ 'user.default-profile-image-phid' => 'PHID-FILE-f57aaefce707fc4060ef',
+
);
diff --git a/src/applications/auth/controller/facebookauth/PhabricatorFacebookAuthController.php b/src/applications/auth/controller/facebookauth/PhabricatorFacebookAuthController.php
index 7f86928722..818e291d21 100644
--- a/src/applications/auth/controller/facebookauth/PhabricatorFacebookAuthController.php
+++ b/src/applications/auth/controller/facebookauth/PhabricatorFacebookAuthController.php
@@ -1,275 +1,293 @@
<?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 PhabricatorFacebookAuthController extends PhabricatorAuthController {
public function shouldRequireLogin() {
return false;
}
public function processRequest() {
$auth_enabled = PhabricatorEnv::getEnvConfig('facebook.auth-enabled');
if (!$auth_enabled) {
return new Aphront400Response();
}
$diagnose_auth =
'<a href="/facebook-auth/diagnose/" class="button green">'.
'Diagnose Facebook Auth Problems'.
'</a>';
$request = $this->getRequest();
if ($request->getStr('error')) {
$view = new AphrontRequestFailureView();
$view->setHeader('Facebook Auth Failed');
$view->appendChild(
'<p>'.
'<strong>Description:</strong> '.
phutil_escape_html($request->getStr('error_description')).
'</p>');
$view->appendChild(
'<p>'.
'<strong>Error:</strong> '.
phutil_escape_html($request->getStr('error')).
'</p>');
$view->appendChild(
'<p>'.
'<strong>Error Reason:</strong> '.
phutil_escape_html($request->getStr('error_reason')).
'</p>');
$view->appendChild(
'<div class="aphront-failure-continue">'.
'<a href="/login/" class="button">Continue</a>'.
'</div>');
return $this->buildStandardPageResponse(
$view,
array(
'title' => 'Facebook Auth Failed',
));
}
$token = $request->getStr('token');
if (!$token) {
$app_id = PhabricatorEnv::getEnvConfig('facebook.application-id');
$app_secret = PhabricatorEnv::getEnvConfig('facebook.application-secret');
$redirect_uri = PhabricatorEnv::getURI('/facebook-auth/');
$code = $request->getStr('code');
$auth_uri = new PhutilURI(
"https://graph.facebook.com/oauth/access_token");
$auth_uri->setQueryParams(
array(
'client_id' => $app_id,
'redirect_uri' => $redirect_uri,
'client_secret' => $app_secret,
'code' => $code,
));
$response = @file_get_contents($auth_uri);
if ($response === false) {
$view = new AphrontRequestFailureView();
$view->setHeader('Facebook Auth Failed');
$view->appendChild(
'<p>Unable to authenticate with Facebook. There are several reasons '.
'this might happen:</p>'.
'<ul>'.
'<li>Phabricator may be configured with the wrong Application '.
'Secret; or</li>'.
'<li>the Facebook OAuth access token may have expired; or</li>'.
'<li>Facebook may have revoked authorization for the '.
'Application; or</li>'.
'<li>Facebook may be having technical problems.</li>'.
'</ul>'.
'<p>You can try again, or login using another method.</p>');
$view->appendChild(
'<div class="aphront-failure-continue">'.
$diagnose_auth.
'<a href="/login/" class="button">Continue</a>'.
'</div>');
return $this->buildStandardPageResponse(
$view,
array(
'title' => 'Facebook Auth Failed',
));
}
$data = array();
parse_str($response, $data);
$token = $data['access_token'];
}
$user_json = @file_get_contents('https://graph.facebook.com/me?access_token='.$token);
$user_data = json_decode($user_json, true);
$user_id = $user_data['id'];
$known_user = id(new PhabricatorUser())
->loadOneWhere('facebookUID = %d', $user_id);
if ($known_user) {
$session_key = $known_user->establishSession('web');
$request->setCookie('phusr', $known_user->getUsername());
$request->setCookie('phsid', $session_key);
return id(new AphrontRedirectResponse())
->setURI('/');
}
+
+ $known_email = id(new PhabricatorUser())
+ ->loadOneWhere('email = %s', $user_data['email']);
+ if ($known_email) {
+ if ($known_email->getFacebookUID()) {
+ throw new Exception(
+ "The email associated with the Facebook account you just logged in ".
+ "with is already associated with another Phabricator account which ".
+ "is, in turn, associated with a Facebook account different from ".
+ "the one you just logged in with.");
+ }
+ $known_email->setFacebookUID($user_id);
+ $session_key = $known_email->establishSession('web');
+ $request->setCookie('phusr', $known_email->getUsername());
+ $request->setCookie('phsid', $session_key);
+ return id(new AphrontRedirectResponse())
+ ->setURI('/');
+ }
$current_user = $this->getRequest()->getUser();
if ($current_user->getPHID()) {
if ($current_user->getFacebookUID() &&
$current_user->getFacebookUID() != $user_id) {
throw new Exception(
"Your account is already associated with a Facebook user ID other ".
"than the one you just logged in with...?");
}
if ($request->isFormPost()) {
$current_user->setFacebookUID($user_id);
$current_user->save();
// TODO: ship them back to the 'account' page or whatever?
return id(new AphrontRedirectResponse())
->setURI('/');
}
$ph_account = $current_user->getUsername();
$fb_account = phutil_escape_html($user_data['name']);
$form = new AphrontFormView();
$form
->addHiddenInput('token', $token)
->setUser($request->getUser())
->setAction('/facebook-auth/')
->appendChild(
'<p class="aphront-form-view-instructions">Do you want to link your '.
"existing Phabricator account (<strong>{$ph_account}</strong>) ".
"with your Facebook account (<strong>{$fb_account}</strong>) so ".
"you can login with Facebook?")
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Link Accounts')
->addCancelButton('/login/'));
$panel = new AphrontPanelView();
$panel->setHeader('Link Facebook Account');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
$panel,
array(
'title' => 'Link Facebook Account',
));
}
$errors = array();
$e_username = true;
$user = new PhabricatorUser();
$matches = null;
if (preg_match('@/([a-zA-Z0-9]+)$@', $user_data['link'], $matches)) {
$user->setUsername($matches[1]);
}
if ($request->isFormPost()) {
$username = $request->getStr('username');
if (!strlen($username)) {
$e_username = 'Required';
$errors[] = 'Username is required.';
} else if (!preg_match('/^[a-zA-Z0-9]+$/', $username, $matches)) {
$e_username = 'Invalid';
$errors[] = 'Username may only contain letters and numbers.';
}
$user->setUsername($username);
$user->setFacebookUID($user_id);
$user->setEmail($user_data['email']);
if (!$errors) {
$image = @file_get_contents('https://graph.facebook.com/me/picture?access_token='.$token);
$file = PhabricatorFile::newFromFileData(
$image,
array(
'name' => 'fbprofile.jpg'
));
$user->setProfileImagePHID($file->getPHID());
$user->setRealName($user_data['name']);
try {
$user->save();
$session_key = $user->establishSession('web');
$request->setCookie('phusr', $user->getUsername());
$request->setCookie('phsid', $session_key);
return id(new AphrontRedirectResponse())->setURI('/');
} catch (AphrontQueryDuplicateKeyException $exception) {
$key = $exception->getDuplicateKey();
if ($key == 'userName') {
$e_username = 'Duplicate';
$errors[] = 'That username is not unique.';
} else {
throw $exception;
}
}
}
}
$error_view = null;
if ($errors) {
$error_view = new AphrontErrorView();
$error_view->setTitle('Facebook Auth Failed');
$error_view->setErrors($errors);
}
$form = new AphrontFormView();
$form
->addHiddenInput('token', $token)
->setUser($request->getUser())
->setAction('/facebook-auth/')
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Username')
->setName('username')
->setValue($user->getUsername())
->setError($e_username))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Create Account'));
$panel = new AphrontPanelView();
$panel->setHeader('Create New Account');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
array(
$error_view,
$panel,
),
array(
'title' => 'Create New Account',
));
}
}
diff --git a/src/applications/auth/controller/login/PhabricatorLoginController.php b/src/applications/auth/controller/login/PhabricatorLoginController.php
index dc871ccb44..774a26d7e9 100644
--- a/src/applications/auth/controller/login/PhabricatorLoginController.php
+++ b/src/applications/auth/controller/login/PhabricatorLoginController.php
@@ -1,134 +1,135 @@
<?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 PhabricatorLoginController extends PhabricatorAuthController {
public function shouldRequireLogin() {
return false;
}
public function processRequest() {
$request = $this->getRequest();
$error = false;
$username = $request->getCookie('phusr');
if ($request->isFormPost()) {
$username = $request->getStr('username');
$user = id(new PhabricatorUser())->loadOneWhere(
'username = %s',
$username);
$okay = false;
if ($user) {
if ($user->comparePassword($request->getStr('password'))) {
$session_key = $user->establishSession('web');
$request->setCookie('phusr', $user->getUsername());
$request->setCookie('phsid', $session_key);
return id(new AphrontRedirectResponse())
->setURI('/');
}
}
if (!$okay) {
$request->clearCookie('phusr');
$request->clearCookie('phsid');
}
$error = true;
}
$error_view = null;
if ($error) {
$error_view = new AphrontErrorView();
$error_view->setTitle('Bad username/password.');
}
$form = new AphrontFormView();
$form
->setUser($request->getUser())
->setAction('/login/')
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Username/Email')
->setName('username')
->setValue($username))
->appendChild(
id(new AphrontFormPasswordControl())
->setLabel('Password')
->setName('password')
->setCaption(
'<a href="/login/email/">Forgot your password? / Email Login</a>'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Login'));
$panel = new AphrontPanelView();
$panel->setHeader('Phabricator Login');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
+// $panel->setCreateButton('Register New Account', '/login/register/');
$panel->appendChild($form);
$fbauth_enabled = PhabricatorEnv::getEnvConfig('facebook.auth-enabled');
if ($fbauth_enabled) {
$auth_uri = new PhutilURI("https://www.facebook.com/dialog/oauth");
$user = $request->getUser();
$redirect_uri = PhabricatorEnv::getURI('/facebook-auth/');
$app_id = PhabricatorEnv::getEnvConfig('facebook.application-id');
// TODO: In theory we should use 'state' to prevent CSRF, but the total
// effect of the CSRF attack is that an attacker can cause a user to login
// to Phabricator if they're already logged into Facebook. This does not
// seem like the most severe threat in the world, and generating CSRF for
// logged-out users is vaugely tricky.
$facebook_auth = new AphrontFormView();
$facebook_auth
->setAction($auth_uri)
->addHiddenInput('client_id', $app_id)
->addHiddenInput('redirect_uri', $redirect_uri)
->addHiddenInput('scope', 'email')
->setUser($request->getUser())
->setMethod('GET')
->appendChild(
'<p class="aphront-form-instructions">Login or register for '.
'Phabricator using your Facebook account.</p>')
->appendChild(
id(new AphrontFormSubmitControl())
->setValue("Login with Facebook \xC2\xBB"));
- $panel->appendChild('<br /><h1>Login with Facebook</h1>');
+ $panel->appendChild('<br /><h1>Login or Register with Facebook</h1>');
$panel->appendChild($facebook_auth);
}
return $this->buildStandardPageResponse(
array(
$error_view,
$panel,
),
array(
'title' => 'Login',
));
}
}
diff --git a/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php b/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php
index 31e07687ff..cb9bab5604 100644
--- a/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php
+++ b/src/applications/differential/view/revisioncomment/DifferentialRevisionCommentView.php
@@ -1,90 +1,96 @@
<?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.
*/
final class DifferentialRevisionCommentView extends AphrontView {
private $comment;
private $handles;
private $markupEngine;
public function setComment($comment) {
$this->comment = $comment;
return $this;
}
public function setHandles(array $handles) {
$this->handles = $handles;
return $this;
}
public function setMarkupEngine($markup_engine) {
$this->markupEngine = $markup_engine;
return $this;
}
public function render() {
require_celerity_resource('phabricator-remarkup-css');
require_celerity_resource('differential-revision-comment-css');
$comment = $this->comment;
$action = $comment->getAction();
$action_class = 'differential-comment-action-'.phutil_escape_html($action);
$date = date('F jS, Y g:i:s A', $comment->getDateCreated());
- $author = $comment->getAuthorPHID();
- $author = $this->handles[$author]->renderLink();
+ $author = $this->handles[$comment->getAuthorPHID()];
+ $author_link = $author->renderLink();
$verb = DifferentialAction::getActionPastTenseVerb($comment->getAction());
$verb = phutil_escape_html($verb);
$content = $comment->getContent();
if (strlen(rtrim($content))) {
- $title = "{$author} {$verb} this revision:";
+ $title = "{$author_link} {$verb} this revision:";
$content =
'<div class="phabricator-remarkup">'.
$this->markupEngine->markupText($content).
'</div>';
} else {
$title = null;
$content =
'<div class="differential-comment-nocontent">'.
- "<p>{$author} {$verb} this revision.</p>".
+ "<p>{$author_link} {$verb} this revision.</p>".
'</div>';
}
+
+ $background = null;
+ $uri = $author->getImageURI();
+ if ($uri) {
+ $background = "background-image: url('{$uri}');";
+ }
return
'<div class="differential-comment '.$action_class.'">'.
'<div class="differential-comment-head">'.
'<div class="differential-comment-date">'.$date.'</div>'.
'<div class="differential-comment-title">'.$title.'</div>'.
'</div>'.
- '<div class="differential-comment-body">'.
+ '<div class="differential-comment-body" style="'.$background.'">'.
'<div class="differential-comment-core">'.
'<div class="differential-comment-content">'.
$content.
'</div>'.
'</div>'.
'</div>'.
'</div>';
}
}
diff --git a/src/applications/files/controller/view/PhabricatorFileViewController.php b/src/applications/files/controller/view/PhabricatorFileViewController.php
index 361a7cb98b..38e9b92654 100644
--- a/src/applications/files/controller/view/PhabricatorFileViewController.php
+++ b/src/applications/files/controller/view/PhabricatorFileViewController.php
@@ -1,112 +1,113 @@
<?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 PhabricatorFileViewController extends PhabricatorFileController {
private $phid;
private $view;
public function willProcessRequest(array $data) {
$this->phid = $data['phid'];
$this->view = $data['view'];
}
public function processRequest() {
$file = id(new PhabricatorFile())->loadOneWhere(
'phid = %s',
$this->phid);
if (!$file) {
return new Aphront404Response();
}
switch ($this->view) {
case 'download':
case 'view':
$data = $file->loadFileData();
$response = new AphrontFileResponse();
$response->setContent($data);
$response->setMimeType($file->getMimeType());
if ($this->view == 'download') {
$response->setDownload($file->getName());
}
return $response;
default:
break;
}
$form = new AphrontFormView();
$form->setAction('/file/view/'.$file->getPHID().'/');
+ $form->setUser($this->getRequest()->getUser());
$form
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Name')
->setName('name')
->setValue($file->getName()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('PHID')
->setName('phid')
->setValue($file->getPHID()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Created')
->setName('created')
->setValue(date('Y-m-d g:i:s A', $file->getDateCreated())))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Mime Type')
->setName('mime')
->setValue($file->getMimeType()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Size')
->setName('size')
->setValue($file->getByteSize().' bytes'))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Engine')
->setName('storageEngine')
->setValue($file->getStorageEngine()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Format')
->setName('storageFormat')
->setValue($file->getStorageFormat()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Handle')
->setName('storageHandle')
->setValue($file->getStorageHandle()))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('View File'));
$panel = new AphrontPanelView();
$panel->setHeader('File Info - '.$file->getName());
$panel->appendChild($form);
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
return $this->buildStandardPageResponse(
array($panel),
array(
'title' => 'File Info - '.$file->getName(),
));
}
}
diff --git a/src/applications/people/storage/user/PhabricatorUser.php b/src/applications/people/storage/user/PhabricatorUser.php
index abef89f7a4..a8180333c1 100644
--- a/src/applications/people/storage/user/PhabricatorUser.php
+++ b/src/applications/people/storage/user/PhabricatorUser.php
@@ -1,145 +1,151 @@
<?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 PHID_TYPE = 'USER';
protected $phid;
protected $userName;
protected $realName;
protected $email;
protected $passwordSalt;
protected $passwordHash;
protected $facebookUID;
protected $profileImagePHID;
private $sessionKey;
+
+ public function getProfileImagePHID() {
+ return nonempty(
+ $this->profileImagePHID,
+ PhabricatorEnv::getEnvConfig('user.default-profile-image-phid'));
+ }
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(self::PHID_TYPE);
}
public function setPassword($password) {
$this->setPasswordSalt(md5(mt_rand()));
$hash = $this->hashPassword($password);
$this->setPasswordHash($hash);
return $this;
}
public function comparePassword($password) {
$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) {
for ($ii = -1; $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->passwordHash.$key.$time_block;
return substr(sha1($vec), 0, $len);
}
public function establishSession($session_type) {
$conn_w = $this->establishConnection('w');
$urandom = fopen('/dev/urandom', 'r');
if (!$urandom) {
throw new Exception("Failed to open /dev/urandom!");
}
$entropy = fread($urandom, 20);
if (strlen($entropy) != 20) {
throw new Exception("Failed to read /dev/urandom!");
}
$session_key = sha1($entropy);
queryfx(
$conn_w,
'INSERT INTO phabricator_session '.
'(userPHID, type, sessionKey, sessionStart)'.
' VALUES '.
'(%s, %s, %s, UNIX_TIMESTAMP()) '.
'ON DUPLICATE KEY UPDATE '.
'sessionKey = VALUES(sessionKey), '.
'sessionStart = VALUES(sessionStart)',
$this->getPHID(),
$session_type,
$session_key);
return $session_key;
}
public 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;
}
}
diff --git a/src/applications/phid/handle/PhabricatorObjectHandle.php b/src/applications/phid/handle/PhabricatorObjectHandle.php
index 5ef9dd861e..bd50f48a4a 100644
--- a/src/applications/phid/handle/PhabricatorObjectHandle.php
+++ b/src/applications/phid/handle/PhabricatorObjectHandle.php
@@ -1,81 +1,91 @@
<?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 PhabricatorObjectHandle {
private $uri;
private $phid;
private $type;
private $name;
private $email;
+ private $imageURI;
public function setURI($uri) {
$this->uri = $uri;
return $this;
}
public function getURI() {
return $this->uri;
}
public function setPHID($phid) {
$this->phid = $phid;
return $this;
}
public function getPHID() {
return $this->phid;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function getName() {
return $this->name;
}
public function setType($type) {
$this->type = $type;
return $this;
}
public function getType() {
return $this->type;
}
public function setEmail($email) {
$this->email = $email;
return $this;
}
public function getEmail() {
return $this->email;
}
+
+ public function setImageURI($uri) {
+ $this->imageURI = $uri;
+ return $this;
+ }
+
+ public function getImageURI() {
+ return $this->imageURI;
+ }
public function renderLink() {
return phutil_render_tag(
'a',
array(
'href' => $this->getURI(),
),
phutil_escape_html($this->getName()));
}
}
diff --git a/src/applications/phid/handle/data/PhabricatorObjectHandleData.php b/src/applications/phid/handle/data/PhabricatorObjectHandleData.php
index 49f05781c9..411c93ea9d 100644
--- a/src/applications/phid/handle/data/PhabricatorObjectHandleData.php
+++ b/src/applications/phid/handle/data/PhabricatorObjectHandleData.php
@@ -1,136 +1,142 @@
<?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 PhabricatorObjectHandleData {
const TYPE_UNKNOWN = '????';
private $phids;
public function __construct(array $phids) {
$this->phids = $phids;
}
public function loadHandles() {
$types = array();
foreach ($this->phids as $phid) {
$type = $this->lookupType($phid);
$types[$type][] = $phid;
}
$handles = array();
foreach ($types as $type => $phids) {
switch ($type) {
case 'USER':
$class = 'PhabricatorUser';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$users = $object->loadAllWhere('phid IN (%Ls)', $phids);
$users = mpull($users, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
if (empty($users[$phid])) {
$handle->setType(self::TYPE_UNKNOWN);
$handle->setName('Unknown User');
} else {
$user = $users[$phid];
$handle->setType($type);
$handle->setName($user->getUsername());
$handle->setURI('/p/'.$user->getUsername().'/');
$handle->setEmail($user->getEmail());
+
+ $img_phid = $user->getProfileImagePHID();
+ if ($img_phid) {
+ $handle->setImageURI(
+ PhabricatorFileURI::getViewURIForPHID($img_phid));
+ }
}
$handles[$phid] = $handle;
}
break;
case 'MLST':
$class = 'PhabricatorMetaMTAMailingList';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$lists = $object->loadAllWhere('phid IN (%Ls)', $phids);
$lists = mpull($lists, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
if (empty($lists[$phid])) {
$handle->setType(self::TYPE_UNKNOWN);
$handle->setName('Unknown Mailing List');
} else {
$list = $lists[$phid];
$handle->setType($type);
$handle->setEmail($list->getEmail());
$handle->setName($list->getName());
$handle->setURI($list->getURI());
}
$handles[$phid] = $handle;
}
break;
case 'FILE':
$class = 'PhabricatorFile';
PhutilSymbolLoader::loadClass($class);
$object = newv($class, array());
$files = $object->loadAllWhere('phid IN (%Ls)', $phids);
$files = mpull($files, null, 'getPHID');
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setPHID($phid);
if (empty($files[$phid])) {
$handle->setType(self::TYPE_UNKNOWN);
$handle->setName('Unknown File');
} else {
$file = $files[$phid];
$handle->setType($type);
$handle->setName($file->getName());
$handle->setURI($file->getViewURI());
}
$handles[$phid] = $handle;
}
break;
default:
foreach ($phids as $phid) {
$handle = new PhabricatorObjectHandle();
$handle->setType($type);
$handle->setPHID($phid);
$handle->setName('Unknown Object');
$handles[$phid] = $handle;
}
break;
}
}
return $handles;
}
private function lookupType($phid) {
$matches = null;
if (preg_match('/^PHID-([^-]{4})-/', $phid, $matches)) {
return $matches[1];
}
return self::TYPE_UNKNOWN;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Jan 19 2025, 22:20 (6 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1129331
Default Alt Text
(35 KB)

Event Timeline