diff options
Diffstat (limited to 'app/services/jira_import/users_mapper_service.rb')
-rw-r--r-- | app/services/jira_import/users_mapper_service.rb | 54 |
1 files changed, 42 insertions, 12 deletions
diff --git a/app/services/jira_import/users_mapper_service.rb b/app/services/jira_import/users_mapper_service.rb index 480c034f952..6c8610bfbf3 100644 --- a/app/services/jira_import/users_mapper_service.rb +++ b/app/services/jira_import/users_mapper_service.rb @@ -2,30 +2,37 @@ 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 - attr_reader :jira_service, :start_at - - def initialize(jira_service, start_at) - @jira_service = jira_service + # 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 - users.to_a.map do |jira_user| + 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(match_user(jira_user)) + }.merge(gitlab_id: find_gitlab_id(jira_user)) end end private - def users - @users ||= client.get(url) + attr_reader :current_user, :project, :jira_service, :start_at + + def jira_users + @jira_users ||= client.get(url) end def client @@ -44,10 +51,33 @@ module JiraImport raise NotImplementedError end - # TODO: Matching user by email and displayName will be done as the part - # of follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/219023 - def match_user(jira_user) - { gitlab_id: nil, gitlab_username: nil, gitlab_name: nil } + 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 |