diff options
author | James Lopez <james@jameslopez.es> | 2016-09-02 15:26:13 +0300 |
---|---|---|
committer | James Lopez <james@jameslopez.es> | 2016-09-09 15:56:10 +0300 |
commit | 621b4eaf22ea92d89c8612293fad4f6b9d322efe (patch) | |
tree | c1f935e6d0dde55f54be831d3157c36cbe13e0c0 /spec/support | |
parent | 13a977475aa813636c31f606e93ee2cc1a9e8d75 (diff) |
fixing a couple of bugs and lots of refactoring of the export file spec
Diffstat (limited to 'spec/support')
-rw-r--r-- | spec/support/import_export/configuration_helper.rb | 10 | ||||
-rw-r--r-- | spec/support/import_export/export_file_helper.rb | 68 |
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 |