Skip to content

Commit d34c458

Browse files
author
Ryan Bigg
committed
Section 8.3.2: Make projects only visible to users with permission to see them
1 parent 725b8b7 commit d34c458

12 files changed

+85
-10
lines changed

ticketee/app/controllers/projects_controller.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
class ProjectsController < ApplicationController
22
before_action :authorize_admin!, except: [:index, :show]
3+
before_action :authenticate_user!, only: [:show]
34
before_action :set_project, only: [:show,
45
:edit,
56
:update,
@@ -45,7 +46,11 @@ def destroy
4546
private
4647

4748
def set_project
48-
@project = Project.find(params[:id])
49+
@project = if current_user.admin?
50+
Project.find(params[:id])
51+
else
52+
Project.readable_by(current_user).find(params[:id])
53+
end
4954
rescue ActiveRecord::RecordNotFound
5055
flash[:alert] = "The project you were looking" +
5156
" for could not be found."

ticketee/app/models/permission.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Permission < ActiveRecord::Base
2+
belongs_to :user
3+
belongs_to :thing, polymorphic: true
4+
end

ticketee/app/models/project.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,11 @@ class Project < ActiveRecord::Base
22
validates :name, presence: true
33

44
has_many :tickets, dependent: :delete_all
5+
6+
has_many :permissions, as: :thing
7+
8+
scope :readable_by, -> (user) do
9+
joins(:permissions).where(permissions: { action: "read",
10+
user_id: user.id })
11+
end
512
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class CreatePermissions < ActiveRecord::Migration
2+
def change
3+
create_table :permissions do |t|
4+
t.integer :user_id
5+
t.integer :thing_id
6+
t.string :thing_type
7+
t.string :action
8+
9+
t.timestamps null: false
10+
end
11+
end
12+
end

ticketee/db/schema.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,16 @@
1111
#
1212
# It's strongly recommended that you check this file into your version control system.
1313

14-
ActiveRecord::Schema.define(version: 20141206010551) do
14+
ActiveRecord::Schema.define(version: 20141207214915) do
15+
16+
create_table "permissions", force: true do |t|
17+
t.integer "user_id"
18+
t.integer "thing_id"
19+
t.string "thing_type"
20+
t.string "action"
21+
t.datetime "created_at", null: false
22+
t.datetime "updated_at", null: false
23+
end
1524

1625
create_table "projects", force: true do |t|
1726
t.string "name"

ticketee/spec/controllers/projects_controller_spec.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@
2121
expect(flash[:alert]).to eql("You must be an admin to do that.")
2222
end
2323
end
24+
25+
it "cannot access the show action without permission" do
26+
project = FactoryGirl.create(:project)
27+
get :show, id: project.id
28+
29+
expect(response).to redirect_to(projects_path)
30+
expect(flash[:alert]).to eql("The project you were looking " +
31+
"for could not be found.")
32+
end
2433
end
2534

2635
it "displays an error for a missing project" do

ticketee/spec/features/creating_tickets_spec.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
let(:user) { FactoryGirl.create(:user) }
55
before do
66
login_as(user)
7-
FactoryGirl.create(:project, name: "Internet Explorer")
7+
project = FactoryGirl.create(:project, name: "Internet Explorer")
8+
define_permission!(user, "read", project)
89

910
visit '/'
10-
click_link "Internet Explorer"
11+
click_link project.name
1112
click_link "New Ticket"
1213
end
1314

ticketee/spec/features/deleting_tickets_spec.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
end
99

1010
before do
11+
login_as(user)
12+
define_permission!(user, "read", project)
1113
visit "/"
1214
click_link project.name
1315
click_link ticket.title

ticketee/spec/features/editing_tickets_spec.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
end
99

1010
before do
11+
define_permission!(user, "read", project)
12+
login_as(user)
13+
1114
visit "/"
1215
click_link project.name
1316
click_link ticket.title
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1-
require 'rails_helper'
1+
require "rails_helper"
2+
3+
feature "Viewing projects" do
4+
let!(:user) { FactoryGirl.create(:user) }
5+
let!(:project) { FactoryGirl.create(:project) }
6+
7+
before do
8+
login_as(user)
9+
define_permission!(user, :read, project)
10+
end
11+
12+
scenario "Listing all projects" do
13+
visit "/"
14+
click_link project.name
215

3-
feature 'Viewing projects' do
4-
scenario 'Listing all projects' do
5-
project = FactoryGirl.create(:project, name: 'Sublime Text 3')
6-
visit '/'
7-
click_link 'Sublime Text 3'
816
expect(page.current_url).to eql(project_url(project))
917
end
1018
end

0 commit comments

Comments
 (0)