# frozen_string_literal: true module JiraImport class UsersMapperService include Gitlab::Utils::StrongMemoize # MAX_USERS must match the pageSize value in app/assets/javascripts/jira_import/utils/constants.js MAX_USERS = 50 # The class is called from UsersImporter and small batches of users are expected # In case the mapping of a big batch of users is expected to be passed here # the implementation needs to change here and handles the matching in batches def initialize(current_user, project, start_at) @current_user = current_user @project = project @jira_service = project.jira_service @start_at = start_at end def execute jira_users.to_a.map do |jira_user| { jira_account_id: jira_user_id(jira_user), jira_display_name: jira_user_name(jira_user), jira_email: jira_user['emailAddress'] }.merge(gitlab_id: find_gitlab_id(jira_user)) end end private attr_reader :current_user, :project, :jira_service, :start_at def jira_users @jira_users ||= client.get(url) end def client @client ||= jira_service.client end def url raise NotImplementedError end def jira_user_id(jira_user) raise NotImplementedError end def jira_user_name(jira_user) raise NotImplementedError end def matched_users strong_memoize(:matched_users) do jira_emails = jira_users.map { |u| u['emailAddress']&.downcase }.compact jira_names = jira_users.map { |u| jira_user_name(u)&.downcase }.compact relations = [] relations << User.by_username(jira_names).select("users.id, users.name, users.username, users.email as user_email") relations << User.by_name(jira_names).select("users.id, users.name, users.username, users.email as user_email") relations << User.by_user_email(jira_emails).select("users.id, users.name, users.username, users.email as user_email") relations << User.by_emails(jira_emails).select("users.id, users.name, users.username, emails.email as user_email") User.from_union(relations).id_in(project_member_ids).select("users.id as user_id, users.name as name, users.username as username, user_email") end end def find_gitlab_id(jira_user) user = matched_users.find do |matched_user| matched_user.user_email&.downcase == jira_user['emailAddress']&.downcase || matched_user.name&.downcase == jira_user_name(jira_user)&.downcase || matched_user.username&.downcase == jira_user_name(jira_user)&.downcase end user&.user_id end def project_member_ids @project_member_ids ||= MembersFinder.new(project, current_user).execute.select(:user_id) end end end