Intro to Authorization Policies0:00
(upbeat music) Okay, the last thing we need to do to finish configuring our app is I need to know who is allowed to do what and either show them or not show them the actions based on what permissions they have. Now, obviously our app right now is very, very simple, but imagine as you're building and getting bigger that you have roles and permissions and certain people can do something or not do something.
that you have roles and permissions and certain people can do something or not do something. And the way to do that in a general Laravel app is to use policies. And so let's start by just reviewing policies really quickly, outside the context of filament, and then let's go ahead and see how filament makes it really easy to use policies. (upbeat music) So if I go to my IDE,
Testing Policy in Routes0:44
(upbeat music) So if I go to my IDE, I'm just gonna go to web.php. And I'm gonna add a new route here. I'm gonna say route gets policy. And we'll have a closure here. Okay, so let's just see if we have the ability to edit a feature. So we'll just go ahead and grab a feature. We'll have feature first and can you do it?
So we'll just go ahead and grab a feature. We'll have feature first and can you do it? And then if we can, feature updates, we'll just say name is new feature name. Great, and this needs to be in an array. So let's do that really quickly. Okay, so if I go ahead and hit this route, so let's go to our app. I'm just gonna hit this policy route. All right, so that happened.
I'm just gonna hit this policy route. All right, so that happened. And let's go ahead and echo feature name. Okay, so we've done that. And here's a new feature name here. But MI as the logged in user allowed to do this. Let's see, we should have a logged in user. So off user, let's hit this route here. Yep, we do have a logged in user. So we need to do something like off user can update the feature.
Creating the Feature Policy2:04
Yep, we do have a logged in user. So we need to do something like off user can update the feature. So we can say if the user can't update the feature, then let's just abort 403. Okay, so if I refresh this page, I'm now getting a 403 forbidden, but what is this doing? And the answer is it's looking for a policy. So let's go ahead and create a policy. Let's use our terminal and say artisan make policy. We'll say it's a feature policy.
Let's use our terminal and say artisan make policy. We'll say it's a feature policy. And if we go to feature policy here, we've got a new policy instance. And what we would need to do is define a update method here. And right now, let's just return true. Okay, so now if I come here and refresh, it's gonna allow me to update the feature to a new name. Let's go back to the web.
it's gonna allow me to update the feature to a new name. Let's go back to the web. So we ran this code and if the user can update this current feature or if it can't, we're gonna abort. Otherwise, we're gonna let it go. So let's give it a new name, hit this route. And yeah, we're allowed to update the feature. But without the policy or if I go back to the policy and if I change it to false or we might do something specific,
and if I change it to false or we might do something specific, like maybe we say user email equals Kevin@padmission.com. So we're allowed to do it when it's me. But if I put a different email here, we're gonna get a 403 forbidden. So this policy feature is something that's baked into Laravel, but filament uses this extensively and it's very powerful.
Enabling Filament Strict Authorization4:01
that's baked into Laravel, but filament uses this extensively and it's very powerful. And so what I wanna do is go to my admin panel provider. And I'm gonna add one more method here and this is strict authorization. So now that I've done this, let's go back to our app and let's try to get to, sorry, the admin. And we're now getting an exception because we have strict authorization mode enabled
And we're now getting an exception because we have strict authorization mode enabled but there's no view any method on the feature policy. And so we need to go to our feature policy, create a view any, passing our user and if I return true here, now I can refresh the page and it does actually allow me to view. So if we go to the features, strict authorization mode is enabled
So if we go to the features, strict authorization mode is enabled but delete any was not set. Why? Why is it even checking delete any? Let's go to our feature resource and on this, sorry, we need to go to the table. So the features table, believe we have a bulk action here for delete. So I'm not gonna show you this.
believe we have a bulk action here for delete. So I'm not gonna show you this. I don't know, should I show you the bulk action delete? I don't know because there's no policy telling me whether I can or can't. So if we go back to the policy, we need a delete any. And so if we say that that's false, if I refresh the page, now hopefully it would work but there's a lot of other methods here.
Generating Full Policy Methods5:43
now hopefully it would work but there's a lot of other methods here. There's view, there's edit, all of those different things. So let's go ahead and delete this policy because what we can do now is let's go back to this and when we want to make the policy again but we can pass in model equals feature. And when we do this, now when we go to our feature policy, we get all of the methods that we want and right now everything's returning false.
we get all of the methods that we want and right now everything's returning false. So if I just change false to true and go back to my browser, now we are still missing a delete any which is not one that Laravel gives standard. So let's just copy delete. We'll say delete any. You can't pass in a feature to delete any because it's multiple and if we refresh now,
You can't pass in a feature to delete any because it's multiple and if we refresh now, we have the ability to have those policies, tell us whether a user can do a certain thing. Now if I click here, my bulk actions for delete are available. If I come back here and change this to false, look what happens. When I refresh the page, there is no bulk action anymore because even though the code says, "Hey, we have a bulk action here,"
because even though the code says, "Hey, we have a bulk action here," what Laravel's doing is saying, "Hey, is this user have a policy that enables them to do that bulk action?" And when the answer is no, then it doesn't show it. So if we did something like create, if we make that false, this is fine. I can still view the page, but now my button's gone. Right?
I can still view the page, but now my button's gone. Right? And so this all works. If I go back to the admin panel provider, I don't need this. I can comment that out and it all still works. All of the policies and all of the authorization still works. But I can tell you, building with filament, there have been so many times where I've added something and I didn't get the right authorization set up
Authorizing Custom Actions7:40
there have been so many times where I've added something and I didn't get the right authorization set up and users that weren't supposed to see it ended up seeing it. And so using this strict authorization makes it, you can't forget every single policy has to be defined and that allows you to make sure that you're safe. Now there is one exception and I wanna show you where that is and you have to be really careful about this. So even though we have strict authorization here, I'm gonna go to my list features page.
So even though we have strict authorization here, I'm gonna go to my list features page. We've got these header actions. So in the browser, we've got no action showing right now because our authorization is blocking the create action, but I can create any action I want. We'll just do an action make test and the action will do nothing, let's just DD that. And so now I have this test action. If I refresh, this is now showing here.
And so now I have this test action. If I refresh, this is now showing here. And if I click it, it executes whatever code is in this callback and this cannot be caught by that strict authorization because the strict authorization does not know what authorization method or even what model this is associated with. So it has no idea how to throw that exception saying that this is not authorized because it really doesn't know how it should be authorized.
saying that this is not authorized because it really doesn't know how it should be authorized. So anytime you make a custom action like this, you would want to define your own authorization. So if we just pass false into here and return, then there we go. Or if we pass true, again, it will show. So you're going to not want to pass false or true here. You're going to want to do whatever logic you can if you're creating these custom actions
You're going to want to do whatever logic you can if you're creating these custom actions so that you ensure that every single action has its own policy authorization. And again, if you wanted a custom policy, you could say gate allows test and then let's pass in the feature model. And I think we need one more parentheses here. So not text, but test. And so if I do this in refresh,
So not text, but test. And so if I do this in refresh, now it's not going to show because my user doesn't have this in the policy, but if I go to my feature policy and at the bottom we'll create a test, public function test, and we will just return true. So if I am allowed to do test, then it's going to show. So again, you can customize your policies.
So if I am allowed to do test, then it's going to show. So again, you can customize your policies. However you want, you're not limited to just what comes with the policy when it's generated, but whatever you do here, just make sure you're authorizing every single action.
