'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|
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={})