This episode is for members only

Sign up to access "Laravel Teams" right now.

Get started
Already a member? Sign in to continue
Playing
29. More authorisation and checks for role changing

Episodes

0%
Your progress
  • Total: 4h 36m
  • Played: 0m
  • Remaining: 4h 36m
Join or sign in to track your progress
01. Introduction and demo
4m 49s
0%
02. Setup with Pest
4m 2s
0%
03. Building the user teams relations
6m 5s
0%
04. Creating a personal team when registering
6m 3s
0%
05. Leaving all teams when an account is deleted
3m 55s
0%
06. Tracking the current team
4m 50s
0%
07. Showing team details in the UI
2m 55s
0%
08. Switching to another team
7m 24s
0%
09. Authorising team switching
6m 53s
0%
10. Updating a team name
10m 48s
0%
11. Basic roles and permissions setup
5m 26s
0%
12. Team roles and permissions middleware
9m 18s
0%
13. Authorising current team updates
3m 43s
0%
14. Testing team permissions through HTTP requests
3m 58s
0%
15. Leaving a team
10m 50s
0%
16. Displaying team members
8m 42s
0%
17. Making team members look better
5m 3s
0%
18. Removing a team member
15m 18s
0%
19. Preventing self removal from a team
4m 7s
0%
20. Storing invitations
13m 31s
0%
21. Validating invitations
6m 38s
0%
22. Authorising team invitation creation
6m 22s
0%
23. Displaying invitations
3m 16s
0%
24. Revoking invitations
12m 46s
0%
25. Sending an invitation email
13m 6s
0%
26. Accepting an invitation
12m 22s
0%
27. Displaying a modal to change a member’s role
10m 31s
0%
28. Updating a member’s role
9m 5s
0%
29. More authorisation and checks for role changing
10m 14s
0%
30. Fixing up the email sending test details
49s
0%
31. Fixing and validating email addresses for invites
1m 32s
0%
32. Tidying up @can directive checks
3m 25s
0%
33. Detaching roles when removing users
5m
0%
34. Adding an extra layer of protection to the team middleware
6m 35s
0%
35. Getting related models through teams
5m 37s
0%
36. Building a helper to access the current team
10m 47s
0%
37. Getting all related models through all teams
7m 15s
0%
38. Creating new teams
13m 7s
0%

Transcript

