Permission Systems that Scale

Fixing Permissions Exercise

Permission Systems that Scale

Lesson Description

The "Fixing Permissions Exercise" Lesson is part of the full, Permission Systems that Scale course featured in this preview video. Here's what you'd learn in this lesson:

Kyle instructs students to spend time fixing the remaining permission bugs in the codebase themselves before walking through each fix, addressing scattered copy-pasted permission checks across pages and UI components, then wraps up by highlighting how the exercise exposes the core flaw of the naive system: duplicated, error-prone logic that needs to be centralized.

Preview

Transcript from the "Fixing Permissions Exercise" Lesson

[00:00:00]
>> Kyle Cook: Now, what I essentially want you to do is I want you to spend some time, maybe 5, 10 minutes, going through and fixing all of the rest of the mistakes that you can fix in the time limit you have. So just search for fixed colon and just try to fix as many of these as you can. And the reason I want you to do this is so that you can actually see what it feels like to use the system as it is. You can see all of the pain points and issues that exist in this system.

[00:00:20]
So as we evolve the system, you can see firsthand how much better it feels to use these newer systems versus this much more naive system. So hopefully you guys were able to spend some time and saw the problems that are available with this permission system. You probably saw a lot of copy and pasting between different things, and now I'm essentially going to go through and write out these permissions myself as well to kind of show you where all those problems are.

[00:00:47]
So first, let's just make sure we search for this fixed keyword inside here so we can look for all those locations and right here we've already fixed this one, so I just want to leave a comment of permission. Right here, so that way when we come back and update our permission systems, we know where all of our permissions live. And since we fixed this, let's just remove that fixed comment so we can slowly see the progress we're making.

[00:01:09]
Now here this is fixing by adding an admin role, so you can see, remember at the beginning when I showed you creating a new document, how admins didn't have the ability to do that, it's because we just forgot to add a check for it here. So this is one of the few instances where we actually need to write React code because we're in the UI so we just want to check to make sure that the user's role is either equal to author or their role is specifically going to be equal to admin, because admins also have the ability to create different documents.

[00:01:33]
So we have now fixed that. We can remove the comment and continue onward. And this is kind of going to be the trend we do everywhere. Here we just don't even have a check around this button right here, so we completely forgot to add this. Let's make sure we add in the check. And since this is creating a new document, we essentially want to use the exact same check we used here. So again, more and more copy pasting between all the different places in our code where we have things being written.

[00:01:54]
So let's copy paste that into here and let's make sure we wrap the entire button inside of that if check. So now again, we're only doing this if we have permission. And we can change this comment to say, Permission, so we can make sure we know where to come and fix this particular issue. There we go. Now you may have seen a lot of these different checks, not checking permissions if they have access to the project or the document.

[00:02:15]
Essentially every single one of our pages in our actual page application, this is where it runs on the server to determine what document to get and everything like that. We're not doing any checks inside of here for if they have permission to view that document, edit that document, or anything else. So this is where we need to add all those permissions. The first one, if we just go back to one of the pages we've already worked on.

[00:02:36]
I believe we have one here at the top. Here we go. This is the permission we're pretty much going to be copying on almost every page to make sure they have access to the project, so it's come into where we have that fixed. Here we go, and we want to make sure first of all they have access to this project, so we can paste down that code, and we already are getting the user down here, so we'll just get rid of that, and we need to get the project as well.

[00:02:57]
So we can say the project is equal to get project by ID. Make sure we await that. There we go. Pass it in that project ID. And then we just want to check to see if it's null, we can just return to not found or something, so if our project is equal to null we'll return not found. There we go, and that cleaned up that issue right there. Now we can finish off with that redirect. And normally we would need to add permissions to make sure they have access to view this document, but we already know a user has access to every single document as long as it's in the project that they're a part of.

[00:03:38]
So this check right here is enough to solve that problem. So we can get rid of those fixed checks, and now we've essentially crossed off a few more things from our list. I'm again going to copy this over because almost every page has this exact same problem. You can see here this is our edit document page. Of course we want to make sure the user has permission to view the project. So this check right here is the check we've done all over the place for making sure they have access to the particular project.

[00:03:59]
So let's make sure we get that check in place. And then since specifically this is our edit document page, we want to make sure that they have access to edit this document as well. So we're just going to add in another permission check down here, and this one is checking that they have edit permission. And if you remember from our permission matrix, if we scroll to where that was, I believe it was on the previous page, you can see for editing documents, only the editor and the author and the admin have permission, so everybody except for a viewer has permission to edit a document.

