From 8ca963bd96a47411f390360fbe3e85766dce00db Mon Sep 17 00:00:00 2001 From: James Lopez Date: Thu, 1 Sep 2016 11:49:55 +0200 Subject: [PATCH] more refactoring of the specs --- .../import_export/export_file_spec.rb | 27 ++------------ .../attribute_configuration_spec.rb | 17 +++++++-- .../import_export/export_file_helper.rb | 36 +++++++++++++++---- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb index 0fff533eb2e..1a04c25012b 100644 --- a/spec/features/projects/import_export/export_file_spec.rb +++ b/spec/features/projects/import_export/export_file_spec.rb @@ -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 diff --git a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb index b098e913a11..336da93c782 100644 --- a/spec/lib/gitlab/import_export/attribute_configuration_spec.rb +++ b/spec/lib/gitlab/import_export/attribute_configuration_spec.rb @@ -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 diff --git a/spec/support/import_export/export_file_helper.rb b/spec/support/import_export/export_file_helper.rb index a2ff15c7bc5..791863b8d16 100644 --- a/spec/support/import_export/export_file_helper.rb +++ b/spec/support/import_export/export_file_helper.rb @@ -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