Browse Source

Feature: Mobile - Unify Pundit usage.

Martin Gruner 2 years ago
parent
commit
05b364e978

+ 51 - 0
spec/policies/application_policy/field_scope_spec.rb

@@ -0,0 +1,51 @@
+# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+require 'rails_helper'
+
+RSpec.describe ApplicationPolicy::FieldScope do
+  subject(:field_scope) { described_class.new(allow: allow_fields, deny: deny_fields) }
+
+  let(:allow_fields) { nil }
+  let(:deny_fields)  { nil }
+
+  context 'when only allowing fields' do
+    let(:allow_fields) { [:field1] }
+
+    it 'accepts allowlisted fields' do
+      expect(field_scope.field_authorized?(:field1)).to be(true)
+    end
+
+    it 'denies unknown fields' do
+      expect(field_scope.field_authorized?(:field2)).to be(false)
+    end
+  end
+
+  context 'when only denying fields' do
+    let(:deny_fields) { [:field1] }
+
+    it 'rejects denylisted fields' do
+      expect(field_scope.field_authorized?(:field1)).to be(false)
+    end
+
+    it 'allows unknown fields' do
+      expect(field_scope.field_authorized?(:field2)).to be(true)
+    end
+  end
+
+  context 'when both allowing and denying' do
+    let(:allow_fields) { [:field1] }
+    let(:deny_fields) { [:field2] }
+
+    it 'accepts allowlisted fields' do
+      expect(field_scope.field_authorized?(:field1)).to be(true)
+    end
+
+    it 'rejects denylisted fields' do
+      expect(field_scope.field_authorized?(:field2)).to be(false)
+    end
+
+    it 'rejects unknown fields' do
+      expect(field_scope.field_authorized?(:field3)).to be(false)
+    end
+  end
+end

+ 0 - 4
spec/policies/macro_policy.rb

@@ -1,4 +0,0 @@
-# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
-
-class MacroPolicy < ApplicationPolicy
-end

+ 15 - 6
spec/policies/organization_policy_spec.rb

@@ -3,36 +3,45 @@
 require 'rails_helper'
 
 describe OrganizationPolicy do
-  subject { described_class.new(user, record) }
+  subject(:organization_policy) { described_class.new(user, record) }
 
   let(:record) { create(:organization) }
 
-  context 'when customer' do
+  shared_examples 'restricts fields' do |method|
+    it "restricts fields for #{method}", :aggregate_failures do
+      expect(organization_policy.public_send(method)).to permit_fields(%i[id name active])
+      expect(organization_policy.public_send(method)).to forbid_fields(%i[shared domain note])
+    end
+  end
+
+  context 'when user is a customer in the same organization' do
     let(:user) { create(:customer, organization: record) }
 
     it { is_expected.to permit_actions(%i[show]) }
     it { is_expected.to forbid_actions(%i[update]) }
+
+    include_examples 'restricts fields', :show?
   end
 
-  context 'when customer without organization' do
+  context 'when user is a customer without organization' do
     let(:user) { create(:customer) }
 
     it { is_expected.to forbid_actions(%i[show update]) }
   end
 
-  context 'when agent and customer' do
+  context 'when user is an agent and customer' do
     let(:user) { create(:agent_and_customer, organization: record) }
 
     it { is_expected.to permit_actions(%i[show update]) }
   end
 
-  context 'when agent' do
+  context 'when user is an agent' do
     let(:user) { create(:agent) }
 
     it { is_expected.to permit_actions(%i[show update]) }
   end
 
-  context 'when admin' do
+  context 'when user is an admin' do
     let(:user) { create(:admin) }
 
     it { is_expected.to permit_actions(%i[show update]) }

+ 32 - 1
spec/policies/user_policy_spec.rb

@@ -3,7 +3,7 @@
 require 'rails_helper'
 
 describe UserPolicy do
-  subject { described_class.new(user, record) }
+  subject(:user_policy) { described_class.new(user, record) }
 
   context 'when user is an admin' do
     let(:user) { create(:user, roles: [partial_admin_role]) }
