class ROTP::TOTP
Attributes
Public Class Methods
@option options [Integer] interval (30) the time interval in seconds for OTP
This defaults to 30 which is standard.
ROTP::OTP::new
# File lib/rotp/totp.rb, line 8 def initialize(s, options = {}) @interval = options[:interval] || DEFAULT_INTERVAL @issuer = options[:issuer] super end
Public Instance Methods
Accepts either a Unix timestamp integer or a Time object. Time objects will be adjusted to UTC automatically @param time [Time/Integer] the time to generate an OTP
for, integer unix timestamp or Time object
# File lib/rotp/totp.rb, line 17 def at(time) generate_otp(timecode(time)) end
Returns the provisioning URI for the OTP
This can then be encoded in a QR Code and used to provision the Google Authenticator app @param [String] name of the account @return [String] provisioning URI
# File lib/rotp/totp.rb, line 56 def provisioning_uri(name = nil) OTP::URI.new(self, account_name: name || @name).to_s end
Verifies the OTP
passed in against the current time OTP
and adjacent intervals up to drift
. Excludes OTPs from ‘after` and earlier. Returns time value of matching OTP
code for use in subsequent call. @param otp [String] the one time password to verify @param drift_behind [Integer] how many seconds to look back @param drift_ahead [Integer] how many seconds to look ahead @param after [Integer] prevent token reuse, last login timestamp @param at [Time] time at which to generate and verify a particular
otp. default Time.now
@return [Integer, nil] the last successful timestamp
interval
ROTP::OTP#verify
# File lib/rotp/totp.rb, line 39 def verify(otp, drift_ahead: 0, drift_behind: 0, after: nil, at: Time.now) timecodes = get_timecodes(at, drift_behind, drift_ahead) timecodes = timecodes.select { |t| t > timecode(after) } if after result = nil timecodes.each do |t| result = t * interval if super(otp, generate_otp(t)) end result end
Private Instance Methods
Get back an array of timecodes for a period
# File lib/rotp/totp.rb, line 63 def get_timecodes(at, drift_behind, drift_ahead) now = timeint(at) timecode_start = timecode(now - drift_behind) timecode_end = timecode(now + drift_ahead) (timecode_start..timecode_end).step(1).to_a end
# File lib/rotp/totp.rb, line 77 def timecode(time) timeint(time) / interval end
Ensure UTC int
# File lib/rotp/totp.rb, line 71 def timeint(time) return time.to_i unless time.class == Time time.utc.to_i end