1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-22 13:30:55 +01:00

Authentication

This commit is contained in:
epriestley 2011-01-26 13:21:12 -08:00
parent 336a8b3212
commit ccf7df6093
33 changed files with 421 additions and 16 deletions

View file

@ -18,6 +18,7 @@ phutil_register_library_map(array(
'AphrontDialogResponse' => 'aphront/response/dialog',
'AphrontDialogView' => 'view/dialog',
'AphrontErrorView' => 'view/form/error',
'AphrontException' => 'aphront/exception/base',
'AphrontFileResponse' => 'aphront/response/file',
'AphrontFormCheckboxControl' => 'view/form/control/checkbox',
'AphrontFormControl' => 'view/form/control/base',
@ -41,6 +42,7 @@ phutil_register_library_map(array(
'AphrontQueryObjectMissingException' => 'storage/exception/objectmissing',
'AphrontQueryParameterException' => 'storage/exception/parameter',
'AphrontQueryRecoverableException' => 'storage/exception/recoverable',
'AphrontRedirectException' => 'aphront/exception/redirect',
'AphrontRedirectResponse' => 'aphront/response/redirect',
'AphrontRequest' => 'aphront/request',
'AphrontResponse' => 'aphront/response/base',
@ -84,6 +86,7 @@ phutil_register_library_map(array(
'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus',
'Javelin' => 'infratructure/javelin/api',
'LiskDAO' => 'storage/lisk/dao',
'PhabricatorAuthController' => 'applications/auth/controlller/base',
'PhabricatorConduitAPIController' => 'applications/conduit/controller/api',
'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/connectionlog',
'PhabricatorConduitConsoleController' => 'applications/conduit/controller/console',
@ -112,6 +115,7 @@ phutil_register_library_map(array(
'PhabricatorFileUploadController' => 'applications/files/controller/upload',
'PhabricatorFileViewController' => 'applications/files/controller/view',
'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
'PhabricatorLoginController' => 'applications/auth/controlller/login',
'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite',
'PhabricatorMetaMTAController' => 'applications/metamta/controller/base',
@ -191,6 +195,7 @@ phutil_register_library_map(array(
'AphrontQueryObjectMissingException' => 'AphrontQueryException',
'AphrontQueryParameterException' => 'AphrontQueryException',
'AphrontQueryRecoverableException' => 'AphrontQueryException',
'AphrontRedirectException' => 'AphrontException',
'AphrontRedirectResponse' => 'AphrontResponse',
'AphrontSideNavView' => 'AphrontView',
'AphrontTableView' => 'AphrontView',
@ -215,6 +220,7 @@ phutil_register_library_map(array(
'DifferentialRevision' => 'DifferentialDAO',
'DifferentialRevisionEditController' => 'DifferentialController',
'DifferentialRevisionListController' => 'DifferentialController',
'PhabricatorAuthController' => 'PhabricatorController',
'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
@ -242,6 +248,7 @@ phutil_register_library_map(array(
'PhabricatorFileUploadController' => 'PhabricatorFileController',
'PhabricatorFileViewController' => 'PhabricatorFileController',
'PhabricatorLiskDAO' => 'LiskDAO',
'PhabricatorLoginController' => 'PhabricatorAuthController',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMetaMTAController' => 'PhabricatorController',
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',

View file

@ -23,6 +23,10 @@ abstract class AphrontController {
private $request;
public function willBeginExecution() {
return;
}
public function willProcessRequest(array $uri_data) {
return;
}

View file

@ -103,6 +103,8 @@ class AphrontDefaultApplicationConfiguration
'lists/edit/(?:(?<id>\d+)/)?$'
=> 'PhabricatorMetaMTAMailingListEditController',
),
'/login/' => 'PhabricatorLoginController',
);
}

View file

@ -0,0 +1,21 @@
<?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 AphrontException extends Exception {
}

View file

@ -0,0 +1,10 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_source('AphrontException.php');

View file

@ -0,0 +1,31 @@
<?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 AphrontRedirectException extends AphrontException {
private $uri;
public function __construct($uri) {
$this->uri = $uri;
}
public function getURI() {
return $this->uri;
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/exception/base');
phutil_require_source('AphrontRedirectException.php');

View file

@ -28,6 +28,7 @@ class AphrontRequest {
private $host;
private $path;
private $requestData;
private $user;
final public function __construct($host, $path) {
$this->host = $host;
@ -88,4 +89,37 @@ class AphrontRequest {
return $this->getExists(self::TYPE_FORM) && $this->isHTTPPost();
}
final public function getCookie($name, $default = null) {
return idx($_COOKIE, $name, $default);
}
final public function clearCookie($name) {
$this->setCookie($name, '', time() - (60 * 60 * 24 * 30));
}
final public function setCookie($name, $value, $expire = null) {
if ($expire === null) {
$expire = time() + (60 * 60 * 24 * 365 * 5);
}
setcookie(
$name,
$value,
$expire,
$path = '/',
$domain = '',
$secure = false,
$http_only = true);
}
final public function setUser($user) {
$this->user = $user;
return $this;
}
final public function getUser() {
return $this->user;
}
}

View file

@ -6,5 +6,7 @@
phutil_require_module('phutil', 'utils');
phutil_require_source('AphrontRequest.php');

View file

@ -0,0 +1,33 @@
<?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.
*/
abstract class PhabricatorAuthController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->setApplicationName('Login');
$page->setBaseURI('/login/');
$page->setTitle(idx($data, 'title'));
$page->appendChild($view);
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorAuthController.php');

View file

@ -0,0 +1,122 @@
<?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;
$login_name = $request->getCookie('phu');
if ($request->isFormPost()) {
$login_name = $request->getStr('login');
$user = id(new PhabricatorUser())->loadOneWhere(
'username = %s',
$login_name);
$user->setPassword('asdf');
$user->save();
$okay = false;
if ($user) {
if ($user->comparePassword($request->getStr('password'))) {
$conn_w = $user->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)',
$user->getPHID(),
'web',
$session_key);
$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
->setAction('/login/')
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Login')
->setName('login')
->setValue($login_name))
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Password')
->setName('password'))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Login'));
$panel = new AphrontPanelView();
$panel->setHeader('Phabricator Login');
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->appendChild($form);
return $this->buildStandardPageResponse(
array(
$error_view,
$panel,
),
array(
'title' => 'Login',
));
}
}

View file

@ -0,0 +1,21 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/auth/controlller/base');
phutil_require_module('phabricator', 'applications/people/storage/user');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorLoginController.php');

View file

@ -18,8 +18,48 @@
abstract class PhabricatorController extends AphrontController {
public function shouldRequireLogin() {
return true;
}
final public function willBeginExecution() {
$request = $this->getRequest();
$user = new PhabricatorUser();
$phusr = $request->getCookie('phusr');
$phsid = $request->getCookie('phsid');
if ($phusr && $phsid) {
$info = queryfx_one(
$user->establishConnection('r'),
'SELECT u.* FROM %T u JOIN %T s ON u.phid = s.userPHID
AND s.type = %s AND s.sessionKey = %s',
$user->getTableName(),
'phabricator_session',
'web',
$phsid);
if ($info) {
$user->loadFromArray($info);
}
}
$request->setUser($user);
if ($this->shouldRequireLogin() && !$user->getPHID()) {
throw new AphrontRedirectException('/login/');
}
}
public function buildStandardPageView() {
$view = new PhabricatorStandardPageView();
$view->setRequest($this->getRequest());
return $view;
}
public function buildStandardPageResponse($view) {
$page = new PhabricatorStandardPageView();
$page = $this->buildStandardPageView();
$page->appendChild($view);
$response = new AphrontWebpageResponse();
$response->setContent($page->render());

View file

@ -7,7 +7,10 @@
phutil_require_module('phabricator', 'aphront/controller');
phutil_require_module('phabricator', 'aphront/exception/redirect');
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/people/storage/user');
phutil_require_module('phabricator', 'storage/queryfx');
phutil_require_module('phabricator', 'view/page/standard');

View file

@ -19,7 +19,7 @@
abstract class PhabricatorConduitController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = new PhabricatorStandardPageView();
$page = $this->buildStandardPageView();
$page->setApplicationName('Conduit');
$page->setBaseURI('/conduit/');

View file

@ -8,7 +8,6 @@
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phabricator', 'view/page/standard');
phutil_require_module('phutil', 'utils');

View file

@ -22,7 +22,7 @@ abstract class DifferentialController extends PhabricatorController {
require_celerity_resource('differential-core-view-css');
$page = new PhabricatorStandardPageView();
$page = $this->buildStandardPageView();
$page->setApplicationName('Differential');
$page->setBaseURI('/differential/');

View file

@ -9,7 +9,6 @@
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phabricator', 'infratructure/celerity/api');
phutil_require_module('phabricator', 'view/page/standard');
phutil_require_module('phutil', 'utils');

View file

@ -19,7 +19,7 @@
abstract class PhabricatorDirectoryController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = new PhabricatorStandardPageView();
$page = $this->buildStandardPageView();
$page->setApplicationName('Directory');
$page->setBaseURI('/');

View file

@ -8,7 +8,6 @@
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phabricator', 'view/page/standard');
phutil_require_module('phutil', 'utils');

View file

@ -19,7 +19,7 @@
abstract class PhabricatorFileController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = new PhabricatorStandardPageView();
$page = $this->buildStandardPageView();
$page->setApplicationName('Files');
$page->setBaseURI('/file/');

View file

@ -8,7 +8,6 @@
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phabricator', 'view/page/standard');
phutil_require_module('phutil', 'utils');

View file

@ -19,7 +19,7 @@
abstract class PhabricatorMetaMTAController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = new PhabricatorStandardPageView();
$page = $this->buildStandardPageView();
$page->setApplicationName('MetaMTA');
$page->setBaseURI('/mail/');

View file

@ -8,7 +8,6 @@
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phabricator', 'view/page/standard');
phutil_require_module('phutil', 'utils');

View file

@ -19,7 +19,7 @@
abstract class PhabricatorPeopleController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = new PhabricatorStandardPageView();
$page = $this->buildStandardPageView();
$page->setApplicationName('People');
$page->setBaseURI('/people/');

View file

@ -8,7 +8,6 @@
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phabricator', 'view/page/standard');
phutil_require_module('phutil', 'utils');

View file

@ -24,6 +24,8 @@ class PhabricatorUser extends PhabricatorUserDAO {
protected $userName;
protected $realName;
protected $email;
protected $passwordSalt;
protected $passwordHash;
public function getConfiguration() {
return array(
@ -35,4 +37,27 @@ class PhabricatorUser extends PhabricatorUserDAO {
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;
}
}

View file

@ -19,7 +19,7 @@
abstract class PhabricatorPHIDController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = new PhabricatorStandardPageView();
$page = $this->buildStandardPageView();
$page->setApplicationName('PHID');
$page->setBaseURI('/phid/');

View file

@ -8,7 +8,6 @@
phutil_require_module('phabricator', 'aphront/response/webpage');
phutil_require_module('phabricator', 'applications/base/controller/base');
phutil_require_module('phabricator', 'view/page/standard');
phutil_require_module('phutil', 'utils');

View file

@ -24,6 +24,16 @@ class PhabricatorStandardPageView extends AphrontPageView {
private $selectedTab;
private $glyph;
private $bodyContent;
private $request;
public function setRequest($request) {
$this->request = $request;
return $this;
}
public function getRequest() {
return $this->request;
}
public function setApplicationName($application_name) {
$this->applicationName = $application_name;
@ -102,9 +112,20 @@ class PhabricatorStandardPageView extends AphrontPageView {
$tabs = '<span class="phabricator-head-tabs">'.$tabs.'</span>';
}
$login_stuff = null;
$request = $this->getRequest();
$user = $request->getUser();
if ($user->getPHID()) {
$login_stuff = 'Logged in as '.phutil_escape_html($user->getUsername());
}
return
'<div class="phabricator-standard-page">'.
'<div class="phabricator-standard-header">'.
'<div class="phabricator-login-details">'.
$login_stuff.
'</div>'.
'<a href="/">Phabricator</a> '.
phutil_render_tag(
'a',

View file

@ -38,9 +38,14 @@ $application->setPath($path);
$request = $application->buildRequest();
$application->setRequest($request);
list($controller, $uri_data) = $application->buildController();
$controller->willProcessRequest($uri_data);
try {
$controller->willBeginExecution();
$controller->willProcessRequest($uri_data);
$response = $controller->processRequest();
} catch (AphrontRedirectException $ex) {
$response = id(new AphrontRedirectResponse())
->setURI($ex->getURI());
} catch (Exception $ex) {
$response = $application->handleException($ex);
}

View file

@ -46,3 +46,7 @@
padding: 0 1em;
text-transform: uppercase;
}
.phabricator-login-details {
float: right;
}