27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

9.3.1 Protecting files<br />

Serving files through a controller<br />

You first need to generate the controller through which you’ll serve the assets. Call it<br />

files, because assets is already reserved by Sprockets:<br />

rails g controller files<br />

Now write a spec to ensure that unauthorized users can’t see the files inside it. For this<br />

spec test, you must create two users, a project, a ticket, and an asset. The first user<br />

should have permission to read this project, and the second user shouldn’t.<br />

Open spec/controllers/files_controller_spec.rb, and add let definitions that set up<br />

your users, project, ticket, and asset inside the describe for FilesController, as<br />

shown in the following listing.<br />

Listing 9.8 spec/controllers/files_controller_spec.rb<br />

describe FilesController do<br />

let(:project) { Factory(:project) }<br />

let(:ticket) { Factory(:ticket, :project => project) }<br />

let(:good_user) { create_user! }<br />

let(:bad_user) { create_user! }<br />

let(:path) { Rails.root + "spec/fixtures/speed.txt" }<br />

let(:asset) do<br />

ticket.assets.create(:asset => File.open(path))<br />

end<br />

before do<br />

good_user.permissions.create!(:action => "view",<br />

:thing => project)<br />

end<br />

end<br />

You used a let for setting up a project, two users, a ticket for this project, a path to the<br />

file that’s served from the controller, and the asset for the ticket. This is the asset you’ll<br />

be serving from the controller for this spec test.<br />

You set up the permission in a before block because you won’t be referencing it<br />

anywhere in your tests, so having it as a let block wouldn’t work. You should use let<br />

blocks only when you’re going to be referencing them inside your tests. If you need<br />

code set up beforehand, you should use a before block instead.<br />

To serve the files from this controller, use the show action, using the id parameter<br />

to find the asset the user is requesting. When the application finds this asset, you want<br />

it to check that the user requesting the asset has permission to read the project this<br />

asset links to. The good_user object should be able to, and the bad_user object<br />

shouldn’t. Now add the spec to test the good_user’s ability to download this asset by<br />

using the code from the following listing.<br />

Listing 9.9 spec/controllers/assets_controller_spec.rb<br />

context "users with access" do<br />

before do<br />

227

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!