I would like to only display the edit action of an article if the user is authorized. I tried to access the controller authorization in the template file like this:
Did you load the Authorize helper? Is there even such a thing? Why did you think that this would work?
For my application, I built a little Authorize helper. With that loaded, I can call $this->Authorize->can(...) in my views to check permissions on individual actions. I have at times had to work around limitations in the plugin, and am therefore currently using a modified fork of it, so I canāt guarantee that this will work for you out of the box, but it should be close enough to give the general idea.
Authentication and authorization are different. Authentication helper can get you details about who is logged in. Checking whether they have permission to do a particular thing is authorization, which doesnāt appear to have a stock helper.
I āgot inspiredā by $this->Authorization->authorize($article); in the ArticleController.php since it works there, without explicit loading a corresponding helper.
the can(ā¦) function is unknown. From the documentation I am not sure if I have to change the UserEntity.php, since I use $id = $this->request->getAttribute('identity'); instead of user_id
I added use Authorization\Identity; to the Application.php since
"If your application uses the cakephp/authentication plugin then the Authorization\Identity class will be used. This class implements the Authentication\IdentityInterface` in addition to the Authorization\IdentityInterface . "
This seems redundant though, as it states it already will be used automatically?
I followed the authorization tutorial so it is loaded in my Apllication.php and its middleware function. Although I miss the ResponseInterface $response in the public function getAuthorizationService().
So $id is the attribute identity now. What type of object is this?
Thatās why I tried refering to the controller: $this->controller->
But there I guess the View object (?) of $this in the template doesnāt have this reference.
Iām not sure of the āmain lineā procedure here.
In my application I wanted a more feature rich Identity than the one created by Authentication/Authorization so I had to write code to insure my substitute object implemented the two required interfaces.
It is the Authorization\IdentityInterface the provides the can() method. So, it sounds like your object isnāt properly implementing that.
Since I manually built my object to have the required features Iām not clear on what solution to suggest in your out-of-the-box case.
EDIT: I may have overlooked or the error has changed, but can() seems not to be the problem, but the $article?:
Call to a member function can() on null
OP (how to spoiler this text?):
I donāt know what could be wrong with my setup. I checked with the files of lukec8 and it seems OK (the same components setup and some differences in ArticlePolicy and ArticleController though).
So I guess I have to dig a little deeper. What object is the $id below? And to make sure, $this is a View? Is there a console where I can test with gettype()? Then I may find out where $id is missing the link with IdentityInterface.
My Identity class
App\Model\Entity\UserIdentity
Parents of my class
array (
'Authentication\\Identity' => 'Authentication\\Identity',
)
My class implements theses required interfaces
array (
'ArrayAccess' => 'ArrayAccess',
'Authentication\\IdentityInterface' => 'Authentication\\IdentityInterface',
'Authorization\\IdentityInterface' => 'Authorization\\IdentityInterface',
)
As I said earlier, my Identity object is different (UserIdentity) but it extends Identity and implements all the required interfaces.
If yours implements those interfaces, you are on the right path.
in <?php foreach ($articles as $article): ?> <tr>.. <td class="actions">... of edit.php (Article template)
and initiating $identity in the top of that template: $id = $this->request->getAttribute('identity');