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

Pass filter arguments to after() and before() methods #3316

Merged
merged 6 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 5 additions & 2 deletions system/Filters/CSRF.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
*/
class CSRF implements FilterInterface
{

/**
* Do whatever processing this filter needs to do.
* By default it should not return anything during
Expand All @@ -68,11 +69,12 @@ class CSRF implements FilterInterface
* redirects, etc.
*
* @param RequestInterface|\CodeIgniter\HTTP\IncomingRequest $request
* @param array|null $arguments
*
* @return mixed
* @throws \CodeIgniter\Security\Exceptions\SecurityException
*/
public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
if ($request->isCLI())
{
Expand Down Expand Up @@ -103,10 +105,11 @@ public function before(RequestInterface $request)
*
* @param RequestInterface|\CodeIgniter\HTTP\IncomingRequest $request
* @param ResponseInterface|\CodeIgniter\HTTP\Response $response
* @param array|null $arguments
*
* @return mixed
*/
public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
}

Expand Down
7 changes: 5 additions & 2 deletions system/Filters/DebugToolbar.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,16 @@
*/
class DebugToolbar implements FilterInterface
{

/**
* We don't need to do anything here.
*
* @param RequestInterface|\CodeIgniter\HTTP\IncomingRequest $request
* @param array|null $arguments
*
* @return void
*/
public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
}

Expand All @@ -67,10 +69,11 @@ public function before(RequestInterface $request)
*
* @param RequestInterface|\CodeIgniter\HTTP\IncomingRequest $request
* @param ResponseInterface|\CodeIgniter\HTTP\Response $response
* @param array|null $arguments
*
* @return void
*/
public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
Services::toolbar()->prepare($request, $response);
}
Expand Down
6 changes: 4 additions & 2 deletions system/Filters/FilterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ interface FilterInterface
* redirects, etc.
*
* @param \CodeIgniter\HTTP\RequestInterface $request
* @param null $arguments
*
* @return mixed
*/
public function before(RequestInterface $request);
public function before(RequestInterface $request, $arguments = null);

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

Expand All @@ -74,10 +75,11 @@ public function before(RequestInterface $request);
*
* @param \CodeIgniter\HTTP\RequestInterface $request
* @param \CodeIgniter\HTTP\ResponseInterface $response
* @param null $arguments
*
* @return mixed
*/
public function after(RequestInterface $request, ResponseInterface $response);
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null);

