more refactoring of the specs
This commit is contained in:
parent
7323d30f44
commit
8ca963bd96
|
@ -8,32 +8,9 @@ feature 'project export', feature: true, js: true do
|
|||
let(:export_path) { "#{Dir::tmpdir}/import_file_spec" }
|
||||
|
||||
let(:sensitive_words) { %w[pass secret token key] }
|
||||
let(:safe_hashes) do
|
||||
let(:safe_models) do
|
||||
{
|
||||
token: [
|
||||
{ # Triggers
|
||||
"id" => 1,
|
||||
"token" => "token",
|
||||
"project_id" => nil,
|
||||
"deleted_at" => nil,
|
||||
"gl_project_id" => project.id
|
||||
},
|
||||
{ # Project hooks
|
||||
"id" => 1,
|
||||
"project_id" => project.id,
|
||||
"service_id" => nil,
|
||||
"push_events" => true,
|
||||
"issues_events" => false,
|
||||
"merge_requests_events" => false,
|
||||
"tag_push_events" => false,
|
||||
"note_events" => false,
|
||||
"enable_ssl_verification" => true,
|
||||
"build_events" => false,
|
||||
"wiki_page_events" => false,
|
||||
"pipeline_events" => false,
|
||||
"token" => "token"
|
||||
}
|
||||
]
|
||||
token: [ProjectHook, Ci::Trigger]
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -9,8 +9,12 @@ require 'spec_helper'
|
|||
describe 'Attribute configuration', lib: true do
|
||||
let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys }
|
||||
let(:relation_names) do
|
||||
names = config_hash['project_tree'].to_s.gsub(/[\[{}\]=>\"\:]/, ',').split(',').delete_if(&:blank?)
|
||||
names.uniq - ['milestones', 'labels'] + ['project'] # Remove duplicated or add missing models
|
||||
names = names_from_tree(config_hash['project_tree'])
|
||||
|
||||
# Remove duplicated or add missing models
|
||||
# - project is not part of the tree, so it has to be added manually.
|
||||
# - milestone, labels have both singular and plural versions in the tree, so remove the duplicates.
|
||||
names.flatten.uniq - ['milestones', 'labels'] + ['project']
|
||||
end
|
||||
|
||||
let(:safe_model_attributes) do
|
||||
|
@ -54,6 +58,15 @@ describe 'Attribute configuration', lib: true do
|
|||
end
|
||||
end
|
||||
|
||||
# Returns a list of models from hashes/arrays contained in +project_tree+
|
||||
def names_from_tree(project_tree)
|
||||
project_tree.map do |branch_or_model|
|
||||
branch_or_model = branch_or_model.to_s if branch_or_model.is_a?(Symbol)
|
||||
|
||||
branch_or_model.is_a?(String) ? branch_or_model : names_from_tree(branch_or_model)
|
||||
end
|
||||
end
|
||||
|
||||
def relation_class_for_name(relation_name)
|
||||
relation_name = Gitlab::ImportExport::RelationFactory::OVERRIDES[relation_name.to_sym] || relation_name
|
||||
relation_name.to_s.classify.constantize
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
module ExportFileHelper
|
||||
IGNORED_ATTRIBUTES = %w[created_at updated_at url group_id]
|
||||
|
||||
def setup_project
|
||||
project = create(:project, :public)
|
||||
|
||||
|
@ -53,22 +55,28 @@ module ExportFileHelper
|
|||
end
|
||||
|
||||
# Recursively finds key/values including +key+ as part of the key, inside a nested hash
|
||||
def deep_find_with_parent(key, object, found = nil)
|
||||
if object.respond_to?(:key?) && object.keys.any? { |k| k.include?(key) }
|
||||
[object[key], object] if object[key]
|
||||
elsif object.is_a? Enumerable
|
||||
object.find { |*a| found, object = deep_find_with_parent(key, a.last, found) }
|
||||
def deep_find_with_parent(sensitive_key_word, object, found = nil)
|
||||
# Returns the parent object and the object found containing a sensitive word as part of the key
|
||||
if object_contains_key?(object, sensitive_key_word)
|
||||
[object[sensitive_key_word], object] if object[sensitive_key_word]
|
||||
elsif object.is_a?(Enumerable)
|
||||
# Recursively lookup for keys containing sensitive words in a Hash or Array
|
||||
object.find { |*hash_or_array| found, object = deep_find_with_parent(sensitive_key_word, hash_or_array.last, found) }
|
||||
[found, object] if found
|
||||
end
|
||||
end
|
||||
|
||||
#Return true if the hash has a key containing a sensitive word
|
||||
def object_contains_key?(object, sensitive_key_word)
|
||||
object.is_a?(Hash) && object.keys.any? { |key| key.include?(sensitive_key_word) }
|
||||
end
|
||||
|
||||
# Returns true if a sensitive word is found inside a hash, excluding safe hashes
|
||||
def has_sensitive_attributes?(sensitive_word, project_hash)
|
||||
loop do
|
||||
object, parent = deep_find_with_parent(sensitive_word, project_hash)
|
||||
parent.except!('created_at', 'updated_at', 'url', 'group_id') if parent
|
||||
|
||||
if object && safe_hashes[sensitive_word.to_sym].include?(parent)
|
||||
if object && is_safe_hash?(parent, sensitive_word)
|
||||
# It's in the safe list, remove hash and keep looking
|
||||
parent.delete(object)
|
||||
elsif object
|
||||
|
@ -78,4 +86,18 @@ module ExportFileHelper
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if it's one of the excluded models in +safe_models+
|
||||
def is_safe_hash?(parent, sensitive_word)
|
||||
return false unless parent
|
||||
|
||||
# Extra attributes that appear in a model but not in the exported hash.
|
||||
excluded_attributes = ['type']
|
||||
|
||||
safe_models[sensitive_word.to_sym].each do |safe_model|
|
||||
return true if (safe_model.attribute_names - parent.keys - excluded_attributes).empty?
|
||||
end
|
||||
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue