Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/import_export/attributes_permitter.rb')
-rw-r--r--lib/gitlab/import_export/attributes_permitter.rb105
1 files changed, 105 insertions, 0 deletions
diff --git a/lib/gitlab/import_export/attributes_permitter.rb b/lib/gitlab/import_export/attributes_permitter.rb
new file mode 100644
index 00000000000..86f51add504
--- /dev/null
+++ b/lib/gitlab/import_export/attributes_permitter.rb
@@ -0,0 +1,105 @@
+# frozen_string_literal: true
+
+# AttributesPermitter builds a hash of permitted attributes for
+# every model defined in import_export.yml that is used to validate and
+# filter out any attributes that are not permitted when doing Project/Group Import
+#
+# Each model's list includes:
+# - attributes defined under included_attributes section
+# - associations defined under project/group tree
+# - methods defined under methods section
+#
+# Given the following import_export.yml example:
+# ```
+# tree:
+# project:
+# - labels:
+# - :priorities
+# included_attributes:
+# labels:
+# - :title
+# - :description
+# methods:
+# labels:
+# - :type
+# ```
+#
+# Produces a list of permitted attributes:
+# ```
+# Gitlab::ImportExport::AttributesPermitter.new.permitted_attributes
+#
+# => { labels: [:priorities, :title, :description, :type] }
+# ```
+#
+# Filters out any other attributes from specific relation hash:
+# ```
+# Gitlab::ImportExport::AttributesPermitter.new.permit(:labels, {id: 5, type: 'opened', description: 'test', sensitive_attribute: 'my_sensitive_attribute'})
+#
+# => {:type=>"opened", :description=>"test"}
+# ```
+module Gitlab
+ module ImportExport
+ class AttributesPermitter
+ attr_reader :permitted_attributes
+
+ def initialize(config: ImportExport::Config.new.to_h)
+ @config = config
+ @attributes_finder = Gitlab::ImportExport::AttributesFinder.new(config: @config)
+ @permitted_attributes = {}
+
+ build_permitted_attributes
+ end
+
+ def permit(relation_name, relation_hash)
+ permitted_attributes = permitted_attributes_for(relation_name)
+
+ relation_hash.select do |key, _|
+ permitted_attributes.include?(key)
+ end
+ end
+
+ def permitted_attributes_for(relation_name)
+ @permitted_attributes[relation_name] || []
+ end
+
+ private
+
+ def build_permitted_attributes
+ build_associations
+ build_attributes
+ build_methods
+ end
+
+ # Deep traverse relations tree to build a list of allowed model relations
+ def build_associations
+ stack = @attributes_finder.tree.to_a
+
+ while stack.any?
+ model_name, relations = stack.pop
+
+ if relations.is_a?(Hash)
+ add_permitted_attributes(model_name, relations.keys)
+
+ stack.concat(relations.to_a)
+ end
+ end
+
+ @permitted_attributes
+ end
+
+ def build_attributes
+ @attributes_finder.included_attributes.each(&method(:add_permitted_attributes))
+ end
+
+ def build_methods
+ @attributes_finder.methods.each(&method(:add_permitted_attributes))
+ end
+
+ def add_permitted_attributes(model_name, attributes)
+ @permitted_attributes[model_name] ||= []
+
+ @permitted_attributes[model_name].concat(attributes) if attributes.any?
+ end
+ end
+ end
+end