[refs #54] Add CanCan rules for issues and comments. Fix serial_id routes and some actions

This commit is contained in:
konstantin.grabar 2011-12-21 18:48:16 +04:00
parent 375c98366f
commit 3ab55d34b8
9 changed files with 86 additions and 30 deletions

View File

@ -77,7 +77,6 @@ GEM
factory_girl_rails (1.4.0)
factory_girl (~> 2.3.0)
railties (>= 3.0.0)
friendly_id (4.0.0.beta8)
grit (2.4.1)
diff-lcs (~> 1.1)
mime-types (~> 1.15)
@ -220,7 +219,6 @@ DEPENDENCIES
delayed_job
devise (~> 1.5.2)
factory_girl_rails (~> 1.4.0)
friendly_id (~> 4.0.0.beta14)
grack!
grit
haml-rails (~> 0.3.4)

View File

@ -1,6 +1,11 @@
class CommentsController < ApplicationController
before_filter :authenticate_user!
before_filter :set_commentable, :only => [:index, :edit, :create]
before_filter :find_project, :only => [:index]
before_filter :find_comment, :only => [:show, :edit, :update, :destroy]
authorize_resource :only => [:show, :edit, :update, :destroy]
authorize_resource :project, :only => [:index]
def index
@comments = @commentable.comments
@ -19,13 +24,11 @@ class CommentsController < ApplicationController
end
def edit
@comment = Comment.find(params[:id])
@issue = @commentable
@project = @issue.project
end
def update
@comment = Comment.find(params[:id])
if @comment.update_attributes(params[:comment])
flash[:notice] = I18n.t("flash.comment.saved")
redirect_to :back
@ -36,7 +39,6 @@ class CommentsController < ApplicationController
end
def destroy
@comment = Comment.find(params[:id])
@comment.destroy
flash[:notice] = t("flash.comment.destroyed")
@ -46,15 +48,24 @@ class CommentsController < ApplicationController
private
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
#params.each do |name, value|
# if name =~ /(.+)_id$/
# return $1.classify.constantize.find(value)
# end
#end
#nil
return Issue.find(params[:issue_id])
end
def set_commentable
@commentable = find_commentable
end
def find_comment
@comment = Comment.find(params[:id])
end
def find_project
@project = @comment.commentable.project
end
end

View File

@ -1,13 +1,15 @@
class IssuesController < ApplicationController
before_filter :authenticate_user!
before_filter :find_project
before_filter :find_issue, :only => [:edit, :update, :destroy]
before_filter :find_project, :except => [:destroy]
before_filter :find_issue_by_serial_id, :only => [:show, :edit]
load_and_authorize_resource
load_and_authorize_resource :except => [:show, :edit, :index]
authorize_resource :only => [:show, :edit]
#authorize_resource :through => :project, :only => [:index], :shallow => true
authorize_resource :project, :only => [:index]
autocomplete :user, :uname
def show
@issue = @project.issues.where(:serial_id => params[:serial_id])[0]
end
def index
@ -30,13 +32,18 @@ class IssuesController < ApplicationController
end
end
def edit
@user_id = @issue.user_id
@user_uname = @issue.user.uname
end
def update
@user_id = params[:user_id]
@user_uname = params[:user_uname]
if @issue.update_attributes( params[:issue].merge({:user_id => @user_id}) )
flash[:notice] = I18n.t("flash.issue.saved")
redirect_to @issue
redirect_to show_issue_path(@project, @issue.serial_id)
else
flash[:error] = I18n.t("flash.issue.saved_error")
render :action => :new
@ -56,7 +63,7 @@ class IssuesController < ApplicationController
@project = Project.find(params[:project_id])
end
def find_issue
@issue = Issue.find(params[:id])
def find_issue_by_serial_id
@issue = @project.issues.where(:serial_id => params[:serial_id])[0]
end
end

View File

@ -96,6 +96,35 @@ class Ability
repository.platform.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
end
can [:show, :index], Issue do |issue|
issue.status == 'open'
end
#can [:show, :index], Issue, with_project_id_in_relations_with(:object_type => 'User', :object_id => user.id) do |issue|
can [:show, :index], Issue do |issue|
issue.project.relations.exists?(:object_type => 'User', :object_id => user.id)
end
can [:create, :new], Issue do |issue|
issue.project.relations.exists?(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id)
end
can [:edit, :update], Issue do |issue|
issue.user_id == user.id || (user.id == issue.project.owner_id && issue.project.owner_type == 'User') ||
issue.project.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
end
can [:create, :new], Comment do |comment|
comment.commentable.project.relations.exists?(:object_type => 'User', :object_id => user.id)
end
can [:edit, :update], Comment do |comment|
comment.user_id == user.id || (user.id == comment.commentable.project.owner_id && comment.commentable.project.owner_type == 'User') ||
comment.commentable.project.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id)
end
#
cannot [:index, :edit, :update, :create, :new, :show], Issue do |issue|
!issue.project.has_issues
end
cannot [:edit, :update, :create, :new, :destroy], Comment do |comment|
!comment.commentable.project.has_issues
end
#can :read, Repository
# TODO: Add personal repos rules
@ -145,6 +174,7 @@ class Ability
cannot :destroy, Platform, :platform_type => 'personal'
cannot :destroy, Repository, :platform => {:platform_type => 'personal'}
cannot :fork, Project, :owner_id => user.id, :owner_type => user.class.to_s
cannot :destroy, Issue
end
# Sub query for platforms, projects relations
@ -161,6 +191,16 @@ class Ability
end
end
def with_project_id_in_relations_with(opts = {})
query = "issues.project_id IN (SELECT target_id FROM relations WHERE relations.target_type = 'issues'"
opts.each do |key, value|
query = query + " AND relations.#{ key } #{ value.class == Array ? 'IN (?)' : '= ?' } "
end
query = query + ")"
return opts.values.unshift query
end
## Sub query for project relations
#def projects_in_relations_with(opts={})
# ["projects.id IN (SELECT target_id FROM relations WHERE relations.object_id #{ opts[:object_id].class == Array ? 'IN (?)' : '= ?' } AND relations.object_type = '#{ opts[:object_type] }' AND relations.target_type = 'Platform') AND relations.role", opts[:object_id]]

