summaryrefslogtreecommitdiff
path: root/lib/gitlab/database_importers/instance_administrators/create_group.rb
blob: bb489ced3d234ca0a4352ac78bf3474f301f7056 (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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# frozen_string_literal: true

module Gitlab
  module DatabaseImporters
    module InstanceAdministrators
      class CreateGroup < ::BaseService
        include Stepable

        NAME = 'GitLab Instance'
        PATH_PREFIX = 'gitlab-instance'
        VISIBILITY_LEVEL = Gitlab::VisibilityLevel::INTERNAL

        steps :validate_application_settings,
          :validate_admins,
          :create_group,
          :save_group_id,
          :add_group_members,
          :track_event

        def initialize
          super(nil)
        end

        def execute
          execute_steps
        end

        private

        def validate_application_settings(result)
          return success(result) if application_settings

          log_error('No application_settings found')
          error(_('No application_settings found'))
        end

        def validate_admins(result)
          unless instance_admins.any?
            log_error('No active admin user found')
            return error(_('No active admin user found'))
          end

          success(result)
        end

        def create_group(result)
          if group_created?
            log_info(_('Instance administrators group already exists'))
            result[:group] = instance_administrators_group
            return success(result)
          end

          result[:group] = ::Groups::CreateService.new(instance_admins.first, create_group_params).execute

          if result[:group].persisted?
            success(result)
          else
            log_error("Could not create instance administrators group. Errors: %{errors}" % { errors: result[:group].errors.full_messages })
            error(_('Could not create group'))
          end
        end

        def save_group_id(result)
          return success(result) if group_created?

          response = application_settings.update(
            instance_administrators_group_id: result[:group].id
          )

          if response
            success(result)
          else
            log_error("Could not save instance administrators group ID, errors: %{errors}" % { errors: application_settings.errors.full_messages })
            error(_('Could not save group ID'))
          end
        end

        def add_group_members(result)
          group = result[:group]
          members = group.add_members(members_to_add(group), Gitlab::Access::MAINTAINER)
          errors = members.flat_map { |member| member.errors.full_messages }

          if errors.any?
            log_error('Could not add admins as members to self-monitoring project. Errors: %{errors}' % { errors: errors })
            error(_('Could not add admins as members'))
          else
            success(result)
          end
        end

        def track_event(result)
          ::Gitlab::Tracking.event("instance_administrators_group", "group_created", namespace: result[:group])

          success(result)
        end

        def group_created?
          instance_administrators_group.present?
        end

        def application_settings
          @application_settings ||= ApplicationSetting.current_without_cache
        end

        def instance_administrators_group
          application_settings.instance_administrators_group
        end

        def instance_admins
          @instance_admins ||= User.admins.active
        end

        def members_to_add(group)
          # Exclude admins who are already members of group because
          # `group.add_members(users)` returns an error if the users parameter contains
          # users who are already members of the group.
          instance_admins - group.members.collect(&:user)
        end

        def create_group_params
          {
            name: NAME,
            visibility_level: VISIBILITY_LEVEL,

            # The 8 random characters at the end are so that the path does not
            # clash with any existing group that the user might have created.
            path: "#{PATH_PREFIX}-#{SecureRandom.hex(4)}"
          }
        end
      end
    end
  end
end