@@ -0,0 +1,13 | |||||
|
1 | class AddViewIssuesPermission < ActiveRecord::Migration | |||
|
2 | def self.up | |||
|
3 | Role.find(:all).each do |r| | |||
|
4 | r.add_permission!(:view_issues) | |||
|
5 | end | |||
|
6 | end | |||
|
7 | ||||
|
8 | def self.down | |||
|
9 | Role.find(:all).each do |r| | |||
|
10 | r.remove_permission!(:view_issues) | |||
|
11 | end | |||
|
12 | end | |||
|
13 | end |
@@ -43,7 +43,7 class SearchController < ApplicationController | |||||
43 | begin; offset = params[:offset].to_time if params[:offset]; rescue; end |
|
43 | begin; offset = params[:offset].to_time if params[:offset]; rescue; end | |
44 |
|
44 | |||
45 | # quick jump to an issue |
|
45 | # quick jump to an issue | |
46 | if @question.match(/^#?(\d+)$/) && Issue.find_by_id($1, :include => :project, :conditions => Project.visible_by(User.current)) |
|
46 | if @question.match(/^#?(\d+)$/) && Issue.visible.find_by_id($1) | |
47 | redirect_to :controller => "issues", :action => "show", :id => $1 |
|
47 | redirect_to :controller => "issues", :action => "show", :id => $1 | |
48 | return |
|
48 | return | |
49 | end |
|
49 | end |
@@ -480,7 +480,7 module ApplicationHelper | |||||
480 | oid = oid.to_i |
|
480 | oid = oid.to_i | |
481 | case prefix |
|
481 | case prefix | |
482 | when nil |
|
482 | when nil | |
483 |
if issue = Issue.find_by_id(oid, :include => |
|
483 | if issue = Issue.visible.find_by_id(oid, :include => :status) | |
484 | link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid}, |
|
484 | link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid}, | |
485 | :class => (issue.closed? ? 'issue closed' : 'issue'), |
|
485 | :class => (issue.closed? ? 'issue closed' : 'issue'), | |
486 | :title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})") |
|
486 | :title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})") |
@@ -1,6 +1,6 | |||||
1 | <div class="contextual"> |
|
1 | <div class="contextual"> | |
2 | <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %> |
|
2 | <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %> | |
3 |
<%= link_to |
|
3 | <%= link_to(l(:label_issue_view_all), { :controller => 'issues' }) + ' |' if User.current.allowed_to?(:view_issues, nil, :global => true) %> | |
4 | <%= link_to l(:label_overall_activity), { :controller => 'projects', :action => 'activity' }%> |
|
4 | <%= link_to l(:label_overall_activity), { :controller => 'projects', :action => 'activity' }%> | |
5 | </div> |
|
5 | </div> | |
6 |
|
6 |
@@ -26,10 +26,10 | |||||
26 |
|
26 | |||
27 | <%= textilizable @changeset.comments %> |
|
27 | <%= textilizable @changeset.comments %> | |
28 |
|
28 | |||
29 | <% if @changeset.issues.any? %> |
|
29 | <% if @changeset.issues.visible.any? %> | |
30 | <h3><%= l(:label_related_issues) %></h3> |
|
30 | <h3><%= l(:label_related_issues) %></h3> | |
31 | <ul> |
|
31 | <ul> | |
32 | <% @changeset.issues.each do |issue| %> |
|
32 | <% @changeset.issues.visible.each do |issue| %> | |
33 | <li><%= link_to_issue issue %>: <%=h issue.subject %></li> |
|
33 | <li><%= link_to_issue issue %>: <%=h issue.subject %></li> | |
34 | <% end %> |
|
34 | <% end %> | |
35 | </ul> |
|
35 | </ul> |
@@ -41,7 +41,7 Redmine::AccessControl.map do |map| | |||||
41 | :issues => [:index, :changes, :show, :context_menu], |
|
41 | :issues => [:index, :changes, :show, :context_menu], | |
42 | :versions => [:show, :status_by], |
|
42 | :versions => [:show, :status_by], | |
43 | :queries => :index, |
|
43 | :queries => :index, | |
44 |
:reports => :issue_report} |
|
44 | :reports => :issue_report} | |
45 | map.permission :add_issues, {:issues => :new} |
|
45 | map.permission :add_issues, {:issues => :new} | |
46 | map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit]} |
|
46 | map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit]} | |
47 | map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} |
|
47 | map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} |
@@ -49,6 +49,7 module Redmine | |||||
49 | :position => 2, |
|
49 | :position => 2, | |
50 | :permissions => [:manage_versions, |
|
50 | :permissions => [:manage_versions, | |
51 | :manage_categories, |
|
51 | :manage_categories, | |
|
52 | :view_issues, | |||
52 | :add_issues, |
|
53 | :add_issues, | |
53 | :edit_issues, |
|
54 | :edit_issues, | |
54 | :manage_issue_relations, |
|
55 | :manage_issue_relations, | |
@@ -74,7 +75,8 module Redmine | |||||
74 |
|
75 | |||
75 | reporter = Role.create! :name => l(:default_role_reporter), |
|
76 | reporter = Role.create! :name => l(:default_role_reporter), | |
76 | :position => 3, |
|
77 | :position => 3, | |
77 |
:permissions => [: |
|
78 | :permissions => [:view_issues, | |
|
79 | :add_issues, | |||
78 | :add_issue_notes, |
|
80 | :add_issue_notes, | |
79 | :save_queries, |
|
81 | :save_queries, | |
80 | :view_gantt, |
|
82 | :view_gantt, | |
@@ -91,7 +93,8 module Redmine | |||||
91 | :browse_repository, |
|
93 | :browse_repository, | |
92 | :view_changesets] |
|
94 | :view_changesets] | |
93 |
|
95 | |||
94 |
Role.non_member.update_attribute :permissions, [: |
|
96 | Role.non_member.update_attribute :permissions, [:view_issues, | |
|
97 | :add_issues, | |||
95 | :add_issue_notes, |
|
98 | :add_issue_notes, | |
96 | :save_queries, |
|
99 | :save_queries, | |
97 | :view_gantt, |
|
100 | :view_gantt, | |
@@ -106,7 +109,8 module Redmine | |||||
106 | :browse_repository, |
|
109 | :browse_repository, | |
107 | :view_changesets] |
|
110 | :view_changesets] | |
108 |
|
111 | |||
109 |
Role.anonymous.update_attribute :permissions, [:view_ |
|
112 | Role.anonymous.update_attribute :permissions, [:view_issues, | |
|
113 | :view_gantt, | |||
110 | :view_calendar, |
|
114 | :view_calendar, | |
111 | :view_time_entries, |
|
115 | :view_time_entries, | |
112 | :view_documents, |
|
116 | :view_documents, |
@@ -10,6 +10,7 roles_001: | |||||
10 | - :manage_members |
|
10 | - :manage_members | |
11 | - :manage_versions |
|
11 | - :manage_versions | |
12 | - :manage_categories |
|
12 | - :manage_categories | |
|
13 | - :view_issues | |||
13 | - :add_issues |
|
14 | - :add_issues | |
14 | - :edit_issues |
|
15 | - :edit_issues | |
15 | - :manage_issue_relations |
|
16 | - :manage_issue_relations | |
@@ -60,6 +61,7 roles_002: | |||||
60 | - :manage_members |
|
61 | - :manage_members | |
61 | - :manage_versions |
|
62 | - :manage_versions | |
62 | - :manage_categories |
|
63 | - :manage_categories | |
|
64 | - :view_issues | |||
63 | - :add_issues |
|
65 | - :add_issues | |
64 | - :edit_issues |
|
66 | - :edit_issues | |
65 | - :manage_issue_relations |
|
67 | - :manage_issue_relations | |
@@ -102,6 +104,7 roles_003: | |||||
102 | - :manage_members |
|
104 | - :manage_members | |
103 | - :manage_versions |
|
105 | - :manage_versions | |
104 | - :manage_categories |
|
106 | - :manage_categories | |
|
107 | - :view_issues | |||
105 | - :add_issues |
|
108 | - :add_issues | |
106 | - :edit_issues |
|
109 | - :edit_issues | |
107 | - :manage_issue_relations |
|
110 | - :manage_issue_relations | |
@@ -135,6 +138,7 roles_004: | |||||
135 | builtin: 1 |
|
138 | builtin: 1 | |
136 | permissions: | |
|
139 | permissions: | | |
137 | --- |
|
140 | --- | |
|
141 | - :view_issues | |||
138 | - :add_issues |
|
142 | - :add_issues | |
139 | - :edit_issues |
|
143 | - :edit_issues | |
140 | - :manage_issue_relations |
|
144 | - :manage_issue_relations | |
@@ -164,6 +168,7 roles_005: | |||||
164 | builtin: 2 |
|
168 | builtin: 2 | |
165 | permissions: | |
|
169 | permissions: | | |
166 | --- |
|
170 | --- | |
|
171 | - :view_issues | |||
167 | - :add_issue_notes |
|
172 | - :add_issue_notes | |
168 | - :view_gantt |
|
173 | - :view_gantt | |
169 | - :view_calendar |
|
174 | - :view_calendar |
@@ -358,6 +358,26 class IssuesControllerTest < ActionController::TestCase | |||||
358 | :content => /Notes/ } } |
|
358 | :content => /Notes/ } } | |
359 | end |
|
359 | end | |
360 |
|
360 | |||
|
361 | def test_show_should_deny_anonymous_access_without_permission | |||
|
362 | Role.anonymous.remove_permission!(:view_issues) | |||
|
363 | get :show, :id => 1 | |||
|
364 | assert_response :redirect | |||
|
365 | end | |||
|
366 | ||||
|
367 | def test_show_should_deny_non_member_access_without_permission | |||
|
368 | Role.non_member.remove_permission!(:view_issues) | |||
|
369 | @request.session[:user_id] = 9 | |||
|
370 | get :show, :id => 1 | |||
|
371 | assert_response 403 | |||
|
372 | end | |||
|
373 | ||||
|
374 | def test_show_should_deny_member_access_without_permission | |||
|
375 | Role.find(1).remove_permission!(:view_issues) | |||
|
376 | @request.session[:user_id] = 2 | |||
|
377 | get :show, :id => 1 | |||
|
378 | assert_response 403 | |||
|
379 | end | |||
|
380 | ||||
361 | def test_show_should_not_disclose_relations_to_invisible_issues |
|
381 | def test_show_should_not_disclose_relations_to_invisible_issues | |
362 | Setting.cross_project_issue_relations = '1' |
|
382 | Setting.cross_project_issue_relations = '1' | |
363 | IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates') |
|
383 | IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates') |
@@ -18,7 +18,7 | |||||
18 | require File.dirname(__FILE__) + '/../test_helper' |
|
18 | require File.dirname(__FILE__) + '/../test_helper' | |
19 |
|
19 | |||
20 | class IssueTest < ActiveSupport::TestCase |
|
20 | class IssueTest < ActiveSupport::TestCase | |
21 | fixtures :projects, :users, :members, :member_roles, |
|
21 | fixtures :projects, :users, :members, :member_roles, :roles, | |
22 | :trackers, :projects_trackers, |
|
22 | :trackers, :projects_trackers, | |
23 | :versions, |
|
23 | :versions, | |
24 | :issue_statuses, :issue_categories, :issue_relations, :workflows, |
|
24 | :issue_statuses, :issue_categories, :issue_relations, :workflows, | |
@@ -64,6 +64,47 class IssueTest < ActiveSupport::TestCase | |||||
64 | assert_equal 'PostgreSQL', issue.custom_value_for(field).value |
|
64 | assert_equal 'PostgreSQL', issue.custom_value_for(field).value | |
65 | end |
|
65 | end | |
66 |
|
66 | |||
|
67 | def test_visible_scope_for_anonymous | |||
|
68 | # Anonymous user should see issues of public projects only | |||
|
69 | issues = Issue.visible(User.anonymous).all | |||
|
70 | assert issues.any? | |||
|
71 | assert_nil issues.detect {|issue| !issue.project.is_public?} | |||
|
72 | # Anonymous user should not see issues without permission | |||
|
73 | Role.anonymous.remove_permission!(:view_issues) | |||
|
74 | issues = Issue.visible(User.anonymous).all | |||
|
75 | assert issues.empty? | |||
|
76 | end | |||
|
77 | ||||
|
78 | def test_visible_scope_for_user | |||
|
79 | user = User.find(9) | |||
|
80 | assert user.projects.empty? | |||
|
81 | # Non member user should see issues of public projects only | |||
|
82 | issues = Issue.visible(user).all | |||
|
83 | assert issues.any? | |||
|
84 | assert_nil issues.detect {|issue| !issue.project.is_public?} | |||
|
85 | # Non member user should not see issues without permission | |||
|
86 | Role.non_member.remove_permission!(:view_issues) | |||
|
87 | user.reload | |||
|
88 | issues = Issue.visible(user).all | |||
|
89 | assert issues.empty? | |||
|
90 | # User should see issues of projects for which he has view_issues permissions only | |||
|
91 | Member.create!(:principal => user, :project_id => 2, :role_ids => [1]) | |||
|
92 | user.reload | |||
|
93 | issues = Issue.visible(user).all | |||
|
94 | assert issues.any? | |||
|
95 | assert_nil issues.detect {|issue| issue.project_id != 2} | |||
|
96 | end | |||
|
97 | ||||
|
98 | def test_visible_scope_for_admin | |||
|
99 | user = User.find(1) | |||
|
100 | user.members.each(&:destroy) | |||
|
101 | assert user.projects.empty? | |||
|
102 | issues = Issue.visible(user).all | |||
|
103 | assert issues.any? | |||
|
104 | # Admin should see issues on private projects that he does not belong to | |||
|
105 | assert issues.detect {|issue| !issue.project.is_public?} | |||
|
106 | end | |||
|
107 | ||||
67 | def test_errors_full_messages_should_include_custom_fields_errors |
|
108 | def test_errors_full_messages_should_include_custom_fields_errors | |
68 | field = IssueCustomField.find_by_name('Database') |
|
109 | field = IssueCustomField.find_by_name('Database') | |
69 |
|
110 |
General Comments 0
You need to be logged in to leave comments.
Login now