Permalink
Browse files

Merge branch 'dev'

  • Loading branch information...
2 parents e4ef0c2 + 7024e5a commit 582210ac4513d44e49c71825f618febf02ecdac8 @nateabele nateabele committed Jul 8, 2012
Showing with 317 additions and 90 deletions.
  1. +5 −4 .gitignore
  2. +6 −4 console/command/Create.php
  3. BIN console/command/create/template/app.phar.gz
  4. +1 −1 net/http/Media.php
  5. +6 −10 net/http/Message.php
  6. +1 −0 net/socket/Curl.php
  7. +37 −2 security/Auth.php
  8. +13 −12 storage/Session.php
  9. +6 −2 template/helper/Form.php
  10. +3 −1 template/helper/Html.php
  11. +10 −6 test/Unit.php
  12. +1 −1 test/filter/Coverage.php
  13. +1 −1 tests/cases/analysis/LoggerTest.php
  14. +1 −1 tests/cases/console/RequestTest.php
  15. +1 −1 tests/cases/console/command/TestTest.php
  16. +1 −1 tests/cases/console/command/create/ControllerTest.php
  17. +1 −1 tests/cases/console/command/create/MockTest.php
  18. +1 −1 tests/cases/console/command/create/ModelTest.php
  19. +2 −2 tests/cases/console/command/create/TestTest.php
  20. +1 −2 tests/cases/data/source/http/adapter/CouchDbTest.php
  21. +2 −2 tests/cases/g11n/LocaleTest.php
  22. +1 −2 tests/cases/g11n/catalog/adapter/GettextTest.php
  23. +1 −2 tests/cases/g11n/catalog/adapter/PhpTest.php
  24. +11 −0 tests/cases/net/http/MediaTest.php
  25. +51 −1 tests/cases/security/AuthTest.php
  26. +25 −0 tests/cases/storage/SessionTest.php
  27. +23 −4 tests/cases/template/helper/FormTest.php
  28. +9 −4 tests/cases/test/DispatcherTest.php
  29. +8 −1 tests/cases/test/GroupTest.php
  30. +25 −7 tests/cases/test/UnitTest.php
  31. +9 −9 tests/cases/util/InflectorTest.php
  32. +1 −1 tests/mocks/console/command/MockLibraryService.php
  33. +3 −3 tests/mocks/data/MockSource.php
  34. +1 −1 tests/mocks/template/helper/MockFormPostInfo.php
  35. +25 −0 tests/mocks/test/cases/MockSetUpThrowsException.php
  36. +24 −0 tests/mocks/test/cases/MockTearDownThrowsException.php
