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

validate_token_service.rb « email_verification « users « services « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 0cfd4876abf0203f00e249c84cbfaa19b54dd66c (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
67
68
69
70
71
72
73
74
75
76
77
# frozen_string_literal: true

module Users
  module EmailVerification
    class ValidateTokenService < EmailVerification::BaseService
      include ActionView::Helpers::DateHelper

      TOKEN_VALID_FOR_MINUTES = 240

      def initialize(attr:, user:, token:)
        super(attr: attr, user: user)

        @token = token
      end

      def execute
        return failure(:rate_limited) if verification_rate_limited?
        return failure(:invalid) unless valid?
        return failure(:expired) if expired_token?

        success
      end

      private

      attr_reader :user

      def verification_rate_limited?
        Gitlab::ApplicationRateLimiter.throttled?(:email_verification, scope: user[attr])
      end

      def valid?
        return false unless token.present?

        Devise.secure_compare(user[attr], digest)
      end

      def expired_token?
        generated_at = case attr
                       when :unlock_token then user.locked_at
                       when :confirmation_token then user.confirmation_sent_at
                       end

        generated_at < TOKEN_VALID_FOR_MINUTES.minutes.ago
      end

      def success
        { status: :success }
      end

      def failure(reason)
        {
          status: :failure,
          reason: reason,
          message: failure_message(reason)
        }
      end

      def failure_message(reason)
        case reason
        when :rate_limited
          format(s_("IdentityVerification|You've reached the maximum amount of tries. "\
             'Wait %{interval} or send a new code and try again.'), interval: email_verification_interval)
        when :expired
          s_('IdentityVerification|The code has expired. Send a new code and try again.')
        when :invalid
          s_('IdentityVerification|The code is incorrect. Enter it again, or send a new code.')
        end
      end

      def email_verification_interval
        interval_in_seconds = Gitlab::ApplicationRateLimiter.rate_limits[:email_verification][:interval]
        distance_of_time_in_words(interval_in_seconds)
      end
    end
  end
end