fixed behavior of AuthMethod::isActive

this is an adjustment of #10188 fixing  #7405
isActive() should not be affected in any way by specifying "optional" property.
isActive() should be determined from only and except.
If it is active it can then be checked if optional or not.
Currently this changes the behavior that except will always have precedence.
This commit is contained in:
Carsten Brandt
2016-02-07 16:35:28 +01:00
parent e43c41c9ea
commit ddade3fc6e
2 changed files with 65 additions and 10 deletions

View File

@ -38,6 +38,7 @@ abstract class AuthMethod extends ActionFilter implements AuthInterface
/**
* @var array list of action IDs that this filter will be applied to, but auth failure will not lead to error.
* It may be used for actions, that are allowed for public, but return some additional data for authenticated users.
* Defaults to empty, meaning authentication is not optional for any action.
* @see isOptional
* @since 2.0.7
*/
@ -90,23 +91,16 @@ abstract class AuthMethod extends ActionFilter implements AuthInterface
}
/**
* Checks, whether the $action is optional
* Checks, whether authentication is optional for the given action.
*
* @param Action $action
* @return boolean
* @see optional
* @since 2.0.7
*/
protected function isOptional($action) {
protected function isOptional($action)
{
$id = $this->getActionId($action);
return in_array($id, $this->optional, true);
}
/**
* {@inheritdoc}
*/
protected function isActive($action)
{
return parent::isActive($action) || $this->isOptional($action);
}
}

View File

@ -3,6 +3,8 @@
namespace yiiunit\framework\filters\auth;
use Yii;
use yii\base\Action;
use yii\filters\auth\AuthMethod;
use yii\filters\auth\HttpBasicAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;
@ -140,6 +142,65 @@ class AuthTest extends \yiiunit\TestCase
$this->authOptional($token, $login, $filter, 'bearer-auth');
$this->authExcept($token, $login, $filter, 'bearer-auth');
}
public function authMethodProvider()
{
return [
['yii\filters\auth\CompositeAuth'],
['yii\filters\auth\HttpBasicAuth'],
['yii\filters\auth\HttpBearerAuth'],
['yii\filters\auth\QueryParamAuth'],
];
}
/**
* @dataProvider authMethodProvider
*/
public function testActive($authClass)
{
/** @var $filter AuthMethod */
$filter = new $authClass;
$reflection = new \ReflectionClass($filter);
$method = $reflection->getMethod('isActive');
$method->setAccessible(true);
$controller = new \yii\web\Controller('test', Yii::$app);
// active by default
$this->assertEquals(true, $method->invokeArgs($filter, [new Action('index', $controller)]));
$this->assertEquals(true, $method->invokeArgs($filter, [new Action('view', $controller)]));
$filter->only = ['index'];
$filter->except = [];
$filter->optional = [];
$this->assertEquals(true, $method->invokeArgs($filter, [new Action('index', $controller)]));
$this->assertEquals(false, $method->invokeArgs($filter, [new Action('view', $controller)]));
$filter->only = ['index'];
$filter->except = [];
$filter->optional = ['view'];
$this->assertEquals(true, $method->invokeArgs($filter, [new Action('index', $controller)]));
$this->assertEquals(false, $method->invokeArgs($filter, [new Action('view', $controller)]));
$filter->only = ['index', 'view'];
$filter->except = ['view'];
$filter->optional = [];
$this->assertEquals(true, $method->invokeArgs($filter, [new Action('index', $controller)]));
$this->assertEquals(false, $method->invokeArgs($filter, [new Action('view', $controller)]));
$filter->only = ['index', 'view'];
$filter->except = ['view'];
$filter->optional = ['view'];
$this->assertEquals(true, $method->invokeArgs($filter, [new Action('index', $controller)]));
$this->assertEquals(false, $method->invokeArgs($filter, [new Action('view', $controller)]));
$filter->only;
$filter->except = ['view'];
$filter->optional = ['view'];
$this->assertEquals(true, $method->invokeArgs($filter, [new Action('index', $controller)]));
$this->assertEquals(false, $method->invokeArgs($filter, [new Action('view', $controller)]));
}
}
/**