From d07934474ee3e18043364ff480f44a77060258e7 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 23 Jul 2012 15:17:59 -0700 Subject: [PATCH] Break AphrontWriteGuard dependency on AphrontRequest Summary: I want to move queryfx() and family to libphutil, for @chad and others (see T1283). We need to break a few dependencies to do this. Since AphrontWriteGuard is independently useful, I broke the dependency between it and AphrontRequest rather than between Connection and WriteGuard. I'll move its implementation to libphutil in a future diff. Test Plan: Loaded site, submitted CSRF form successfully, monkeyed with CSRF token, submitted CSRF form, got error. Reviewers: btrahan, vrana Reviewed By: vrana CC: aran Maniphest Tasks: T1283 Differential Revision: https://secure.phabricator.com/D3042 --- src/aphront/writeguard/AphrontWriteGuard.php | 20 +++++++++++++------- webroot/index.php | 2 +- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/aphront/writeguard/AphrontWriteGuard.php b/src/aphront/writeguard/AphrontWriteGuard.php index e0a61284cf..257318cca1 100644 --- a/src/aphront/writeguard/AphrontWriteGuard.php +++ b/src/aphront/writeguard/AphrontWriteGuard.php @@ -51,7 +51,7 @@ final class AphrontWriteGuard { private static $instance; private static $allowUnguardedWrites = false; - private $request; + private $callback; private $allowDepth = 0; @@ -63,18 +63,23 @@ final class AphrontWriteGuard { * active at a time. You must explicitly call @{method:dispose} when you are * done with a write guard: * - * $guard = new AphrontWriteGuard(); + * $guard = new AphrontWriteGuard($callback); * // ... * $guard->dispose(); * * Normally, you do not need to manage guards yourself -- the Aphront stack * handles it for you. * - * @param AphrontRequest Request to read CSRF token information from. + * This class accepts a callback, which will be invoked when a write is + * attempted. The callback should validate the presence of a CSRF token in + * the request, or abort the request (e.g., by throwing an exception) if a + * valid token isn't present. + * + * @param callable CSRF callback. * @return this * @task manage */ - public function __construct(AphrontRequest $request) { + public function __construct($callback) { if (self::$instance) { throw new Exception( "An AphrontWriteGuard already exists. Dispose of the previous guard ". @@ -86,7 +91,7 @@ final class AphrontWriteGuard { "unguarded writes unconditionally. This is not allowed and indicates ". "a serious error."); } - $this->request = $request; + $this->callback = $callback; self::$instance = $this; } @@ -154,9 +159,8 @@ final class AphrontWriteGuard { } $instance = self::$instance; - if ($instance->allowDepth == 0) { - $instance->request->validateCSRF(); + call_user_func($instance->callback); } } @@ -256,6 +260,8 @@ final class AphrontWriteGuard { /** * When the object is destroyed, make sure @{method:dispose} was called. + * + * @task internal */ public function __destruct() { if (isset(self::$instance)) { diff --git a/webroot/index.php b/webroot/index.php index cfca18e57a..31c0d4d939 100644 --- a/webroot/index.php +++ b/webroot/index.php @@ -145,7 +145,7 @@ $application->setPath($path); $application->willBuildRequest(); $request = $application->buildRequest(); -$write_guard = new AphrontWriteGuard($request); +$write_guard = new AphrontWriteGuard(array($request, 'validateCSRF')); PhabricatorEventEngine::initialize(); $application->setRequest($request);