View File

@ -1,5 +1,5 @@
class Issue < ActiveRecord::Base
STATUSES = ['open', 'close']
STATUSES = ['open', 'closed']
belongs_to :project
belongs_to :user

View File

@ -3,10 +3,9 @@
%ul.wat-cf
%li.first= link_to t("layout.issues.list"), project_issues_path(@project)
%li= link_to t("layout.issues.new"), new_project_issue_path(@project)
%li.active= link_to t("layout.issues.edit"), edit_project_issue_path(@project)
.content
%h2.title
= t("layout.issues.edit_header")
.inner
= form_for @issue, :url => project_issue_path(@issue), :html => { :class => :form } do |f|
= form_for @issue, :url => project_issue_path(@project, @issue), :html => { :class => :form } do |f|
= render :partial => "form", :locals => {:f => f}

View File

@ -2,7 +2,7 @@
.secondary-navigation
%ul.wat-cf
%li.first.active= link_to t("layout.issues.list"), project_issues_path(@project)
%li= link_to t("layout.issues.new"), new_project_issue_path(@project) if can? :create, Issue
%li= link_to t("layout.issues.new"), new_project_issue_path(@project) if can? :new, Issue.new(:project_id => @project.id)
.content
%h2.title
= t("layout.issues.list_header")

View File

@ -2,7 +2,7 @@
.secondary-navigation
%ul.wat-cf
%li.first= link_to t("layout.issues.list"), project_issues_path(@project)
%li= link_to t("layout.issues.edit"), edit_project_issue_path(@project, @issue) if can? :edit, @issue
%li= link_to t("layout.issues.edit"), edit_project_issue_path(@project, @issue.serial_id) if can? :edit, @issue
.content
.inner
%p

View File

@ -67,7 +67,8 @@ Rosa::Application.routes.draw do
resources :categories, :only => [:index, :show]
end
match "projects/:project_id/issues/:serial_id" => 'issues#show', :as => :show_issue, :via => :get
match "projects/:project_id/issues/:serial_id" => 'issues#show', :serial_id => /\d+/, :as => :show_issue, :via => :get
match "projects/:project_id/issues/:serial_id/edit" => 'issues#edit', :serial_id => /\d+/, :as => :edit_issue, :via => :get
resources :projects do
resources :issues, :except => [:show] do
resources :comments, :only => [:edit, :create, :update, :destroy]