Просмотр исходного кода

Feature: Mobile - add missing StorePolicy.

Martin Gruner 2 лет назад
Родитель
Сommit
20154f158a

+ 3 - 4
app/graphql/gql/types/stored_file_type.rb

@@ -10,10 +10,9 @@ module Gql::Types
     field :size, Integer, null: true, description: 'File size in bytes'
     field :type, String, null: true, description: "File's content-type."
 
-    # TODO: StorePolicy is missing right now...
-    # def self.authorize(object, ctx)
-    #   Pundit.authorize ctx.current_user, object, :show?
-    # end
+    def self.authorize(object, ctx)
+      Pundit.authorize ctx.current_user, object, :show?
+    end
 
     def type
       object.preferences['Content-Type']

+ 42 - 0
app/policies/store_policy.rb

@@ -0,0 +1,42 @@
+# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+class StorePolicy < ApplicationPolicy
+
+  # Store objects are authorized based on the policy of the object that "owns" them,
+  #   like the ticket or knowledge base answer they are attached to.
+  # If no owner class or record can be found, forbid access by default.
+
+  def show?
+    store_object_policy(store_object_owner)&.show?
+  end
+
+  def destroy?
+    store_object_policy(store_object_owner)&.destroy?
+  end
+
+  def user_required?
+    false
+  end
+
+  def custom_exception
+    ActiveRecord::RecordNotFound.new
+  end
+
+  private
+
+  def store_object_class
+    record.store_object&.name&.safe_constantize
+  end
+
+  def store_object_policy(target)
+    Pundit.policy user, target
+  end
+
+  def store_object_owner
+    if store_object_class == UploadCache
+      return UploadCache.new(record.o_id)
+    end
+
+    store_object_class&.find record.o_id
+  end
+end

+ 18 - 0
app/policies/upload_cache_policy.rb

@@ -0,0 +1,18 @@
+# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+class UploadCachePolicy < ApplicationPolicy
+
+  # UploadCache is currently not restricted other than knowing the form_id
+  #   to access the data.
+  def show?
+    true
+  end
+
+  def destroy?
+    true
+  end
+
+  def user_required?
+    false
+  end
+end

+ 64 - 0
spec/policies/store_policy_spec.rb

@@ -0,0 +1,64 @@
+# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+require 'rails_helper'
+
+describe StorePolicy do
+  subject { described_class.new(user, record) }
+
+  include_context 'basic Knowledge Base'
+
+  let(:record_class) { Store }
+  let(:object)       { create(:knowledge_base_answer, visibility, :with_attachment, category: category) }
+
+  let(:record) do
+    record_class.create!(object: object.class.to_s, o_id: object.id, filename: 'test', data: 'test')
+  end
+
+  context 'without a user' do
+    let(:user) { nil }
+
+    context 'with published object' do
+      let(:visibility) { :published }
+
+      it { is_expected.to permit_actions :show }
+      it { is_expected.to forbid_actions :destroy }
+    end
+
+    context 'with private object' do
+      let(:visibility) { :internal }
+
+      it { is_expected.to forbid_actions :show, :destroy }
+    end
+  end
+
+  context 'with a user' do
+    context 'with full access' do
+      let(:user)       { create :admin }
+      let(:visibility) { :published }
+
+      it { is_expected.to permit_actions :show, :destroy }
+    end
+
+    context 'with limited access' do
+      let(:user) { create :agent }
+      let(:visibility) { :internal }
+
+      it { is_expected.to permit_actions :show }
+      it { is_expected.to forbid_actions :destroy }
+    end
+
+    context 'without access' do
+      let(:user) { create :agent }
+      let(:visibility) { :draft }
+
+      it { is_expected.to forbid_actions :show, :destroy }
+    end
+
+    context 'with object that does not have a policy' do
+      let(:record) { create :store_image, object: 'NonExistingObject' }
+      let(:user)   { create :admin }
+
+      it { is_expected.to forbid_actions :show, :destroy }
+    end
+  end
+end

+ 20 - 0
spec/policies/upload_cache_policy_spec.rb

@@ -0,0 +1,20 @@
+# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+require 'rails_helper'
+
+describe UploadCachePolicy do
+  subject { described_class.new(user, record) }
+
+  let(:record) { UploadCache.new(123) }
+  let(:user)   { create(:user) }
+
+  context 'without a user' do
+    let(:user) { nil }
+
+    it { is_expected.to permit_actions :show, :destroy }
+  end
+
+  context 'with a user' do
+    it { is_expected.to permit_actions :show, :destroy }
+  end
+end