mirror of
https://github.com/redmine/redmine.git
synced 2025-11-09 06:46:01 +01:00
git-svn-id: http://svn.redmine.org/redmine/branches/3.3-stable@15478 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -29,11 +29,11 @@ class ContextMenusController < ApplicationController
|
||||
|
||||
@allowed_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
|
||||
|
||||
@can = {:edit => User.current.allowed_to?(:edit_issues, @projects),
|
||||
@can = {:edit => @issues.all?(&:attributes_editable?),
|
||||
:log_time => (@project && User.current.allowed_to?(:log_time, @project)),
|
||||
:copy => User.current.allowed_to?(:copy_issues, @projects) && Issue.allowed_target_projects.any?,
|
||||
:add_watchers => User.current.allowed_to?(:add_issue_watchers, @projects),
|
||||
:delete => User.current.allowed_to?(:delete_issues, @projects)
|
||||
:delete => @issues.all?(&:deletable?)
|
||||
}
|
||||
if @project
|
||||
if @issue
|
||||
@@ -41,12 +41,11 @@ class ContextMenusController < ApplicationController
|
||||
else
|
||||
@assignables = @project.assignable_users
|
||||
end
|
||||
@trackers = @project.trackers
|
||||
else
|
||||
#when multiple projects, we only keep the intersection of each set
|
||||
@assignables = @projects.map(&:assignable_users).reduce(:&)
|
||||
@trackers = @projects.map(&:trackers).reduce(:&)
|
||||
end
|
||||
@trackers = @projects.map {|p| Issue.allowed_target_trackers(p) }.reduce(:&)
|
||||
@versions = @projects.map {|p| p.shared_versions.open}.reduce(:&)
|
||||
|
||||
@priorities = IssuePriority.active.reverse
|
||||
|
||||
@@ -211,6 +211,10 @@ class IssuesController < ApplicationController
|
||||
unless User.current.allowed_to?(:copy_issues, @projects)
|
||||
raise ::Unauthorized
|
||||
end
|
||||
else
|
||||
unless @issues.all?(&:attributes_editable?)
|
||||
raise ::Unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
@allowed_projects = Issue.allowed_target_projects
|
||||
@@ -230,7 +234,7 @@ class IssuesController < ApplicationController
|
||||
end
|
||||
@custom_fields = @issues.map{|i|i.editable_custom_fields}.reduce(:&)
|
||||
@assignables = target_projects.map(&:assignable_users).reduce(:&)
|
||||
@trackers = target_projects.map(&:trackers).reduce(:&)
|
||||
@trackers = target_projects.map {|p| Issue.allowed_target_trackers(p) }.reduce(:&)
|
||||
@versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&)
|
||||
@categories = target_projects.map {|p| p.issue_categories}.reduce(:&)
|
||||
if @copy
|
||||
@@ -263,6 +267,10 @@ class IssuesController < ApplicationController
|
||||
unless User.current.allowed_to?(:add_issues, target_projects)
|
||||
raise ::Unauthorized
|
||||
end
|
||||
else
|
||||
unless @issues.all?(&:attributes_editable?)
|
||||
raise ::Unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
unsaved_issues = []
|
||||
@@ -316,6 +324,7 @@ class IssuesController < ApplicationController
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise Unauthorized unless @issues.all?(&:deletable?)
|
||||
@hours = TimeEntry.where(:issue_id => @issues.map(&:id)).sum(:hours).to_f
|
||||
if @hours > 0
|
||||
case params[:todo]
|
||||
@@ -465,9 +474,15 @@ class IssuesController < ApplicationController
|
||||
@issue.safe_attributes = attrs
|
||||
|
||||
if @issue.project
|
||||
@issue.tracker ||= @issue.project.trackers.first
|
||||
@issue.tracker ||= @issue.allowed_target_trackers.first
|
||||
if @issue.tracker.nil?
|
||||
render_error l(:error_no_tracker_in_project)
|
||||
if @issue.project.trackers.any?
|
||||
# None of the project trackers is allowed to the user
|
||||
render_error :message => l(:error_no_tracker_allowed_for_new_issue_in_project), :status => 403
|
||||
else
|
||||
# Project has no trackers
|
||||
render_error l(:error_no_tracker_in_project)
|
||||
end
|
||||
return false
|
||||
end
|
||||
if @issue.status.nil?
|
||||
|
||||
@@ -168,6 +168,16 @@ module IssuesHelper
|
||||
link_to(l(:button_add), new_project_issue_path(issue.project, :issue => attrs))
|
||||
end
|
||||
|
||||
def trackers_options_for_select(issue)
|
||||
trackers = issue.allowed_target_trackers
|
||||
if issue.new_record? && issue.parent_issue_id.present?
|
||||
trackers = trackers.reject do |tracker|
|
||||
issue.tracker_id != tracker.id && tracker.disabled_core_fields.include?('parent_issue_id')
|
||||
end
|
||||
end
|
||||
trackers.collect {|t| [t.name, t.id]}
|
||||
end
|
||||
|
||||
class IssueFieldsRows
|
||||
include ActionView::Helpers::TagHelper
|
||||
|
||||
|
||||
@@ -120,10 +120,10 @@ class Issue < ActiveRecord::Base
|
||||
# Returns a SQL conditions string used to find all issues visible by the specified user
|
||||
def self.visible_condition(user, options={})
|
||||
Project.allowed_to_condition(user, :view_issues, options) do |role, user|
|
||||
if user.id && user.logged?
|
||||
sql = if user.id && user.logged?
|
||||
case role.issues_visibility
|
||||
when 'all'
|
||||
nil
|
||||
'1=1'
|
||||
when 'default'
|
||||
user_ids = [user.id] + user.groups.map(&:id).compact
|
||||
"(#{table_name}.is_private = #{connection.quoted_false} OR #{table_name}.author_id = #{user.id} OR #{table_name}.assigned_to_id IN (#{user_ids.join(',')}))"
|
||||
@@ -136,13 +136,22 @@ class Issue < ActiveRecord::Base
|
||||
else
|
||||
"(#{table_name}.is_private = #{connection.quoted_false})"
|
||||
end
|
||||
unless role.permissions_all_trackers?(:view_issues)
|
||||
tracker_ids = role.permissions_tracker_ids(:view_issues)
|
||||
if tracker_ids.any?
|
||||
sql = "(#{sql} AND #{table_name}.tracker_id IN (#{tracker_ids.join(',')}))"
|
||||
else
|
||||
sql = '1=0'
|
||||
end
|
||||
end
|
||||
sql
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if usr or current user is allowed to view the issue
|
||||
def visible?(usr=nil)
|
||||
(usr || User.current).allowed_to?(:view_issues, self.project) do |role, user|
|
||||
if user.logged?
|
||||
visible = if user.logged?
|
||||
case role.issues_visibility
|
||||
when 'all'
|
||||
true
|
||||
@@ -156,17 +165,36 @@ class Issue < ActiveRecord::Base
|
||||
else
|
||||
!self.is_private?
|
||||
end
|
||||
unless role.permissions_all_trackers?(:view_issues)
|
||||
visible &&= role.permissions_tracker_ids?(:view_issues, tracker_id)
|
||||
end
|
||||
visible
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if user or current user is allowed to edit or add a note to the issue
|
||||
# Returns true if user or current user is allowed to edit or add notes to the issue
|
||||
def editable?(user=User.current)
|
||||
attributes_editable?(user) || user.allowed_to?(:add_issue_notes, project)
|
||||
attributes_editable?(user) || notes_addable?(user)
|
||||
end
|
||||
|
||||
# Returns true if user or current user is allowed to edit the issue
|
||||
def attributes_editable?(user=User.current)
|
||||
user.allowed_to?(:edit_issues, project)
|
||||
user_tracker_permission?(user, :edit_issues)
|
||||
end
|
||||
|
||||
# Overrides Redmine::Acts::Attachable::InstanceMethods#attachments_editable?
|
||||
def attachments_editable?(user=User.current)
|
||||
attributes_editable?(user)
|
||||
end
|
||||
|
||||
# Returns true if user or current user is allowed to add notes to the issue
|
||||
def notes_addable?(user=User.current)
|
||||
user_tracker_permission?(user, :add_issue_notes)
|
||||
end
|
||||
|
||||
# Returns true if user or current user is allowed to delete the issue
|
||||
def deletable?(user=User.current)
|
||||
user_tracker_permission?(user, :delete_issues)
|
||||
end
|
||||
|
||||
def initialize(attributes=nil, *args)
|
||||
@@ -416,10 +444,10 @@ class Issue < ActiveRecord::Base
|
||||
'custom_fields',
|
||||
'lock_version',
|
||||
'notes',
|
||||
:if => lambda {|issue, user| issue.new_record? || user.allowed_to?(:edit_issues, issue.project) }
|
||||
:if => lambda {|issue, user| issue.new_record? || issue.attributes_editable?(user) }
|
||||
|
||||
safe_attributes 'notes',
|
||||
:if => lambda {|issue, user| user.allowed_to?(:add_issue_notes, issue.project)}
|
||||
:if => lambda {|issue, user| issue.notes_addable?(user)}
|
||||
|
||||
safe_attributes 'private_notes',
|
||||
:if => lambda {|issue, user| !issue.new_record? && user.allowed_to?(:set_notes_private, issue.project)}
|
||||
@@ -434,7 +462,7 @@ class Issue < ActiveRecord::Base
|
||||
}
|
||||
|
||||
safe_attributes 'parent_issue_id',
|
||||
:if => lambda {|issue, user| (issue.new_record? || user.allowed_to?(:edit_issues, issue.project)) &&
|
||||
:if => lambda {|issue, user| (issue.new_record? || issue.attributes_editable?(user)) &&
|
||||
user.allowed_to?(:manage_subtasks, issue.project)}
|
||||
|
||||
def safe_attribute_names(user=nil)
|
||||
@@ -479,12 +507,14 @@ class Issue < ActiveRecord::Base
|
||||
end
|
||||
|
||||
if (t = attrs.delete('tracker_id')) && safe_attribute?('tracker_id')
|
||||
self.tracker_id = t
|
||||
if allowed_target_trackers(user).where(:id => t.to_i).exists?
|
||||
self.tracker_id = t
|
||||
end
|
||||
end
|
||||
if project
|
||||
# Set the default tracker to accept custom field values
|
||||
# Set a default tracker to accept custom field values
|
||||
# even if tracker is not specified
|
||||
self.tracker ||= project.trackers.first
|
||||
self.tracker ||= allowed_target_trackers(user).first
|
||||
end
|
||||
|
||||
statuses_allowed = new_statuses_allowed_to(user)
|
||||
@@ -822,16 +852,6 @@ class Issue < ActiveRecord::Base
|
||||
!leaf?
|
||||
end
|
||||
|
||||
def assignable_trackers
|
||||
trackers = project.trackers
|
||||
if new_record? && parent_issue_id.present?
|
||||
trackers = trackers.reject do |tracker|
|
||||
tracker_id != tracker.id && tracker.disabled_core_fields.include?('parent_issue_id')
|
||||
end
|
||||
end
|
||||
trackers
|
||||
end
|
||||
|
||||
# Users the issue can be assigned to
|
||||
def assignable_users
|
||||
users = project.assignable_users.to_a
|
||||
@@ -1373,9 +1393,43 @@ class Issue < ActiveRecord::Base
|
||||
end
|
||||
Project.where(condition).having_trackers
|
||||
end
|
||||
|
||||
# Returns a scope of trackers that user can assign the issue to
|
||||
def allowed_target_trackers(user=User.current)
|
||||
self.class.allowed_target_trackers(project, user, tracker_id_was)
|
||||
end
|
||||
|
||||
# Returns a scope of trackers that user can assign project issues to
|
||||
def self.allowed_target_trackers(project, user=User.current, current_tracker=nil)
|
||||
if project
|
||||
scope = project.trackers.sorted
|
||||
unless user.admin?
|
||||
roles = user.roles_for_project(project).select {|r| r.has_permission?(:add_issues)}
|
||||
unless roles.any? {|r| r.permissions_all_trackers?(:add_issues)}
|
||||
tracker_ids = roles.map {|r| r.permissions_tracker_ids(:add_issues)}.flatten.uniq
|
||||
if current_tracker
|
||||
tracker_ids << current_tracker
|
||||
end
|
||||
scope = scope.where(:id => tracker_ids)
|
||||
end
|
||||
end
|
||||
scope
|
||||
else
|
||||
Tracker.none
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def user_tracker_permission?(user, permission)
|
||||
if user.admin?
|
||||
true
|
||||
else
|
||||
roles = user.roles_for_project(project).select {|r| r.has_permission?(permission)}
|
||||
roles.any? {|r| r.permissions_all_trackers?(permission) || r.permissions_tracker_ids?(permission, tracker_id)}
|
||||
end
|
||||
end
|
||||
|
||||
def after_project_change
|
||||
# Update project_id on related time entries
|
||||
TimeEntry.where({:issue_id => id}).update_all(["project_id = ?", project_id])
|
||||
|
||||
@@ -37,7 +37,7 @@ class IssueImport < Import
|
||||
# Returns a scope of trackers that user is allowed to
|
||||
# import issue to
|
||||
def allowed_target_trackers
|
||||
project.trackers
|
||||
Issue.allowed_target_trackers(project, user)
|
||||
end
|
||||
|
||||
def tracker
|
||||
|
||||
@@ -199,7 +199,14 @@ class MailHandler < ActionMailer::Base
|
||||
end
|
||||
|
||||
issue = Issue.new(:author => user, :project => project)
|
||||
issue.safe_attributes = issue_attributes_from_keywords(issue)
|
||||
attributes = issue_attributes_from_keywords(issue)
|
||||
if handler_options[:no_permission_check]
|
||||
issue.tracker_id = attributes['tracker_id']
|
||||
if project
|
||||
issue.tracker_id ||= project.trackers.first.try(:id)
|
||||
end
|
||||
end
|
||||
issue.safe_attributes = attributes
|
||||
issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)}
|
||||
issue.subject = cleaned_up_subject
|
||||
if issue.subject.blank?
|
||||
@@ -420,10 +427,6 @@ class MailHandler < ActionMailer::Base
|
||||
'done_ratio' => get_keyword(:done_ratio, :format => '(\d|10)?0')
|
||||
}.delete_if {|k, v| v.blank? }
|
||||
|
||||
if issue.new_record? && attrs['tracker_id'].nil?
|
||||
attrs['tracker_id'] = issue.project.trackers.first.try(:id)
|
||||
end
|
||||
|
||||
attrs
|
||||
end
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ class Role < ActiveRecord::Base
|
||||
acts_as_positioned :scope => :builtin
|
||||
|
||||
serialize :permissions, ::Role::PermissionsAttributeCoder
|
||||
store :settings, :accessors => [:permissions_all_trackers, :permissions_tracker_ids]
|
||||
attr_protected :builtin
|
||||
|
||||
validates_presence_of :name
|
||||
@@ -188,6 +189,56 @@ class Role < ActiveRecord::Base
|
||||
setable_permissions
|
||||
end
|
||||
|
||||
def permissions_tracker_ids(*args)
|
||||
if args.any?
|
||||
Array(permissions_tracker_ids[args.first.to_s]).map(&:to_i)
|
||||
else
|
||||
super || {}
|
||||
end
|
||||
end
|
||||
|
||||
def permissions_tracker_ids=(arg)
|
||||
h = arg.to_hash
|
||||
h.values.each {|v| v.reject!(&:blank?)}
|
||||
super(h)
|
||||
end
|
||||
|
||||
# Returns true if tracker_id belongs to the list of
|
||||
# trackers for which permission is given
|
||||
def permissions_tracker_ids?(permission, tracker_id)
|
||||
permissions_tracker_ids(permission).include?(tracker_id)
|
||||
end
|
||||
|
||||
def permissions_all_trackers
|
||||
super || {}
|
||||
end
|
||||
|
||||
def permissions_all_trackers=(arg)
|
||||
super(arg.to_hash)
|
||||
end
|
||||
|
||||
# Returns true if permission is given for all trackers
|
||||
def permissions_all_trackers?(permission)
|
||||
permissions_all_trackers[permission.to_s].to_s != '0'
|
||||
end
|
||||
|
||||
# Sets the trackers that are allowed for a permission.
|
||||
# tracker_ids can be an array of tracker ids or :all for
|
||||
# no restrictions.
|
||||
#
|
||||
# Examples:
|
||||
# role.set_permission_trackers :add_issues, [1, 3]
|
||||
# role.set_permission_trackers :add_issues, :all
|
||||
def set_permission_trackers(permission, tracker_ids)
|
||||
h = {permission.to_s => (tracker_ids == :all ? '1' : '0')}
|
||||
self.permissions_all_trackers = permissions_all_trackers.merge(h)
|
||||
|
||||
h = {permission.to_s => (tracker_ids == :all ? [] : tracker_ids)}
|
||||
self.permissions_tracker_ids = permissions_tracker_ids.merge(h)
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
# Find all the roles that can be given to a project member
|
||||
def self.find_all_givable
|
||||
Role.givable.to_a
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
<%= link_to l(:button_log_time), new_issue_time_entry_path(@issue), :class => 'icon icon-time-add' if User.current.allowed_to?(:log_time, @project) %>
|
||||
<%= watcher_link(@issue, User.current) %>
|
||||
<%= link_to l(:button_copy), project_copy_issue_path(@project, @issue), :class => 'icon icon-copy' if User.current.allowed_to?(:copy_issues, @project) && Issue.allowed_target_projects.any? %>
|
||||
<%= link_to l(:button_delete), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if User.current.allowed_to?(:delete_issues, @project) %>
|
||||
<%= link_to l(:button_delete), issue_path(@issue), :data => {:confirm => issues_destroy_confirmation_message(@issue)}, :method => :delete, :class => 'icon icon-del' if @issue.deletable? %>
|
||||
</div>
|
||||
|
||||
@@ -27,21 +27,22 @@
|
||||
<% end %>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
<fieldset><legend><%= l(:field_notes) %></legend>
|
||||
<%= f.text_area :notes, :cols => 60, :rows => 10, :class => 'wiki-edit', :no_label => true %>
|
||||
<%= wikitoolbar_for 'issue_notes' %>
|
||||
|
||||
<% if @issue.safe_attribute? 'private_notes' %>
|
||||
<%= f.check_box :private_notes, :no_label => true %> <label for="issue_private_notes"><%= l(:field_private_notes) %></label>
|
||||
<% if @issue.notes_addable? %>
|
||||
<fieldset><legend><%= l(:field_notes) %></legend>
|
||||
<%= f.text_area :notes, :cols => 60, :rows => 10, :class => 'wiki-edit', :no_label => true %>
|
||||
<%= wikitoolbar_for 'issue_notes' %>
|
||||
|
||||
<% if @issue.safe_attribute? 'private_notes' %>
|
||||
<%= f.check_box :private_notes, :no_label => true %> <label for="issue_private_notes"><%= l(:field_private_notes) %></label>
|
||||
<% end %>
|
||||
|
||||
<%= call_hook(:view_issues_edit_notes_bottom, { :issue => @issue, :notes => @notes, :form => f }) %>
|
||||
</fieldset>
|
||||
|
||||
<fieldset><legend><%= l(:label_attachment_plural) %></legend>
|
||||
<p><%= render :partial => 'attachments/form', :locals => {:container => @issue} %></p>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
<%= call_hook(:view_issues_edit_notes_bottom, { :issue => @issue, :notes => @notes, :form => f }) %>
|
||||
</fieldset>
|
||||
|
||||
<fieldset><legend><%= l(:label_attachment_plural) %></legend>
|
||||
<p><%= render :partial => 'attachments/form', :locals => {:container => @issue} %></p>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<%= f.hidden_field :lock_version %>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<% end %>
|
||||
|
||||
<% if @issue.safe_attribute? 'tracker_id' %>
|
||||
<p><%= f.select :tracker_id, @issue.assignable_trackers.collect {|t| [t.name, t.id]}, {:required => true},
|
||||
<p><%= f.select :tracker_id, trackers_options_for_select(@issue), {:required => true},
|
||||
:onchange => "updateIssueFrom('#{escape_javascript update_issue_form_path(@project, @issue)}', this)" %></p>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<% reply_links = authorize_for('issues', 'edit') -%>
|
||||
<% reply_links = issue.notes_addable? -%>
|
||||
<% for journal in journals %>
|
||||
<div id="change-<%= journal.id %>" class="<%= journal.css_classes %>">
|
||||
<div id="note-<%= journal.indice %>">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="contextual">
|
||||
<% if User.current.allowed_to?(:add_issues, @project, :global => true) && (@project.nil? || @project.trackers.any?) %>
|
||||
<% if User.current.allowed_to?(:add_issues, @project, :global => true) && (@project.nil? || Issue.allowed_target_trackers(@project).any?) %>
|
||||
<%= link_to l(:label_issue_new), _new_project_issue_path(@project), :class => 'icon icon-add new-issue' %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -77,7 +77,7 @@ end %>
|
||||
<% if @issue.description? %>
|
||||
<div class="description">
|
||||
<div class="contextual">
|
||||
<%= link_to l(:button_quote), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon icon-comment' if authorize_for('issues', 'edit') %>
|
||||
<%= link_to l(:button_quote), quoted_issue_path(@issue), :remote => true, :method => 'post', :class => 'icon icon-comment' if @issue.notes_addable? %>
|
||||
</div>
|
||||
|
||||
<p><strong><%=l(:field_description)%></strong></p>
|
||||
|
||||
@@ -7,17 +7,17 @@
|
||||
<% end %>
|
||||
|
||||
<% unless @role.anonymous? %>
|
||||
<p><%= f.select :issues_visibility, Role::ISSUES_VISIBILITY_OPTIONS.collect {|v| [l(v.last), v.first]} %></p>
|
||||
<p class="view_issues_shown"><%= f.select :issues_visibility, Role::ISSUES_VISIBILITY_OPTIONS.collect {|v| [l(v.last), v.first]} %></p>
|
||||
<% end %>
|
||||
|
||||
<% unless @role.anonymous? %>
|
||||
<p><%= f.select :time_entries_visibility, Role::TIME_ENTRIES_VISIBILITY_OPTIONS.collect {|v| [l(v.last), v.first]} %></p>
|
||||
<p class="view_time_entries_shown"><%= f.select :time_entries_visibility, Role::TIME_ENTRIES_VISIBILITY_OPTIONS.collect {|v| [l(v.last), v.first]} %></p>
|
||||
<% end %>
|
||||
|
||||
<p><%= f.select :users_visibility, Role::USERS_VISIBILITY_OPTIONS.collect {|v| [l(v.last), v.first]} %></p>
|
||||
|
||||
<% unless @role.builtin? %>
|
||||
<p id="manage_members_options">
|
||||
<p class="manage_members_shown">
|
||||
<label><%= l(:label_member_management) %></label>
|
||||
<label class="block">
|
||||
<%= radio_button_tag 'role[all_roles_managed]', 1, @role.all_roles_managed?, :id => 'role_all_roles_managed_on',
|
||||
@@ -52,7 +52,8 @@
|
||||
<% perms_by_module[mod].each do |permission| %>
|
||||
<label class="floating">
|
||||
<%= check_box_tag 'role[permissions][]', permission.name, (@role.permissions.include? permission.name),
|
||||
:id => "role_permissions_#{permission.name}" %>
|
||||
:id => "role_permissions_#{permission.name}",
|
||||
:data => {:shows => ".#{permission.name}_shown"} %>
|
||||
<%= l_or_humanize(permission.name, :prefix => 'permission_') %>
|
||||
</label>
|
||||
<% end %>
|
||||
@@ -62,10 +63,50 @@
|
||||
<%= hidden_field_tag 'role[permissions][]', '' %>
|
||||
</div>
|
||||
|
||||
<%= javascript_tag do %>
|
||||
$(document).ready(function(){
|
||||
$("#role_permissions_manage_members").change(function(){
|
||||
$("#manage_members_options").toggle($(this).is(":checked"));
|
||||
}).change();
|
||||
});
|
||||
<div id="role-permissions-trackers" class="view_issues_shown">
|
||||
<h3><%= l(:label_issue_tracking) %></h3>
|
||||
<% permissions = %w(view_issues add_issues edit_issues add_issue_notes delete_issues) %>
|
||||
|
||||
<div class="autoscroll">
|
||||
<table class="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= l(:label_tracker) %></th>
|
||||
<% permissions.each do |permission| %>
|
||||
<th class="<%= "#{permission}_shown" %>"><%= l("permission_#{permission}") %></th>
|
||||
<% end %>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="name"><b><%= l(:label_tracker_all) %></b></td>
|
||||
<% permissions.each do |permission| %>
|
||||
<td class="<%= "#{permission}_shown" %>">
|
||||
<%= hidden_field_tag "role[permissions_all_trackers][#{permission}]", '0', :id => nil %>
|
||||
<%= check_box_tag "role[permissions_all_trackers][#{permission}]",
|
||||
'1',
|
||||
@role.permissions_all_trackers?(permission),
|
||||
:class => "#{permission}_shown",
|
||||
:data => {:disables => ".#{permission}_tracker"} %>
|
||||
</td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% Tracker.sorted.all.each do |tracker| %>
|
||||
<tr class="<%= cycle("odd", "even") %>">
|
||||
<td class="name"><%= tracker.name %></td>
|
||||
<% permissions.each do |permission| %>
|
||||
<td class="<%= "#{permission}_shown" %>"><%= check_box_tag "role[permissions_tracker_ids][#{permission}][]",
|
||||
tracker.id,
|
||||
@role.permissions_tracker_ids?(permission, tracker.id),
|
||||
:class => "#{permission}_tracker",
|
||||
:id => "role_permissions_tracker_ids_add_issues_#{tracker.id}" %></td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<% permissions.each do |permission| %>
|
||||
<%= hidden_field_tag "role[permissions_tracker_ids][#{permission}][]", '' %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -213,6 +213,7 @@ en:
|
||||
error_can_not_read_import_file: "An error occurred while reading the file to import"
|
||||
error_attachment_extension_not_allowed: "Attachment extension %{extension} is not allowed"
|
||||
error_ldap_bind_credentials: "Invalid LDAP Account/Password"
|
||||
error_no_tracker_allowed_for_new_issue_in_project: "The project doesn't have any trackers for which you can create an issue"
|
||||
|
||||
mail_subject_lost_password: "Your %{value} password"
|
||||
mail_body_lost_password: 'To change your password, click on the following link:'
|
||||
@@ -561,6 +562,7 @@ en:
|
||||
label_member_plural: Members
|
||||
label_tracker: Tracker
|
||||
label_tracker_plural: Trackers
|
||||
label_tracker_all: All trackers
|
||||
label_tracker_new: New tracker
|
||||
label_workflow: Workflow
|
||||
label_issue_status: Issue status
|
||||
|
||||
@@ -233,6 +233,7 @@ fr:
|
||||
error_can_not_read_import_file: "Une erreur est survenue lors de la lecture du fichier à importer"
|
||||
error_attachment_extension_not_allowed: "L'extension %{extension} n'est pas autorisée"
|
||||
error_ldap_bind_credentials: "Identifiant ou mot de passe LDAP incorrect"
|
||||
error_no_tracker_allowed_for_new_issue_in_project: "Le projet ne dispose d'aucun tracker sur lequel vous pouvez créer une demande"
|
||||
|
||||
mail_subject_lost_password: "Votre mot de passe %{value}"
|
||||
mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :'
|
||||
@@ -573,6 +574,7 @@ fr:
|
||||
label_member_plural: Membres
|
||||
label_tracker: Tracker
|
||||
label_tracker_plural: Trackers
|
||||
label_tracker_all: Tous les trackers
|
||||
label_tracker_new: Nouveau tracker
|
||||
label_workflow: Workflow
|
||||
label_issue_status: Statut de demandes
|
||||
|
||||
5
db/migrate/20160529063352_add_roles_settings.rb
Normal file
5
db/migrate/20160529063352_add_roles_settings.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddRolesSettings < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :roles, :settings, :text
|
||||
end
|
||||
end
|
||||
@@ -88,8 +88,6 @@ Redmine::AccessControl.map do |map|
|
||||
map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
|
||||
|
||||
map.project_module :issue_tracking do |map|
|
||||
# Issue categories
|
||||
map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
|
||||
# Issues
|
||||
map.permission :view_issues, {:issues => [:index, :show],
|
||||
:auto_complete => [:issues],
|
||||
@@ -120,62 +118,64 @@ Redmine::AccessControl.map do |map|
|
||||
map.permission :add_issue_watchers, {:watchers => [:new, :create, :append, :autocomplete_for_user]}
|
||||
map.permission :delete_issue_watchers, {:watchers => :destroy}
|
||||
map.permission :import_issues, {:imports => [:new, :create, :settings, :mapping, :run, :show]}
|
||||
# Issue categories
|
||||
map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
|
||||
end
|
||||
|
||||
map.project_module :time_tracking do |map|
|
||||
map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
|
||||
map.permission :view_time_entries, {:timelog => [:index, :report, :show]}, :read => true
|
||||
map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
|
||||
map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
|
||||
map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
|
||||
map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
|
||||
end
|
||||
|
||||
map.project_module :news do |map|
|
||||
map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy], :attachments => :upload}, :require => :member
|
||||
map.permission :view_news, {:news => [:index, :show]}, :public => true, :read => true
|
||||
map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy], :attachments => :upload}, :require => :member
|
||||
map.permission :comment_news, {:comments => :create}
|
||||
end
|
||||
|
||||
map.project_module :documents do |map|
|
||||
map.permission :view_documents, {:documents => [:index, :show, :download]}, :read => true
|
||||
map.permission :add_documents, {:documents => [:new, :create, :add_attachment], :attachments => :upload}, :require => :loggedin
|
||||
map.permission :edit_documents, {:documents => [:edit, :update, :add_attachment], :attachments => :upload}, :require => :loggedin
|
||||
map.permission :delete_documents, {:documents => [:destroy]}, :require => :loggedin
|
||||
map.permission :view_documents, {:documents => [:index, :show, :download]}, :read => true
|
||||
end
|
||||
|
||||
map.project_module :files do |map|
|
||||
map.permission :manage_files, {:files => [:new, :create], :attachments => :upload}, :require => :loggedin
|
||||
map.permission :view_files, {:files => :index, :versions => :download}, :read => true
|
||||
map.permission :manage_files, {:files => [:new, :create], :attachments => :upload}, :require => :loggedin
|
||||
end
|
||||
|
||||
map.project_module :wiki do |map|
|
||||
map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
|
||||
map.permission :view_wiki_pages, {:wiki => [:index, :show, :special, :date_index]}, :read => true
|
||||
map.permission :view_wiki_edits, {:wiki => [:history, :diff, :annotate]}, :read => true
|
||||
map.permission :export_wiki_pages, {:wiki => [:export]}, :read => true
|
||||
map.permission :edit_wiki_pages, :wiki => [:new, :edit, :update, :preview, :add_attachment], :attachments => :upload
|
||||
map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
|
||||
map.permission :delete_wiki_pages, {:wiki => [:destroy, :destroy_version]}, :require => :member
|
||||
map.permission :view_wiki_pages, {:wiki => [:index, :show, :special, :date_index]}, :read => true
|
||||
map.permission :export_wiki_pages, {:wiki => [:export]}, :read => true
|
||||
map.permission :view_wiki_edits, {:wiki => [:history, :diff, :annotate]}, :read => true
|
||||
map.permission :edit_wiki_pages, :wiki => [:new, :edit, :update, :preview, :add_attachment], :attachments => :upload
|
||||
map.permission :delete_wiki_pages_attachments, {}
|
||||
map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
|
||||
map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
|
||||
end
|
||||
|
||||
map.project_module :repository do |map|
|
||||
map.permission :manage_repository, {:repositories => [:new, :create, :edit, :update, :committers, :destroy]}, :require => :member
|
||||
map.permission :browse_repository, {:repositories => [:show, :browse, :entry, :raw, :annotate, :changes, :diff, :stats, :graph]}, :read => true
|
||||
map.permission :view_changesets, {:repositories => [:show, :revisions, :revision]}, :read => true
|
||||
map.permission :browse_repository, {:repositories => [:show, :browse, :entry, :raw, :annotate, :changes, :diff, :stats, :graph]}, :read => true
|
||||
map.permission :commit_access, {}
|
||||
map.permission :manage_related_issues, {:repositories => [:add_related_issue, :remove_related_issue]}
|
||||
map.permission :manage_repository, {:repositories => [:new, :create, :edit, :update, :committers, :destroy]}, :require => :member
|
||||
end
|
||||
|
||||
map.project_module :boards do |map|
|
||||
map.permission :manage_boards, {:boards => [:new, :create, :edit, :update, :destroy]}, :require => :member
|
||||
map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true, :read => true
|
||||
map.permission :add_messages, {:messages => [:new, :reply, :quote], :attachments => :upload}
|
||||
map.permission :edit_messages, {:messages => :edit, :attachments => :upload}, :require => :member
|
||||
map.permission :edit_own_messages, {:messages => :edit, :attachments => :upload}, :require => :loggedin
|
||||
map.permission :delete_messages, {:messages => :destroy}, :require => :member
|
||||
map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
|
||||
map.permission :manage_boards, {:boards => [:new, :create, :edit, :update, :destroy]}, :require => :member
|
||||
end
|
||||
|
||||
map.project_module :calendar do |map|
|
||||
@@ -233,7 +233,7 @@ Redmine::MenuManager.map :project_menu do |menu|
|
||||
menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
|
||||
menu.push :new_issue, { :controller => 'issues', :action => 'new', :copy_from => nil }, :param => :project_id, :caption => :label_issue_new,
|
||||
:html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) },
|
||||
:if => Proc.new { |p| Setting.new_project_issue_tab_enabled? && p.trackers.any? },
|
||||
:if => Proc.new { |p| Setting.new_project_issue_tab_enabled? && Issue.allowed_target_trackers(p).any? },
|
||||
:permission => :add_issues
|
||||
menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
|
||||
menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
|
||||
|
||||
@@ -719,9 +719,10 @@ function toggleDisabledOnChange() {
|
||||
var checked = $(this).is(':checked');
|
||||
$($(this).data('disables')).attr('disabled', checked);
|
||||
$($(this).data('enables')).attr('disabled', !checked);
|
||||
$($(this).data('shows')).toggle(checked);
|
||||
}
|
||||
function toggleDisabledInit() {
|
||||
$('input[data-disables], input[data-enables]').each(toggleDisabledOnChange);
|
||||
$('input[data-disables], input[data-enables], input[data-shows]').each(toggleDisabledOnChange);
|
||||
}
|
||||
|
||||
(function ( $ ) {
|
||||
@@ -751,7 +752,7 @@ function toggleDisabledInit() {
|
||||
}( jQuery ));
|
||||
|
||||
$(document).ready(function(){
|
||||
$('#content').on('change', 'input[data-disables], input[data-enables]', toggleDisabledOnChange);
|
||||
$('#content').on('change', 'input[data-disables], input[data-enables], input[data-shows]', toggleDisabledOnChange);
|
||||
toggleDisabledInit();
|
||||
});
|
||||
|
||||
|
||||
@@ -152,6 +152,7 @@ table.list td.buttons img, div.buttons img {vertical-align:middle;}
|
||||
table.list td.reorder {width:15%; white-space:nowrap; text-align:center; }
|
||||
table.list table.progress td {padding-right:0px;}
|
||||
table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; }
|
||||
#role-permissions-trackers table.list th {white-space:normal;}
|
||||
|
||||
.table-list-cell {display: table-cell; vertical-align: top; padding:2px; }
|
||||
|
||||
|
||||
@@ -1864,6 +1864,31 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def test_new_should_propose_allowed_trackers
|
||||
role = Role.find(1)
|
||||
role.set_permission_trackers 'add_issues', [1, 3]
|
||||
role.save!
|
||||
@request.session[:user_id] = 2
|
||||
|
||||
get :new, :project_id => 1
|
||||
assert_response :success
|
||||
assert_select 'select[name=?]', 'issue[tracker_id]' do
|
||||
assert_select 'option', 2
|
||||
assert_select 'option[value="1"]'
|
||||
assert_select 'option[value="3"]'
|
||||
end
|
||||
end
|
||||
|
||||
def test_new_without_allowed_trackers_should_respond_with_403
|
||||
role = Role.find(1)
|
||||
role.set_permission_trackers 'add_issues', []
|
||||
role.save!
|
||||
@request.session[:user_id] = 2
|
||||
|
||||
get :new, :project_id => 1
|
||||
assert_response 403
|
||||
end
|
||||
|
||||
def test_new_should_preselect_default_version
|
||||
version = Version.generate!(:project_id => 1)
|
||||
Project.find(1).update_attribute :default_version_id, version.id
|
||||
@@ -2432,6 +2457,23 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_nil issue.custom_field_value(cf2)
|
||||
end
|
||||
|
||||
def test_create_should_ignore_unallowed_trackers
|
||||
role = Role.find(1)
|
||||
role.set_permission_trackers :add_issues, [3]
|
||||
role.save!
|
||||
@request.session[:user_id] = 2
|
||||
|
||||
issue = new_record(Issue) do
|
||||
post :create, :project_id => 1, :issue => {
|
||||
:tracker_id => 1,
|
||||
:status_id => 1,
|
||||
:subject => 'Test'
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
assert_equal 3, issue.tracker_id
|
||||
end
|
||||
|
||||
def test_post_create_with_watchers
|
||||
@request.session[:user_id] = 2
|
||||
ActionMailer::Base.deliveries.clear
|
||||
@@ -3830,6 +3872,30 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_redirected_to '/issues/11?issue_count=3&issue_position=2&next_issue_id=12&prev_issue_id=8'
|
||||
end
|
||||
|
||||
def test_update_with_permission_on_tracker_should_be_allowed
|
||||
role = Role.find(1)
|
||||
role.set_permission_trackers :edit_issues, [1]
|
||||
role.save!
|
||||
issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :subject => 'Original subject')
|
||||
|
||||
@request.session[:user_id] = 2
|
||||
put :update, :id => issue.id, :issue => {:subject => 'Changed subject'}
|
||||
assert_response 302
|
||||
assert_equal 'Changed subject', issue.reload.subject
|
||||
end
|
||||
|
||||
def test_update_without_permission_on_tracker_should_be_denied
|
||||
role = Role.find(1)
|
||||
role.set_permission_trackers :edit_issues, [1]
|
||||
role.save!
|
||||
issue = Issue.generate!(:project_id => 1, :tracker_id => 2, :subject => 'Original subject')
|
||||
|
||||
@request.session[:user_id] = 2
|
||||
put :update, :id => issue.id, :issue => {:subject => 'Changed subject'}
|
||||
assert_response 302
|
||||
assert_equal 'Original subject', issue.reload.subject
|
||||
end
|
||||
|
||||
def test_get_bulk_edit
|
||||
@request.session[:user_id] = 2
|
||||
get :bulk_edit, :ids => [1, 3]
|
||||
@@ -4660,6 +4726,32 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_response 404
|
||||
end
|
||||
|
||||
def test_destroy_with_permission_on_tracker_should_be_allowed
|
||||
role = Role.find(1)
|
||||
role.set_permission_trackers :delete_issues, [1]
|
||||
role.save!
|
||||
issue = Issue.generate!(:project_id => 1, :tracker_id => 1)
|
||||
|
||||
@request.session[:user_id] = 2
|
||||
assert_difference 'Issue.count', -1 do
|
||||
delete :destroy, :id => issue.id
|
||||
end
|
||||
assert_response 302
|
||||
end
|
||||
|
||||
def test_destroy_without_permission_on_tracker_should_be_denied
|
||||
role = Role.find(1)
|
||||
role.set_permission_trackers :delete_issues, [2]
|
||||
role.save!
|
||||
issue = Issue.generate!(:project_id => 1, :tracker_id => 1)
|
||||
|
||||
@request.session[:user_id] = 2
|
||||
assert_no_difference 'Issue.count' do
|
||||
delete :destroy, :id => issue.id
|
||||
end
|
||||
assert_response 403
|
||||
end
|
||||
|
||||
def test_default_search_scope
|
||||
get :index
|
||||
|
||||
|
||||
@@ -132,6 +132,22 @@ class RolesControllerTest < ActionController::TestCase
|
||||
assert_equal [:edit_project], role.permissions
|
||||
end
|
||||
|
||||
def test_update_trackers_permissions
|
||||
put :update, :id => 1, :role => {
|
||||
:permissions_all_trackers => {'add_issues' => '0'},
|
||||
:permissions_tracker_ids => {'add_issues' => ['1', '3', '']}
|
||||
}
|
||||
|
||||
assert_redirected_to '/roles'
|
||||
role = Role.find(1)
|
||||
|
||||
assert_equal({'add_issues' => '0'}, role.permissions_all_trackers)
|
||||
assert_equal({'add_issues' => ['1', '3']}, role.permissions_tracker_ids)
|
||||
|
||||
assert_equal false, role.permissions_all_trackers?(:add_issues)
|
||||
assert_equal [1, 3], role.permissions_tracker_ids(:add_issues).sort
|
||||
end
|
||||
|
||||
def test_update_with_failure
|
||||
put :update, :id => 1, :role => {:name => ''}
|
||||
assert_response :success
|
||||
|
||||
@@ -342,6 +342,69 @@ class IssueTest < ActiveSupport::TestCase
|
||||
assert_include issue, issues
|
||||
end
|
||||
|
||||
def test_visible_scope_for_member_with_limited_tracker_ids
|
||||
role = Role.find(1)
|
||||
role.set_permission_trackers :view_issues, [2]
|
||||
role.save!
|
||||
user = User.find(2)
|
||||
|
||||
issues = Issue.where(:project_id => 1).visible(user).to_a
|
||||
assert issues.any?
|
||||
assert_equal [2], issues.map(&:tracker_id).uniq
|
||||
|
||||
assert Issue.where(:project_id => 1).all? {|issue| issue.visible?(user) ^ issue.tracker_id != 2}
|
||||
end
|
||||
|
||||
def test_visible_scope_should_consider_tracker_ids_on_each_project
|
||||
user = User.generate!
|
||||
|
||||
project1 = Project.generate!
|
||||
role1 = Role.generate!
|
||||
role1.add_permission! :view_issues
|
||||
role1.set_permission_trackers :view_issues, :all
|
||||
role1.save!
|
||||
User.add_to_project(user, project1, role1)
|
||||
|
||||
project2 = Project.generate!
|
||||
role2 = Role.generate!
|
||||
role2.add_permission! :view_issues
|
||||
role2.set_permission_trackers :view_issues, [2]
|
||||
role2.save!
|
||||
User.add_to_project(user, project2, role2)
|
||||
|
||||
visible_issues = [
|
||||
Issue.generate!(:project => project1, :tracker_id => 1),
|
||||
Issue.generate!(:project => project1, :tracker_id => 2),
|
||||
Issue.generate!(:project => project2, :tracker_id => 2)
|
||||
]
|
||||
hidden_issue = Issue.generate!(:project => project2, :tracker_id => 1)
|
||||
|
||||
issues = Issue.where(:project_id => [project1.id, project2.id]).visible(user)
|
||||
assert_equal visible_issues.map(&:id), issues.ids.sort
|
||||
|
||||
assert visible_issues.all? {|issue| issue.visible?(user)}
|
||||
assert !hidden_issue.visible?(user)
|
||||
end
|
||||
|
||||
def test_visible_scope_should_not_consider_roles_without_view_issues_permission
|
||||
user = User.generate!
|
||||
role1 = Role.generate!
|
||||
role1.remove_permission! :view_issues
|
||||
role1.set_permission_trackers :view_issues, :all
|
||||
role1.save!
|
||||
role2 = Role.generate!
|
||||
role2.add_permission! :view_issues
|
||||
role2.set_permission_trackers :view_issues, [2]
|
||||
role2.save!
|
||||
User.add_to_project(user, Project.find(1), [role1, role2])
|
||||
|
||||
issues = Issue.where(:project_id => 1).visible(user).to_a
|
||||
assert issues.any?
|
||||
assert_equal [2], issues.map(&:tracker_id).uniq
|
||||
|
||||
assert Issue.where(:project_id => 1).all? {|issue| issue.visible?(user) ^ issue.tracker_id != 2}
|
||||
end
|
||||
|
||||
def test_visible_scope_for_admin
|
||||
user = User.find(1)
|
||||
user.members.each(&:destroy)
|
||||
@@ -737,9 +800,10 @@ class IssueTest < ActiveSupport::TestCase
|
||||
target = Tracker.find(2)
|
||||
target.core_fields = %w(assigned_to_id due_date)
|
||||
target.save!
|
||||
user = User.find(2)
|
||||
|
||||
issue = Issue.new(:tracker => source)
|
||||
issue.safe_attributes = {'tracker_id' => 2, 'due_date' => '2012-07-14'}
|
||||
issue = Issue.new(:project => Project.find(1), :tracker => source)
|
||||
issue.send :safe_attributes=, {'tracker_id' => 2, 'due_date' => '2012-07-14'}, user
|
||||
assert_equal target, issue.tracker
|
||||
assert_equal Date.parse('2012-07-14'), issue.due_date
|
||||
end
|
||||
@@ -1437,6 +1501,91 @@ class IssueTest < ActiveSupport::TestCase
|
||||
assert_not_include project, Issue.allowed_target_projects(User.find(1))
|
||||
end
|
||||
|
||||
def test_allowed_target_trackers_with_one_role_allowed_on_all_trackers
|
||||
user = User.generate!
|
||||
role = Role.generate!
|
||||
role.add_permission! :add_issues
|
||||
role.set_permission_trackers :add_issues, :all
|
||||
role.save!
|
||||
User.add_to_project(user, Project.find(1), role)
|
||||
|
||||
assert_equal [1, 2, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
|
||||
end
|
||||
|
||||
def test_allowed_target_trackers_with_one_role_allowed_on_some_trackers
|
||||
user = User.generate!
|
||||
role = Role.generate!
|
||||
role.add_permission! :add_issues
|
||||
role.set_permission_trackers :add_issues, [1, 3]
|
||||
role.save!
|
||||
User.add_to_project(user, Project.find(1), role)
|
||||
|
||||
assert_equal [1, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
|
||||
end
|
||||
|
||||
def test_allowed_target_trackers_with_two_roles_allowed_on_some_trackers
|
||||
user = User.generate!
|
||||
role1 = Role.generate!
|
||||
role1.add_permission! :add_issues
|
||||
role1.set_permission_trackers :add_issues, [1]
|
||||
role1.save!
|
||||
role2 = Role.generate!
|
||||
role2.add_permission! :add_issues
|
||||
role2.set_permission_trackers :add_issues, [3]
|
||||
role2.save!
|
||||
User.add_to_project(user, Project.find(1), [role1, role2])
|
||||
|
||||
assert_equal [1, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
|
||||
end
|
||||
|
||||
def test_allowed_target_trackers_with_two_roles_allowed_on_all_trackers_and_some_trackers
|
||||
user = User.generate!
|
||||
role1 = Role.generate!
|
||||
role1.add_permission! :add_issues
|
||||
role1.set_permission_trackers :add_issues, :all
|
||||
role1.save!
|
||||
role2 = Role.generate!
|
||||
role2.add_permission! :add_issues
|
||||
role2.set_permission_trackers :add_issues, [1, 3]
|
||||
role2.save!
|
||||
User.add_to_project(user, Project.find(1), [role1, role2])
|
||||
|
||||
assert_equal [1, 2, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
|
||||
end
|
||||
|
||||
def test_allowed_target_trackers_should_not_consider_roles_without_add_issues_permission
|
||||
user = User.generate!
|
||||
role1 = Role.generate!
|
||||
role1.remove_permission! :add_issues
|
||||
role1.set_permission_trackers :add_issues, :all
|
||||
role1.save!
|
||||
role2 = Role.generate!
|
||||
role2.add_permission! :add_issues
|
||||
role2.set_permission_trackers :add_issues, [1, 3]
|
||||
role2.save!
|
||||
User.add_to_project(user, Project.find(1), [role1, role2])
|
||||
|
||||
assert_equal [1, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
|
||||
end
|
||||
|
||||
def test_allowed_target_trackers_without_project_should_be_empty
|
||||
issue = Issue.new
|
||||
assert_nil issue.project
|
||||
assert_equal [], issue.allowed_target_trackers(User.find(2)).ids
|
||||
end
|
||||
|
||||
def test_allowed_target_trackers_should_include_current_tracker
|
||||
user = User.generate!
|
||||
role = Role.generate!
|
||||
role.add_permission! :add_issues
|
||||
role.set_permission_trackers :add_issues, [3]
|
||||
role.save!
|
||||
User.add_to_project(user, Project.find(1), role)
|
||||
|
||||
issue = Issue.generate!(:project => Project.find(1), :tracker => Tracker.find(1))
|
||||
assert_equal [1, 3], issue.allowed_target_trackers(user).ids.sort
|
||||
end
|
||||
|
||||
def test_move_to_another_project_with_same_category
|
||||
issue = Issue.find(1)
|
||||
issue.project = Project.find(2)
|
||||
|
||||
Reference in New Issue
Block a user