From e90b1e147e69fb05bd10c2a9b4198af7ee386eb1 Mon Sep 17 00:00:00 2001
From: James Lopez <james@jameslopez.es>
Date: Thu, 10 Mar 2016 15:35:44 +0100
Subject: [PATCH] refactored project creation to create the associations as
 well

---
 .../projects/import_export/project_factory.rb | 40 +++++++++++++++++++
 .../import_export/project_tree_restorer.rb    | 15 +++----
 2 files changed, 48 insertions(+), 7 deletions(-)
 create mode 100644 app/services/projects/import_export/project_factory.rb

diff --git a/app/services/projects/import_export/project_factory.rb b/app/services/projects/import_export/project_factory.rb
new file mode 100644
index 00000000000..1ca0cfb8673
--- /dev/null
+++ b/app/services/projects/import_export/project_factory.rb
@@ -0,0 +1,40 @@
+module Projects
+  module ImportExport
+    module ProjectFactory
+      extend self
+
+      def create(project_params:, user:)
+        project = Project.new(project_params.except('id'))
+        project.creator = user
+        check_namespace(project_params['namespace_id'], project, user)
+      end
+
+      def check_namespace(namespace_id, project, user)
+        if namespace_id
+          # Find matching namespace and check if it allowed
+          # for current user if namespace_id passed.
+          unless allowed_namespace?(user, namespace_id)
+            project.namespace_id = nil
+            deny_namespace(project)
+          end
+        else
+          # Set current user namespace if namespace_id is nil
+          project.namespace_id = user.namespace_id
+        end
+        project
+      end
+
+      private
+
+      def allowed_namespace?(user, namespace_id)
+        namespace = Namespace.find_by(id: namespace_id)
+        user.can?(:create_projects, namespace)
+      end
+
+      def deny_namespace(project)
+        project.errors.add(:namespace, "is not valid")
+      end
+
+    end
+  end
+end
diff --git a/app/services/projects/import_export/project_tree_restorer.rb b/app/services/projects/import_export/project_tree_restorer.rb
index e30cb25ea61..980a376be16 100644
--- a/app/services/projects/import_export/project_tree_restorer.rb
+++ b/app/services/projects/import_export/project_tree_restorer.rb
@@ -3,7 +3,7 @@ module Projects
     class ProjectTreeRestorer
       attr_reader :project
 
-      def initialize(path: , user: user)
+      def initialize(path:, user:)
         @path = path
         @user = user
       end
@@ -13,22 +13,23 @@ module Projects
       def restore
         json = IO.read(@path)
         tree_hash = ActiveSupport::JSON.decode(json)
+        project_params = tree_hash.reject { |_key, value| value.is_a?(Array) }
+        project = Projects::ImportExport::ProjectFactory.create(project_params: project_params, user: @user)
+        project.save
         relation_hash = {}
         ImportExport.project_tree.each do |relation|
           next if tree_hash[relation.to_s].empty?
-          relation_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s])
+          relation_hash[relation.to_s] = create_relation(relation, tree_hash[relation.to_s], project.id)
+          project.update_attribute(relation, relation_hash[relation.to_s])
         end
-        project_params = tree_hash.delete_if { |_key, value | value.is_a?(Array)}
-        @project = ::Projects::CreateService.new(@user, project_params).execute
-        @project.saved?
       end
 
       private
 
-      def create_relation(relation, relation_hash_list)
+      def create_relation(relation, relation_hash_list, project_id)
         relation_hash_list.map do |relation_hash|
           Projects::ImportExport::RelationFactory.create(
-            relation_sym: relation, relation_hash: relation_hash)
+            relation_sym: relation, relation_hash: relation_hash.merge(project_id: project_id))
         end
       end
     end
-- 
GitLab