diff -Nrup redmine-1.0.4/app/controllers/issues_controller.rb redmine-1.0.4-issue-permissions/app/controllers/issues_controller.rb --- redmine-1.0.4/app/controllers/issues_controller.rb 2010-11-28 13:51:00.000000000 -0700 +++ redmine-1.0.4-issue-permissions/app/controllers/issues_controller.rb 2011-01-21 16:46:05.469555300 -0700 @@ -103,7 +103,8 @@ class IssuesController < ApplicationCont @changesets = @issue.changesets.visible.all @changesets.reverse! if User.current.wants_comments_in_reverse_order? @allowed_statuses = @issue.new_statuses_allowed_to(User.current) - @edit_allowed = User.current.allowed_to?(:edit_issues, @project) + @edit_allowed = @issue.editable? + @edit_planning_allowed = @issue.planning_editable? @priorities = IssuePriority.all @time_entry = TimeEntry.new respond_to do |format| @@ -267,7 +268,8 @@ private def update_issue_from_params @allowed_statuses = @issue.new_statuses_allowed_to(User.current) @priorities = IssuePriority.all - @edit_allowed = User.current.allowed_to?(:edit_issues, @project) + @edit_allowed = @issue.editable? + @edit_planning_allowed = @issue.planning_editable? @time_entry = TimeEntry.new @notes = params[:notes] || (params[:issue].present? ? params[:issue][:notes] : nil) diff -Nrup redmine-1.0.4/app/models/issue.rb redmine-1.0.4-issue-permissions/app/models/issue.rb --- redmine-1.0.4/app/models/issue.rb 2010-11-28 13:51:00.000000000 -0700 +++ redmine-1.0.4-issue-permissions/app/models/issue.rb 2011-01-21 16:46:05.469555300 -0700 @@ -78,6 +78,25 @@ class Issue < ActiveRecord::Base (usr || User.current).allowed_to?(:view_issues, self.project) end + # Returns true if usr or current user is allowed to edit the issue + def editable?(usr=nil) + user = usr || User.current + return user.allowed_to?(:edit_issues, self.project) || + (user.allowed_to?(:edit_own_issues, self.project) && self.assigned_to == user) || + (user.allowed_to?(:edit_own_issues, self.project) && self.author == user && self.assigned_to.nil?) + end + + def descr_editable?(usr=nil) + user = usr || User.current + return user.allowed_to?(:edit_issues, self.project) || + (user.allowed_to?(:edit_own_issues, self.project) && self.author == user && self.assigned_to.nil?) + end + + def planning_editable?(usr=nil) + user = usr || User.current + return editable?(user) && user.allowed_to?(:edit_issue_planning, self.project) + end + def after_initialize if new_record? # set default values for new records only diff -Nrup redmine-1.0.4/app/models/mail_handler.rb redmine-1.0.4-issue-permissions/app/models/mail_handler.rb --- redmine-1.0.4/app/models/mail_handler.rb 2010-11-28 13:51:00.000000000 -0700 +++ redmine-1.0.4-issue-permissions/app/models/mail_handler.rb 2011-01-21 16:46:05.485181000 -0700 @@ -174,8 +174,9 @@ class MailHandler < ActionMailer::Base return unless issue # check permission unless @@handler_options[:no_permission_check] - raise UnauthorizedAction unless user.allowed_to?(:add_issue_notes, issue.project) || user.allowed_to?(:edit_issues, issue.project) - raise UnauthorizedAction unless status.nil? || user.allowed_to?(:edit_issues, issue.project) + raise UnauthorizedAction unless user.allowed_to?(:add_issue_notes, issue.project) + raise UnauthorizedAction unless issue.editable?(user) + raise UnauthorizedAction unless status.nil? end # add the note diff -Nrup redmine-1.0.4/app/views/issues/_attributes.rhtml redmine-1.0.4-issue-permissions/app/views/issues/_attributes.rhtml --- redmine-1.0.4/app/views/issues/_attributes.rhtml 2010-11-28 13:51:00.000000000 -0700 +++ redmine-1.0.4-issue-permissions/app/views/issues/_attributes.rhtml 2011-01-21 17:09:38.732206700 -0700 @@ -8,7 +8,7 @@ <% end %>
<%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), {:required => true}, :disabled => !@issue.leaf? %>
-<%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %>
+<%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), {:include_blank => true}, :disabled => !@issue.planning_editable? %>
<% unless @project.issue_categories.empty? %><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}), :include_blank => true %> <%= prompt_to_remote(image_tag('add.png', :style => 'vertical-align: middle;'), @@ -19,7 +19,7 @@ :tabindex => 199) if authorize_for('issue_categories', 'new') %>
<% end %> <% unless @issue.assignable_versions.empty? %> -<%= f.select :fixed_version_id, version_options_for_select(@issue.assignable_versions, @issue.fixed_version), :include_blank => true %> +
<%= f.select :fixed_version_id, version_options_for_select(@issue.assignable_versions, @issue.fixed_version), {:include_blank => true}, :disabled => !@issue.planning_editable? %> <%= prompt_to_remote(image_tag('add.png', :style => 'vertical-align: middle;'), l(:label_version_new), 'version[name]', @@ -31,11 +31,11 @@
<%= f.text_field :start_date, :size => 10, :disabled => !@issue.leaf? %><%= calendar_for('issue_start_date') if @issue.leaf? %>
-<%= f.text_field :due_date, :size => 10, :disabled => !@issue.leaf? %><%= calendar_for('issue_due_date') if @issue.leaf? %>
-<%= f.text_field :estimated_hours, :size => 3, :disabled => !@issue.leaf? %> <%= l(:field_hours) %>
+<%= f.text_field :start_date, :size => 10, :disabled => !@issue.leaf? || !@issue.planning_editable? %><%= calendar_for('issue_start_date') if @issue.leaf? && @issue.planning_editable? %>
+<%= f.text_field :due_date, :size => 10, :disabled => !@issue.leaf? || !@issue.planning_editable? %><%= calendar_for('issue_due_date') if @issue.leaf? && @issue.planning_editable? %>
+<%= f.text_field :estimated_hours, :size => 3, :disabled => !@issue.leaf? || !@issue.planning_editable? %> <%= l(:field_hours) %>
<% if @issue.leaf? && Issue.use_field_for_done_ratio? %> -<%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %>
+<%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }), {},:disabled => !@issue.planning_editable? %>
<% end %><%= f.select :status_id, (@allowed_statuses.collect {|p| [p.name, p.id]}), :required => true %>
-<%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true %>
+<%= f.select :assigned_to_id, (@issue.assignable_users.collect {|m| [m.name, m.id]}), :include_blank => true, :disabled => !@issue.planning_editable? %>
<%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %>
+<%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10]}), :disabled => !@issue.planning_editable? %>
<% end %> -<% unless @issue.assignable_versions.empty? %> -<%= f.select :fixed_version_id, (@issue.assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true %>
+<% unless @issue.fixed_assignable_versions.empty? %> +<%= f.select :fixed_version_id, (@issue.fixed_assignable_versions.collect {|v| [v.name, v.id]}), :include_blank => true, :disabled => !@issue.planning_editable? %>
<% end %>