Browse Source

Fix autoPostRedirect()

Mark Scherer 9 years ago
parent
commit
41f71c6d31

+ 8 - 7
src/Controller/Component/CommonComponent.php

@@ -155,10 +155,10 @@ class CommonComponent extends Component {
 	 *
 	 *
 	 * @param mixed $whereTo URL
 	 * @param mixed $whereTo URL
 	 * @param bool $allowSelf if redirect to the same controller/action (url) is allowed
 	 * @param bool $allowSelf if redirect to the same controller/action (url) is allowed
-	 * @param int|null $status
+	 * @param int $status
 	 * @return \Cake\Network\Response
 	 * @return \Cake\Network\Response
 	 */
 	 */
-	public function autoRedirect($whereTo, $allowSelf = false, $status = null) {
+	public function autoRedirect($whereTo, $allowSelf = false, $status = 302) {
 		if ($allowSelf || $this->Controller->referer(null, true) !== '/' . $this->Controller->request->url) {
 		if ($allowSelf || $this->Controller->referer(null, true) !== '/' . $this->Controller->request->url) {
 			return $this->Controller->redirect($this->Controller->referer($whereTo, true), $status);
 			return $this->Controller->redirect($this->Controller->referer($whereTo, true), $status);
 		}
 		}
@@ -200,7 +200,7 @@ class CommonComponent extends Component {
 			$referer = Router::parse($referer);
 			$referer = Router::parse($referer);
 		}
 		}
 
 
-		if (!$conditionalAutoRedirect || empty($this->Controller->autoRedirectActions) || is_array($referer) && !empty($referer['action'])) {
+		if ($conditionalAutoRedirect && !empty($this->Controller->autoRedirectActions) && is_array($referer) && !empty($referer['action'])) {
 			// Be sure that controller offset exists, otherwise you
 			// Be sure that controller offset exists, otherwise you
 			// will run into problems, if you use url rewriting.
 			// will run into problems, if you use url rewriting.
 			$refererController = null;
 			$refererController = null;
@@ -211,12 +211,13 @@ class CommonComponent extends Component {
 			if (!isset($this->Controller->autoRedirectActions)) {
 			if (!isset($this->Controller->autoRedirectActions)) {
 				$this->Controller->autoRedirectActions = [];
 				$this->Controller->autoRedirectActions = [];
 			}
 			}
+
 			foreach ($this->Controller->autoRedirectActions as $action) {
 			foreach ($this->Controller->autoRedirectActions as $action) {
 				list($controller, $action) = pluginSplit($action);
 				list($controller, $action) = pluginSplit($action);
-				if (!empty($controller) && $refererController !== '*' && $refererController != $controller) {
+				if (!empty($controller) && $refererController !== '*' && $refererController !== $controller) {
 					continue;
 					continue;
 				}
 				}
-				if (empty($controller) && $refererController != $this->Controller->request->params['controller']) {
+				if (empty($controller) && $refererController !== $this->Controller->request->params['controller']) {
 					continue;
 					continue;
 				}
 				}
 				if (!in_array($referer['action'], $this->Controller->autoRedirectActions, true)) {
 				if (!in_array($referer['action'], $this->Controller->autoRedirectActions, true)) {
@@ -229,7 +230,7 @@ class CommonComponent extends Component {
 	}
 	}
 
 
 	/**
 	/**
-	 * Automatically add missing url parts of the current url including
+	 * Automatically add missing URL parts of the current URL including
 	 * - querystring (especially for 3.x then)
 	 * - querystring (especially for 3.x then)
 	 * - passed params
 	 * - passed params
 	 *
 	 *
@@ -237,7 +238,7 @@ class CommonComponent extends Component {
 	 * @param int|null $status
 	 * @param int|null $status
 	 * @return \Cake\Network\Response
 	 * @return \Cake\Network\Response
 	 */
 	 */
-	public function completeRedirect($url = null, $status = null) {
+	public function completeRedirect($url = null, $status = 302) {
 		if ($url === null) {
 		if ($url === null) {
 			$url = $this->Controller->request->params;
 			$url = $this->Controller->request->params;
 			unset($url['pass']);
 			unset($url['pass']);

+ 59 - 22
tests/TestCase/Controller/Component/CommonComponentTest.php

@@ -12,17 +12,25 @@ use Tools\TestSuite\TestCase;
  */
  */
 class CommonComponentTest extends TestCase {
 class CommonComponentTest extends TestCase {
 
 
-	//public $fixtures = array('core.sessions', 'plugin.tools.tools_users', 'plugin.tools.roles');
-
+	/**
+	 * @return void
+	 */
 	public function setUp() {
 	public function setUp() {
 		parent::setUp();
 		parent::setUp();
 
 
 		Configure::write('App.namespace', 'TestApp');
 		Configure::write('App.namespace', 'TestApp');
+		Configure::write('App.fullBaseUrl', 'http://localhost');
 
 
-		$this->Controller = new CommonComponentTestController(new Request('/test'));
+		$this->request = new Request('/my_controller/foo');
+		$this->request->params['controller'] = 'MyController';
+		$this->request->params['action'] = 'foo';
+		$this->Controller = new CommonComponentTestController($this->request);
 		$this->Controller->startupProcess();
 		$this->Controller->startupProcess();
 	}
 	}
 
 
+	/**
+	 * @return void
+	 */
 	public function tearDown() {
 	public function tearDown() {
 		parent::tearDown();
 		parent::tearDown();
 
 
@@ -31,8 +39,6 @@ class CommonComponentTest extends TestCase {
 	}
 	}
 
 
 	/**
 	/**
-	 * CommonComponentTest::testLoadComponent()
-	 *
 	 * @return void
 	 * @return void
 	 */
 	 */
 	public function testLoadComponent() {
 	public function testLoadComponent() {
@@ -70,8 +76,6 @@ class CommonComponentTest extends TestCase {
 	}
 	}
 
 
 	/**
 	/**
-	 * CommonComponentTest::testGetParams()
-	 *
 	 * @return void
 	 * @return void
 	 */
 	 */
 	public function testGetParams() {
 	public function testGetParams() {
@@ -83,8 +87,6 @@ class CommonComponentTest extends TestCase {
 	}
 	}
 
 
 	/**
 	/**
-	 * CommonComponentTest::testGetDefaultUrlParams()
-	 *
 	 * @return void
 	 * @return void
 	 */
 	 */
 	public function testGetDefaultUrlParams() {
 	public function testGetDefaultUrlParams() {
@@ -106,8 +108,6 @@ class CommonComponentTest extends TestCase {
 	}
 	}
 
 
 	/**
 	/**
-	 * CommonComponentTest::testIsForeignReferer()
-	 *
 	 * @return void
 	 * @return void
 	 */
 	 */
 	public function testIsForeignReferer() {
 	public function testIsForeignReferer() {
@@ -125,39 +125,69 @@ class CommonComponentTest extends TestCase {
 	}
 	}
 
 
 	/**
 	/**
-	 * CommonComponentTest::testAutoRedirect()
-	 *
 	 * @return void
 	 * @return void
 	 */
 	 */
 	public function testPostRedirect() {
 	public function testPostRedirect() {
 		$is = $this->Controller->Common->postRedirect(['action' => 'foo']);
 		$is = $this->Controller->Common->postRedirect(['action' => 'foo']);
 		$is = $this->Controller->response->header();
 		$is = $this->Controller->response->header();
-		$this->assertSame('/foo', $is['Location']);
+		$this->assertSame('http://localhost/foo', $is['Location']);
 		$this->assertSame(302, $this->Controller->response->statusCode());
 		$this->assertSame(302, $this->Controller->response->statusCode());
 	}
 	}
 
 
 	/**
 	/**
-	 * CommonComponentTest::testAutoRedirect()
-	 *
 	 * @return void
 	 * @return void
 	 */
 	 */
 	public function testAutoRedirect() {
 	public function testAutoRedirect() {
 		$is = $this->Controller->Common->autoRedirect(['action' => 'foo']);
 		$is = $this->Controller->Common->autoRedirect(['action' => 'foo']);
 		$is = $this->Controller->response->header();
 		$is = $this->Controller->response->header();
-		$this->assertSame('/foo', $is['Location']);
-		$this->assertSame(200, $this->Controller->response->statusCode());
+		$this->assertSame('http://localhost/foo', $is['Location']);
+		$this->assertSame(302, $this->Controller->response->statusCode());
 	}
 	}
 
 
 	/**
 	/**
-	 * CommonComponentTest::testAutoRedirect()
-	 *
 	 * @return void
 	 * @return void
 	 */
 	 */
 	public function testAutoRedirectReferer() {
 	public function testAutoRedirectReferer() {
+		$this->request->env('HTTP_REFERER', 'http://localhost/my_controller/some-referer-action');
+
 		$is = $this->Controller->Common->autoRedirect(['action' => 'foo'], true);
 		$is = $this->Controller->Common->autoRedirect(['action' => 'foo'], true);
 		$is = $this->Controller->response->header();
 		$is = $this->Controller->response->header();
-		$this->assertSame('/foo', $is['Location']);
-		$this->assertSame(200, $this->Controller->response->statusCode());
+		$this->assertSame('http://localhost/my_controller/some-referer-action', $is['Location']);
+		$this->assertSame(302, $this->Controller->response->statusCode());
+	}
+
+	/**
+	 * @return void
+	 */
+	public function testAutoPostRedirect() {
+		$is = $this->Controller->Common->autoPostRedirect(['action' => 'foo'], true);
+		$is = $this->Controller->response->header();
+		$this->assertSame('http://localhost/foo', $is['Location']);
+		$this->assertSame(302, $this->Controller->response->statusCode());
+	}
+
+	/**
+	 * @return void
+	 */
+	public function testAutoPostRedirectReferer() {
+		$this->request->env('HTTP_REFERER', 'http://localhost/my_controller/allowed');
+
+		$is = $this->Controller->Common->autoPostRedirect(['controller' => 'MyController', 'action' => 'foo'], true);
+		$is = $this->Controller->response->header();
+		$this->assertSame('http://localhost/my_controller/allowed', $is['Location']);
+		$this->assertSame(302, $this->Controller->response->statusCode());
+	}
+
+	/**
+	 * @return void
+	 */
+	public function testAutoPostRedirectRefererNotWhitelisted() {
+		$this->request->env('HTTP_REFERER', 'http://localhost/my_controller/wrong');
+
+		$is = $this->Controller->Common->autoPostRedirect(['controller' => 'MyController', 'action' => 'foo'], true);
+		$is = $this->Controller->response->header();
+		$this->assertSame('http://localhost/my_controller/foo', $is['Location']);
+		$this->assertSame(302, $this->Controller->response->statusCode());
 	}
 	}
 
 
 }
 }
@@ -167,9 +197,16 @@ class CommonComponentTest extends TestCase {
  */
  */
 class CommonComponentTestController extends Controller {
 class CommonComponentTestController extends Controller {
 
 
+	public $name = 'MyController';
+
 	/**
 	/**
 	 * @var array
 	 * @var array
 	 */
 	 */
 	public $components = ['Tools.Common'];
 	public $components = ['Tools.Common'];
 
 
+	/**
+	 * @var array
+	 */
+	public $autoRedirectActions = ['allowed'];
+
 }
 }