Skip to content

Commit

Permalink
Merge pull request #37 from haltuf/master
Browse files Browse the repository at this point in the history
Add Secured as attribute for PHP >= 8.0
  • Loading branch information
hrach authored Nov 17, 2022
2 parents 6e11dd0 + 19d993d commit 63c7481
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 2 deletions.
12 changes: 12 additions & 0 deletions src/Secured.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php declare(strict_types=1);

namespace Nextras\Application\UI;

use Attribute;


#[Attribute(Attribute::TARGET_METHOD)]
class Secured
{

}
3 changes: 2 additions & 1 deletion src/SecuredLinksControlTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public function signalReceived(string $signal): void

if (method_exists($this, $method)) {
$reflection = new \ReflectionMethod($this, $method);
$secured = Nette\Application\UI\ComponentReflection::parseAnnotation($reflection, 'secured') !== NULL;
$secured = Nette\Application\UI\ComponentReflection::parseAnnotation($reflection, 'secured') !== NULL
|| (method_exists($reflection, 'getAttributes') && count($reflection->getAttributes(Secured::class)) > 0);
if ($secured) {
$params = array($this->getUniqueId());
if ($this->params) {
Expand Down
2 changes: 1 addition & 1 deletion src/SecuredLinksPresenterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function createSecuredLink(Component $component, string $link, string $de
$method = $component->formatSignalMethod($signal);
$signalReflection = $reflection->getMethod($method);

if (!$signalReflection->hasAnnotation('secured')) {
if (!$signalReflection->hasAnnotation('secured') && count($signalReflection->getAttributes(Secured::class)) === 0) {
break;
}

Expand Down
95 changes: 95 additions & 0 deletions tests/cases/SecuredLinksTest.attribute.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php
/**
* @phpVersion >= 8.0.0
*/

use Nette\Application\Request;
use Nette\Application\Routers\SimpleRouter;
use Nette\Application\UI\Control;
use Nette\Application\UI\Presenter;
use Nette\Http\Request as HttpRequest;
use Nette\Http\Response;
use Nette\Http\UrlScript;
use Nextras\Application\UI\Secured;
use Nextras\Application\UI\SecuredLinksControlTrait;
use Nextras\Application\UI\SecuredLinksPresenterTrait;
use Tester\Assert;

require __DIR__ . '/../bootstrap.php';


class TestControl extends Control
{
use SecuredLinksControlTrait;
#[Secured]
public function handlePay($amount = 0)
{
}
}


class TestPresenter extends Presenter
{
use SecuredLinksPresenterTrait;
protected function startup()
{
parent::startup();
$this['mycontrol'] = new TestControl;
}
public function renderDefault()
{
$this->terminate();
}
#[Secured]
public function handlePay($amount = 0)
{
}
#[Secured]
public function handlePay2($amount)
{
}
#[Secured]
public function handleList(array $sections)
{
}
}


$url = new UrlScript('http://localhost/index.php', '/index.php');

$httpRequest = new HttpRequest($url);
$httpResponse = new Response();

$router = new SimpleRouter();
$request = new Request('Test', HttpRequest::GET, array());

$sessionSection = Mockery::mock('alias:Nette\Http\SessionSection');
$sessionSection->token = 'abcd';

$session = Mockery::mock('Nette\Http\Session');
$session->shouldReceive('getSection')->with('Nextras.Application.UI.SecuredLinksPresenterTrait')->andReturn($sessionSection);
$session->shouldReceive('getId')->times(8)->andReturn('session_id_1');

$presenter = new TestPresenter();
$presenter->autoCanonicalize = FALSE;
$presenter->injectPrimary(NULL, NULL, $router, $httpRequest, $httpResponse, $session, NULL);
$presenter->run($request);


Assert::same( '/index.php?action=default&do=pay&presenter=Test&_sec=7VNmMotk', $presenter->link('pay!') );
Assert::same( '/index.php?amount=200&action=default&do=pay&presenter=Test&_sec=7VNmMotk', $presenter->link('pay!', [200]) );
Assert::same( '/index.php?amount=100&action=default&do=pay2&presenter=Test&_sec=JtQFHCP3', $presenter->link('pay2!', [100]) );
Assert::same( '/index.php?amount=200&action=default&do=pay2&presenter=Test&_sec=S2PM9nnh', $presenter->link('pay2!', [200]) );
Assert::same( '/index.php?sections[0]=a&sections[1]=b&action=default&do=list&presenter=Test&_sec=btNfK0zF', urldecode($presenter->link('list!', [['a', 'b']])) );
Assert::same( '/index.php?sections[0]=a&sections[1]=c&action=default&do=list&presenter=Test&_sec=2oGtxq6E', urldecode($presenter->link('list!', [['a', 'c']])) );

Assert::same( '/index.php?action=default&do=mycontrol-pay&presenter=Test&mycontrol-_sec=_eyaqc4b', $presenter['mycontrol']->link('pay') );
Assert::same( '/index.php?mycontrol-amount=200&action=default&do=mycontrol-pay&presenter=Test&mycontrol-_sec=_eyaqc4b', $presenter['mycontrol']->link('pay', [200]) );


$session->shouldReceive('getId')->times(2)->andReturn('session_id_2');

Assert::same( '/index.php?sections[0]=a&sections[1]=b&action=default&do=list&presenter=Test&_sec=Y3v1C1cr', urldecode($presenter->link('list!', [['a', 'b']])) );
Assert::same( '/index.php?sections[0]=a&sections[1]=c&action=default&do=list&presenter=Test&_sec=kfY-zsLy', urldecode($presenter->link('list!', [['a', 'c']])) );

Mockery::close();
10 changes: 10 additions & 0 deletions tests/cases/SecuredLinksTest.php7.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use Nette\Application\Request;
use Nette\Application\Routers\SimpleRouter;
use Nette\Application\UI\BadSignalException;
use Nette\Application\UI\Presenter;
use Nette\Http\Request as HttpRequest;
use Nette\Http\Response;
Expand Down Expand Up @@ -64,4 +65,13 @@ $presenter->run(new Request('Test', 'GET', [
'_sec' => 'JqCasYHU',
]));

Assert::exception(function () use ($presenter) {
$presenter->run(new Request('Test', 'GET', [
'action' => 'default',
'do' => 'pay',
'value' => '0',
//'_sec' => 'JqCasYHU',
]));
}, BadSignalException::class, "Invalid security token for signal 'pay' in class TestPresenter.");

Mockery::close();

0 comments on commit 63c7481

Please sign in to comment.