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 134 135 136 137 138 139 140 141 142
|
# frozen_string_literal: true
module Groups
module ImportExport
class ImportService
attr_reader :current_user, :group, :shared
def initialize(group:, user:)
@group = group
@current_user = user
@user_role = user_role
@shared = Gitlab::ImportExport::Shared.new(@group)
@logger = ::Import::Framework::Logger.build
end
def async_execute
group_import_state = GroupImportState.safe_find_or_create_by!(group: group, user: current_user)
jid = GroupImportWorker.with_status.perform_async(current_user.id, group.id)
if jid.present?
group_import_state.update!(jid: jid)
else
group_import_state.fail_op('Failed to schedule import job')
false
end
end
def execute
Gitlab::Tracking.event(self.class.name, 'create', label: 'import_group_from_file')
if valid_user_permissions? && import_file && valid_import_file? && restorers.all?(&:restore)
notify_success
Gitlab::Tracking.event(
self.class.name,
'create',
label: 'import_access_level',
user: current_user,
extra: { user_role: user_role, import_type: 'import_group_from_file' }
)
group
else
notify_error!
end
ensure
remove_base_tmp_dir
remove_import_file
end
private
def user_role
# rubocop:disable Style/MultilineTernaryOperator
access_level = group.parent ?
current_user&.group_members&.find_by(source_id: group.parent&.id)&.access_level :
Gitlab::Access::OWNER
Gitlab::Access.human_access(access_level)
# rubocop:enable Style/MultilineTernaryOperator
end
def import_file
@import_file ||= Gitlab::ImportExport::FileImporter.import(
importable: group,
archive_file: nil,
shared: shared,
user: current_user
)
end
def restorers
[tree_restorer]
end
def tree_restorer
@tree_restorer ||=
Gitlab::ImportExport::Group::TreeRestorer.new(
user: current_user,
shared: shared,
group: group
)
end
def remove_import_file
upload = group.import_export_upload_by_user(current_user)
return unless upload&.import_file&.file
upload.remove_import_file!
upload.save!
end
def valid_user_permissions?
if current_user.can?(:admin_group, group)
true
else
shared.error(::Gitlab::ImportExport::Error.permission_error(current_user, group))
false
end
end
def valid_import_file?
return true if File.exist?(File.join(shared.export_path, 'tree/groups/_all.ndjson'))
shared.error(::Gitlab::ImportExport::Error.incompatible_import_file_error)
false
end
def notify_success
@logger.info(
group_id: group.id,
group_name: group.name,
message: 'Group Import/Export: Import succeeded'
)
end
def notify_error
@logger.error(
group_id: group.id,
group_name: group.name,
message: "Group Import/Export: Errors occurred, see '#{Gitlab::ErrorTracking::Logger.file_name}' for details"
)
end
def notify_error!
notify_error
raise Gitlab::ImportExport::Error, shared.errors.to_sentence
end
def remove_base_tmp_dir
FileUtils.rm_rf(shared.base_path)
end
end
end
end
Groups::ImportExport::ImportService.prepend_mod_with('Groups::ImportExport::ImportService')
|