@@ -146,11 +146,26 @@ describe UserPolicy do
   context 'when user is a customer' do
     let(:user) { create(:customer) }
 
+    shared_examples 'restricts fields' do |method|
+      it "restricts fields for #{method}", :aggregate_failures do
+        expect(user_policy.public_send(method)).to permit_fields(%i[id firstname lastname image image_source active])
+        expect(user_policy.public_send(method)).to forbid_fields(%i[email phone mobile note])
+      end
+    end
+
+    shared_examples 'does not restrict fields' do |method|
+      it "does not restrict fields for #{method}" do
+        expect(user_policy.public_send(method)).to be(true)
+      end
+    end
+
     context 'when record is an admin user' do
       let(:record) { create(:admin) }
 
       it { is_expected.to permit_actions(%i[nested_show]) }
       it { is_expected.to forbid_actions(%i[show update destroy]) }
+
+      include_examples 'restricts fields', :nested_show?
     end
 
     context 'when record is an agent user' do
@@ -158,6 +173,8 @@ describe UserPolicy do
 
       it { is_expected.to permit_actions(%i[nested_show]) }
       it { is_expected.to forbid_actions(%i[show update destroy]) }
+
+      include_examples 'restricts fields', :nested_show?
     end
 
     context 'when record is a customer user' do
@@ -165,6 +182,8 @@ describe UserPolicy do
 
       it { is_expected.to permit_actions(%i[nested_show]) }
       it { is_expected.to forbid_actions(%i[show update destroy]) }
+
+      include_examples 'restricts fields', :nested_show?
     end
 
     context 'when record is any user' do
@@ -172,6 +191,8 @@ describe UserPolicy do
 
       it { is_expected.to permit_actions(%i[nested_show]) }
       it { is_expected.to forbid_actions(%i[show update destroy]) }
+
+      include_examples 'restricts fields', :nested_show?
     end
 
     context 'when record is a colleague' do
@@ -180,6 +201,9 @@ describe UserPolicy do
 
       it { is_expected.to permit_actions(%i[show nested_show]) }
       it { is_expected.to forbid_actions(%i[update destroy]) }
+
+      include_examples 'restricts fields', :nested_show?
+      include_examples 'restricts fields', :show?
     end
 
     context 'when record is the same user' do
@@ -187,6 +211,9 @@ describe UserPolicy do
 
       it { is_expected.to permit_actions(%i[show nested_show]) }
       it { is_expected.to forbid_actions(%i[update destroy]) }
+
+      include_examples 'does not restrict fields', :nested_show?
+      include_examples 'does not restrict fields', :show?
     end
 
     context 'when record is both admin and customer' do
@@ -194,6 +221,8 @@ describe UserPolicy do
 
       it { is_expected.to permit_action(:nested_show) }
       it { is_expected.to forbid_actions(%i[show update destroy]) }
+
+      include_examples 'restricts fields', :nested_show?
     end
 
     context 'when record is both agent and customer' do
@@ -201,6 +230,8 @@ describe UserPolicy do
 
       it { is_expected.to permit_action(:nested_show) }
       it { is_expected.to forbid_actions(%i[show update destroy]) }
+
+      include_examples 'restricts fields', :nested_show?
     end
 
   end

+ 13 - 0
spec/support/custom_matchers/policies/field_scope.rb

@@ -0,0 +1,13 @@
+# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+RSpec::Matchers.define :permit_fields do |expected|
+  match { expected.all? { |f| actual.field_authorized?(f) } }
+  description { 'checks if FieldScope permits expected fields' }
+  failure_message { "did not grant field authorization for #{expected.reject { |f| actual.field_authorized?(f) }}" }
+end
+
+RSpec::Matchers.define :forbid_fields do |expected|
+  match { expected.all? { |f| !actual.field_authorized?(f) } }
+  description { 'checks if FieldScope forbids expected fields' }
+  failure_message { "incorrectly grants field authorization for #{expected.select { |f| actual.field_authorized?(f) }}" }
+end