//--------------------------------------------------------------------
}
2 changes: 1 addition & 1 deletion system/Filters/Filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ public function run(string $uri, string $position = 'before')
}
elseif ($position === 'after')
{
$result = $class->after($this->request, $this->response);
$result = $class->after($this->request, $this->response, $this->arguments[$alias] ?? null);

if ($result instanceof ResponseInterface)
{
Expand Down
7 changes: 4 additions & 3 deletions system/Filters/Honeypot.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ class Honeypot implements FilterInterface
* then the requester is a bot
*
* @param \CodeIgniter\HTTP\RequestInterface $request
* @param array|null $arguments
*
* @return void
* @throws \CodeIgniter\Honeypot\Exceptions\HoneypotException
*/
public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
$honeypot = Services::honeypot(new \Config\Honeypot());
if ($honeypot->hasContent($request))
Expand All @@ -73,10 +73,11 @@ public function before(RequestInterface $request)
*
* @param \CodeIgniter\HTTP\RequestInterface $request
* @param \CodeIgniter\HTTP\ResponseInterface $response
* @param array|null $arguments
*
* @return void
*/
public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
$honeypot = Services::honeypot(new \Config\Honeypot());
$honeypot->attachHoneypot($response);
Expand Down
41 changes: 40 additions & 1 deletion tests/system/Filters/FiltersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
require_once __DIR__ . '/fixtures/InvalidClass.php';
require_once __DIR__ . '/fixtures/Multiple1.php';
require_once __DIR__ . '/fixtures/Multiple2.php';
require_once __DIR__ . '/fixtures/Role.php';

/**
* @backupGlobals enabled
Expand All @@ -25,6 +26,7 @@ class FiltersTest extends \CodeIgniter\Test\CIUnitTestCase
protected function setUp(): void
{
parent::setUp();
Services::reset();

$this->request = Services::request();
$this->response = Services::response();
Expand Down Expand Up @@ -623,17 +625,54 @@ public function testEnableFilterWithArguments()
],
];

$filters = new Filters((object) $config, $this->request, $this->response);
$filters = new Filters((object)$config, $this->request, $this->response);

$filters = $filters->initialize('admin/foo/bar');

$filters->enableFilter('role:admin , super', 'before');
$filters->enableFilter('role:admin , super', 'after');

$found = $filters->getFilters();

$this->assertTrue(in_array('role', $found['before']));
$this->assertEquals(['admin', 'super'], $filters->getArguments('role'));
$this->assertEquals(['role' => ['admin', 'super']], $filters->getArguments());

$response = $filters->run('admin/foo/bar', 'before');
$this->assertEquals('admin;super', $response);

$response = $filters->run('admin/foo/bar', 'after');
$this->assertEquals('admin;super', $response->getBody());
}

public function testEnableFilterWithNoArguments()
{
$_SERVER['REQUEST_METHOD'] = 'GET';

$config = [
'aliases' => ['role' => 'CodeIgniter\Filters\fixtures\Role'],
'globals' => [
'before' => [],
'after' => [],
],
];

$filters = new Filters((object)$config, $this->request, $this->response);

$filters = $filters->initialize('admin/foo/bar');

$filters->enableFilter('role', 'before');
$filters->enableFilter('role', 'after');

$found = $filters->getFilters();

$this->assertTrue(in_array('role', $found['before']));

$response = $filters->run('admin/foo/bar', 'before');
$this->assertEquals('Is null', $response);

$response = $filters->run('admin/foo/bar', 'after');
$this->assertEquals('Is null', $response->getBody());
}

public function testEnableNonFilter()
Expand Down
4 changes: 2 additions & 2 deletions tests/system/Filters/fixtures/GoogleCurious.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
class GoogleCurious implements FilterInterface
{

public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
return 'This is curious';
}

public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
}

Expand Down
4 changes: 2 additions & 2 deletions tests/system/Filters/fixtures/GoogleEmpty.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
class GoogleEmpty implements FilterInterface
{

public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
$request = '';
return $request;
}

public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
}

Expand Down
4 changes: 2 additions & 2 deletions tests/system/Filters/fixtures/GoogleMe.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class GoogleMe implements FilterInterface
{
public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
$request->url = 'http://google.com';

Expand All @@ -15,7 +15,7 @@ public function before(RequestInterface $request)

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

public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
$response->csp = 'http://google.com';

Expand Down
4 changes: 2 additions & 2 deletions tests/system/Filters/fixtures/GoogleYou.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
class GoogleYou implements FilterInterface
{

public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
$response = Services::response();
$response->csp = 'http://google.com';
return $response;
}

public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
}

Expand Down
4 changes: 2 additions & 2 deletions tests/system/Filters/fixtures/Multiple1.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
class Multiple1 implements FilterInterface
{

public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
$request->csp = 'http://exampleMultipleCSP.com';
return $request;
}

public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
}

Expand Down
4 changes: 2 additions & 2 deletions tests/system/Filters/fixtures/Multiple2.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
class Multiple2 implements FilterInterface
{

public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
$request->url = 'http://exampleMultipleURL.com';
return $request;
}

public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
}

Expand Down
45 changes: 45 additions & 0 deletions tests/system/Filters/fixtures/Role.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace CodeIgniter\Filters\fixtures;

use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;

class Role implements FilterInterface
{

public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
if (is_array($arguments))
{
$response->setBody(join(';', $arguments));
}
elseif (is_null($arguments))
{
$response->setBody('Is null');
}
else
{
$response->setBody('Something else');
}
return $response;
}

public function before(RequestInterface $request, $arguments = null)
{
if (is_array($arguments))
{
return join(';', $arguments);
}
elseif (is_null($arguments))
{
return 'Is null';
}
else
{
return 'Something else';
}
}

}
2 changes: 2 additions & 0 deletions user_guide_src/source/changelogs/v4.0.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ Bugs Fixed:
- Fixed bug in Image GD handler that would try to compress images twice in certain cases
- Ensure get translation output logic work on selected locale, dashed locale, and fallback "en"
- Fix is_unique/is_not_unique validation called on POST/PUT via API in Postgresql
- Added ``$arguments`` parameter to after() and before() in FilterInterface. This is a breaking change, so all code implementing the FilterInterface must be updated
- Fixed a bug where filter arguments were not passed to after()



Expand Down
15 changes: 12 additions & 3 deletions user_guide_src/source/incoming/filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ but may leave the methods empty if they are not needed. A skeleton filter class

class MyFilter implements FilterInterface
{
public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
// Do something here
}

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

public function after(RequestInterface $request, ResponseInterface $response)
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
// Do something here
}
Expand All @@ -58,7 +58,7 @@ Since before filters are executed prior to your controller being executed, you m
actions in the controller from happening. You can do this by passing back anything that is not the request object.
This is typically used to perform redirects, like in this example::

public function before(RequestInterface $request)
public function before(RequestInterface $request, $arguments = null)
{
$auth = service('auth');

Expand Down Expand Up @@ -179,6 +179,15 @@ a list of URI patterns that filter should apply to::
'bar' => ['before' => ['api/*', 'admin/*']]
];

Filter arguments
=================

When configuring filters, additional arguments may be passed to a filter when setting up the route::

$routes->add('users/delete/(:segment)', 'AdminController::index', ['filter' => 'admin-auth:dual,noreturn']);

In this example, the array ``['dual', 'noreturn']`` will be passed in ``$arguments`` to the filter's ``before()`` and ``after()`` implementation methods.

****************
Provided Filters
****************
Expand Down
Loading