From 49bf8674abbbb8626e55cff04c863c03ae5b55d1 Mon Sep 17 00:00:00 2001 From: James Lopez Date: Wed, 26 Oct 2016 18:44:11 +0100 Subject: Fixed Import/Export foreign key issue to do with project members --- lib/gitlab/import_export/attribute_cleaner.rb | 28 ++++++++++++++++ lib/gitlab/import_export/members_mapper.rb | 7 +++- lib/gitlab/import_export/relation_factory.rb | 7 ++-- .../gitlab/import_export/attribute_cleaner_spec.rb | 37 ++++++++++++++++++++++ 4 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 lib/gitlab/import_export/attribute_cleaner.rb create mode 100644 spec/lib/gitlab/import_export/attribute_cleaner_spec.rb diff --git a/lib/gitlab/import_export/attribute_cleaner.rb b/lib/gitlab/import_export/attribute_cleaner.rb new file mode 100644 index 00000000000..34169319b26 --- /dev/null +++ b/lib/gitlab/import_export/attribute_cleaner.rb @@ -0,0 +1,28 @@ +module Gitlab + module ImportExport + class AttributeCleaner + ALLOWED_REFERENCES = RelationFactory::PROJECT_REFERENCES + RelationFactory::USER_REFERENCES + ['group_id'] + + def self.clean(*args) + new(*args).clean + end + + def initialize(relation_hash:, relation_class:) + @relation_hash = relation_hash + @relation_class = relation_class + end + + def clean + @relation_hash.reject do |key, _value| + prohibited_key?(key) || !@relation_class.attribute_method?(key) + end.except('id') + end + + private + + def prohibited_key?(key) + key.end_with?('_id') && !ALLOWED_REFERENCES.include?(key) + end + end + end +end diff --git a/lib/gitlab/import_export/members_mapper.rb b/lib/gitlab/import_export/members_mapper.rb index 36c4cf6efa0..b790733f4a7 100644 --- a/lib/gitlab/import_export/members_mapper.rb +++ b/lib/gitlab/import_export/members_mapper.rb @@ -55,7 +55,12 @@ module Gitlab end def member_hash(member) - member.except('id').merge(source_id: @project.id, importing: true) + parsed_hash(member).merge('source_id' => @project.id, 'importing' => true) + end + + def parsed_hash(member) + Gitlab::ImportExport::AttributeCleaner.clean(relation_hash: member.deep_stringify_keys, + relation_class: ProjectMember) end def find_project_user_query(member) diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index b0726268ca6..ed7a4c9b16e 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -9,7 +9,7 @@ module Gitlab builds: 'Ci::Build', hooks: 'ProjectHook' }.freeze - USER_REFERENCES = %w[author_id assignee_id updated_by_id user_id].freeze + USER_REFERENCES = %w[author_id assignee_id updated_by_id user_id created_by_id].freeze BUILD_MODELS = %w[Ci::Build commit_status].freeze @@ -23,7 +23,7 @@ module Gitlab def initialize(relation_sym:, relation_hash:, members_mapper:, user:) @relation_name = OVERRIDES[relation_sym] || relation_sym - @relation_hash = relation_hash.except('id', 'noteable_id') + @relation_hash = relation_hash.except('noteable_id').merge('project_id' => project_id) @members_mapper = members_mapper @user = user @imported_object_retries = 0 @@ -149,7 +149,8 @@ module Gitlab end def parsed_relation_hash - @relation_hash.reject { |k, _v| !relation_class.attribute_method?(k) } + @parsed_relation_hash ||= Gitlab::ImportExport::AttributeCleaner.clean(relation_hash: @relation_hash, + relation_class: relation_class) end def set_st_diffs diff --git a/spec/lib/gitlab/import_export/attribute_cleaner_spec.rb b/spec/lib/gitlab/import_export/attribute_cleaner_spec.rb new file mode 100644 index 00000000000..63bab0f0d0d --- /dev/null +++ b/spec/lib/gitlab/import_export/attribute_cleaner_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe Gitlab::ImportExport::AttributeCleaner, lib: true do + let(:relation_class){ double('relation_class').as_null_object } + let(:unsafe_hash) do + { + 'id' => 101, + 'service_id' => 99, + 'moved_to_id' => 99, + 'namespace_id' => 99, + 'ci_id' => 99, + 'random_project_id' => 99, + 'random_id' => 99, + 'milestone_id' => 99, + 'project_id' => 99, + 'user_id' => 99, + 'random_id_in_the_middle' => 99, + 'notid' => 99 + } + end + + let(:post_safe_hash) do + { + 'project_id' => 99, + 'user_id' => 99, + 'random_id_in_the_middle' => 99, + 'notid' => 99 + } + end + + it 'removes unwanted attributes from the hash' do + # allow(relation_class).to receive(:attribute_method?).and_return(true) + parsed_hash = described_class.clean(relation_hash: unsafe_hash, relation_class: relation_class) + + expect(parsed_hash).to eq(post_safe_hash) + end +end -- cgit v1.2.1