Add view_issues permission (#3187).
A migration adds this permission to all existing roles to preserve current behaviour. This permission controls access to issues, roadmap and changelog. git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@3039 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
326ed79b43
commit
dfd0204052
|
@ -43,7 +43,7 @@ class SearchController < ApplicationController
|
||||||
begin; offset = params[:offset].to_time if params[:offset]; rescue; end
|
begin; offset = params[:offset].to_time if params[:offset]; rescue; end
|
||||||
|
|
||||||
# quick jump to an issue
|
# quick jump to an issue
|
||||||
if @question.match(/^#?(\d+)$/) && Issue.find_by_id($1, :include => :project, :conditions => Project.visible_by(User.current))
|
if @question.match(/^#?(\d+)$/) && Issue.visible.find_by_id($1)
|
||||||
redirect_to :controller => "issues", :action => "show", :id => $1
|
redirect_to :controller => "issues", :action => "show", :id => $1
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
@ -480,7 +480,7 @@ module ApplicationHelper
|
||||||
oid = oid.to_i
|
oid = oid.to_i
|
||||||
case prefix
|
case prefix
|
||||||
when nil
|
when nil
|
||||||
if issue = Issue.find_by_id(oid, :include => [:project, :status], :conditions => Project.visible_by(User.current))
|
if issue = Issue.visible.find_by_id(oid, :include => :status)
|
||||||
link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid},
|
link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid},
|
||||||
:class => (issue.closed? ? 'issue closed' : 'issue'),
|
:class => (issue.closed? ? 'issue closed' : 'issue'),
|
||||||
:title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})")
|
:title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="contextual">
|
<div class="contextual">
|
||||||
<%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %>
|
<%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %>
|
||||||
<%= link_to l(:label_issue_view_all), { :controller => 'issues' } %> |
|
<%= link_to(l(:label_issue_view_all), { :controller => 'issues' }) + ' |' if User.current.allowed_to?(:view_issues, nil, :global => true) %>
|
||||||
<%= link_to l(:label_overall_activity), { :controller => 'projects', :action => 'activity' }%>
|
<%= link_to l(:label_overall_activity), { :controller => 'projects', :action => 'activity' }%>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,10 @@
|
||||||
|
|
||||||
<%= textilizable @changeset.comments %>
|
<%= textilizable @changeset.comments %>
|
||||||
|
|
||||||
<% if @changeset.issues.any? %>
|
<% if @changeset.issues.visible.any? %>
|
||||||
<h3><%= l(:label_related_issues) %></h3>
|
<h3><%= l(:label_related_issues) %></h3>
|
||||||
<ul>
|
<ul>
|
||||||
<% @changeset.issues.each do |issue| %>
|
<% @changeset.issues.visible.each do |issue| %>
|
||||||
<li><%= link_to_issue issue %>: <%=h issue.subject %></li>
|
<li><%= link_to_issue issue %>: <%=h issue.subject %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
class AddViewIssuesPermission < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
Role.find(:all).each do |r|
|
||||||
|
r.add_permission!(:view_issues)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
Role.find(:all).each do |r|
|
||||||
|
r.remove_permission!(:view_issues)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -41,7 +41,7 @@ Redmine::AccessControl.map do |map|
|
||||||
:issues => [:index, :changes, :show, :context_menu],
|
:issues => [:index, :changes, :show, :context_menu],
|
||||||
:versions => [:show, :status_by],
|
:versions => [:show, :status_by],
|
||||||
:queries => :index,
|
:queries => :index,
|
||||||
:reports => :issue_report}, :public => true
|
:reports => :issue_report}
|
||||||
map.permission :add_issues, {:issues => :new}
|
map.permission :add_issues, {:issues => :new}
|
||||||
map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit]}
|
map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit]}
|
||||||
map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
|
map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
|
||||||
|
|
|
@ -49,6 +49,7 @@ module Redmine
|
||||||
:position => 2,
|
:position => 2,
|
||||||
:permissions => [:manage_versions,
|
:permissions => [:manage_versions,
|
||||||
:manage_categories,
|
:manage_categories,
|
||||||
|
:view_issues,
|
||||||
:add_issues,
|
:add_issues,
|
||||||
:edit_issues,
|
:edit_issues,
|
||||||
:manage_issue_relations,
|
:manage_issue_relations,
|
||||||
|
@ -74,7 +75,8 @@ module Redmine
|
||||||
|
|
||||||
reporter = Role.create! :name => l(:default_role_reporter),
|
reporter = Role.create! :name => l(:default_role_reporter),
|
||||||
:position => 3,
|
:position => 3,
|
||||||
:permissions => [:add_issues,
|
:permissions => [:view_issues,
|
||||||
|
:add_issues,
|
||||||
:add_issue_notes,
|
:add_issue_notes,
|
||||||
:save_queries,
|
:save_queries,
|
||||||
:view_gantt,
|
:view_gantt,
|
||||||
|
@ -91,7 +93,8 @@ module Redmine
|
||||||
:browse_repository,
|
:browse_repository,
|
||||||
:view_changesets]
|
:view_changesets]
|
||||||
|
|
||||||
Role.non_member.update_attribute :permissions, [:add_issues,
|
Role.non_member.update_attribute :permissions, [:view_issues,
|
||||||
|
:add_issues,
|
||||||
:add_issue_notes,
|
:add_issue_notes,
|
||||||
:save_queries,
|
:save_queries,
|
||||||
:view_gantt,
|
:view_gantt,
|
||||||
|
@ -106,7 +109,8 @@ module Redmine
|
||||||
:browse_repository,
|
:browse_repository,
|
||||||
:view_changesets]
|
:view_changesets]
|
||||||
|
|
||||||
Role.anonymous.update_attribute :permissions, [:view_gantt,
|
Role.anonymous.update_attribute :permissions, [:view_issues,
|
||||||
|
:view_gantt,
|
||||||
:view_calendar,
|
:view_calendar,
|
||||||
:view_time_entries,
|
:view_time_entries,
|
||||||
:view_documents,
|
:view_documents,
|
||||||
|
|
|
@ -10,6 +10,7 @@ roles_001:
|
||||||
- :manage_members
|
- :manage_members
|
||||||
- :manage_versions
|
- :manage_versions
|
||||||
- :manage_categories
|
- :manage_categories
|
||||||
|
- :view_issues
|
||||||
- :add_issues
|
- :add_issues
|
||||||
- :edit_issues
|
- :edit_issues
|
||||||
- :manage_issue_relations
|
- :manage_issue_relations
|
||||||
|
@ -60,6 +61,7 @@ roles_002:
|
||||||
- :manage_members
|
- :manage_members
|
||||||
- :manage_versions
|
- :manage_versions
|
||||||
- :manage_categories
|
- :manage_categories
|
||||||
|
- :view_issues
|
||||||
- :add_issues
|
- :add_issues
|
||||||
- :edit_issues
|
- :edit_issues
|
||||||
- :manage_issue_relations
|
- :manage_issue_relations
|
||||||
|
@ -102,6 +104,7 @@ roles_003:
|
||||||
- :manage_members
|
- :manage_members
|
||||||
- :manage_versions
|
- :manage_versions
|
||||||
- :manage_categories
|
- :manage_categories
|
||||||
|
- :view_issues
|
||||||
- :add_issues
|
- :add_issues
|
||||||
- :edit_issues
|
- :edit_issues
|
||||||
- :manage_issue_relations
|
- :manage_issue_relations
|
||||||
|
@ -135,6 +138,7 @@ roles_004:
|
||||||
builtin: 1
|
builtin: 1
|
||||||
permissions: |
|
permissions: |
|
||||||
---
|
---
|
||||||
|
- :view_issues
|
||||||
- :add_issues
|
- :add_issues
|
||||||
- :edit_issues
|
- :edit_issues
|
||||||
- :manage_issue_relations
|
- :manage_issue_relations
|
||||||
|
@ -164,6 +168,7 @@ roles_005:
|
||||||
builtin: 2
|
builtin: 2
|
||||||
permissions: |
|
permissions: |
|
||||||
---
|
---
|
||||||
|
- :view_issues
|
||||||
- :add_issue_notes
|
- :add_issue_notes
|
||||||
- :view_gantt
|
- :view_gantt
|
||||||
- :view_calendar
|
- :view_calendar
|
||||||
|
|
|
@ -358,6 +358,26 @@ class IssuesControllerTest < ActionController::TestCase
|
||||||
:content => /Notes/ } }
|
:content => /Notes/ } }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_show_should_deny_anonymous_access_without_permission
|
||||||
|
Role.anonymous.remove_permission!(:view_issues)
|
||||||
|
get :show, :id => 1
|
||||||
|
assert_response :redirect
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_show_should_deny_non_member_access_without_permission
|
||||||
|
Role.non_member.remove_permission!(:view_issues)
|
||||||
|
@request.session[:user_id] = 9
|
||||||
|
get :show, :id => 1
|
||||||
|
assert_response 403
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_show_should_deny_member_access_without_permission
|
||||||
|
Role.find(1).remove_permission!(:view_issues)
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
get :show, :id => 1
|
||||||
|
assert_response 403
|
||||||
|
end
|
||||||
|
|
||||||
def test_show_should_not_disclose_relations_to_invisible_issues
|
def test_show_should_not_disclose_relations_to_invisible_issues
|
||||||
Setting.cross_project_issue_relations = '1'
|
Setting.cross_project_issue_relations = '1'
|
||||||
IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
|
IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
require File.dirname(__FILE__) + '/../test_helper'
|
require File.dirname(__FILE__) + '/../test_helper'
|
||||||
|
|
||||||
class IssueTest < ActiveSupport::TestCase
|
class IssueTest < ActiveSupport::TestCase
|
||||||
fixtures :projects, :users, :members, :member_roles,
|
fixtures :projects, :users, :members, :member_roles, :roles,
|
||||||
:trackers, :projects_trackers,
|
:trackers, :projects_trackers,
|
||||||
:versions,
|
:versions,
|
||||||
:issue_statuses, :issue_categories, :issue_relations, :workflows,
|
:issue_statuses, :issue_categories, :issue_relations, :workflows,
|
||||||
|
@ -64,6 +64,47 @@ class IssueTest < ActiveSupport::TestCase
|
||||||
assert_equal 'PostgreSQL', issue.custom_value_for(field).value
|
assert_equal 'PostgreSQL', issue.custom_value_for(field).value
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_visible_scope_for_anonymous
|
||||||
|
# Anonymous user should see issues of public projects only
|
||||||
|
issues = Issue.visible(User.anonymous).all
|
||||||
|
assert issues.any?
|
||||||
|
assert_nil issues.detect {|issue| !issue.project.is_public?}
|
||||||
|
# Anonymous user should not see issues without permission
|
||||||
|
Role.anonymous.remove_permission!(:view_issues)
|
||||||
|
issues = Issue.visible(User.anonymous).all
|
||||||
|
assert issues.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_visible_scope_for_user
|
||||||
|
user = User.find(9)
|
||||||
|
assert user.projects.empty?
|
||||||
|
# Non member user should see issues of public projects only
|
||||||
|
issues = Issue.visible(user).all
|
||||||
|
assert issues.any?
|
||||||
|
assert_nil issues.detect {|issue| !issue.project.is_public?}
|
||||||
|
# Non member user should not see issues without permission
|
||||||
|
Role.non_member.remove_permission!(:view_issues)
|
||||||
|
user.reload
|
||||||
|
issues = Issue.visible(user).all
|
||||||
|
assert issues.empty?
|
||||||
|
# User should see issues of projects for which he has view_issues permissions only
|
||||||
|
Member.create!(:principal => user, :project_id => 2, :role_ids => [1])
|
||||||
|
user.reload
|
||||||
|
issues = Issue.visible(user).all
|
||||||
|
assert issues.any?
|
||||||
|
assert_nil issues.detect {|issue| issue.project_id != 2}
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_visible_scope_for_admin
|
||||||
|
user = User.find(1)
|
||||||
|
user.members.each(&:destroy)
|
||||||
|
assert user.projects.empty?
|
||||||
|
issues = Issue.visible(user).all
|
||||||
|
assert issues.any?
|
||||||
|
# Admin should see issues on private projects that he does not belong to
|
||||||
|
assert issues.detect {|issue| !issue.project.is_public?}
|
||||||
|
end
|
||||||
|
|
||||||
def test_errors_full_messages_should_include_custom_fields_errors
|
def test_errors_full_messages_should_include_custom_fields_errors
|
||||||
field = IssueCustomField.find_by_name('Database')
|
field = IssueCustomField.find_by_name('Database')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue