From b58a88643aed2ffb71084cef513fe71927dba17f Mon Sep 17 00:00:00 2001 From: Marius BALTEANU Date: Sun, 25 Aug 2019 21:07:52 +0200 Subject: [PATCH 2/2] Reject version custom field values not visible for the user --- app/models/version.rb | 28 ++++++++++++++++++++++++++++ test/unit/version_test.rb | 23 +++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/app/models/version.rb b/app/models/version.rb index e538f21b3..b5765f4b8 100644 --- a/app/models/version.rb +++ b/app/models/version.rb @@ -163,11 +163,39 @@ class Version < ActiveRecord::Base 'custom_field_values', 'custom_fields' + def safe_attributes=(attrs, user=User.current) + if attrs.respond_to?(:to_unsafe_hash) + attrs = attrs.to_unsafe_hash + end + + return unless attrs.is_a?(Hash) + attrs = attrs.deep_dup + + # Reject custom fields values not visible by the user + if attrs['custom_field_values'].present? + editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s} + attrs['custom_field_values'].reject! {|k, v| !editable_custom_field_ids.include?(k.to_s)} + end + + # Reject custom fields not visible by the user + if attrs['custom_fields'].present? + editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s} + attrs['custom_fields'].reject! {|c| !editable_custom_field_ids.include?(c['id'].to_s)} + end + + super(attrs, user) + end + # Returns true if +user+ or current user is allowed to view the version def visible?(user=User.current) user.allowed_to?(:view_issues, self.project) end + # Returns the custom_field_values that can be edited by the given user + def editable_custom_field_values(user=nil) + visible_custom_field_values(user) + end + def visible_custom_field_values(user = nil) user ||= User.current custom_field_values.select do |value| diff --git a/test/unit/version_test.rb b/test/unit/version_test.rb index 764910430..c7d5c07dc 100644 --- a/test/unit/version_test.rb +++ b/test/unit/version_test.rb @@ -299,6 +299,29 @@ class VersionTest < ActiveSupport::TestCase assert_includes Version.like('like scope'), version end + def test_safe_attributes_should_include_only_custom_fields_visible_to_user + cf1 = VersionCustomField.create!(:name => 'Visible field', + :field_format => 'string', + :visible => false, :role_ids => [1]) + cf2 = VersionCustomField.create!(:name => 'Non visible field', + :field_format => 'string', + :visible => false, :role_ids => [3]) + user = User.find(2) + version = Version.new(:project_id => 1, :name => 'v4') + + version.send :safe_attributes=, {'custom_field_values' => { + cf1.id.to_s => 'value1', cf2.id.to_s => 'value2' + }}, user + assert_equal 'value1', version.custom_field_value(cf1) + assert_nil version.custom_field_value(cf2) + version.send :safe_attributes=, {'custom_fields' => [ + {'id' => cf1.id.to_s, 'value' => 'valuea'}, + {'id' => cf2.id.to_s, 'value' => 'valueb'} + ]}, user + assert_equal 'valuea', version.custom_field_value(cf1) + assert_nil version.custom_field_value(cf2) + end + private def add_issue(version, attributes={}) -- 2.22.0