Commit 8ca963bd authored by James Lopez's avatar James Lopez
Browse files

more refactoring of the specs

parent 23630e1a762b
......@@ -8,32 +8,9 @@
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 @@
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 @@
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
......
module ExportFileHelper
IGNORED_ATTRIBUTES = %w[created_at updated_at url group_id]
def setup_project
project = create(:project, :public)
......@@ -53,22 +55,28 @@ def in_directory_with_expanded_export(project)
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 @@ def has_sensitive_attributes?(sensitive_word, project_hash)
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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment