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

more refactoring of the specs

parent 7323d30f
...@@ -8,32 +8,9 @@ feature 'project export', feature: true, js: true do ...@@ -8,32 +8,9 @@ feature 'project export', feature: true, js: true do
let(:export_path) { "#{Dir::tmpdir}/import_file_spec" } let(:export_path) { "#{Dir::tmpdir}/import_file_spec" }
let(:sensitive_words) { %w[pass secret token key] } let(:sensitive_words) { %w[pass secret token key] }
let(:safe_hashes) do let(:safe_models) do
{ {
token: [ token: [ProjectHook, Ci::Trigger]
{ # 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"
}
]
} }
end end
......
...@@ -9,8 +9,12 @@ require 'spec_helper' ...@@ -9,8 +9,12 @@ require 'spec_helper'
describe 'Attribute configuration', lib: true do describe 'Attribute configuration', lib: true do
let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys } let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys }
let(:relation_names) do let(:relation_names) do
names = config_hash['project_tree'].to_s.gsub(/[\[{}\]=>\"\:]/, ',').split(',').delete_if(&:blank?) names = names_from_tree(config_hash['project_tree'])
names.uniq - ['milestones', 'labels'] + ['project'] # Remove duplicated or add missing models
# 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 end
let(:safe_model_attributes) do let(:safe_model_attributes) do
...@@ -54,6 +58,15 @@ describe 'Attribute configuration', lib: true do ...@@ -54,6 +58,15 @@ describe 'Attribute configuration', lib: true do
end end
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) def relation_class_for_name(relation_name)
relation_name = Gitlab::ImportExport::RelationFactory::OVERRIDES[relation_name.to_sym] || relation_name relation_name = Gitlab::ImportExport::RelationFactory::OVERRIDES[relation_name.to_sym] || relation_name
relation_name.to_s.classify.constantize relation_name.to_s.classify.constantize
......
module ExportFileHelper module ExportFileHelper
IGNORED_ATTRIBUTES = %w[created_at updated_at url group_id]
def setup_project def setup_project
project = create(:project, :public) project = create(:project, :public)
...@@ -53,22 +55,28 @@ module ExportFileHelper ...@@ -53,22 +55,28 @@ module ExportFileHelper
end end
# Recursively finds key/values including +key+ as part of the key, inside a nested hash # Recursively finds key/values including +key+ as part of the key, inside a nested hash
def deep_find_with_parent(key, object, found = nil) def deep_find_with_parent(sensitive_key_word, object, found = nil)
if object.respond_to?(:key?) && object.keys.any? { |k| k.include?(key) } # Returns the parent object and the object found containing a sensitive word as part of the key
[object[key], object] if object[key] if object_contains_key?(object, sensitive_key_word)
elsif object.is_a? Enumerable [object[sensitive_key_word], object] if object[sensitive_key_word]
object.find { |*a| found, object = deep_find_with_parent(key, a.last, found) } 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 [found, object] if found
end end
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 # Returns true if a sensitive word is found inside a hash, excluding safe hashes
def has_sensitive_attributes?(sensitive_word, project_hash) def has_sensitive_attributes?(sensitive_word, project_hash)
loop do loop do
object, parent = deep_find_with_parent(sensitive_word, project_hash) 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 # It's in the safe list, remove hash and keep looking
parent.delete(object) parent.delete(object)
elsif object elsif object
...@@ -78,4 +86,18 @@ module ExportFileHelper ...@@ -78,4 +86,18 @@ module ExportFileHelper
end end
end 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 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