Class: RailsBase::Mfa::Totp::ValidateCode
- Inherits:
-
ServiceBase
- Object
- ServiceBase
- RailsBase::Mfa::Totp::ValidateCode
- Includes:
- Helper
- Defined in:
- app/services/rails_base/mfa/totp/validate_code.rb
Instance Method Summary collapse
- #call ⇒ Object
-
#consume_otp! ⇒ Object
An OTP cannot be used more than once in a given timestep Storing timestep of last valid OTP is sufficient to satisfy this requirement.
- #validate! ⇒ Object
- #validate_and_consume_otp ⇒ Object
Methods included from Helper
#current_code, #lgp, #otp, #secret
Methods inherited from ServiceBase
inherited, #internal_validate, #service_base_logging
Methods included from ServiceLogging
#aletered_message, #class_name, #log, #log_prefix, #logger, #service_id
Instance Method Details
#call ⇒ Object
10 11 12 13 14 |
# File 'app/services/rails_base/mfa/totp/validate_code.rb', line 10 def call return if validate_and_consume_otp context.fail!(message: "Invalid TOTP code") end |
#consume_otp! ⇒ Object
An OTP cannot be used more than once in a given timestep Storing timestep of last valid OTP is sufficient to satisfy this requirement
34 35 36 37 38 39 40 41 42 43 44 |
# File 'app/services/rails_base/mfa/totp/validate_code.rb', line 34 def consume_otp! timestep = Time.now.utc.to_i / otp.interval if user.consumed_timestep != timestep user.consumed_timestep = timestep log(level: :debug, msg: "#{lgp} Consuming timestep based on code input") return user.save(validate: false) end log(level: :debug, msg: "#{lgp} Timestep for code was already consumed. Invalid code") false end |
#validate! ⇒ Object
46 47 48 49 50 |
# File 'app/services/rails_base/mfa/totp/validate_code.rb', line 46 def validate! raise "Expected user to be a User. " unless User === user raise "Expected otp_code to be present" if otp_code.nil? raise "Expected `otp_secret` passed in or `otp_secret` present on User" if secret.nil? end |
#validate_and_consume_otp ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'app/services/rails_base/mfa/totp/validate_code.rb', line 16 def validate_and_consume_otp if user.consumed_timestep # reconstruct the timestamp of the last consumed timestep = user.consumed_timestep * otp.interval end if otp.verify(otp_code.gsub(/\s+/, ""), drift_behind: User.totp_drift_behind, drift_ahead: User.totp_drift_ahead, after: ) log(level: :debug, msg: "#{lgp} Correct code provided") return consume_otp! else log(level: :debug, msg: "#{lgp} InValid code provided") end false end |