##// END OF EJS Templates
Limit trackers for new issue to certain roles (#7839)....
Jean-Philippe Lang -
r15082:79df68e17fc0
parent child
Show More
@@ -0,0 +1,5
1 class AddRolesSettings < ActiveRecord::Migration
2 def change
3 add_column :roles, :settings, :text
4 end
5 end No newline at end of file
@@ -467,7 +467,13 class IssuesController < ApplicationController
467 if @issue.project
467 if @issue.project
468 @issue.tracker ||= @issue.allowed_target_trackers.first
468 @issue.tracker ||= @issue.allowed_target_trackers.first
469 if @issue.tracker.nil?
469 if @issue.tracker.nil?
470 render_error l(:error_no_tracker_in_project)
470 if @issue.project.trackers.any?
471 # None of the project trackers is allowed to the user
472 render_error :message => l(:error_no_tracker_allowed_for_new_issue_in_project), :status => 403
473 else
474 # Project has no trackers
475 render_error l(:error_no_tracker_in_project)
476 end
471 return false
477 return false
472 end
478 end
473 if @issue.status.nil?
479 if @issue.status.nil?
@@ -1368,16 +1368,27 class Issue < ActiveRecord::Base
1368
1368
1369 # Returns a scope of trackers that user can assign the issue to
1369 # Returns a scope of trackers that user can assign the issue to
1370 def allowed_target_trackers(user=User.current)
1370 def allowed_target_trackers(user=User.current)
1371 if project
1371 self.class.allowed_target_trackers(project, user, tracker_id_was)
1372 self.class.allowed_target_trackers(project, user, tracker_id_was)
1373 else
1374 Tracker.none
1375 end
1376 end
1372 end
1377
1373
1378 # Returns a scope of trackers that user can assign project issues to
1374 # Returns a scope of trackers that user can assign project issues to
1379 def self.allowed_target_trackers(project, user=User.current, current_tracker=nil)
1375 def self.allowed_target_trackers(project, user=User.current, current_tracker=nil)
1380 project.trackers.sorted
1376 if project
1377 scope = project.trackers.sorted
1378 unless user.admin?
1379 roles = user.roles_for_project(project).select {|r| r.has_permission?(:add_issues)}
1380 unless roles.any? {|r| r.permissions_all_trackers?(:add_issues)}
1381 tracker_ids = roles.map {|r| r.permissions_tracker_ids(:add_issues)}.flatten.uniq
1382 if current_tracker
1383 tracker_ids << current_tracker
1384 end
1385 scope = scope.where(:id => tracker_ids)
1386 end
1387 end
1388 scope
1389 else
1390 Tracker.none
1391 end
1381 end
1392 end
1382
1393
1383 private
1394 private
@@ -37,7 +37,7 class IssueImport < Import
37 # Returns a scope of trackers that user is allowed to
37 # Returns a scope of trackers that user is allowed to
38 # import issue to
38 # import issue to
39 def allowed_target_trackers
39 def allowed_target_trackers
40 project.trackers
40 Issue.allowed_target_trackers(project, user)
41 end
41 end
42
42
43 def tracker
43 def tracker
@@ -73,6 +73,7 class Role < ActiveRecord::Base
73 acts_as_positioned :scope => :builtin
73 acts_as_positioned :scope => :builtin
74
74
75 serialize :permissions, ::Role::PermissionsAttributeCoder
75 serialize :permissions, ::Role::PermissionsAttributeCoder
76 store :settings, :accessors => [:permissions_all_trackers, :permissions_tracker_ids]
76 attr_protected :builtin
77 attr_protected :builtin
77
78
78 validates_presence_of :name
79 validates_presence_of :name
@@ -188,6 +189,56 class Role < ActiveRecord::Base
188 setable_permissions
189 setable_permissions
189 end
190 end
190
191
192 def permissions_tracker_ids(*args)
193 if args.any?
194 Array(permissions_tracker_ids[args.first.to_s]).map(&:to_i)
195 else
196 super || {}
197 end
198 end
199
200 def permissions_tracker_ids=(arg)
201 h = arg.to_hash
202 h.values.each {|v| v.reject!(&:blank?)}
203 super(h)
204 end
205
206 # Returns true if tracker_id belongs to the list of
207 # trackers for which permission is given
208 def permissions_tracker_ids?(permission, tracker_id)
209 permissions_tracker_ids(permission).include?(tracker_id)
210 end
211
212 def permissions_all_trackers
213 super || {}
214 end
215
216 def permissions_all_trackers=(arg)
217 super(arg.to_hash)
218 end
219
220 # Returns true if permission is given for all trackers
221 def permissions_all_trackers?(permission)
222 permissions_all_trackers[permission.to_s].to_s != '0'
223 end
224
225 # Sets the trackers that are allowed for a permission.
226 # tracker_ids can be an array of tracker ids or :all for
227 # no restrictions.
228 #
229 # Examples:
230 # role.set_permission_trackers :add_issues, [1, 3]
231 # role.set_permission_trackers :add_issues, :all
232 def set_permission_trackers(permission, tracker_ids)
233 h = {permission.to_s => (tracker_ids == :all ? '1' : '0')}
234 self.permissions_all_trackers = permissions_all_trackers.merge(h)
235
236 h = {permission.to_s => (tracker_ids == :all ? [] : tracker_ids)}
237 self.permissions_tracker_ids = permissions_tracker_ids.merge(h)
238
239 self
240 end
241
191 # Find all the roles that can be given to a project member
242 # Find all the roles that can be given to a project member
192 def self.find_all_givable
243 def self.find_all_givable
193 Role.givable.to_a
244 Role.givable.to_a
@@ -62,6 +62,50
62 <%= hidden_field_tag 'role[permissions][]', '' %>
62 <%= hidden_field_tag 'role[permissions][]', '' %>
63 </div>
63 </div>
64
64
65 <div id="role-permissions-trackers">
66 <h3><%= l(:label_issue_tracking) %></h3>
67 <% permissions = %w(add_issues) %>
68 <table class="list">
69 <thead>
70 <tr>
71 <th><%= l(:label_tracker) %></th>
72 <% permissions.each do |permission| %>
73 <th><%= l("permission_#{permission}") %></th>
74 <% end %>
75 </thead>
76 <tbody>
77 <tr>
78 <td class="name"><b><%= l(:label_tracker_all) %></b></td>
79 <% permissions.each do |permission| %>
80 <td>
81 <%= hidden_field_tag "role[permissions_all_trackers][#{permission}]", '0', :id => nil %>
82 <%= check_box_tag "role[permissions_all_trackers][#{permission}]",
83 '1',
84 @role.permissions_all_trackers?(permission),
85 :data => {:disables => ".#{permission}_tracker"} %>
86 </td>
87 <% end %>
88 </tr>
89 <% Tracker.sorted.all.each do |tracker| %>
90 <tr>
91 <td class="name"><%= tracker.name %></td>
92 <% permissions.each do |permission| %>
93 <td><%= check_box_tag "role[permissions_tracker_ids][#{permission}][]",
94 tracker.id,
95 @role.permissions_tracker_ids?(permission, tracker.id),
96 :class => "#{permission}_tracker",
97 :id => "role_permissions_tracker_ids_add_issues_#{tracker.id}" %></td>
98 <% end %>
99 </tr>
100 <% end %>
101 </tbody>
102 </table>
103
104 <% permissions.each do |permission| %>
105 <%= hidden_field_tag "role[permissions_tracker_ids][#{permission}][]", '' %>
106 <% end %>
107 </div>
108
65 <%= javascript_tag do %>
109 <%= javascript_tag do %>
66 $(document).ready(function(){
110 $(document).ready(function(){
67 $("#role_permissions_manage_members").change(function(){
111 $("#role_permissions_manage_members").change(function(){
@@ -213,6 +213,7 en:
213 error_can_not_read_import_file: "An error occurred while reading the file to import"
213 error_can_not_read_import_file: "An error occurred while reading the file to import"
214 error_attachment_extension_not_allowed: "Attachment extension %{extension} is not allowed"
214 error_attachment_extension_not_allowed: "Attachment extension %{extension} is not allowed"
215 error_ldap_bind_credentials: "Invalid LDAP Account/Password"
215 error_ldap_bind_credentials: "Invalid LDAP Account/Password"
216 error_no_tracker_allowed_for_new_issue_in_project: "The project doesn't have any trackers for which you can create an issue"
216
217
217 mail_subject_lost_password: "Your %{value} password"
218 mail_subject_lost_password: "Your %{value} password"
218 mail_body_lost_password: 'To change your password, click on the following link:'
219 mail_body_lost_password: 'To change your password, click on the following link:'
@@ -561,6 +562,7 en:
561 label_member_plural: Members
562 label_member_plural: Members
562 label_tracker: Tracker
563 label_tracker: Tracker
563 label_tracker_plural: Trackers
564 label_tracker_plural: Trackers
565 label_tracker_all: All trackers
564 label_tracker_new: New tracker
566 label_tracker_new: New tracker
565 label_workflow: Workflow
567 label_workflow: Workflow
566 label_issue_status: Issue status
568 label_issue_status: Issue status
@@ -233,6 +233,7 fr:
233 error_can_not_read_import_file: "Une erreur est survenue lors de la lecture du fichier Γ  importer"
233 error_can_not_read_import_file: "Une erreur est survenue lors de la lecture du fichier Γ  importer"
234 error_attachment_extension_not_allowed: "L'extension %{extension} n'est pas autorisΓ©e"
234 error_attachment_extension_not_allowed: "L'extension %{extension} n'est pas autorisΓ©e"
235 error_ldap_bind_credentials: "Identifiant ou mot de passe LDAP incorrect"
235 error_ldap_bind_credentials: "Identifiant ou mot de passe LDAP incorrect"
236 error_no_tracker_allowed_for_new_issue_in_project: "Le projet ne dispose d'aucun tracker sur lequel vous pouvez crΓ©er une demande"
236
237
237 mail_subject_lost_password: "Votre mot de passe %{value}"
238 mail_subject_lost_password: "Votre mot de passe %{value}"
238 mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :'
239 mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :'
@@ -573,6 +574,7 fr:
573 label_member_plural: Membres
574 label_member_plural: Membres
574 label_tracker: Tracker
575 label_tracker: Tracker
575 label_tracker_plural: Trackers
576 label_tracker_plural: Trackers
577 label_tracker_all: Tous les trackers
576 label_tracker_new: Nouveau tracker
578 label_tracker_new: Nouveau tracker
577 label_workflow: Workflow
579 label_workflow: Workflow
578 label_issue_status: Statut de demandes
580 label_issue_status: Statut de demandes
@@ -1864,6 +1864,31 class IssuesControllerTest < ActionController::TestCase
1864 end
1864 end
1865 end
1865 end
1866
1866
1867 def test_new_should_propose_allowed_trackers
1868 role = Role.find(1)
1869 role.set_permission_trackers 'add_issues', [1, 3]
1870 role.save!
1871 @request.session[:user_id] = 2
1872
1873 get :new, :project_id => 1
1874 assert_response :success
1875 assert_select 'select[name=?]', 'issue[tracker_id]' do
1876 assert_select 'option', 2
1877 assert_select 'option[value="1"]'
1878 assert_select 'option[value="3"]'
1879 end
1880 end
1881
1882 def test_new_without_allowed_trackers_should_respond_with_403
1883 role = Role.find(1)
1884 role.set_permission_trackers 'add_issues', []
1885 role.save!
1886 @request.session[:user_id] = 2
1887
1888 get :new, :project_id => 1
1889 assert_response 403
1890 end
1891
1867 def test_new_should_preselect_default_version
1892 def test_new_should_preselect_default_version
1868 version = Version.generate!(:project_id => 1)
1893 version = Version.generate!(:project_id => 1)
1869 Project.find(1).update_attribute :default_version_id, version.id
1894 Project.find(1).update_attribute :default_version_id, version.id
@@ -2432,6 +2457,23 class IssuesControllerTest < ActionController::TestCase
2432 assert_nil issue.custom_field_value(cf2)
2457 assert_nil issue.custom_field_value(cf2)
2433 end
2458 end
2434
2459
2460 def test_create_should_ignore_unallowed_trackers
2461 role = Role.find(1)
2462 role.set_permission_trackers :add_issues, [3]
2463 role.save!
2464 @request.session[:user_id] = 2
2465
2466 issue = new_record(Issue) do
2467 post :create, :project_id => 1, :issue => {
2468 :tracker_id => 1,
2469 :status_id => 1,
2470 :subject => 'Test'
2471 }
2472 assert_response 302
2473 end
2474 assert_equal 3, issue.tracker_id
2475 end
2476
2435 def test_post_create_with_watchers
2477 def test_post_create_with_watchers
2436 @request.session[:user_id] = 2
2478 @request.session[:user_id] = 2
2437 ActionMailer::Base.deliveries.clear
2479 ActionMailer::Base.deliveries.clear
@@ -132,6 +132,22 class RolesControllerTest < ActionController::TestCase
132 assert_equal [:edit_project], role.permissions
132 assert_equal [:edit_project], role.permissions
133 end
133 end
134
134
135 def test_update_trackers_permissions
136 put :update, :id => 1, :role => {
137 :permissions_all_trackers => {'add_issues' => '0'},
138 :permissions_tracker_ids => {'add_issues' => ['1', '3', '']}
139 }
140
141 assert_redirected_to '/roles'
142 role = Role.find(1)
143
144 assert_equal({'add_issues' => '0'}, role.permissions_all_trackers)
145 assert_equal({'add_issues' => ['1', '3']}, role.permissions_tracker_ids)
146
147 assert_equal false, role.permissions_all_trackers?(:add_issues)
148 assert_equal [1, 3], role.permissions_tracker_ids(:add_issues).sort
149 end
150
135 def test_update_with_failure
151 def test_update_with_failure
136 put :update, :id => 1, :role => {:name => ''}
152 put :update, :id => 1, :role => {:name => ''}
137 assert_response :success
153 assert_response :success
@@ -1438,6 +1438,91 class IssueTest < ActiveSupport::TestCase
1438 assert_not_include project, Issue.allowed_target_projects(User.find(1))
1438 assert_not_include project, Issue.allowed_target_projects(User.find(1))
1439 end
1439 end
1440
1440
1441 def test_allowed_target_trackers_with_one_role_allowed_on_all_trackers
1442 user = User.generate!
1443 role = Role.generate!
1444 role.add_permission! :add_issues
1445 role.set_permission_trackers :add_issues, :all
1446 role.save!
1447 User.add_to_project(user, Project.find(1), role)
1448
1449 assert_equal [1, 2, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
1450 end
1451
1452 def test_allowed_target_trackers_with_one_role_allowed_on_some_trackers
1453 user = User.generate!
1454 role = Role.generate!
1455 role.add_permission! :add_issues
1456 role.set_permission_trackers :add_issues, [1, 3]
1457 role.save!
1458 User.add_to_project(user, Project.find(1), role)
1459
1460 assert_equal [1, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
1461 end
1462
1463 def test_allowed_target_trackers_with_two_roles_allowed_on_some_trackers
1464 user = User.generate!
1465 role1 = Role.generate!
1466 role1.add_permission! :add_issues
1467 role1.set_permission_trackers :add_issues, [1]
1468 role1.save!
1469 role2 = Role.generate!
1470 role2.add_permission! :add_issues
1471 role2.set_permission_trackers :add_issues, [3]
1472 role2.save!
1473 User.add_to_project(user, Project.find(1), [role1, role2])
1474
1475 assert_equal [1, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
1476 end
1477
1478 def test_allowed_target_trackers_with_two_roles_allowed_on_all_trackers_and_some_trackers
1479 user = User.generate!
1480 role1 = Role.generate!
1481 role1.add_permission! :add_issues
1482 role1.set_permission_trackers :add_issues, :all
1483 role1.save!
1484 role2 = Role.generate!
1485 role2.add_permission! :add_issues
1486 role2.set_permission_trackers :add_issues, [1, 3]
1487 role2.save!
1488 User.add_to_project(user, Project.find(1), [role1, role2])
1489
1490 assert_equal [1, 2, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
1491 end
1492
1493 def test_allowed_target_trackers_should_not_consider_roles_without_add_issues_permission
1494 user = User.generate!
1495 role1 = Role.generate!
1496 role1.remove_permission! :add_issues
1497 role1.set_permission_trackers :add_issues, :all
1498 role1.save!
1499 role2 = Role.generate!
1500 role2.add_permission! :add_issues
1501 role2.set_permission_trackers :add_issues, [1, 3]
1502 role2.save!
1503 User.add_to_project(user, Project.find(1), [role1, role2])
1504
1505 assert_equal [1, 3], Issue.new(:project => Project.find(1)).allowed_target_trackers(user).ids.sort
1506 end
1507
1508 def test_allowed_target_trackers_without_project_should_be_empty
1509 issue = Issue.new
1510 assert_nil issue.project
1511 assert_equal [], issue.allowed_target_trackers(User.find(2)).ids
1512 end
1513
1514 def test_allowed_target_trackers_should_include_current_tracker
1515 user = User.generate!
1516 role = Role.generate!
1517 role.add_permission! :add_issues
1518 role.set_permission_trackers :add_issues, [3]
1519 role.save!
1520 User.add_to_project(user, Project.find(1), role)
1521
1522 issue = Issue.generate!(:project => Project.find(1), :tracker => Tracker.find(1))
1523 assert_equal [1, 3], issue.allowed_target_trackers(user).ids.sort
1524 end
1525
1441 def test_move_to_another_project_with_same_category
1526 def test_move_to_another_project_with_same_category
1442 issue = Issue.find(1)
1527 issue = Issue.find(1)
1443 issue.project = Project.find(2)
1528 issue.project = Project.find(2)
General Comments 0
You need to be logged in to leave comments. Login now