BigW Consortium Gitlab

gpg.rb 1.95 KB
Newer Older
1 2 3 4
module Gitlab
  module Gpg
    extend self

5 6
    MUTEX = Mutex.new

7 8 9 10 11 12 13
    module CurrentKeyChain
      extend self

      def add(key)
        GPGME::Key.import(key)
      end

Alexis Reigel committed
14
      def fingerprints_from_key(key)
15 16 17 18 19 20 21 22
        import = GPGME::Key.import(key)

        return [] if import.imported == 0

        import.imports.map(&:fingerprint)
      end
    end

Alexis Reigel committed
23
    def fingerprints_from_key(key)
24
      using_tmp_keychain do
Alexis Reigel committed
25 26 27
        CurrentKeyChain.fingerprints_from_key(key)
      end
    end
28

Alexis Reigel committed
29 30 31
    def primary_keyids_from_key(key)
      using_tmp_keychain do
        fingerprints = CurrentKeyChain.fingerprints_from_key(key)
32 33 34 35 36

        GPGME::Key.find(:public, fingerprints).map { |raw_key| raw_key.primary_subkey.keyid }
      end
    end

37
    def user_infos_from_key(key)
38
      using_tmp_keychain do
Alexis Reigel committed
39
        fingerprints = CurrentKeyChain.fingerprints_from_key(key)
40

41 42 43
        GPGME::Key.find(:public, fingerprints).flat_map do |raw_key|
          raw_key.uids.map { |uid| { name: uid.name, email: uid.email } }
        end
44 45 46
      end
    end

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
    # Allows thread safe switching of temporary keychain files
    #
    # 1. The current thread may use nesting of temporary keychain
    # 2. Another thread needs to wait for the lock to be released
    def using_tmp_keychain(&block)
      if MUTEX.locked? && MUTEX.owned?
        optimistic_using_tmp_keychain(&block)
      else
        MUTEX.synchronize do
          optimistic_using_tmp_keychain(&block)
        end
      end
    end

    # 1. Returns the custom home directory if one has been set by calling
    #    `GPGME::Engine.home_dir=`
    # 2. Returns the default home directory otherwise
    def current_home_dir
      GPGME::Engine.info.first.home_dir || GPGME::Engine.dirinfo('homedir')
    end

    private

    def optimistic_using_tmp_keychain
71
      previous_dir = current_home_dir
72 73
      Dir.mktmpdir do |dir|
        GPGME::Engine.home_dir = dir
74
        yield
75
      end
76 77
    ensure
      GPGME::Engine.home_dir = previous_dir
78 79 80
    end
  end
end