Class: ROTP::TOTP
Constant Summary
Constants inherited from OTP
Instance Attribute Summary collapse
-
#interval ⇒ Object
readonly
Returns the value of attribute interval.
-
#issuer ⇒ Object
readonly
Returns the value of attribute issuer.
Attributes inherited from OTP
Instance Method Summary collapse
-
#at(time, padding = true) ⇒ Object
Accepts either a Unix timestamp integer or a Time object.
-
#initialize(s, options = {}) ⇒ TOTP
constructor
A new instance of TOTP.
-
#now(padding = true) ⇒ Integer
Generate the current time OTP.
-
#provisioning_uri(name) ⇒ String
Returns the provisioning URI for the OTP This can then be encoded in a QR Code and used to provision the Google Authenticator app.
-
#verify(otp, time = Time.now) ⇒ Object
Verifies the OTP passed in against the current time OTP.
-
#verify_with_drift(otp, drift, time = Time.now) ⇒ Object
Verifies the OTP passed in against the current time OTP and adjacent intervals up to
drift
. -
#verify_with_drift_and_prior(otp, drift, prior_time = nil, time = Time.now) ⇒ Object
Verifies the OTP passed in against the current time OTP and adjacent intervals up to
drift
.
Methods inherited from OTP
Constructor Details
#initialize(s, options = {}) ⇒ TOTP
Returns a new instance of TOTP.
9 10 11 12 13 |
# File 'lib/rotp/totp.rb', line 9 def initialize(s, = {}) @interval = [:interval] || DEFAULT_INTERVAL @issuer = [:issuer] super end |
Instance Attribute Details
#interval ⇒ Object (readonly)
Returns the value of attribute interval.
5 6 7 |
# File 'lib/rotp/totp.rb', line 5 def interval @interval end |
#issuer ⇒ Object (readonly)
Returns the value of attribute issuer.
5 6 7 |
# File 'lib/rotp/totp.rb', line 5 def issuer @issuer end |
Instance Method Details
#at(time, padding = true) ⇒ Object
Accepts either a Unix timestamp integer or a Time object. Time objects will be adjusted to UTC automatically
19 20 21 22 23 24 25 |
# File 'lib/rotp/totp.rb', line 19 def at(time, padding=true) unless time.class == Time time = Time.at(time.to_i) end generate_otp(timecode(time), padding) end |
#now(padding = true) ⇒ Integer
Generate the current time OTP
29 30 31 |
# File 'lib/rotp/totp.rb', line 29 def now(padding=true) generate_otp(timecode(Time.now), padding) end |
#provisioning_uri(name) ⇒ String
Returns the provisioning URI for the OTP This can then be encoded in a QR Code and used to provision the Google Authenticator app
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/rotp/totp.rb', line 80 def provisioning_uri(name) # The format of this URI is documented at: # https://github.com/google/google-authenticator/wiki/Key-Uri-Format # For compatibility the issuer appears both before that account name and also in the # query string. issuer_string = issuer.nil? ? "" : "#{URI.encode(issuer)}:" params = { secret: secret, period: interval == 30 ? nil : interval, issuer: issuer, digits: digits == DEFAULT_DIGITS ? nil : digits, algorithm: digest.upcase == 'SHA1' ? nil : digest.upcase, } encode_params("otpauth://totp/#{issuer_string}#{URI.encode(name)}", params) end |
#verify(otp, time = Time.now) ⇒ Object
Verifies the OTP passed in against the current time OTP
35 36 37 |
# File 'lib/rotp/totp.rb', line 35 def verify(otp, time = Time.now) super(otp, self.at(time)) end |
#verify_with_drift(otp, drift, time = Time.now) ⇒ Object
Verifies the OTP passed in against the current time OTP and adjacent intervals up to drift
.
44 45 46 47 48 49 |
# File 'lib/rotp/totp.rb', line 44 def verify_with_drift(otp, drift, time = Time.now) time = time.to_i times = (time-drift..time+drift).step(interval).to_a times << time + drift if times.last < time + drift times.any? { |ti| verify(otp, ti) } end |
#verify_with_drift_and_prior(otp, drift, prior_time = nil, time = Time.now) ⇒ Object
Verifies the OTP passed in against the current time OTP and adjacent intervals up to drift
. Excludes OTPs from prior_time and earlier. Returns time value of matching OTP code for use in subsequent call.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/rotp/totp.rb', line 59 def verify_with_drift_and_prior(otp, drift, prior_time = nil, time = Time.now) # calculate normalized bin start times based on drift first_bin = (time - drift).to_i / interval * interval last_bin = (time + drift).to_i / interval * interval # if prior_time was supplied, adjust first bin if necessary to exclude it if prior_time prior_bin = prior_time.to_i / interval * interval first_bin = prior_bin + interval if prior_bin >= first_bin # fail if we've already used the last available OTP code return if first_bin > last_bin end times = (first_bin..last_bin).step(interval).to_a times.find { |ti| verify(otp, ti) } end |