summaryrefslogtreecommitdiff
path: root/spec/support/import_export
diff options
context:
space:
mode:
authorJames Lopez <james@jameslopez.es>2016-09-02 14:26:13 +0200
committerJames Lopez <james@jameslopez.es>2016-09-09 14:56:10 +0200
commit621b4eaf22ea92d89c8612293fad4f6b9d322efe (patch)
treec1f935e6d0dde55f54be831d3157c36cbe13e0c0 /spec/support/import_export
parent13a977475aa813636c31f606e93ee2cc1a9e8d75 (diff)
downloadgitlab-ce-621b4eaf22ea92d89c8612293fad4f6b9d322efe.tar.gz
fixing a couple of bugs and lots of refactoring of the export file spec
Diffstat (limited to 'spec/support/import_export')
-rw-r--r--spec/support/import_export/configuration_helper.rb10
-rw-r--r--spec/support/import_export/export_file_helper.rb68
2 files changed, 61 insertions, 17 deletions
diff --git a/spec/support/import_export/configuration_helper.rb b/spec/support/import_export/configuration_helper.rb
index fec83765253..d7582057c83 100644
--- a/spec/support/import_export/configuration_helper.rb
+++ b/spec/support/import_export/configuration_helper.rb
@@ -12,4 +12,14 @@ module ConfigurationHelper
relation_name = Gitlab::ImportExport::RelationFactory::OVERRIDES[relation_name.to_sym] || relation_name
relation_name.to_s.classify.constantize
end
+
+ def parsed_attributes(relation_name, attributes)
+ excluded_attributes = config_hash['excluded_attributes'][relation_name]
+ included_attributes = config_hash['included_attributes'][relation_name]
+
+ attributes = attributes - JSON[excluded_attributes.to_json] if excluded_attributes
+ attributes = attributes & JSON[included_attributes.to_json] if included_attributes
+
+ attributes
+ end
end
diff --git a/spec/support/import_export/export_file_helper.rb b/spec/support/import_export/export_file_helper.rb
index 8e56bca21a3..de066f1cd66 100644
--- a/spec/support/import_export/export_file_helper.rb
+++ b/spec/support/import_export/export_file_helper.rb
@@ -1,4 +1,8 @@
module ExportFileHelper
+ include ConfigurationHelper
+
+ ObjectWithParent = Struct.new(:object, :parent, :key_found)
+
def setup_project
project = create(:project, :public)
@@ -54,48 +58,78 @@ module ExportFileHelper
# Recursively finds key/values including +key+ as part of the key, inside a nested hash
def deep_find_with_parent(sensitive_key_word, object, found = nil)
+ sensitive_key_found = object_contains_key?(object, sensitive_key_word)
+
# 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]
+ if sensitive_key_found && object[sensitive_key_found]
+ ObjectWithParent.new(object[sensitive_key_found], object, sensitive_key_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
+ object_with_parent = nil
+
+ object.find do |*hash_or_array|
+ object_with_parent = deep_find_with_parent(sensitive_key_word, hash_or_array.last, found)
+ end
+
+ object_with_parent
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) }
+ return false unless object.is_a?(Hash)
+
+ object.keys.find { |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)
+ # Returns the offended ObjectWithParent object if a sensitive word is found inside a hash,
+ # excluding the whitelisted safe hashes.
+ def find_sensitive_attributes(sensitive_word, project_hash)
loop do
- object, parent = deep_find_with_parent(sensitive_word, project_hash)
+ object_with_parent = deep_find_with_parent(sensitive_word, project_hash)
+
+ return nil unless object_with_parent && object_with_parent.object
- if object && is_safe_hash?(parent, sensitive_word)
+ if is_safe_hash?(object_with_parent.parent, sensitive_word)
# It's in the safe list, remove hash and keep looking
- parent.delete(object)
- elsif object
- return true
+ object_with_parent.parent.delete(object_with_parent.key_found)
else
- return false
+ return object_with_parent
end
+
+ nil
end
end
- # Returns true if it's one of the excluded models in +safe_models+
+ # Returns true if it's one of the excluded models in +safe_list+
def is_safe_hash?(parent, sensitive_word)
- return false unless parent
+ return false unless parent && safe_list[sensitive_word.to_sym]
# 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?
+ safe_list[sensitive_word.to_sym].each do |model|
+ # Check whether this is a hash attribute inside a model
+ if model.is_a?(Symbol)
+ return true if (safe_hashes[model] - parent.keys).empty?
+ else
+ return true if safe_model?(model, excluded_attributes, parent)
+ end
end
false
end
+
+ def associations_for(safe_model)
+ safe_model.reflect_on_all_associations.map { |assoc| assoc.name.to_s }
+ end
+
+ # Compares model attributes with those those found in the hash
+ # and returns true if there is a match, ignoring some excluded attributes.
+ def safe_model?(model, excluded_attributes, parent)
+ excluded_attributes += associations_for(model)
+ parsed_model_attributes = parsed_attributes(model.name.underscore, model.attribute_names)
+
+ (parsed_model_attributes - parent.keys - excluded_attributes).empty?
+ end
end