diff --git a/app/models/project.rb b/app/models/project.rb index e40af996..d283e269 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -108,6 +108,12 @@ class Project < ActiveRecord::Base def self.allowed_to_condition(user, permission, options={}) statements = [] base_statement = "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}" + if perm = Redmine::AccessControl.permission(permission) + unless perm.project_module.nil? + # If the permission belongs to a project module, make sure the module is enabled + base_statement << " AND EXISTS (SELECT em.id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.project_module}' AND em.project_id=#{Project.table_name}.id)" + end + end if options[:project] project_statement = "#{Project.table_name}.id = #{options[:project].id}" project_statement << " OR #{Project.table_name}.parent_id = #{options[:project].id}" if options[:with_subprojects] diff --git a/app/models/query.rb b/app/models/query.rb index f8c23614..ac877772 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -277,7 +277,7 @@ class Query < ActiveRecord::Base elsif project project_clauses << "#{Project.table_name}.id = %d" % project.id end - project_clauses << Project.visible_by(User.current) + project_clauses << Project.allowed_to_condition(User.current, :view_issues) project_clauses.join(' AND ') end diff --git a/lib/redmine/access_control.rb b/lib/redmine/access_control.rb index f5b25f27..25cf63d6 100644 --- a/lib/redmine/access_control.rb +++ b/lib/redmine/access_control.rb @@ -30,8 +30,15 @@ module Redmine @permissions end + # Returns the permission of given name or nil if it wasn't found + # Argument should be a symbol + def permission(name) + permissions.detect {|p| p.name == name} + end + + # Returns the actions that are allowed by the permission of given name def allowed_actions(permission_name) - perm = @permissions.detect {|p| p.name == permission_name} + perm = permission(permission_name) perm ? perm.actions : [] end @@ -94,6 +101,7 @@ module Redmine @actions << "#{controller}/#{actions}" end end + @actions.flatten! end def public? diff --git a/test/fixtures/enabled_modules.yml b/test/fixtures/enabled_modules.yml index da63bad5..6639dfa1 100644 --- a/test/fixtures/enabled_modules.yml +++ b/test/fixtures/enabled_modules.yml @@ -43,4 +43,16 @@ enabled_modules_011: name: issue_tracking project_id: 2 id: 11 +enabled_modules_012: + name: time_tracking + project_id: 3 + id: 12 +enabled_modules_013: + name: issue_tracking + project_id: 3 + id: 13 +enabled_modules_014: + name: issue_tracking + project_id: 5 + id: 14 \ No newline at end of file diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index 9e2a9ffd..517aee3a 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -62,6 +62,17 @@ class IssuesControllerTest < Test::Unit::TestCase assert_no_tag :tag => 'a', :content => /Issue of a private subproject/ assert_no_tag :tag => 'a', :content => /Issue on project 2/ end + + def test_index_should_not_list_issues_when_module_disabled + EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1") + get :index + assert_response :success + assert_template 'index.rhtml' + assert_not_nil assigns(:issues) + assert_nil assigns(:project) + assert_no_tag :tag => 'a', :content => /Can't print recipes/ + assert_tag :tag => 'a', :content => /Subproject issue/ + end def test_index_with_project Setting.display_subprojects_issues = 0 diff --git a/test/unit/lib/redmine/access_control_test.rb b/test/unit/lib/redmine/access_control_test.rb new file mode 100644 index 00000000..5dd87d28 --- /dev/null +++ b/test/unit/lib/redmine/access_control_test.rb @@ -0,0 +1,49 @@ +# Redmine - project management software +# Copyright (C) 2006-2008 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require File.dirname(__FILE__) + '/../../../test_helper' + +class Redmine::AccessControlTest < Test::Unit::TestCase + + def setup + @access_module = Redmine::AccessControl + end + + def test_permissions + perms = @access_module.permissions + assert perms.is_a?(Array) + assert perms.first.is_a?(Redmine::AccessControl::Permission) + end + + def test_module_permission + perm = @access_module.permission(:view_issues) + assert perm.is_a?(Redmine::AccessControl::Permission) + assert_equal :view_issues, perm.name + assert_equal :issue_tracking, perm.project_module + assert perm.actions.is_a?(Array) + assert perm.actions.include?('issues/index') + end + + def test_no_module_permission + perm = @access_module.permission(:edit_project) + assert perm.is_a?(Redmine::AccessControl::Permission) + assert_equal :edit_project, perm.name + assert_nil perm.project_module + assert perm.actions.is_a?(Array) + assert perm.actions.include?('projects/settings') + end +end