Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for assigning validation data to strong_password method #222

Merged
merged 4 commits into from
May 8, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 67 additions & 10 deletions src/Authentication/Passwords/ValidationRules.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,38 @@ class ValidationRules
* better security if this is done manually, since you can
* personalize based on a specific user at that point.
*
* @param string $str
* @param string|null $error
* @param string $value Field value
* @param string $error1 Error that will be returned (for call without validation data array)
* @param array $data Validation data array
* @param string $error2 Error that will be returned (for call with validation data array)
*
* @return bool
*/
public function strong_password(string $str, string &$error = null)
public function strong_password(string $value, string &$error1 = null, array $data = [], string &$error2 = null)
{
$checker = service('passwords');
$user = (function_exists("user") && user()) ? user() : $this->buildUserFromRequest();

$result = $checker->check($str, $user);
if (function_exists('user') && user())
{
$user = user();
}
else
{
$user = empty($data) ? $this->buildUserFromRequest() : $this->buildUserFromData($data);
}

$result = $checker->check($value, $user);

if ($result === false)
{
$error = $checker->error();
if (empty($data))
{
$error1 = $checker->error();
}
else
{
$error2 = $checker->error();
}
}

return $result;
Expand All @@ -46,17 +63,57 @@ public function strong_password(string $str, string &$error = null)
/**
* Builds a new user instance from the global request.
*
* @return User
* @return \Myth\Auth\Entities\User
*/
protected function buildUserFromRequest()
{
$fields = $this->prepareValidFields();

$request = service('request');

if (in_array($request->getMethod(), ['put', 'patch', 'delete']))
michalsn marked this conversation as resolved.
Show resolved Hide resolved
{
$data = $request->getRawInput();

$fields = array_fill_keys($fields, null);
$data = array_intersect_key(array_merge($fields, $data), $fields);
}
else
{
$data = $request->getVar($fields);
}

return new User($data);
}

/**
* Builds a new user instance from assigned data..
*
* @param array $data Assigned data
*
* @return \Myth\Auth\Entities\User
*/
protected function buildUserFromData(array $data = [])
{
$fields = $this->prepareValidFields();

$data = array_intersect_key($data, array_fill_keys($fields, null));

return new User($data);
}

/**
* Prepare valid user fields
*
* @return array
*/
protected function prepareValidFields(): array
{
$config = config('Auth');
$fields = array_merge($config->validFields, $config->personalFields);
$fields[] = 'password';

$data = service('request')->getPost($fields);

return new User($data);
return $fields;
}

}
130 changes: 130 additions & 0 deletions tests/unit/ValidationRulesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Validation\Validation;
use Config\Services;
use Myth\Auth\Authentication\Passwords\ValidationRules;


class ValidationRulesTest extends CIUnitTestCase
{
protected $validation;
protected $config = [
'ruleSets' => [
ValidationRules::class,
],
];

//--------------------------------------------------------------------

protected function setUp(): void
{
parent::setUp();

Services::reset(true);

$this->validation = new Validation((object) $this->config, \Config\Services::renderer());
$this->validation->reset();

$_REQUEST = [];
}

//--------------------------------------------------------------------

public function testStrongPasswordLongRule()
{
$rules = [
'password' => 'strong_password[]',
];

$data = [
'email' => '[email protected]',
'password' => '!!!gerard!!!abootylicious',
];

$this->validation->setRules($rules);

$this->assertTrue($this->validation->run($data));
}

//--------------------------------------------------------------------

public function testStrongPasswordLongRuleWithPostRequest()
{
$_REQUEST = $data = [
'email' => '[email protected]',
'password' => '!!!gerard!!!abootylicious',
];

$request = service('request');
$request->setMethod('post')->setGlobal('post', $data);

$this->validation->setRules([
'password' => 'strong_password[]',
]);

$result = $this->validation->withRequest($request)->run();
$this->assertTrue($result);
}

//--------------------------------------------------------------------

public function testStrongPasswordLongRuleWithRawInputRequest()
{
$data = [
'email' => '[email protected]',
'password' => '!!!gerard!!!abootylicious',
];

$request = service('request');
$request->setMethod('patch')->setBody(http_build_query($data));

$this->validation->setRules([
'password' => 'strong_password[]',
]);

$result = $this->validation->withRequest($request)->run();
$this->assertTrue($result);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this return false now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, in this test I'm using strong_password[], so validation class grabs data from request and passes it to this rule (as a $data parameter).

}

//--------------------------------------------------------------------

public function testStrongPasswordShortRuleWithPostRequest()
{
$_REQUEST = $data = [
'email' => '[email protected]',
'password' => '!!!gerard!!!abootylicious',
];

$request = service('request');
$request->setMethod('post')->setGlobal('post', $data);

$this->validation->setRules([
'password' => 'strong_password',
]);

$result = $this->validation->withRequest($request)->run();
$this->assertTrue($result);
}

//--------------------------------------------------------------------

public function testStrongPasswordShortRuleWithRawInputRequest()
{
$data = [
'email' => '[email protected]',
'password' => '!!!gerard!!!abootylicious',
];

$request = service('request');
$request->setMethod('patch')->setBody(http_build_query($data));

$this->validation->setRules([
'password' => 'strong_password',
]);

$result = $this->validation->withRequest($request)->run();
$this->assertTrue($result);
}

}