1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-22 23:02:42 +01:00

CSRF / Logout

This commit is contained in:
epriestley 2011-01-30 18:52:29 -08:00
parent 58d1506499
commit 29f7219a49
26 changed files with 152 additions and 7 deletions

View file

@ -137,6 +137,7 @@ phutil_register_library_map(array(
'PhabricatorFileViewController' => 'applications/files/controller/view', 'PhabricatorFileViewController' => 'applications/files/controller/view',
'PhabricatorLiskDAO' => 'applications/base/storage/lisk', 'PhabricatorLiskDAO' => 'applications/base/storage/lisk',
'PhabricatorLoginController' => 'applications/auth/controlller/login', 'PhabricatorLoginController' => 'applications/auth/controlller/login',
'PhabricatorLogoutController' => 'applications/auth/controlller/logout',
'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base', 'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/base',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite', 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/phpmailerlite',
'PhabricatorMetaMTAController' => 'applications/metamta/controller/base', 'PhabricatorMetaMTAController' => 'applications/metamta/controller/base',
@ -290,6 +291,7 @@ phutil_register_library_map(array(
'PhabricatorFileViewController' => 'PhabricatorFileController', 'PhabricatorFileViewController' => 'PhabricatorFileController',
'PhabricatorLiskDAO' => 'LiskDAO', 'PhabricatorLiskDAO' => 'LiskDAO',
'PhabricatorLoginController' => 'PhabricatorAuthController', 'PhabricatorLoginController' => 'PhabricatorAuthController',
'PhabricatorLogoutController' => 'PhabricatorAuthController',
'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter', 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
'PhabricatorMetaMTAController' => 'PhabricatorController', 'PhabricatorMetaMTAController' => 'PhabricatorController',
'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO', 'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',

View file

@ -116,6 +116,7 @@ class AphrontDefaultApplicationConfiguration
), ),
'/login/' => 'PhabricatorLoginController', '/login/' => 'PhabricatorLoginController',
'/logout/' => 'PhabricatorLogoutController',
); );
} }

View file

