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 %>
diff -Nrup redmine-1.0.4/app/views/issues/_edit.rhtml redmine-1.0.4-issue-permissions/app/views/issues/_edit.rhtml --- redmine-1.0.4/app/views/issues/_edit.rhtml 2010-11-28 13:51:00.000000000 -0700 +++ redmine-1.0.4-issue-permissions/app/views/issues/_edit.rhtml 2011-01-21 16:46:05.500806700 -0700 @@ -6,13 +6,13 @@ :multipart => true} do |f| %> <%= error_messages_for 'issue', 'time_entry' %>
- <% if @edit_allowed || !@allowed_statuses.empty? %> + <% if @edit_allowed %>
<%= l(:label_change_properties) %> - <% if !@issue.new_record? && !@issue.errors.any? && @edit_allowed %> + <% if !@issue.new_record? && !@issue.errors.any? && @issue.descr_editable? %> (<%= link_to l(:label_more), {}, :onclick => 'Effect.toggle("issue_descr_fields", "appear", {duration:0.3}); return false;' %>) <% end %> - <%= render :partial => (@edit_allowed ? 'form' : 'form_update'), :locals => {:f => f} %> + <%= render :partial => 'form', :locals => {:f => f} %>
<% end %> <% if authorize_for('timelog', 'edit') %> diff -Nrup redmine-1.0.4/app/views/issues/_form_update.rhtml redmine-1.0.4-issue-permissions/app/views/issues/_form_update.rhtml --- redmine-1.0.4/app/views/issues/_form_update.rhtml 2010-11-28 13:51:00.000000000 -0700 +++ redmine-1.0.4-issue-permissions/app/views/issues/_form_update.rhtml 2011-01-21 16:46:05.516432400 -0700 @@ -1,14 +1,14 @@

<%= 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? %>

<% if 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 %> -<% 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 %>
diff -Nrup redmine-1.0.4/config/locales/en.yml redmine-1.0.4-issue-permissions/config/locales/en.yml --- redmine-1.0.4/config/locales/en.yml 2010-11-28 13:52:00.000000000 -0700 +++ redmine-1.0.4-issue-permissions/config/locales/en.yml 2011-01-21 16:46:05.516432400 -0700 @@ -362,6 +362,8 @@ en: permission_view_issues: View Issues permission_add_issues: Add issues permission_edit_issues: Edit issues + permission_edit_own_issues: Edit own issues + permission_edit_issue_planning: Edit issue planning permission_manage_issue_relations: Manage issue relations permission_add_issue_notes: Add notes permission_edit_issue_notes: Edit notes diff -Nrup redmine-1.0.4/lib/redmine/default_data/loader.rb redmine-1.0.4-issue-permissions/lib/redmine/default_data/loader.rb --- redmine-1.0.4/lib/redmine/default_data/loader.rb 2010-11-28 13:52:00.000000000 -0700 +++ redmine-1.0.4-issue-permissions/lib/redmine/default_data/loader.rb 2011-01-21 16:46:05.532058100 -0700 @@ -52,6 +52,7 @@ module Redmine :view_issues, :add_issues, :edit_issues, + :edit_issue_planning, :manage_issue_relations, :manage_subtasks, :add_issue_notes, @@ -79,6 +80,7 @@ module Redmine :permissions => [:view_issues, :add_issues, :add_issue_notes, + :edit_own_issues, :save_queries, :view_gantt, :view_calendar, diff -Nrup redmine-1.0.4/lib/redmine.rb redmine-1.0.4-issue-permissions/lib/redmine.rb --- redmine-1.0.4/lib/redmine.rb 2010-11-28 13:52:00.000000000 -0700 +++ redmine-1.0.4-issue-permissions/lib/redmine.rb 2011-01-21 16:46:05.532058100 -0700 @@ -66,6 +66,8 @@ Redmine::AccessControl.map do |map| :reports => [:issue_report, :issue_report_details]} map.permission :add_issues, {:issues => [:new, :create, :update_form]} map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]} + map.permission :edit_own_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]} + map.permission :edit_issue_planning, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]} map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} map.permission :manage_subtasks, {} map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]}