summaryrefslogtreecommitdiff
path: root/lib/gitlab/identifier.rb
blob: a8b93f1d4b226904e0a98218be25f01433ca8405 (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
# Detect user based on identifier like
# key-13 or user-36 or last commit
module Gitlab
  module Identifier
    def identify(identifier, project = nil, newrev = nil)
      if identifier.blank?
        identify_using_commit(project, newrev)
      elsif identifier =~ /\Auser-\d+\Z/
        # git push over http
        identify_using_user(identifier)
      elsif identifier =~ /\Akey-\d+\Z/
        # git push over ssh
        identify_using_ssh_key(identifier)
      end
    end

    # Tries to identify a user based on a commit SHA.
    def identify_using_commit(project, ref)
      return if project.nil? && ref.nil?

      commit = project.commit(ref)

      return if !commit || !commit.author_email

      identify_with_cache(:email, commit.author_email) do
        commit.author
      end
    end

    # Tries to identify a user based on a user identifier (e.g. "user-123").
    # rubocop: disable CodeReuse/ActiveRecord
    def identify_using_user(identifier)
      user_id = identifier.gsub("user-", "")

      identify_with_cache(:user, user_id) do
        User.find_by(id: user_id)
      end
    end
    # rubocop: enable CodeReuse/ActiveRecord

    # Tries to identify a user based on an SSH key identifier (e.g. "key-123").
    def identify_using_ssh_key(identifier)
      key_id = identifier.gsub("key-", "")

      identify_with_cache(:ssh_key, key_id) do
        User.find_by_ssh_key_id(key_id)
      end
    end

    def identify_with_cache(category, key)
      if identification_cache[category].key?(key)
        identification_cache[category][key]
      else
        identification_cache[category][key] = yield
      end
    end

    def identification_cache
      @identification_cache ||= {
        email: {},
        user: {},
        ssh_key: {}
      }
    end
  end
end