Browse Source

Merge pull request #4907 from cakephp/issue-4889

Fix DigestAuthenticate with simulated HTTP methods.
José Lorenzo Rodríguez 11 years ago
parent
commit
b999e30f65

+ 1 - 1
src/Auth/DigestAuthenticate.php

@@ -112,7 +112,7 @@ class DigestAuthenticate extends BasicAuthenticate {
 		$password = $user[$field];
 		unset($user[$field]);
 
-		$hash = $this->generateResponseHash($digest, $password, $request->env('REQUEST_METHOD'));
+		$hash = $this->generateResponseHash($digest, $password, $request->env('ORIGINAL_REQUEST_METHOD'));
 		if ($digest['response'] === $hash) {
 			return $user;
 		}

+ 5 - 2
src/Network/Request.php

@@ -253,14 +253,16 @@ class Request implements \ArrayAccess {
 
 /**
  * Sets the REQUEST_METHOD environment variable based on the simulated _method
- * HTTP override value.
+ * HTTP override value. The 'ORIGINAL_REQUEST_METHOD' is also preserved, if you
+ * want the read the non-simulated HTTP method the client used.
  *
  * @param array $data Array of post data.
  * @return array
  */
 	protected function _processPost($data) {
+		$method = $this->env('REQUEST_METHOD');
 		if (
-			in_array($this->env('REQUEST_METHOD'), array('PUT', 'DELETE', 'PATCH')) &&
+			in_array($method, array('PUT', 'DELETE', 'PATCH')) &&
 			strpos($this->env('CONTENT_TYPE'), 'application/x-www-form-urlencoded') === 0
 		) {
 			$data = $this->input();
@@ -269,6 +271,7 @@ class Request implements \ArrayAccess {
 		if ($this->env('HTTP_X_HTTP_METHOD_OVERRIDE')) {
 			$data['_method'] = $this->env('HTTP_X_HTTP_METHOD_OVERRIDE');
 		}
+		$this->_environment['ORIGINAL_REQUEST_METHOD'] = $method;
 		if (isset($data['_method'])) {
 			$this->_environment['REQUEST_METHOD'] = $data['_method'];
 			unset($data['_method']);

+ 36 - 0
tests/TestCase/Auth/DigestAuthenticateTest.php

@@ -176,6 +176,42 @@ DIGEST;
 	}
 
 /**
+ * test authenticate success
+ *
+ * @return void
+ */
+	public function testAuthenticateSuccessSimulatedRequestMethod() {
+		$request = new Request([
+			'url' => 'posts/index',
+			'post' => ['_method' => 'PUT'],
+			'environment' => ['REQUEST_METHOD' => 'GET']
+		]);
+		$request->addParams(array('pass' => array()));
+
+		$digest = <<<DIGEST
+Digest username="mariano",
+realm="localhost",
+nonce="123",
+uri="/dir/index.html",
+qop=auth,
+nc=1,
+cnonce="123",
+response="06b257a54befa2ddfb9bfa134224aa29",
+opaque="123abc"
+DIGEST;
+		$request->env('PHP_AUTH_DIGEST', $digest);
+
+		$result = $this->auth->authenticate($request, $this->response);
+		$expected = array(
+			'id' => 1,
+			'username' => 'mariano',
+			'created' => new Time('2007-03-17 01:16:23'),
+			'updated' => new Time('2007-03-17 01:18:31')
+		);
+		$this->assertEquals($expected, $result);
+	}
+
+/**
  * test scope failure.
  *
  * @expectedException \Cake\Network\Exception\UnauthorizedException

+ 7 - 0
tests/TestCase/Network/RequestTest.php

@@ -425,6 +425,13 @@ class RequestTest extends TestCase {
 
 		$request = new Request(['environment' => ['HTTP_X_HTTP_METHOD_OVERRIDE' => 'PUT']]);
 		$this->assertEquals('PUT', $request->env('REQUEST_METHOD'));
+
+		$request = new Request([
+			'environment' => ['REQUEST_METHOD' => 'POST'],
+			'post' => ['_method' => 'PUT']
+		]);
+		$this->assertEquals('PUT', $request->env('REQUEST_METHOD'));
+		$this->assertEquals('POST', $request->env('ORIGINAL_REQUEST_METHOD'));
 	}
 
 /**