Skip to content
Draft
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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"stan": "@phpstan",
"stan-baseline": "tools/phpstan --generate-baseline",
"stan-setup": "phive install",
"rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector:\"~2.3.1\" && mv composer.backup composer.json",
"rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector --with-dependencies && mv composer.backup composer.json",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why was this change needed?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

That change was necessary for the cs-stan / Coding Standard & Static Analysis test to work and return its results.
I simply wanted to test what that test said; if necessary, I'll undo that commit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I guess we would need to get 3.x green again independently.

"rector-check": "vendor/bin/rector process --dry-run",
"rector-fix": "vendor/bin/rector process",
"test": "phpunit",
Expand Down
6 changes: 6 additions & 0 deletions docs/en/component.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ $this->loadComponent('Authorization.Authorization', [
]);
```

The same can be done at runtime, for example in `beforeFilter()`:

```php
$this->Authorization->skipAuthorizationActions('login', 'logout');
```

By default, every action requires authorization when authorization checking is
enabled.

Expand Down
27 changes: 27 additions & 0 deletions src/Controller/Component/AuthorizationComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Authorization\AuthorizationServiceInterface;
use Authorization\Exception\ForbiddenException;
use Authorization\IdentityInterface;
use Authorization\Policy\Result;
use Authorization\Policy\ResultInterface;
use Cake\Controller\Component;
use Cake\Http\ServerRequest;
Expand Down Expand Up @@ -130,6 +131,16 @@
$action = $this->getDefaultAction($request);
}

$skipAuthorization = $this->checkAction($action, 'skipAuthorization');
if ($skipAuthorization) {
$this->skipAuthorization();

return match ($method) {

Check failure on line 138 in src/Controller/Component/AuthorizationComponent.php

View workflow job for this annotation

GitHub Actions / cs-stan / Coding Standard & Static Analysis

Match expression does not handle remaining value: string
'can' => true,
'canResult' => new Result(true),
};
}

$identity = $this->getIdentity($request);
if (!$identity instanceof IdentityInterface) {
return $this->getService($request)->{$method}(null, $action, $resource);
Expand Down Expand Up @@ -178,6 +189,22 @@
return $this;
}

/**
* Adds actions that should skip the automatic authorization check.
*
* Actions registered here are marked as authorized in `authorizeAction()`,
* which runs on the configured `authorizationEvent`.
*
* @param string ...$actions Controller actions to skip authorization for.
* @return $this
*/
public function skipAuthorizationActions(string ...$actions)
{
$this->_config['skipAuthorization'] = array_merge($this->_config['skipAuthorization'], $actions);

return $this;
}

/**
* Allows to map controller action to another authorization policy action.
*
Expand Down
18 changes: 18 additions & 0 deletions tests/TestCase/Controller/Component/AuthorizationComponentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,24 @@ public function testAuthorizeModel(): void
$this->assertEquals(['foo', 'bar', 'baz'], $this->Auth->getConfig('authorizeModel'));
}

public function testSkipAuthorizationActions(): void
{
$this->Auth->skipAuthorizationActions('foo', 'bar');
$this->assertEquals(['foo', 'bar'], $this->Auth->getConfig('skipAuthorization'));

$this->Auth->skipAuthorizationActions('baz');
$this->assertEquals(['foo', 'bar', 'baz'], $this->Auth->getConfig('skipAuthorization'));
}

public function testSkipAuthorizationActionsAppliedOnAuthorizeAction(): void
{
$service = $this->Controller->getRequest()->getAttribute('authorization');

$this->Auth->skipAuthorizationActions('edit');
$this->Auth->authorizeAction();
$this->assertTrue($service->authorizationChecked());
}

public function testMapAction(): void
{
$this->Auth->mapAction('foo', 'bar');
Expand Down
Loading