summaryrefslogtreecommitdiff
path: root/app/services/projects/create_service.rb
blob: a6820183bee9ed83a3d94a3b9cb20933f9a00ec8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
module Projects
  class CreateService < BaseService
    def initialize(user, params)
      @current_user, @params = user, params.dup
    end

    def execute
      forked_from_project_id = params.delete(:forked_from_project_id)

      @project = Project.new(params)

      # Make sure that the user is allowed to use the specified visibility
      # level
      unless Gitlab::VisibilityLevel.allowed_for?(current_user,
                                                  params[:visibility_level])
        deny_visibility_level(@project)
        return @project
      end

      # Set project name from path
      if @project.name.present? && @project.path.present?
        # if both name and path set - everything is ok
      elsif @project.path.present?
        # Set project name from path
        @project.name = @project.path.dup
      elsif @project.name.present?
        # For compatibility - set path from name
        # TODO: remove this in 8.0
        @project.path = @project.name.dup.parameterize
      end

      # get namespace id
      namespace_id = params[:namespace_id]

      if namespace_id
        # Find matching namespace and check if it allowed
        # for current user if namespace_id passed.
        unless allowed_namespace?(current_user, namespace_id)
          @project.namespace_id = nil
          deny_namespace
          return @project
        end
      else
        # Set current user namespace if namespace_id is nil
        @project.namespace_id = current_user.namespace_id
      end

      @project.creator = current_user

      if forked_from_project_id
        @project.build_forked_project_link(forked_from_project_id: forked_from_project_id)
      end

      Project.transaction do
        @project.save

        if @project.persisted? && !@project.import?
          unless @project.create_repository
            raise 'Failed to create repository'
          end
        end
      end

      after_create_actions if @project.persisted?

      @project
    rescue => e
      message = "Unable to save project: #{e.message}"
      Rails.logger.error(message)
      @project.errors.add(:base, message) if @project
      @project
    end

    protected

    def deny_namespace
      @project.errors.add(:namespace, "is not valid")
    end

    def allowed_namespace?(user, namespace_id)
      namespace = Namespace.find_by(id: namespace_id)
      current_user.can?(:create_projects, namespace)
    end

    def after_create_actions
      log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"")

      @project.create_wiki if @project.wiki_enabled?

      @project.build_missing_services

      @project.create_labels

      event_service.create_project(@project, current_user)
      system_hook_service.execute_hooks_for(@project, :create)

      unless @project.group
        @project.team << [current_user, :master, current_user]
      end

      @project.import_start if @project.import?
    end
  end
end