Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions lib/oauth2/access_token.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module OAuth2
class AccessToken
attr_reader :client, :token, :expires_in, :expires_at, :params
attr_reader :client, :token, :expires_in, :expires_at, :params, :time_skew
attr_accessor :options, :refresh_token, :response

class << self
Expand Down Expand Up @@ -37,17 +37,27 @@ def from_kvform(client, kvform)
# @option opts [String] :header_format ('Bearer %s') the string format to use for the Authorization header
# @option opts [String] :param_name ('access_token') the parameter name to use for transmission of the
# Access Token value in :body or :query transmission mode
def initialize(client, token, opts = {}) # rubocop:disable Metrics/AbcSize
def initialize(client, token, opts = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
local_now = Time.now.to_i
opts = opts.dup
@client = client
@token = token.to_s
opts = opts.dup
@time_skew = 0

[:refresh_token, :expires_in, :expires_at].each do |arg|
instance_variable_set("@#{arg}", opts.delete(arg) || opts.delete(arg.to_s))
end

@expires_in ||= opts.delete('expires')
@expires_in &&= @expires_in.to_i
@expires_at &&= @expires_at.to_i
@expires_at ||= Time.now.to_i + @expires_in if @expires_in

if @expires_in
@expires_at ||= local_now + @expires_in
calculated_issued_at = @expires_at - @expires_in
@time_skew = local_now - calculated_issued_at
end

@options = {:mode => opts.delete(:mode) || :header,
:header_format => opts.delete(:header_format) || 'Bearer %s',
:param_name => opts.delete(:param_name) || 'access_token'}
Expand All @@ -72,7 +82,7 @@ def expires?
#
# @return [Boolean]
def expired?
expires? && (expires_at <= Time.now.to_i)
expires? && (expires_at + time_skew <= Time.now.to_i)
end

# Refreshes the current Access Token
Expand Down
24 changes: 24 additions & 0 deletions spec/oauth2/access_token_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,30 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
allow(Time).to receive(:now).and_return(@now)
expect(access).to be_expired
end

describe 'time skew' do
let(:time_skew) { 10 }
let(:expires_in) { 300 }
let(:expires_at) { Time.now.to_i - 10 + expires_in }
let!(:access) { described_class.new(client, token, :refresh_token => 'abaca', :expires_at => expires_at, :expires_in => expires_in) }

context 'when not within time skew correction' do
let(:now) { Time.at(expires_at) + time_skew + 1 }

it 'access is expired' do
allow(Time).to receive(:now).and_return(now)
expect(access).to be_expired
end
end

context 'when within time skew correction' do
let(:now) { Time.at(expires_at) + time_skew - 1 }

it 'access is not expired' do
expect(access).not_to be_expired
end
end
end
end

describe '#refresh' do
Expand Down