تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Introducing Negative Permissions0:00

If we are going to talk about permissions, we need to talk about negative permissions. These allow us to explicitly assign permissions that deny access to something. And these are very important because they serve multiple purposes. First of all, it allows us to, well, essentially explicitly deny access to something. But from a documentation standpoint, it's also very useful because whenever you have a group-based system where permissions are assigned to groups, things get, well, a little confusing. You have to start to parse what can or can't a User do. And if you have negative permissions, then at least those stand out. Well, this User can't do that, that User can't do that, and so on. So we need to implement that.

Well, this User can't do that, that User can't do that, and so on. So we need to implement that. And of course, the permission itself really isn't anything special. All we have to do is just create the permission. So let's say that we want a permission that will deny access to delete any Article. And, you know, if I had thought about this beforehand, we could have probably done something like this, where we had the system, then a colon, and then whether it was an allow or a deny, and then a colon, and then whatever the permission would be. But I didn't think that far ahead. So we're going to follow the convention that we have right now.

Creating Deny Permissions1:20

But I didn't think that far ahead. So we're going to follow the convention that we have right now. And so we're going to create a negative permission that denies access to delete any Article. So the description is deny delete any Article. And then we just need to apply this to a given User, let's say the Author. So I also created a group for the Editors. And the permissions that they have are just what the Editors would need. The ability to update and delete any Article. They can't create anything. And I went ahead and assigned that to the Author.

Adding Policy Precedence1:53

They can't create anything. And I went ahead and assigned that to the author. But let's say that we want to prevent the author from being able to delete any article. They can still delete their own, but we don't want them to be able to delete any other authors. So let's sign in as the author, and let's take a look at what that's going to look like. Of course, we haven't really implemented that. So what we are going to see in the articles index is that the author can delete everything, because now they have that permission. But we need to go to the ArticlePolicy, because that is where we define the delete action. And negative permissions typically have precedence over everything else.

But we need to go to the ArticlePolicy, because that is where we define the delete action. And negative permissions typically have precedence over everything else. In fact, I can't really think of any system where negative permissions don't. So as a general rule of thumb, a negative permission has more precedence than any other permission. So really, the first thing we need to do here is check if the User has the permission that denies them the ability to delete any Article. Well, then we will simply return the deny as not found response. Now, you might be thinking this isn't going to work. And you are absolutely correct, because, well, that didn't work anyway. We shouldn't see any delete buttons.

Fixing Delete Button Checks3:07

And you are absolutely correct, because, well, that didn't work anyway. We shouldn't see any delete buttons. So let's take a look at the index for our articles. And let's take a look. So here we have the can directive. If we can update, then, oh, okay. We are showing the delete button based upon if the User can update the article. So we need an endcan there so that we can check if the User can delete the provided article. So now back in the browser, we see what I would expect to see. All of the delete buttons are gone.

So now back in the browser, we see what I would expect to see. All of the delete buttons are gone. Because inside of our delete action, the very first thing we check, if this User has the denyDelete permission, then we immediately return a deny as not found. So we aren't even checking if the user can delete their own at this point in time. And this is where negative permissions can start to not necessarily complicate things, but they can complicate things. You know, it can be as simple as doing something like this, to where we simply check for that permission and return. But in this case, it's not.

Refactoring with User Methods4:15

to where we simply check for that permission and return. But in this case, it's not. Really, we have two checks. We need to check if the User is trying to delete their own article, like what we checked down here. But then we also need to check if the userId is not the same as the authorId for the article. And you know what? Let's do this. Let's go to the User model and let's define a couple of methods here. So we can have one that is simply wrote.

Let's go to the User model and let's define a couple of methods here. So we can have one that is simply wrote. And we will provide an article and it will return a boolean value. And if the user wrote that article, then all we have to do is check if the ID of the user is the same as the article's author ID. But then I want another method that says didNotWrite. In which case, we will return if the user ID is not the same as the article's author ID. This way, inside of our policy, our code is going to read a little bit better. So if the user did not wrote the provided article, then the first thing we need to do is check if the user has this negative permission.

So if the User did not write the provided Article, then the first thing we need to do is check if the User has this negative permission that denies them the ability to delete any Article. And if so, we immediately return our response of deny is not found. Otherwise, we need to check if the User has the permission to delete any, in which case we return the allowed response. This makes it so that now we fall down to checking if the User can delete their own Article, in which case we don't even need to check if they wrote their own Article because we wouldn't be here if this is true. Well, not necessarily, but this is going to be okay.

article because we wouldn't be here if this is true. Well, not necessarily, but this is going to be okay. But you know what, let's do this. We will return, if the $user has the permission, the allowed response. Otherwise, return response()->deny('not found'). That way, we can be a little explicit here. So if the $user did not write this, then this code is going to handle that. But if they did write that, then this code will handle that. So it's a little bit more complicated, but not so much. So back inside of the browser, whenever we refresh the page,

So it's a little bit more complicated, but not so much. So back inside of the browser, whenever we refresh the page, we will see that now we can delete our own articles, but we cannot delete articles from other users. And now we have a model that we can use for any of our other actions. Like when it comes to updating an Article, we can take the same approach. So that if the User did not write the Article, then we would check for the update any deny. In which case, we would return deny as not found. Otherwise, we check if the User can update any,

In which case, we would return deny as not found. Otherwise, we check if the user can update any, we return the appropriate response. Otherwise, we check if the user can update and then return whether if they are allowed or they are denied that ability. And then we would just need to replicate that everywhere else. Except when it comes to create, this is one of those that would be much simpler. Because here we would just need to check if the user has that negative permission that denies them the ability to create an article. Then we would simply return the deny as not found.

Adding More Deny Permissions7:29

that denies them the ability to create an Article. Then we would simply return the deny as not found. Now, of course, we don't have those permissions, but let's go ahead and let's create them. We, of course, need to be signed in as admin, but we can create. That first one was denying access to create an Article. So we can say deny article create. But then we also had the article update any deny. In which case, we would say deny update any article. And now that we have those negative permissions, we can assign them to users.

In which case, we would say deny update any Article. And now that we have those negative permissions, we can assign them to users. And since our code is already set up to handle those, we will now be able to explicitly deny access to those abilities. So when building a system that uses permissions, always plan for negative permissions. They are extremely important, and they give you even more control over what you're using.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