00:00
So I suppose the benefit of writing tests is in the last episode we completely forgot to test in the UI whether we could update a member's role. So let's go ahead and do that now and then we'll work on some of the validation and permission checking around role updates. OK, so let's change Mabel's role over here from a team member to a team admin.
00:19
Hit change role and there we go. Sure enough, this is changed over and of course you could update this to send an email, whatever you needed to do. OK, I'm going to change this role now back to member and let's go over and start to think about some of the checks that we need here. So the first one is the permission. That's the most important. We need to check if the user has permission.
00:40
We can write a test to check the user is in that team. We don't necessarily need to do that, remember, because we already know that this is within the context of the team that we're currently sending the request down to. So it doesn't matter as much, but we'll go ahead and write a test for that anyway, doesn't hurt. We need to validate the role to make sure it exists.
01:04
And to be honest, I think that's pretty much it. So let's go ahead and work on the one with permission. This is probably the most difficult. So once again, let's go ahead and grab one of our other tests that we've already set up here and let's fill this in first of all. So let's say it does not update the role, if no permission, going to make sense.
01:27
We'll go ahead and do the setup in exactly the same way. So we'll have a user here. Let's have another user as part of this team who is not an admin. So we can go ahead and keep this here. So let's say member or another user. So we know that this user as part of this team is just a team member.
01:50
And now let's act as the other user and let's go ahead and try to update my user. So basically the user who owns the team who we know is an admin. So let's go ahead and try and update their role to be a team member. So we're basically trying to downgrade them when we shouldn't be able to.
02:10
And of course, here we can we could do some assertions, but we basically want to assert that this is forbidden like we've done previously. OK, let's run this in isolation and we'll go ahead and make sure that this is working. So let's run a pest filter on this test and let's have a look. And yeah, we get failed. So temporary property ID on null.
02:28
OK, so let's just check this out. And it looks like this probably comes from the middleware. OK, yeah, so we want to exclude this middleware while we're trying to run this because the user who we are acting as we created quietly and they belong to the other team. So we could either switch that over to just create. So we know that they're a part of that. Let's just try that one more time and it should now work properly or we could go ahead and exclude that middleware either way.
02:55
But when we create quietly, this user who is trying to sign in and make a request obviously doesn't have a team so that middleware fails. And we could even improve our middleware. We might do that later. OK, anyway, so we know that this is not working, so we do get a redirect and we do not get a forbidden. So what do we do? Well, back over here, let's go ahead and update our request.
03:18
So let's go ahead and create out a request in here. Team member update request or team member patch request, whatever you want to call this. Let's switch this over team member update request and let's go and open this up and let's authorize this. And we know that we already started to build this out. So we want to say auth user can or this user, since we're already directly within a request here, can and let's just remind ourselves what we call this change member role.
03:54
And we know that we get the team into the request and we want to check that we can do this against the user, not the currently authenticated user, the user that we're passing in. OK, let's go ahead and run our test and see if this works. And yeah, it still fails. So let's see why this is. We're still getting a redirect. Yeah. So once again, if we come over to our test here and think about this, this other user, when they sign in and make this request, they'll be within the context of their current team. So remember, just when we're writing our tests, let's actually exclude that middleware that we had, so that team permission middleware.
04:32
Otherwise, they're always going to be in the context of their current team. And while it might not update them, this will fail our test. We'll have a really good think about this in a minute just in case, but let's just run that. And yeah, we get green. OK, so let's think about this over in our team member controller. So we will get through the team in here. Remember, we are finding that user within that team that we're authorizing.
04:56
Now, the important thing here is when we do an assign role on this member, this is always going to happen within the context of the team that we are only authorized to be a part of through that middleware. So this should work absolutely fine. It is confusing because we're sort of setting this global. But this test has proved that we can't do this cross user if we're trying to set another team for this. OK, so another test that we want to write is check that the user is within the team. So let's go ahead and build this one out.
05:25
So we'll just do another copy and paste on this test here. And let's pull this down. So does not update the user if they are not in the team. And this one's actually pretty straightforward. We don't really need much of this stuff. We don't need to exclude the middleware. We basically just want to grab another user out. So any user, it doesn't matter.
05:54
They can have their own team or not. And if we try to, as this user, update another user who doesn't exist within this team, then we want to assert that this is forbidden. Let's go ahead and run this test. So again, we'll just do this in isolation with the name of this. So let's filter down to this. And it does fail. Let's just have a look here. And we actually get an error. So argument one must be of type models user null given.
06:21
OK, so the reason this is now failing is failing because we're not allowed. But it's failing because over in our team member controller, this can't find that user. So we can't do anything with it. So as long as we go ahead and update our policy to specifically reject this, then we know it's going to work. So we have that first line of defense. But now we just want to check that the user is within the team directly within the policy.
06:47
So as we've done before, we can do exactly the same thing. Team members doesn't contain that member. If it doesn't contain that member, then just return false. And that just makes our policy a little bit clearer. Let's go ahead and run that test and we get green. Great. OK, so the last thing we want to do is make sure that we're validating the role that we are actually passing in.
07:11
So this is pretty straightforward because it just basically includes a validation rule. So let's go over to our test here and let's get rid of this one because we've done this. Let's go and copy this one over because, again, this test is going to be pretty straightforward. Let's say it validates the role to make sure it exists.
07:35
The last thing we want to do is allow any text to be passed in here. It will fail because the package that we're using will check if the role exists in the database for us. But there's nothing wrong with doing this directly within validation. And we're not even going to add the validation error to the client side because it's not really something that a user should be able to control.
07:54
We just want to fail this. OK, so let's roll with this simple example here. This might not work depending on when over in the policy each of these gets run. I think authorise will be first and then the validation rules. So let's try this out and we'll go ahead and switch around our test if we need to.
08:12
OK, so the rule for this is pretty straightforward. We want this to be nullable because remember is completely optional, but we also want it to exist. So let's go ahead and bring in our rule class in here and say exists. We want this to be in the roles table under the name column and that should be everything that we need.
08:30
So let's go back over to our test and fill this in. So what should happen if this fails? Well, we should say assert invalid or we could say assert session has errors and we could choose role in there. OK, so the role, let's change over to some wrong role and let's see what happens.
08:53
So I have a feeling this is going to fail with a forbidden because the authorisation check comes first, but let's try it out. So let's go and run this test and yet fails because yeah. OK, so we do need to do this in the opposite way around. So for the test itself is going to be more like this test here.
09:14
So let's grab all of the setup we used for this and actually make a proper request down to this. And we will use this another user. We'll actually call them member because we're looking at a best case scenario for authorisation, but not for validation. And let's try that out again. And yeah, we get it passed. So great.
09:36
So we can even say assert invalid as well. Just to add another assertion in there. OK, great. All of our tests are working. We know this works now. We now know that if we try to adjust any of these, it's not going to work, which is great.
09:52
So we can even go ahead and do that manually within here and change over one of these options to something that shouldn't be existed. So we can change that to a team member and it's going to redirect us back. It's not going to show us a validation message because we don't really care about this. We shouldn't be able to change these. But of course, when we do this successfully, it goes ahead and works.
38 episodes4 hrs 36 mins

Overview

Need team functionality in your Laravel application? Let’s build it from scratch.

We’ll cover the basics of creating teams, switching between them, sending secure team invites by email, and managing team members.

Powering everything will be roles and permissions for each member, with the ability to switch roles directly from your team dashboard.

Once you’re done, you’ll have mastered team functionality in Laravel.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!