diff --git a/Gemfile.lock b/Gemfile.lock index 3bf319e35..33a001a38 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 0964f2f36..e50844862 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -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 diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index fa83ead1f..140a5c15c 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -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 diff --git a/app/models/ability.rb b/app/models/ability.rb index fd6118a6b..f3e67d84b 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -3,7 +3,7 @@ class Ability def initialize(user) user ||= User.new # guest user (not logged in) - + if user.admin? can :manage, :all else @@ -73,7 +73,7 @@ class Ability can [:read, :update], Group, groups_in_relations_with(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id) do |group| group.objects.exists?(:role => ['writer', 'admin'], :object_type => 'User', :object_id => user.id) end - + can :manage, Platform, :owner_type => 'User', :owner_id => user.id can :manage, Platform, platforms_in_relations_with(:role => 'admin', :object_type => 'User', :object_id => user.id) do |platform| platform.relations.exists?(:role => 'admin', :object_type => 'User', :object_id => user.id) @@ -95,10 +95,39 @@ class Ability can [:new, :create], Repository do |repository| 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 - + # Same rights for groups: can [:read, :create], PrivateUser, :platform => {:owner_type => 'Group', :owner_id => user.group_ids} can :publish, BuildList do |build_list| @@ -121,7 +150,7 @@ class Ability can [:read, :update, :process_build, :build], Project, projects_in_relations_with(:role => ['writer', 'admin'], :object_type => 'Group', :object_id => user.group_ids) do |project| project.relations.exists?(:role => ['writer', 'admin'], :object_type => 'Group', :object_id => user.group_ids) end - + can :manage, Platform, :owner_type => 'Group', :owner_id => user.group_ids #can :read, Platform, :groups => {:id => user.group_ids} can :read, Platform, platforms_in_relations_with(:role => 'reader', :object_type => 'Group', :object_id => user.group_ids) do |platform| @@ -140,11 +169,12 @@ class Ability cannot :create, [Platform, User] end end - + # Shared cannot rights for all users (guests, registered, admin) 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]] diff --git a/app/models/issue.rb b/app/models/issue.rb index 0e971f55f..ad6f57468 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1,5 +1,5 @@ class Issue < ActiveRecord::Base - STATUSES = ['open', 'close'] + STATUSES = ['open', 'closed'] belongs_to :project belongs_to :user diff --git a/app/views/issues/edit.html.haml b/app/views/issues/edit.html.haml index 99a3533b0..aa09ab66f 100644 --- a/app/views/issues/edit.html.haml +++ b/app/views/issues/edit.html.haml @@ -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} diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml index 9b8661458..aa3323b70 100644 --- a/app/views/issues/index.html.haml +++ b/app/views/issues/index.html.haml @@ -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") diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml index a68e58fea..51c080e4a 100644 --- a/app/views/issues/show.html.haml +++ b/app/views/issues/show.html.haml @@ -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 diff --git a/config/routes.rb b/config/routes.rb index b3fc4bc05..120556a0b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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]