1 00:00:00,000 --> 00:00:02,000 [?music?] 2 00:00:02,000 --> 00:00:05,000 [Master Class: Designer and Developer Workflow: Restricting Access] 3 00:00:05,000 --> 00:00:09,000 [Jim Hoskins] So now we've associated users with jobs and we can easily see 4 00:00:09,000 --> 00:00:14,000 how we could display which user is associated with a job within our view. 5 00:00:14,000 --> 00:00:18,000 The next step is we want to make it so that only people who are logged in 6 00:00:18,000 --> 00:00:22,000 can create a job, and when they go ahead and create that job, we want to make sure 7 00:00:22,000 --> 00:00:27,000 that we associate the user who is signed in with the new job that they've created. 8 00:00:27,000 --> 00:00:30,000 That way, later on, we can always check to make sure 9 00:00:30,000 --> 00:00:33,000 A. That there's a user associated with a job, 10 00:00:33,000 --> 00:00:37,000 and B. When somebody tries to edit a job, we can make sure that they're authorized to do so 11 00:00:37,000 --> 00:00:42,000 by checking that the user associated with that job is the user trying to edit it. 12 00:00:42,000 --> 00:00:46,000 So the way we're going to do this is by modifying the controller 13 00:00:46,000 --> 00:00:51,000 to make sure that jobs/new and jobs create method 14 00:00:51,000 --> 00:00:55,000 are only accessible by people who are currently logged in, 15 00:00:55,000 --> 00:00:57,000 so if we were to type in job/new, 16 00:00:57,000 --> 00:01:02,000 right now, I'm signed out and we can go to Job Title and we can go ahead and fill in all this 17 00:01:02,000 --> 00:01:07,000 and create a new job, which is not what we want at all. 18 00:01:07,000 --> 00:01:10,000 So let's go and check out our controllers. 19 00:01:10,000 --> 00:01:13,000 I'm going to go ahead and clean a little bit of this up. 20 00:01:13,000 --> 00:01:16,000 I don't need to be looking at that. 21 00:01:16,000 --> 00:01:20,000 And what we are going to be focusing on is the jobs controller, 22 00:01:20,000 --> 00:01:23,000 and this is our standard restful controller. 23 00:01:23,000 --> 00:01:29,000 We have index, show, new, edit, create, update, and destroy. 24 00:01:29,000 --> 00:01:33,000 To go through each of these methods and think about how we are logically going to worry about 25 00:01:33,000 --> 00:01:38,000 the authorization, the index is always going to be available to everybody. 26 00:01:38,000 --> 00:01:43,000 We're always going to show all the jobs in the database 27 00:01:43,000 --> 00:01:46,000 and we're always going to be allowing anybody to see a specific job, 28 00:01:46,000 --> 00:01:50,000 so show is also going to be publicly available. 29 00:01:50,000 --> 00:01:55,000 The new method which shows the form should only be visible to people who are signed in, 30 00:01:55,000 --> 00:01:58,000 so that way, if you're not signed in, you can't see the new form 31 00:01:58,000 --> 00:02:01,000 and the new form should only be visible to people who are logged in. 32 00:02:01,000 --> 00:02:05,000 And similarly, the create method, which actually does the job of creating it 33 00:02:05,000 --> 00:02:09,000 should only be accessible to people who are logged in. 34 00:02:09,000 --> 00:02:12,000 Simply protecting the new form isn't enough because 35 00:02:12,000 --> 00:02:15,000 somebody could easily enough just post directly to create 36 00:02:15,000 --> 00:02:19,000 and if we're not checking there, we're not doing an effective job protecting our application. 37 00:02:19,000 --> 00:02:22,000 The edit and update methods are slightly more complex; 38 00:02:22,000 --> 00:02:25,000 not only do we want to make sure somebody is logged in, 39 00:02:25,000 --> 00:02:29,000 but we also want to ensure that the person who is logged in 40 00:02:29,000 --> 00:02:33,000 is the person who is associated with that job 41 00:02:33,000 --> 00:02:37,000 and destroy has the same authorization requirements as edit and update. 42 00:02:37,000 --> 00:02:42,000 We need to make sure that the job is the job associated with the current user. 43 00:02:42,000 --> 00:02:45,000 So in order to make sure that the new and create are only accessible 44 00:02:45,000 --> 00:02:48,000 when somebody's user or current user is defined, 45 00:02:48,000 --> 00:02:50,000 we're going to use a feature in Rails called filters. 46 00:02:50,000 --> 00:02:53,000 And basically, what they are is we're going to define a method 47 00:02:53,000 --> 00:02:56,000 and we're actually going to define it in the application controller. 48 00:02:56,000 --> 00:02:59,000 That way, we can use this everywhere. 49 00:02:59,000 --> 00:03:05,000 We'll specify at the top of our jobs controller that this new method should be called before 50 00:03:05,000 --> 00:03:07,000 any time we request new or create. 51 00:03:07,000 --> 00:03:11,000 And if this method returns false, then Rails will not allow 52 00:03:11,000 --> 00:03:16,000 our method to actually execute and allows us to protect our method 53 00:03:16,000 --> 00:03:20,000 based on the return value of that method. 54 00:03:20,000 --> 00:03:23,000 So I'm going to open up applicationController 55 00:03:23,000 --> 00:03:26,000 and this is where we're going to write our method that will determine 56 00:03:26,000 --> 00:03:28,000 whether or not we're logged in. 57 00:03:28,000 --> 00:03:32,000 So I'm going to call this method require_current_user. 58 00:03:32,000 --> 00:03:36,000 We'll just do def require_current_user. 59 00:03:36,000 --> 00:03:41,000 And basically, all I want to do is check that there is a current user, 60 00:03:41,000 --> 00:03:46,000 and if there isn't, we'll go ahead and put up an error message 61 00:03:46,000 --> 00:03:51,000 and redirect to the homepage, for instance, and show that error message. 62 00:03:51,000 --> 00:03:54,000 Now, by redirecting from within a before filter, 63 00:03:54,000 --> 00:03:57,000 we actually stop the rest of the requests from happening 64 00:03:57,000 --> 00:04:01,000 so we don't have to worry about things in our actual actions executing after this 65 00:04:01,000 --> 00:04:03,000 after we redirected somebody. 66 00:04:03,000 --> 00:04:07,000 So as long as there's a redirect_to call inside of our before filter, 67 00:04:07,000 --> 00:04:10,000 it is enough to stop the request from happening 68 00:04:10,000 --> 00:04:15,000 and act as a defense or barrier against unwanted requests. 69 00:04:15,000 --> 00:04:22,000 So to simply do that, we'll just say unless current_user. 70 00:04:22,000 --> 00:04:28,000 We will redirect_to root_path 71 00:04:28,000 --> 00:04:32,000 and we will go ahead and put a flash message 72 00:04:32,000 --> 00:04:35,000 for [error] 73 00:04:35,000 --> 00:04:41,000 and say flash[:error] = "You must be logged in." 74 00:04:41,000 --> 00:04:45,000 So now that we have a controller method called require_current_user, 75 00:04:45,000 --> 00:04:47,000 we can use this as a before filter. 76 00:04:47,000 --> 00:04:49,000 So how do we do that? 77 00:04:49,000 --> 00:04:51,000 We'll open up the jobs controller 78 00:04:51,000 --> 00:04:58,000 and we will use the before_filter method 79 00:04:58,000 --> 00:05:00,000 and this will take a symbol that is the name of our method, 80 00:05:00,000 --> 00:05:06,000 which was require_current_user. 81 00:05:06,000 --> 00:05:11,000 So let's see where this gets us. 82 00:05:11,000 --> 00:05:13,000 So if I were to refresh, 83 00:05:13,000 --> 00:05:18,000 and we jumped into a redirect loop and that's because we're requiring the current user 84 00:05:18,000 --> 00:05:21,000 for any method inside of our jobs controller, 85 00:05:21,000 --> 00:05:26,000 including the index action, which is the homepage that we're trying to redirect to. 86 00:05:26,000 --> 00:05:29,000 So in this case, we got redirected to the homepage 87 00:05:29,000 --> 00:05:32,000 which also requires a current user which redirects to the homepage, 88 00:05:32,000 --> 00:05:34,000 so on and so forth, 89 00:05:34,000 --> 00:05:36,000 and that's obviously not good. 90 00:05:36,000 --> 00:05:41,000 But fortunately, we also don't want to actually require a current user on the homepage, 91 00:05:41,000 --> 00:05:43,000 so we need to change our before filter. 92 00:05:43,000 --> 00:05:46,000 Besides just taking a method, before filter can take options. 93 00:05:46,000 --> 00:05:51,000 For instance, the option except, and this will take a list of methods 94 00:05:51,000 --> 00:05:55,000 that we do not want to apply this before filter to. 95 00:05:55,000 --> 00:05:59,000 So for instance, we don't want to require a user for index: 96 00:05:59,000 --> 00:06:00,000 :require_current_user, :except => [:index, :show] 97 00:06:00,000 --> 00:06:03,000 nor the show page. 98 00:06:03,000 --> 00:06:06,000 Alternatively, we could have used the only option 99 00:06:06,000 --> 00:06:10,000 and specified which methods should have the before filter, 100 00:06:10,000 --> 00:06:13,000 but in this case, since there are fewer methods that are the exception, 101 00:06:13,000 --> 00:06:15,000 except is a better option here. 102 00:06:15,000 --> 00:06:18,000 So if we save this and refresh, 103 00:06:18,000 --> 00:06:21,000 now we're able to access Easy Jobs! here 104 00:06:21,000 --> 00:06:24,000 and that's because we are no longer requiring a current user, 105 00:06:24,000 --> 00:06:27,000 but if I were to click Edit here, for instance, 106 00:06:27,000 --> 00:06:29,000 we're getting redirected back to home. 107 00:06:29,000 --> 00:06:33,000 Now, it doesn't look like our flash error is showing up in our layout, 108 00:06:33,000 --> 00:06:37,000 so let's take a look at that and see if we can't just get it in there real quick. 109 00:06:37,000 --> 00:06:47,000 So that's going to be in the app/views/layouts application.html.haml. 110 00:06:47,000 --> 00:06:50,000 We have a flash notice, but we don't have one for error, 111 00:06:50,000 --> 00:06:53,000 so I'm just going to copy and paste, change this to error, 112 00:06:53,000 --> 00:07:02,000 and I'll allow Nick to add the appropriate styling to differentiate between errors and notice. 113 00:07:02,000 --> 00:07:06,000 So if I refresh, and let's click Edit here, 114 00:07:06,000 --> 00:07:09,000 we now get "You must be logged in," and I'm sure Nick will style this 115 00:07:09,000 --> 00:07:13,000 to make this very visible so you can see that there is an error.