Skip to content

Commit

Permalink
Added controller authorization and limited owners to projects they cr…
Browse files Browse the repository at this point in the history
…eate
  • Loading branch information
coxandrew committed Jan 30, 2011
1 parent 07830a5 commit f7ea601
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 76 deletions.
14 changes: 12 additions & 2 deletions app/controllers/application_controller.rb
Expand Up @@ -8,6 +8,11 @@ class ApplicationController < ActionController::Base

private

rescue_from CanCan::AccessDenied do |exception|
flash[:error] = "Sorry, you are not permitted to view that page."
redirect_back_or_default
end

def current_user
@current_user ||= User.find(session[:username]) if session[:username]
end
Expand All @@ -25,8 +30,9 @@ def user_projects

def login_required
if current_user.nil?
session[:return_to] = request.fullpath
redirect_to sessions_new_path, :alert => "You must first log in before accessing this page"
store_request
redirect_to sessions_new_path,
:alert => "You must first log in before accessing this page"
end
end

Expand All @@ -35,6 +41,10 @@ def redirect_back_or_default(default = root_path)
session[:return_to] = nil
end

def store_request
session[:return_to] = request.fullpath
end

def get_features
@features = @project.features.select { |feature| feature.present? }
end
Expand Down
15 changes: 3 additions & 12 deletions app/controllers/features_controller.rb
@@ -1,6 +1,7 @@
class FeaturesController < ApplicationController
before_filter :get_project, :only => [:show, :new, :create, :edit]
before_filter :get_feature, :only => [:show, :edit]
load_and_authorize_resource :project
load_and_authorize_resource :feature, :through => :project

before_filter :get_features, :only => [:show, :new, :edit]

def new
Expand Down Expand Up @@ -33,14 +34,4 @@ def destroy

redirect_to(features_url)
end

private

def get_project
@project = Project.find(params[:project_id])
end

def get_feature
@feature = Feature.find(params[:id])
end
end
16 changes: 4 additions & 12 deletions app/controllers/flows_controller.rb
@@ -1,6 +1,8 @@
class FlowsController < ApplicationController
before_filter :get_project, :only => [:show, :new, :create, :update, :edit]
before_filter :get_feature, :only => [:show, :new, :create, :update, :edit]
load_and_authorize_resource :project
load_and_authorize_resource :feature
load_and_authorize_resource :flow, :through => :feature

before_filter :get_features, :only => [:show, :new, :edit]

def show
Expand Down Expand Up @@ -41,14 +43,4 @@ def destroy

redirect_to(flows_url)
end

private

def get_project
@project = Project.find(params[:project_id])
end

def get_feature
@feature = Feature.find(params[:feature_id])
end
end
13 changes: 5 additions & 8 deletions app/controllers/projects_controller.rb
@@ -1,5 +1,6 @@
class ProjectsController < ApplicationController
before_filter :get_project, :only => [:show, :edit, :update, :destroy]
load_and_authorize_resource

before_filter :get_features, :only => [:show]

def index
Expand All @@ -11,7 +12,9 @@ def new
end

def create
@project = Project.new(params[:project])
@project = Project.new(params[:project].merge(
:owner_id => current_user.id)
)
if @project.save
redirect_to(@project, :notice => 'Project was successfully created.')
else
Expand All @@ -33,10 +36,4 @@ def destroy

redirect_to(root_path)
end

private

def get_project
@project = Project.find(params[:id])
end
end
17 changes: 5 additions & 12 deletions app/controllers/screens_controller.rb
@@ -1,6 +1,9 @@
class ScreensController < ApplicationController
before_filter :get_project, :only => [:new, :show, :destroy, :create]
before_filter :get_feature, :only => [:new, :show, :destroy, :create]
load_and_authorize_resource :project
load_and_authorize_resource :feature
load_and_authorize_resource :flow
load_and_authorize_resource :screen, :through => :flow

before_filter :get_features, :only => [:show, :new]

def new
Expand Down Expand Up @@ -30,14 +33,4 @@ def destroy

redirect_to([@project, @feature, flow])
end

private

def get_project
@project = Project.find(params[:project_id])
end