View
@@ -1,4 +1,5 @@
-.DS_Store
-app/libraries/*
-app/resources/tmp/*
-.*.sw[op]
+# OS X
+.DS_Store
+
+# Vim
+.*.sw[a-z]
View
@@ -232,24 +232,26 @@ protected function _save(array $params = array()) {
}
$contents = $this->_template();
$result = String::insert($contents, $params);
-
- $path = str_replace('\\', '/', "{$params['namespace']}\\{$params['class']}");
+ $namespace = str_replace($this->_library['prefix'], '\\', $params['namespace']);
+ $path = str_replace('\\', '/', "{$namespace}\\{$params['class']}");
$path = $this->_library['path'] . stristr($path, '/');
$file = str_replace('//', '/', "{$path}.php");
$directory = dirname($file);
+ $relative = str_replace($this->_library['path'] . '/', "", $file);
if ((!is_dir($directory)) && !mkdir($directory, 0755, true)) {
return false;
}
if (file_exists($file)) {
- $prompt = "{$file} already exists. Overwrite?";
+ $prompt = "{$relative} already exists. Overwrite?";
$choices = array('y', 'n');
if ($this->in($prompt, compact('choices')) != 'y') {
return "{$params['class']} skipped.";
}
}
+
if (file_put_contents($file, "<?php\n\n{$result}\n\n?>")) {
- return "{$params['class']} created in {$params['namespace']}.";
+ return "{$params['class']} created in {$relative}.";
}
return false;
}
Binary file not shown.
View
@@ -453,7 +453,7 @@ public static function asset($path, $type, array $options = array()) {
$file = $self::path($path, $type, $options);
}
- if ($path[0] === '/') {
+ if (strlen($path) > 0 && $path[0] === '/') {
if ($options['base'] && strpos($path, $options['base']) !== 0) {
$path = "{$options['base']}{$path}";
}
View
@@ -107,17 +107,13 @@ public function headers($key = null, $value = null) {
}
}
- if ($value) {
- $this->headers = array_merge($this->headers, array($key => $value));
- } else {
- foreach ((array) $key as $header => $value) {
- if (!is_string($header)) {
- if (preg_match('/(.*?):(.+)/i', $value, $match)) {
- $this->headers[$match[1]] = trim($match[2]);
- }
- } else {
- $this->headers[$header] = $value;
+ foreach (($value ? array($key => $value) : (array) $key) as $header => $value) {
+ if (!is_string($header)) {
+ if (preg_match('/(.*?):(.+)/', $value, $match)) {
+ $this->headers[$match[1]] = trim($match[2]);
}
+ } else {
+ $this->headers[$header] = $value;
}
}
$headers = array();
View
@@ -178,6 +178,7 @@ public function timeout($time) {
* @param string $charset
*/
public function encoding($charset) {}
+
/**
* Sets the options to be used in subsequent curl requests.
*
View
@@ -24,6 +24,22 @@
* the data returned from the credential check is written to the session, which is automatically
* accessed on subsequent checks (though manual re-checking can be forced on a per-instance basis).
*
+ * To be secure by default (and if you don't override it), a `password` field is never stored in
+ * the session adapter. This prevents a possible password hash to be leaked in a cookie (for
+ * example). You can also be very specific on what you want to store in the session:
+ *
+ * {{{
+ * Auth::config(array(
+ * 'default' => array(
+ * 'session' => array(
+ * 'persist' => array('username', 'email')
+ * )
+ * )
+ * ));
+ * }}}
+ *
+ * You can also pass an optional `persist` param to the `check` method to override this default.
+ *
* For additional information on configuring and working with `Auth`, see the `Form` adapter.
*
* @see lithium\security\auth\adapter\Form
@@ -69,7 +85,8 @@ protected static function _initConfig($name, $config) {
$defaults = array('session' => array(
'key' => $name,
'class' => static::$_classes['session'],
- 'options' => array()
+ 'options' => array(),
+ 'persist' => array()
));
$config = parent::_initConfig($name, $config) + $defaults;
$config['session'] += $defaults['session'];
@@ -99,19 +116,27 @@ protected static function _initConfig($name, $config) {
* - `'writeSession'` _boolean_: Upon a successful credentials check, the returned
* user information is, by default, written to the session. Set this to `false`
* to disable session writing for this authentication check.
+ * - `'persist'` _array_: A list of fields that should be stored in the session.
* @return array After a successful credential check against the adapter (or a successful
* lookup against the current session), returns an array of user information from the
* storage backend used by the configured adapter.
* @filter
*/
public static function check($name, $credentials = null, array $options = array()) {
- $defaults = array('checkSession' => true, 'writeSession' => true);
+ $config = static::config($name);
+ $defaults = array(
+ 'checkSession' => true,
+ 'writeSession' => true,
+ 'persist' => $config['session']['persist'] ?: static::_config('persist')
+ );
+
$options += $defaults;
$params = compact('name', 'credentials', 'options');
return static::_filter(__FUNCTION__, $params, function($self, $params) {
extract($params);
$config = $self::invokeMethod('_config', array($name));
+ $persist = $options['persist'];
if ($config === null) {
throw new ConfigException("Configuration `{$name}` has not been defined.");
@@ -125,6 +150,16 @@ public static function check($name, $credentials = null, array $options = array(
}
if (($credentials) && $data = $self::adapter($name)->check($credentials, $options)) {
+ if ($options['persist']) {
+ foreach ($data as $key => $value) {
+ if (!in_array($key, $options['persist'])) {
+ unset($data[$key]);
+ }
+ }
+ } else {
+ unset($data['password']);
+ }
+
return ($options['writeSession']) ? $self::set($name, $data) : $data;
}
return false;
View
@@ -147,16 +147,17 @@ public static function write($key, $value = null, array $options = array()) {
}
}
$result = false;
- $settings = static::_config($name);
- if ($options['strategies']) {
- $options += array('key' => $key, 'class' => __CLASS__);
- $value = static::applyStrategies(__FUNCTION__, $name, $value, $options);
- }
- $params = compact('key', 'value', 'options');
+ $original = $value;
foreach ($methods as $name => $method) {
+ $settings = static::_config($name);
$filters = $settings['filters'];
+ if ($options['strategies']) {
+ $options += array('key' => $key, 'class' => __CLASS__);
+ $value = static::applyStrategies(__FUNCTION__, $name, $original, $options);
+ }
+ $params = compact('key', 'value', 'options');
$result = static::_filter(__FUNCTION__, $params, $method, $filters) || $result;
}
return $result;
@@ -192,15 +193,15 @@ public static function delete($key, array $options = array()) {
}
$result = false;
$options += array('key' => $key, 'class' => __CLASS__);
-
- if ($options['strategies']) {
- $options += array('key' => $key, 'class' => __CLASS__);
- $key = static::applyStrategies(__FUNCTION__, $name, $key, $options);
- }
- $params = compact('key', 'options');
+ $original = $key;
foreach ($methods as $name => $method) {
$settings = static::_config($name);
+ if ($options['strategies']) {
+ $options += array('key' => $key, 'class' => __CLASS__);
+ $key = static::applyStrategies(__FUNCTION__, $name, $original, $options);
+ }
+ $params = compact('key', 'options');
$filters = $settings['filters'];
$result = static::_filter(__FUNCTION__, $params, $method, $filters) || $result;
}
View
@@ -786,10 +786,14 @@ protected function _defaults($method, $name, $options) {
(!isset($options['value']) || $options['value'] === null) &&
$name && $value = $this->binding($name)->data
);
- if ($hasValue) {
+ $isZero = (isset($value) && ($value === 0 || $value === "0"));
+ if ($hasValue || $isZero) {
$options['value'] = $value;
}
- if (isset($options['default']) && empty($options['value'])) {
+ if (isset($options['value']) && !$isZero) {
+ $isZero = ($options['value'] === 0 || $options['value'] === "0");
+ }
+ if (isset($options['default']) && empty($options['value']) && !$isZero) {
$options['value'] = $options['default'];
}
unset($options['default']);
View
@@ -110,7 +110,9 @@ class Html extends \lithium\template\Helper {
* @return string A meta tag containing the specified encoding (literally).
*/
public function charset($encoding = null) {
- $encoding = $encoding ?: $this->_context->response()->encoding;
+ if ($response = $this->_context->response()) {
+ $encoding = $encoding ?: $response->encoding;
+ }
return $this->_render(__METHOD__, 'charset', compact('encoding'));
}
View
@@ -744,8 +744,12 @@ protected function _runTestMethod($method, $options) {
));
}
$this->_expected = array();
- $this->tearDown();
+ try {
+ $this->tearDown();
+ } catch (Exception $e) {
+ $this->_handleException($e, __LINE__ - 2);
+ }
return $passed;
}
@@ -1008,16 +1012,16 @@ protected function _arrayPermute($items, $perms = array()) {
}
/**
- * Removes everything from `resources/tmp/tests` directory. Call from
- * inside of your test method or `tearDown()`.
+ * Removes everything from `resources/tmp/tests` directory. Call from inside of your test
+ * method or `tearDown()`.
*
- * Uses `DIRECTORY_SEPARATOR` as `getPathname()` is used in a a direct
- * string comparison. The method may contain slashes and backslashes.
+ * Uses `DIRECTORY_SEPARATOR` as `getPathname()` is used in a a direct string comparison.
+ * The method may contain slashes and backslashes.
*
* If the file to unlink is readonly, it throws a exception (Permission denied) on Windows.
* So, the file is checked before an unlink is tried. (this will make the tests run slower
* but is prefered over a if (!unlink { chmod; unlink }.
- * See: http://stringoftheseus.com/blog/2010/12/22/php-unlink-permisssion-denied-error-on-windows/
+ * http://stringoftheseus.com/blog/2010/12/22/php-unlink-permisssion-denied-error-on-windows/
*
* @param string $path Path to directory with contents to remove. If first
* character is NOT a slash (`/`) or a Windows drive letter (`C:`)
View
@@ -100,7 +100,7 @@ function($cls) { return Inspector::executable($cls, array('public' => false)); }
* @param array $result The raw line number results
* @return array
*/
- protected static function collectLines($result) {
+ public static function collectLines($result) {
$output = null;
$aggregate = array('covered' => 0, 'executable' => 0);
@@ -28,7 +28,7 @@ public function skip() {
}
}
$this->_testPath = "{$path}/tmp/tests";
- $this->skipIf(!is_writable($this->_testPath), "Path `{$this->_testPath}` is not readable.");
+ $this->skipIf(!is_writable($this->_testPath), "Path `{$this->_testPath}` is not writable.");
}
public function setUp() {
@@ -118,7 +118,7 @@ public function testConstructWithConfigArgs() {
public function testConstructWithEnv() {
$base = Libraries::get(true, 'resources') . '/tmp/tests';
- $this->skipIf(!is_readable($base), "Path `{$base}` is not writable.");
+ $this->skipIf(!is_readable($base), "Path `{$base}` is not readable.");
chdir(Libraries::get(true, 'resources') . '/tmp');
$request = new Request(array('env' => array('working' => '/some/other/path')));
@@ -148,7 +148,7 @@ public function testRunMultipleTestsWithAbsolutePath() {
$path = LITHIUM_LIBRARY_PATH . '/lithium/tests/mocks/test/cases';
$command->run($path);
- $expected = "1 / 1 pass\n0 fails and 2 exceptions\n";
+ $expected = "4 exceptions";
$expected = preg_quote($expected, '/');
$result = $command->response->output;
$this->assertPattern("/{$expected}/", $result);
@@ -78,7 +78,7 @@ public function testRun() {
));
$controller->path = $this->_testPath;
$controller->run('controller');
- $expected = "PostsController created in create_test\\controllers.\n";
+ $expected = "PostsController created in controllers/PostsController.php.\n";
$result = $controller->response->output;
$this->assertEqual($expected, $result);
@@ -52,7 +52,7 @@ public function testMockModel() {
));
$mock->path = $this->_testPath;
$mock->run('mock');
- $expected = "MockPosts created in create_test\\tests\\mocks\\models.\n";
+ $expected = "MockPosts created in tests/mocks/models/MockPosts.php.\n";
$result = $mock->response->output;
$this->assertEqual($expected, $result);
@@ -22,7 +22,7 @@ class ModelTest extends \lithium\test\Unit {
public function skip() {
$this->_testPath = Libraries::get(true, 'resources') . '/tmp/tests';
- $this->skipIf(!is_writable($this->_testPath), "Path `{$this->_testPath}` is not readable.");
+ $this->skipIf(!is_writable($this->_testPath), "Path `{$this->_testPath}` is not writable.");
}
public function setUp() {
@@ -53,7 +53,7 @@ public function testTestModel() {
));
$test->path = $this->_testPath;
$test->run('test');
- $expected = "PostsTest created in create_test\\tests\\cases\\models.\n";
+ $expected = "PostsTest created in tests/cases/models/PostsTest.php.\n";
$result = $test->response->output;
$this->assertEqual($expected, $result);
@@ -102,7 +102,7 @@ public function someMethod() {}
$test = new Test(array('request' => $this->request, 'classes' => $this->classes));
$test->path = $this->_testPath;
$test->run('test');
- $expected = "Post{$id}sTest created in create_test\\tests\\cases\\models.\n";
+ $expected = "Post{$id}sTest created in tests/cases/models/Post{$id}sTest.php.\n";
$result = $test->response->output;
$this->assertEqual($expected, $result);
@@ -70,8 +70,7 @@ public function testConnect() {
public function testDisconnect() {
$couchdb = new CouchDb($this->_testConfig);
- $result = $couchdb->connect();
- $this->assertTrue($result);
+ $couchdb->connect();
$result = $couchdb->disconnect();
$this->assertTrue($result);
@@ -425,9 +425,9 @@ public function testPreferredEmpty() {
public function testPreferredMalformedContainingChrome() {
$available = array('fr', 'de');
- $random_firefox_4 = 'de-DE,de;q=0.7,chrome://global/locale/intl.properties;q=0.3';
+ $randomFirefox4 = 'de-DE,de;q=0.7,chrome://global/locale/intl.properties;q=0.3';
$request = new ActionRequest(array(
- 'env' => array('HTTP_ACCEPT_LANGUAGE' => $random_firefox_4)
+ 'env' => array('HTTP_ACCEPT_LANGUAGE' => $randomFirefox4)
));
$result = Locale::preferred($request, $available);
$this->assertIdentical('de', $result);
@@ -20,8 +20,7 @@ class GettextTest extends \lithium\test\Unit {
public function skip() {
$path = Libraries::get(true, 'resources') . '/tmp/tests';
- $message = "Path {$path} is not writable.";
- $this->skipIf(!is_writable($path), $message);
+ $this->skipIf(!is_writable($path), "Path `{$path}` is not writable.");
}
public function setUp() {
@@ -20,8 +20,7 @@ class PhpTest extends \lithium\test\Unit {
public function skip() {
$this->_path = $path = Libraries::get(true, 'resources') . '/tmp/tests';
- $message = "{$path} is not writable.";
- $this->skipIf(!is_writable($path), $message);
+ $this->skipIf(!is_writable($path), "Path `{$path}` is not writable.");
}
public function setUp() {
Oops, something went wrong.

0 comments on commit 582210a

Please sign in to comment.