@ -86,7 +86,9 @@ class AphrontRequest {
} }
final public function isFormPost() { final public function isFormPost() {
return $this->getExists(self::TYPE_FORM) && $this->isHTTPPost(); return $this->getExists(self::TYPE_FORM) &&
$this->isHTTPPost() &&
$this->getUser()->validateCSRFToken($this->getStr('__csrf__'));
} }
final public function getCookie($name, $default = null) { final public function getCookie($name, $default = null) {

View file

@ -26,7 +26,7 @@ class PhabricatorLoginController extends PhabricatorAuthController {
$request = $this->getRequest(); $request = $this->getRequest();
$error = false; $error = false;
$login_name = $request->getCookie('phu'); $login_name = $request->getCookie('phusr');
if ($request->isFormPost()) { if ($request->isFormPost()) {
$login_name = $request->getStr('login'); $login_name = $request->getStr('login');
@ -89,6 +89,7 @@ class PhabricatorLoginController extends PhabricatorAuthController {
$form = new AphrontFormView(); $form = new AphrontFormView();
$form $form
->setUser($request->getUser())
->setAction('/login/') ->setAction('/login/')
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())

View file

@ -0,0 +1,37 @@
<?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 PhabricatorLogoutController extends PhabricatorAuthController {
public function shouldRequireLogin() {
return true;
}
public function processRequest() {
$request = $this->getRequest();
if ($request->isFormPost()) {
$request->clearCookie('phsid');
return id(new AphrontRedirectResponse())
->setURI('/login/');
}
return id(new AphrontRedirectResponse())->setURI('/');
}
}

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/redirect');
phutil_require_module('phabricator', 'applications/auth/controlller/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorLogoutController.php');

View file

@ -26,6 +26,9 @@ class PhabricatorConduitConsoleController
} }
public function processRequest() { public function processRequest() {
$request = $this->getRequest();
$methods = $this->getAllMethods(); $methods = $this->getAllMethods();
if (empty($methods[$this->method])) { if (empty($methods[$this->method])) {
$this->method = key($methods); $this->method = key($methods);
@ -55,6 +58,7 @@ class PhabricatorConduitConsoleController
$form = new AphrontFormView(); $form = new AphrontFormView();
$form $form
->setUser($request->getUser())
->setAction('/api/'.$this->method) ->setAction('/api/'.$this->method)
->appendChild( ->appendChild(
id(new AphrontFormStaticControl()) id(new AphrontFormStaticControl())

View file

@ -25,6 +25,8 @@ class DifferentialDiffViewController extends DifferentialController {
} }
public function processRequest() { public function processRequest() {
$request = $this->getRequest();
$diff = id(new DifferentialDiff())->load($this->id); $diff = id(new DifferentialDiff())->load($this->id);
if (!$diff) { if (!$diff) {
return new Aphront404Response(); return new Aphront404Response();
@ -40,6 +42,7 @@ class DifferentialDiffViewController extends DifferentialController {
$action_form = new AphrontFormView(); $action_form = new AphrontFormView();
$action_form $action_form
->setUser($request->getUser())
->setAction('/differential/revision/edit/') ->setAction('/differential/revision/edit/')
->addHiddenInput('diffID', $diff->getID()) ->addHiddenInput('diffID', $diff->getID())
->addHiddenInput('viaDiffView', 1) ->addHiddenInput('viaDiffView', 1)

View file

@ -100,6 +100,7 @@ class DifferentialRevisionEditController extends DifferentialController {
} }
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setUser($request->getUser());
if ($diff) { if ($diff) {
$form->addHiddenInput('diffID', $diff->getID()); $form->addHiddenInput('diffID', $diff->getID());
} }

View file

@ -84,6 +84,7 @@ class DifferentialRevisionViewController extends DifferentialController {
$comment_form->setRevision($revision); $comment_form->setRevision($revision);
$comment_form->setActions($this->getRevisionCommentActions($revision)); $comment_form->setActions($this->getRevisionCommentActions($revision));
$comment_form->setActionURI('/differential/comment/save/'); $comment_form->setActionURI('/differential/comment/save/');
$comment_form->setUser($request->getUser());
return $this->buildStandardPageResponse( return $this->buildStandardPageResponse(
'<div class="differential-primary-pane">'. '<div class="differential-primary-pane">'.

View file

@ -21,6 +21,7 @@ final class DifferentialAddCommentView extends AphrontView {
private $revision; private $revision;
private $actions; private $actions;
private $actionURI; private $actionURI;
private $user;
public function setRevision($revision) { public function setRevision($revision) {
$this->revision = $revision; $this->revision = $revision;
@ -36,8 +37,11 @@ final class DifferentialAddCommentView extends AphrontView {
$this->actionURI = $uri; $this->actionURI = $uri;
} }
public function render() { public function setUser(PhabricatorUser $user) {
$this->user = $user;
}
public function render() {
$revision = $this->revision; $revision = $this->revision;
$actions = array(); $actions = array();
@ -47,6 +51,7 @@ final class DifferentialAddCommentView extends AphrontView {
$form = new AphrontFormView(); $form = new AphrontFormView();
$form $form
->setUser($this->user)
->setAction($this->actionURI) ->setAction($this->actionURI)
->addHiddenInput('revision_id', $revision->getID()) ->addHiddenInput('revision_id', $revision->getID())
->appendChild( ->appendChild(

View file

@ -64,6 +64,7 @@ class PhabricatorDirectoryCategoryEditController
} }
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setUser($request->getUser());
if ($category->getID()) { if ($category->getID()) {
$form->setAction('/directory/category/edit/'.$category->getID().'/'); $form->setAction('/directory/category/edit/'.$category->getID().'/');
} else { } else {

View file

@ -73,6 +73,8 @@ class PhabricatorDirectoryItemEditController
} }
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setUser($request->getUser());
if ($item->getID()) { if ($item->getID()) {
$form->setAction('/directory/item/edit/'.$item->getID().'/'); $form->setAction('/directory/item/edit/'.$item->getID().'/');
} else { } else {

View file

@ -34,6 +34,7 @@ class PhabricatorFileUploadController extends PhabricatorFileController {
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setAction('/file/upload/'); $form->setAction('/file/upload/');
$form->setUser($request->getUser());
$form $form
->setEncType('multipart/form-data') ->setEncType('multipart/form-data')

View file

@ -65,6 +65,7 @@ class PhabricatorMetaMTAMailingListEditController
} }
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setUser($request->getUser());
if ($list->getID()) { if ($list->getID()) {
$form->setAction('/mail/lists/edit/'.$list->getID().'/'); $form->setAction('/mail/lists/edit/'.$list->getID().'/');
} else { } else {

View file

@ -49,6 +49,7 @@ class PhabricatorMetaMTASendController extends PhabricatorMetaMTAController {
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setUser($request->getUser());
$form->setAction('/mail/send/'); $form->setAction('/mail/send/');
$form $form
->appendChild( ->appendChild(

View file

@ -26,6 +26,8 @@ class PhabricatorMetaMTAViewController extends PhabricatorMetaMTAController {
public function processRequest() { public function processRequest() {
$request = $this->getRequest();
$mail = id(new PhabricatorMetaMTAMail())->load($this->id); $mail = id(new PhabricatorMetaMTAMail())->load($this->id);
if (!$mail) { if (!$mail) {
return new Aphront404Response(); return new Aphront404Response();
@ -34,6 +36,7 @@ class PhabricatorMetaMTAViewController extends PhabricatorMetaMTAController {
$status = PhabricatorMetaMTAMail::getReadableStatus($mail->getStatus()); $status = PhabricatorMetaMTAMail::getReadableStatus($mail->getStatus());
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setUser($request->getUser());
$form->setAction('/mail/send/'); $form->setAction('/mail/send/');
$form $form
->appendChild( ->appendChild(

View file

@ -84,6 +84,7 @@ class PhabricatorPeopleEditController extends PhabricatorPeopleController {
} }
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setUser($request->getUser());
if ($user->getUsername()) { if ($user->getUsername()) {
$form->setAction('/people/edit/'.$user->getUsername().'/'); $form->setAction('/people/edit/'.$user->getUsername().'/');
} else { } else {

View file

@ -27,6 +27,8 @@ class PhabricatorUser extends PhabricatorUserDAO {
protected $passwordSalt; protected $passwordSalt;
protected $passwordHash; protected $passwordHash;
private $sessionKey;
public function getConfiguration() { public function getConfiguration() {
return array( return array(
self::CONFIG_AUX_PHID => true, self::CONFIG_AUX_PHID => true,
@ -60,4 +62,29 @@ class PhabricatorUser extends PhabricatorUserDAO {
return $password; return $password;
} }
const CSRF_CYCLE_FREQUENCY = 3600;
public function getCSRFToken() {
return $this->generateCSRFToken(time());
}
public function validateCSRFToken($token) {
for ($ii = -1; $ii <= 1; $ii++) {
$time = time() + (self::CSRF_CYCLE_FREQUENCY * $ii);
$valid = $this->generateCSRFToken($time);
if ($token == $valid) {
return true;
}
}
return false;
}
private function generateCSRFToken($epoch) {
$time_block = floor($epoch / (60 * 60));
// TODO: this should be a secret lolol
$key = '0b7ec0592e0a2829d8b71df2fa269b2c6172eca3';
$vec = $this->getPHID().$this->passwordHash.$key.$time_block;
return substr(md5($vec), 0, 16);
}
} }

View file

@ -39,6 +39,7 @@ class PhabricatorPHIDAllocateController
asort($options); asort($options);
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setUser($request->getUser());
$form->setAction('/phid/new/'); $form->setAction('/phid/new/');
$form $form

View file

@ -14,6 +14,7 @@ phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit'); phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/layout/panel'); phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils'); phutil_require_module('phutil', 'utils');

View file

@ -82,6 +82,7 @@ class PhabricatorPHIDLookupController
} }
$lookup_form = new AphrontFormView(); $lookup_form = new AphrontFormView();
$lookup_form->setUser($request->getUser());
$lookup_form $lookup_form
->setAction('/phid/') ->setAction('/phid/')
->appendChild( ->appendChild(

View file

@ -73,6 +73,8 @@ class PhabricatorPHIDTypeEditController
} }
$form = new AphrontFormView(); $form = new AphrontFormView();
$form->setUser($request->getUser());
if ($type->getID()) { if ($type->getID()) {
$form->setAction('/phid/type/edit/'.$type->getID().'/'); $form->setAction('/phid/type/edit/'.$type->getID().'/');
} else { } else {
@ -85,6 +87,7 @@ class PhabricatorPHIDTypeEditController
$type_immutable = false; $type_immutable = false;
} }
$form $form
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())

View file

@ -23,6 +23,12 @@ final class AphrontFormView extends AphrontView {
private $header; private $header;
private $data = array(); private $data = array();
private $encType; private $encType;
private $user;
public function setUser(PhabricatorUser $user) {
$this->user = $user;
return $this;
}
public function setAction($action) { public function setAction($action) {
$this->action = $action; $this->action = $action;
@ -59,8 +65,13 @@ final class AphrontFormView extends AphrontView {
} }
private function renderDataInputs() { private function renderDataInputs() {
if (!$this->user) {
throw new Exception('You must pass the user to AphrontFormView.');
}
$data = $this->data + array( $data = $this->data + array(
'__form__' => 1, '__form__' => 1,
'__csrf__' => $this->user->getCSRFToken(),
); );
$inputs = array(); $inputs = array();
foreach ($data as $key => $value) { foreach ($data as $key => $value) {

View file

@ -117,7 +117,26 @@ class PhabricatorStandardPageView extends AphrontPageView {
if ($request) { if ($request) {
$user = $request->getUser(); $user = $request->getUser();
if ($user->getPHID()) { if ($user->getPHID()) {
$login_stuff = 'Logged in as '.phutil_escape_html($user->getUsername()); $login_stuff =
'Logged in as '.phutil_escape_html($user->getUsername()).
' &middot; '.
'<form action="/logout/" method="post" style="display: inline;">'.
phutil_render_tag(
'input',
array(
'type' => 'hidden',
'name' => '__csrf__',
'value' => $user->getCSRFToken(),
)).
phutil_render_tag(
'input',
array(
'type' => 'hidden',
'name' => '__form__',
'value' => true,
)).
'<button class="small grey">Logout</button>'.
'</form>';
} }
} }