[00:04:28]
So we can just come in here and say if the user.role is equal to viewer, oops, make sure I spell that properly. There we go. Well then we know that they don't have permission to do this, so we'll just redirect them wherever. It doesn't really matter, but we'll just redirect them to the login page again. You could redirect them to the project page or something else. This is just easy enough. That solves those particular permissions, and again, we'll just copy this over because we're going to have very similar permissions in the rest of our pages.

[00:04:52]
This is our new document page, so only users that have access to create a new document should be able to do so. So we'll come in here with our permission for first checking that they have access to the project, that's what that first check is for, and then the second check is going to be only for people that have access specifically to create a new document. So we know that if the role is equal to viewer or if the user's role is equal to editor, those people do not have permission to create a brand new project.

[00:05:16]
So if either of those are true, we'll just make sure we redirect the user. Get rid of those fixed checks, and now you can see we've almost gone through all the different checks inside of our code. Let's just copy this one more time, go to the next page. This is a page for editing a project, so this one is actually a little bit more self-explanatory. We don't even need this big project check up here because we're not checking to see if they can view the project, we're only checking if they can actually edit the project.

[00:05:39]
So we can actually simplify this quite a bit. By just having our check right here, if the user's role is not equal to admin, admins are the only ones that have access to editing a project, so we can just say anytime that they're not an admin, we're going to redirect them from this particular page. There we go. Make sure that we'll put a little question mark on here just because it could be null, and we'll make sure that we check that as well.

[00:06:04]
There we go. And actually I'll just come in here. I'll say if user role is equal to null or there we go. Well, it's not user role, user, there we go. So if the user is null or they're not an admin, then we'll redirect them because they don't have access to this particular page. That cleans up our issues here and it looks like the last of our permission checks are just inside of our UI. So this right here is the button for deleting a project, again, something only admins have access to, but currently anyone can access this button, even though it would block them on the actual backend.

[00:06:34]
So we'll just say if the user role is equal to admin, then we'll make sure that we render out this button. Come down below that card, there we go. That fixes that and we'll just change this comment to permission. So again, we remember to come back to this permission when we update our code. Finally here on our new project page, this one's really simple, it's the exact same stuff we had on our edit project page, so we'll just scroll up to where we had that and we'll copy the exact same permission because only admins can create new projects.

[00:06:59]
Paste that down and make sure we just import get current user, and we'll import the redirect code, make sure I get it from the right location. There we go. And then finally right here, this is for creating a document. I showed you that viewers were able to create documents if they were able to navigate directly to the URL, which is obviously not ideal. So we want to make sure that if the user.role is equal to the viewer, that they don't have access to actually do anything for creating a document.

[00:07:23]
We have our permission comment, and now you can see we fixed all of our current permission errors. And to just test to make sure that this is working properly, what we can do is we can go into our application. I'm going to log into an admin user and go to a page I know. My viewer doesn't have access to this particular document here. I'll copy the URL. We'll log in as a user that definitely does not have access to this, and when I paste in this URL and hit enter, it should just redirect me back to the page I'm already on.

[00:07:46]
And as you can see, it did. So we at least solved some of our permission errors in our application. And this is something that you may not think is important for permission systems at scale, like why are we fixing bugs in our permission system. But it's because when you use these lackluster permission systems, these type of bugs are incredibly common and easy to crop up. You may not have as many as were in this system because this is a little bit exaggerated, but they will crop up over time if you don't have a good solid system in place.

[00:08:10]
So now let's talk about the problems that we have with this particular system. Obviously, the biggest problem that you notice is we copy and pasted almost the exact same code between every single page. If we go ahead and we take a look at one of these pages, this line of code right here, are like 10 lines of code, this was copied and pasted probably 56 different times, and it's actually a relatively complicated permission check.

[00:08:30]
I mean, when I read this, it's not entirely clear what it does unless I spend some time reading it, and it's very easy to accidentally, you know, have a not equals inside of here, or maybe you accidentally changed this or symbol to an and symbol, and now all of a sudden all of your code is broken because you accidentally just made one small typo in your code. Also, this is really easy to make when you have to go back and update who has permissions to view a project, cause now you have to update 8 different places in your code, and if you mess one of them up, you now have security vulnerabilities.

[00:08:56]
And essentially that kind of ties into my second point is it's very easy to make a typo or forget to add a condition somewhere. Now at this point, essentially what we want to do is centralize all of our logic, at least as best as possible, so that way when we change what our permissions look like, at least it's in one place. Even if our permission code is still kind of ugly, it's only ugly in one place instead of ugly everywhere inside of our application.

Learn Straight from the Experts Who Shape the Modern Web

  • 250+
    In-depth Courses
  • Industry Leading Experts
  • 24
    Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now