summaryrefslogtreecommitdiff
path: root/app/controllers/import/base_controller.rb
blob: afdea4f7c9d5476baca9f0b061d4f7096d31d04d (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
# frozen_string_literal: true

class Import::BaseController < ApplicationController
  include ActionView::Helpers::SanitizeHelper

  before_action :import_rate_limit, only: [:create]

  def status
    respond_to do |format|
      format.json do
        render json: { imported_projects: serialized_imported_projects,
                       provider_repos: serialized_provider_repos,
                       incompatible_repos: serialized_incompatible_repos,
                       namespaces: serialized_namespaces }
      end
      format.html
    end
  end

  def realtime_changes
    Gitlab::PollingInterval.set_header(response, interval: 3_000)

    render json: already_added_projects.to_json(only: [:id], methods: [:import_status])
  end

  protected

  def importable_repos
    raise NotImplementedError
  end

  def incompatible_repos
    []
  end

  def provider_name
    raise NotImplementedError
  end

  def provider_url
    raise NotImplementedError
  end

  private

  def filter_attribute
    :name
  end

  def sanitized_filter_param
    @filter ||= sanitize(params[:filter])
  end

  def filtered(collection)
    return collection unless sanitized_filter_param

    collection.select { |item| item[filter_attribute].include?(sanitized_filter_param) }
  end

  def serialized_provider_repos
    Import::ProviderRepoSerializer.new(current_user: current_user).represent(importable_repos, provider: provider_name, provider_url: provider_url)
  end

  def serialized_incompatible_repos
    Import::ProviderRepoSerializer.new(current_user: current_user).represent(incompatible_repos, provider: provider_name, provider_url: provider_url)
  end

  def serialized_imported_projects
    ProjectSerializer.new.represent(already_added_projects, serializer: :import, provider_url: provider_url)
  end

  def already_added_projects
    @already_added_projects ||= filtered(find_already_added_projects(provider_name))
  end

  def serialized_namespaces
    NamespaceSerializer.new.represent(namespaces)
  end

  def namespaces
    current_user.manageable_groups_with_routes
  end

  # rubocop: disable CodeReuse/ActiveRecord
  def find_already_added_projects(import_type)
    current_user.created_projects.where(import_type: import_type).with_import_state
  end
  # rubocop: enable CodeReuse/ActiveRecord

  # rubocop: disable CodeReuse/ActiveRecord
  def find_jobs(import_type)
    current_user.created_projects
      .with_import_state
      .where(import_type: import_type)
      .to_json(only: [:id], methods: [:import_status])
  end
  # rubocop: enable CodeReuse/ActiveRecord

  # deprecated: being replaced by app/services/import/base_service.rb
  def find_or_create_namespace(names, owner)
    names = params[:target_namespace].presence || names

    return current_user.namespace if names == owner

    group = Groups::NestedCreateService.new(current_user, group_path: names).execute

    group.errors.any? ? current_user.namespace : group
  rescue => e
    Gitlab::AppLogger.error(e)

    current_user.namespace
  end

  # deprecated: being replaced by app/services/import/base_service.rb
  def project_save_error(project)
    project.errors.full_messages.join(', ')
  end

  def import_rate_limit
    key = "project_import".to_sym

    if rate_limiter.throttled?(key, scope: [current_user, key])
      rate_limiter.log_request(request, "#{key}_request_limit".to_sym, current_user)

      redirect_back_or_default(options: { alert: _('This endpoint has been requested too many times. Try again later.') })
    end
  end

  def rate_limiter
    ::Gitlab::ApplicationRateLimiter
  end
end