Welcome to mirror list, hosted at ThFree Co, Russian Federation.

two_factor_backupable_pbkdf2.rb « models « devise « lib « devise-pbkdf2-encryptable « gems « vendor - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: eef906f537716ce2ecd731708de38f29f8854ed9 (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
module Devise
  module Models
    module TwoFactorBackupablePbkdf2
      extend ActiveSupport::Concern

      # 1) Invalidates all existing backup codes
      # 2) Generates otp_number_of_backup_codes backup codes
      # 3) Stores the hashed backup codes in the database
      # 4) Returns a plaintext array of the generated backup codes
      #
      def generate_otp_backup_codes_pbkdf2!
        codes           = []
        number_of_codes = self.class.otp_number_of_backup_codes
        code_length     = self.class.otp_backup_code_length

        number_of_codes.times do
          codes << SecureRandom.hex(code_length / 2) # Hexstring has length 2*n
        end

        hashed_codes = codes.map do |code|
          Devise::Pbkdf2Encryptable::Encryptors::Pbkdf2Sha512.digest(
            code,
            Devise::Pbkdf2Encryptable::Encryptors::Pbkdf2Sha512::STRETCHES,
            Devise.friendly_token[0, 16])
        end

        self.otp_backup_codes = hashed_codes

        codes
      end

      # Returns true and invalidates the given code if that code is a valid
      #   backup code.
      #
      def invalidate_otp_backup_code_pdkdf2!(code)
        codes = self.otp_backup_codes || []

        codes.each do |backup_code|
          next unless Devise::Pbkdf2Encryptable::Encryptors::Pbkdf2Sha512.compare(backup_code, code)

          codes.delete(backup_code)
          self.otp_backup_codes = codes
          return true
        end

        false
      end

      protected

      module ClassMethods
        Devise::Models.config(self, :otp_backup_code_length,
                                    :otp_number_of_backup_codes,
                                    :pepper)
      end
    end
  end
end