Browse Source

Update CsrfComponent to use immutable methods.

Use immutable methods in CsrfComponent. This requires changing some
protected method return values, but that is within our BC guidelines.
mark_story 8 years ago
parent
commit
c0d360d4a4

+ 12 - 7
src/Controller/Component/CsrfComponent.php

@@ -86,20 +86,24 @@ class CsrfComponent extends Component
 
         $cookieData = $request->getCookie($cookieName);
         if ($cookieData) {
-            $request->params['_csrfToken'] = $cookieData;
+            $request = $request->withParam('_csrfToken', $cookieData);
         }
 
         if ($request->is('requested')) {
+            $controller->request = $request;
+
             return;
         }
 
         if ($request->is('get') && $cookieData === null) {
-            $this->_setCookie($request, $response);
+            list($request, $response) = $this->_setCookie($request, $response);
+            $controller->response = $response;
         }
         if ($request->is(['put', 'post', 'delete', 'patch']) || $request->getData()) {
             $this->_validateToken($request);
-            unset($request->data[$this->_config['field']]);
+            $request = $request->withoutData($this->_config['field']);
         }
+        $controller->request = $request;
     }
 
     /**
@@ -122,22 +126,23 @@ class CsrfComponent extends Component
      *
      * @param \Cake\Http\ServerRequest $request The request object.
      * @param \Cake\Http\Response $response The response object.
-     * @return void
+     * @return array An array of the modified request, response.
      */
     protected function _setCookie(ServerRequest $request, Response $response)
     {
         $expiry = new Time($this->_config['expiry']);
         $value = hash('sha512', Security::randomBytes(16), false);
 
-        $request->params['_csrfToken'] = $value;
-        $response->cookie([
-            'name' => $this->_config['cookieName'],
+        $request = $request->withParam('_csrfToken', $value);
+        $response = $response->withCookie($this->_config['cookieName'], [
             'value' => $value,
             'expire' => $expiry->format('U'),
             'path' => $request->getAttribute('webroot'),
             'secure' => $this->_config['secure'],
             'httpOnly' => $this->_config['httpOnly'],
         ]);
+
+        return [$request, $response];
     }
 
     /**

+ 4 - 4
tests/TestCase/Controller/Component/CsrfComponentTest.php

@@ -75,13 +75,13 @@ class CsrfComponentTest extends TestCase
         $event = new Event('Controller.startup', $controller);
         $this->component->startup($event);
 
-        $cookie = $controller->response->cookie('csrfToken');
+        $cookie = $controller->response->getCookie('csrfToken');
         $this->assertNotEmpty($cookie, 'Should set a token.');
         $this->assertRegExp('/^[a-f0-9]+$/', $cookie['value'], 'Should look like a hash.');
         $this->assertEquals(0, $cookie['expire'], 'session duration.');
         $this->assertEquals('/dir/', $cookie['path'], 'session path.');
 
-        $this->assertEquals($cookie['value'], $controller->request->params['_csrfToken']);
+        $this->assertEquals($cookie['value'], $controller->request->getParam('_csrfToken'));
     }
 
     /**
@@ -343,8 +343,8 @@ class CsrfComponentTest extends TestCase
         $event = new Event('Controller.startup', $controller);
         $component->startup($event);
 
-        $this->assertEmpty($controller->response->cookie('csrfToken'));
-        $cookie = $controller->response->cookie('token');
+        $this->assertEmpty($controller->response->getCookie('csrfToken'));
+        $cookie = $controller->response->getCookie('token');
         $this->assertNotEmpty($cookie, 'Should set a token.');
         $this->assertRegExp('/^[a-f0-9]+$/', $cookie['value'], 'Should look like a hash.');
         $this->assertWithinRange((new Time('+1 hour'))->format('U'), $cookie['expire'], 1, 'session duration.');