This episode is for members only

Sign up to access "Laravel Teams" right now.

Get started
Already a member? Sign in to continue
Playing
09. Authorising team switching

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
A really important part about team switching is we need to make sure that the user belongs to the team that they're trying to switch to. At the moment we could pass in any team ID and we would actually be switched over to that team and of course potentially be able to view any of the items within that team.
00:16
So let's start out by writing a test and then we'll go ahead and fill in of how we can authorise this. We'll do this a couple of ways, we'll just do some refactoring along the way. So let's start with our test and let's say cannot switch to a team that the user does not belong to, something like that. So how do we set this test up? Of course we need a user, so let's start out with the user that is trying to switch.
00:44
But then what we'll do is we'll create out another team and let's go ahead and just create this out like this. And then we're going to try and switch to that team. So let's say acting as the user, let's try to switch to that team. So we'll make a patch request exactly the same way to team set current with another team in there.
01:07
So we know that we don't belong to that because we've not attached it at all within this test. So there's a couple of things that we can do here. The first one is to assert that this is forbidden. So we want to return a forbidden response here, but we also want to make sure that that hasn't actually been switched in the background.
01:23
Now, it's very unlikely that if it is forbidden, it's ever going to get to this point, but there's no harm including it. So let's say current team ID not to be another team ID. So basically just make sure that we get a forbidden and that the ID hasn't been updated. Okay, so if we run this test as it is, it will fail because we can see that we get a redirect,
01:48
which of course we shouldn't do and this will have failed as well, but obviously not got to that point just yet. So let's figure out how we can do this. So the first thing that we could do is authorize this manually by just going ahead
02:04
and manually returning a forbidden response in its longest form. We could do something like this and we're going to change this over. We could say if request user teams contains team or doesn't contain team, then we can abort with a 403.
02:22
So that will pass our test and of course it would pass the expectation because we haven't got to this point because abort will stop the execution of this and obviously just return the status code. Now an easier way to do this is to say abort
02:37
unless if you did want to go down the route of doing this directly within your controllers, you could say abort unless the users teams contains that team. So you could say user teams and contains and pass that team in and you can abort with a 403 unless that's the case and that should pass the test as well.
02:57
Now we don't necessarily want to do this because we're going to be pulling authorization into a lot of what we're building here when we get to roles and permissions. So it would be good to start to create out our team policy,
03:10
which gives us a bunch of ways that we can authorize. So let's get rid of this and let's go ahead and instead create out a policy for this. So let's say PHP artisan make policy and we'll call this team policy and inside of this team policy,
03:27
we can just create out a bunch of methods to authorize certain things so we can get rid of the constructor here. Let's create out a set current. So this is going to authorize this for a particular team.
03:41
We'll get the user in here implicitly. We don't need to pass that in when we actually invoke this and then this is where we can add our check. So let's just return false in here for now
03:51
and let's go ahead and switch this over. To do this we're going to use the gate facade and we're going to say authorize set current. So that's the method that we just gave the name for
04:02
and we're going to pass in team. So now we have one place where we can authorize any team actions and like I said, there are going to be loads more later. So we don't need to pass the user in here
04:12
because over in our team policy this will automatically get passed in. Let's go ahead and run our test and we'll probably get a fail here because the other test that we created,
04:20
it switches the current team for the user, is obviously going to fail because we are manually returning false here. But we can go ahead and just fill this in now. So what's the condition that we can set current?
04:30
Well, that's just going to be that the user that we get in here, teams, contains that team. So as long as the user belongs to that team, return true or false if they don't.
04:42
Okay, let's go ahead and run our controller tests and yeah, that looks good. Let's just go ahead and run all of our tests just to make sure and there we go.
04:49
So successfully now authorizing this using a policy which we're going to make a lot of use of a little bit later. Now one thing that you can do and this is totally optional and we are going to be using these throughout the rest of the course
05:02
is to create a form request. These just tidy things up so you don't have to manually authorize using the gate facade directly in your controllers.
05:11
Let's take a look at what this looks like and then our test should still pass once we've done this refactor. Okay, so I'm going to go ahead and make out a form request here. So make request and let's call this set current team request.
05:28
Now the point of form request if you haven't come across them before is that they extend the base request but they allow you to authorize and add validation rules.
05:39
Now obviously we don't have any validation rules here but let's switch this over first of all. So set current team request. Let's get rid of this gate, this manual gate authorization
05:49
and we could get rid of these two as well now and let's go over to that request and see what we've got. So we've got validation rules here, which we don't need so we can ignore them, but we have this authorized method.
05:59
So in here what we can do is just return for example, this user, which will always be in here because remember it extends our base request it always has access to the currently authenticated user
06:11
and we can say something like can. So we could say set current and then the team well, where does that come from? Well again, because this is a request
06:20
we can access any of the models that we have resolved via root model binding. So much like we just got them in the controller over here we can say this and team.
06:31
So that's part of that request now. So this should work in exactly the same way. Let's go ahead and run our tests and find out and yeah, there we go.
06:39
We can switch properly when we are part of a team and of course we can't switch if we're not part of a team. So a little refactor there, which is completely optional but I find this helps nicely tidy up our controllers.
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!