def get_feature
@feature = Feature.find(params[:feature_id])
end
end
38 changes: 13 additions & 25 deletions app/models/ability.rb
Expand Up @@ -2,17 +2,20 @@ class Ability
include CanCan::Ability

def initialize(user)
# Define abilities for the passed in user here. For example:
#
# user ||= User.new # guest user (not logged in)
# if user.admin?
# can :manage, :all
# else
# can :read, :all
# end

if user.role? :owner
can :manage, :all
can :manage, Project, :owner_id => user.id

# TODO: Are these conditional blocks necessary?
#
# If they're not authorized to manage the project, we may not need
# to check these.
can :manage, Feature do |feature|
feature.project.owner_id == user.id
end
can :manage, Flow do |flow|
flow.feature.project.owner_id == user.id
end
can :manage, Screen
end

if user.role? :member
Expand All @@ -24,20 +27,5 @@ def initialize(user)
if user.role? :viewer
can :read, :all
end

#
# The first argument to `can` is the action you are giving the user permission to do.
# If you pass :manage it will apply to every action. Other common actions here are
# :read, :create, :update and :destroy.
#
# The second argument is the resource the user can perform the action on. If you pass
# :all it will apply to every resource. Otherwise pass a Ruby class of the resource.
#
# The third argument is an optional hash of conditions to further filter the objects.
# For example, here the user can only update published articles.
#
# can :update, Article, :published => true
#
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
end
end
1 change: 1 addition & 0 deletions app/models/project.rb
@@ -1,3 +1,4 @@
class Project < ActiveRecord::Base
has_many :features, :dependent => :destroy
belongs_to :owner, :class_name => "User"
end
1 change: 1 addition & 0 deletions app/models/user.rb
Expand Up @@ -4,6 +4,7 @@ class User < ActiveRecord::Base

has_one :assignment
has_one :role, :through => :assignment
has_many :projects, :foreign_key => "owner_id"

validates_presence_of :password, :on => :create
validates_confirmation_of :password
Expand Down
2 changes: 2 additions & 0 deletions app/views/projects/new.html.erb
@@ -1,3 +1,5 @@
<h2>New project</h2>

<hr />

<%= render 'form' %>
3 changes: 3 additions & 0 deletions app/views/shared/_notices.html.erb
@@ -1,3 +1,6 @@
<% if flash[:error] %>
<p id="error"><%= flash[:error] %></p>
<% end %>
<% if alert %>
<p id="alert"><%= alert %></p>
<% end %>
Expand Down
9 changes: 9 additions & 0 deletions db/migrate/20110130154422_add_owner_id_to_projects.rb
@@ -0,0 +1,9 @@
class AddOwnerIdToProjects < ActiveRecord::Migration
def self.up
add_column :projects, :owner_id, :integer
end

def self.down
remove_column :projects, :owner_id
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20110130140432) do
ActiveRecord::Schema.define(:version => 20110130154422) do

create_table "assignments", :force => true do |t|
t.integer "user_id"
Expand Down Expand Up @@ -40,6 +40,7 @@
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "owner_id"
end

create_table "roles", :force => true do |t|
Expand Down
12 changes: 8 additions & 4 deletions db/seeds.rb
Expand Up @@ -16,8 +16,10 @@
cox.role = owner

# University Web
uni_web = Project.create(:name => "University Web",
:description => "School administration app for Ruby Mendicant University")
uni_web = Project.create(
:name => "University Web",
:description => "School administration app for Ruby Mendicant University",
:owner_id => jordan.id)
admin_users = Feature.create(:name => "User Administration",
:description => "Add, edit and delete users. Assign permissions. Track students' progress throughout a course.",
:project_id => uni_web.id)
Expand All @@ -31,8 +33,10 @@
:feature_id => admin_courses.id)

# UX Lab
ux_lab = Project.create(:name => "UX Lab",
:description => "A resource manager for storing and sharing design images and documents for a project.")
ux_lab = Project.create(
:name => "UX Lab",
:description => "A resource manager for storing and sharing design images and documents for a project.",
:owner_id => cox.id)
Feature.create(:name => "Projects",
:description => "A project is the main organizational element that contains all of your features.",
:project_id => ux_lab.id)
Expand Down

0 comments on commit f7ea601

Please sign in to comment.