diff --git a/lib/open_project/global_roles/engine.rb b/lib/open_project/global_roles/engine.rb index 1812ecc914..3822d43b38 100644 --- a/lib/open_project/global_roles/engine.rb +++ b/lib/open_project/global_roles/engine.rb @@ -47,7 +47,26 @@ module OpenProject::GlobalRoles end config.to_prepare do - User.register_allowance_evaluator OpenProject::GlobalRoles::PrincipalAllowanceEvaluator::Global + principal_roles_table = PrincipalRole.arel_table + query = Authorization::UserGlobalRolesQuery + roles_table = query.roles_table + users_table = query.users_table + + query.transformations + .register :all, + :principal_roles_join, + before: [:roles_join] do |statement, user| + + statement.outer_join(principal_roles_table) + .on(users_table[:id].eq(principal_roles_table[:principal_id])) + end + + query.transformations + .register query.roles_member_roles_join, + :or_is_principal_role do |statement, user| + + statement.or(principal_roles_table[:role_id].eq(roles_table[:id])) + end end end end diff --git a/lib/open_project/global_roles/principal_allowance_evaluator/global.rb b/lib/open_project/global_roles/principal_allowance_evaluator/global.rb deleted file mode 100644 index 6656dfc0db..0000000000 --- a/lib/open_project/global_roles/principal_allowance_evaluator/global.rb +++ /dev/null @@ -1,37 +0,0 @@ -#-- copyright -# OpenProject Global Roles Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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. -#++ - -module OpenProject - module GlobalRoles - module PrincipalAllowanceEvaluator - class Global < OpenProject::PrincipalAllowanceEvaluator::Base - def granted_for_global?(membership, action, options) - return false unless membership.is_a?(PrincipalRole) - granted = super - - granted || membership.role.allowed_to?(action).present? - end - - def global_granting_candidates - @user.principal_roles - end - end - end - end -end diff --git a/spec/factories/principal_role_factory.rb b/spec/factories/principal_role_factory.rb index fcea8b6e02..df25d803f9 100644 --- a/spec/factories/principal_role_factory.rb +++ b/spec/factories/principal_role_factory.rb @@ -19,7 +19,12 @@ FactoryGirl.define do factory :principal_role do |pr| - pr.association :role, factory: :global_role - pr.association :principal, factory: :user + pr.association :role, :factory => :global_role + pr.association :principal, :factory => :user + end +end + +FactoryGirl.define do + factory :empty_principal_role, :class => PrincipalRole do |pr| end end diff --git a/spec/lib/global_roles/principal_allowance_evaluator/global_spec.rb b/spec/lib/global_roles/principal_allowance_evaluator/global_spec.rb deleted file mode 100644 index 931268ae0e..0000000000 --- a/spec/lib/global_roles/principal_allowance_evaluator/global_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -#-- copyright -# OpenProject Global Roles Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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__) + '/../../../spec_helper' - -describe OpenProject::GlobalRoles::PrincipalAllowanceEvaluator::Global do - let(:klass) { OpenProject::GlobalRoles::PrincipalAllowanceEvaluator::Global } - let(:user) { FactoryGirl.build(:user) } - let(:filter) { klass.new user } - let(:member) { FactoryGirl.build(:member) } - let(:principal_role) { - FactoryGirl.build(:principal_role, - role: role) - } - let(:principal_role2) { FactoryGirl.build(:principal_role) } - let(:role) { FactoryGirl.build(:global_role) } - let(:project) { FactoryGirl.build(:project) } - - describe '#granted_for_project?' do - it { expect(filter.granted_for_project?(member, :action, project)).to be_falsey } - end - - describe '#denied_for_project?' do - it { expect(filter.denied_for_project?(member, :action, project)).to be_falsey } - end - - describe '#granted_for_global?' do - describe 'WHEN checking a Member' do - it { expect(filter.granted_for_global?(member, :action, {})).to be_falsey } - end - - describe "WHEN checking a PrincipalRole - WHEN the PrincipalRole has a Role that is allowed the action" do - before do - role.permissions = [:action] - end - - it { expect(filter.granted_for_global?(principal_role, :action, {})).to be_truthy } - end - - describe "WHEN checking a PrincipalRole - WHEN the PrincipalRole has a Role that is not allowed the action" do - it { expect(filter.granted_for_global?(principal_role, :action, {})).to be_falsey } - end - end - - describe '#denied_for_global?' do - it { expect(filter.denied_for_global?(principal_role, :action, {})).to be_falsey } - end - - describe '#project_granting_candidates' do - it { expect(filter.project_granting_candidates(project)).to match_array([]) } - end - - describe '#global_granting_candidates' do - describe 'WHEN the user has a PrincipalRole assigned' do - before do - user.principal_roles = [principal_role] - end - - it { filter.global_granting_candidates =~ [principal_role] } - end - - describe 'WHEN the user has multiple PrincipalRole assigned' do - before do - user.principal_roles = [principal_role, principal_role2] - end - - it { filter.global_granting_candidates =~ [principal_role, principal_role2] } - end - - describe 'WHEN the user has no PrincipalRoles assigned' do - it { filter.global_granting_candidates =~ [] } - end - end -end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb deleted file mode 100644 index 2d940ad3ad..0000000000 --- a/spec/models/user_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -#-- copyright -# OpenProject Global Roles Plugin -# -# Copyright (C) 2010 - 2014 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# version 3. -# -# 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__) + '/../spec_helper' - -describe User, type: :model do - let(:klass) { User } - - describe '#registered_allowance_evaluators' do - it { - expect(klass.registered_allowance_evaluators).to include( - OpenProject::GlobalRoles::PrincipalAllowanceEvaluator::Global - ) - } - end -end diff --git a/spec/models/users/allowed_to_spec.rb b/spec/models/users/allowed_to_spec.rb new file mode 100644 index 0000000000..a1f9f02b9e --- /dev/null +++ b/spec/models/users/allowed_to_spec.rb @@ -0,0 +1,145 @@ +#-- copyright +# OpenProject is a project management system. +# +# Copyright (C) 2010-2013 the OpenProject Foundation (OPF) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# See doc/COPYRIGHT.rdoc for more details. +#++ + +require 'spec_helper' + +describe User, 'allowed to' do + let(:user) { member.principal } + let(:anonymous) { FactoryGirl.build(:anonymous) } + let(:project) { FactoryGirl.build(:project, is_public: false) } + let(:project2) { FactoryGirl.build(:project, is_public: false) } + let(:role) { FactoryGirl.build(:role) } + let(:role2) { FactoryGirl.build(:role) } + let(:anonymous_role) { FactoryGirl.build(:anonymous_role) } + let(:member) { FactoryGirl.build(:member, project: project, + roles: [role]) } + + let(:action) { :the_one } + let(:other_action) { :another } + let(:public_action) { :view_project } + let(:global_permission) { Redmine::AccessControl.permissions.find { |p| p.global? } } + let(:global_role) { FactoryGirl.build(:global_role, :permissions => [global_permission.name]) } + let(:principal_role) { FactoryGirl.build(:empty_principal_role, principal: user, + role: global_role) } + + + before do + user.save! + anonymous.save! + end + + context "w/o the context being a project + w/o the user being member in a project + w/ the user having the global role + w/ the global role having the necessary permission" do + before do + global_role.save! + + principal_role.save! + end + + it 'is true' do + expect(user.allowed_to?(global_permission.name, nil, global: true)).to be_truthy + end + end + + context "w/o the context being a project + w/o the user being member in a project + w/ the user having the global role + w/o the global role having the necessary permission" do + + before do + global_role.permissions = [] + global_role.save! + + principal_role.save! + end + + it 'is false' do + expect(user.allowed_to?(global_permission.name, nil, global: true)).to be_falsey + end + end + + context "w/o the context being a project + w/o the user being member in a project + w/o the user having the global role + w/ the global role having the necessary permission" do + + before do + global_role.permissions = [] + global_role.save! + end + + it 'is false' do + expect(user.allowed_to?(global_permission.name, nil, global: true)).to be_falsey + end + end + + context "w/o the context being a project + w/o the user being member in a project + w/o the user having the global role + w/ the user being admin" do + + before do + user.update_attribute(:admin, true) + end + + it 'is true' do + expect(user.allowed_to?(global_permission.name, nil, global: true)).to be_truthy + end + end + + context "w/ the context being a project + w/o the user being member in the project + w/ the user having the global role + w/o the global role having the necessary permission" do + before do + global_role.permissions = [] + global_role.save! + + principal_role.save! + end + + it 'is false' do + expect(user.allowed_to?(global_permission.name, project)).to be_falsey + end + end + + context "w/ the context being a project + w/o the user being member in a project + w/o the user having the global role + w/ the global role having the necessary permission" do + + before do + global_role.permissions = [] + global_role.save! + end + + it 'is false' do + expect(user.allowed_to?(global_permission.name, project)).to be_falsey + end + end + + context "w/ the context being a project + w/o the user being member in a project + w/o the user having the global role + w/ the user being admin" do + + before do + user.update_attribute(:admin, true) + end + + it 'is true' do + expect(user.allowed_to?(global_permission.name, project)).to be_truthy + end + end +end +