Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revoke Refresh Token on access token use #769

Merged
merged 1 commit into from
Apr 20, 2016

Conversation

Fredar
Copy link
Contributor

@Fredar Fredar commented Dec 29, 2015

Creating another PR based on #691. Copying description:

This PR allows refresh tokens to not either revoke at some point in the future (if you want to allow some wiggle room for network failures, etc) set refresh_token_revoked_in to some number of seconds in the future.

Also allows for refresh tokens to not be revoked until an access token created with that refresh token is successfully used once. Set refresh_token_revoked_on_use to true.

Both are off by default.

end

context 'revoked token' do
time = DateTime.now + 1.day

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use DateTime.now without zone. Use one of Time.zone.now, DateTime.now.current, DateTime.now.in_time_zone, DateTime.now.utc, DateTime.now.getlocal, DateTime.now.iso8601, DateTime.now.jisx0301, DateTime.now.rfc3339, DateTime.now.to_i, DateTime.now.to_f instead.

@Fredar
Copy link
Contributor Author

Fredar commented Dec 29, 2015

@tute I have updated code for all your comments from earlier PR, except this one.
I dont think we need to check for that, should be safe to revoke either way.
What do you think?

What about Time.now and Unnecessary spacing barks in lib/generators, should we ignore them?
Please have a general look, thanks!

@tute
Copy link
Contributor

tute commented Jan 3, 2016

I have updated code for all your comments from earlier PR, except this one.
I dont think we need to check for that, should be safe to revoke either way.
What do you think?

You are probably right.

What about Time.now and Unnecessary spacing barks in lib/generators, should we ignore them?

Yep!

Please have a general look, thanks!

Doing it now. Thank you!

def change
add_column :oauth_access_tokens, :previous_refresh_token, :string, default: "", null: false
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to update this migration with the one with the new coding style? Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

@tute
Copy link
Contributor

tute commented Jan 3, 2016

Left a few comments, this is looking great. Thank you!

end

before do
@time = Time.now.round

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not use Time.now without zone. Use one of Time.zone.now, Time.now.current, Time.now.in_time_zone, Time.now.utc, Time.now.getlocal, Time.now.iso8601, Time.now.jisx0301, Time.now.rfc3339, Time.now.to_i, Time.now.to_f instead.

@Fredar
Copy link
Contributor Author

Fredar commented Jan 7, 2016

@tute Thanks for the comments.
I have updated or responded where needed.

@Fredar Fredar force-pushed the feature/revoke-on-use branch 2 times, most recently from df2f3a8 to 9b64f35 Compare January 10, 2016 15:08
@Fredar
Copy link
Contributor Author

Fredar commented Jan 10, 2016

@tute I think we should instantly revoke token here:

def revoke_previous_refresh_token!
  if old_refresh_token && !old_refresh_token.revoked?
    old_refresh_token.revoke_in(refresh_token_revoked_in)
  end
  update_attribute :previous_refresh_token, ""
end

I will change the code to:

def revoke_previous_refresh_token!
  if old_refresh_token && !old_refresh_token.revoked?
    old_refresh_token.revoke
  end
  update_attribute :previous_refresh_token, ""
end

This method is only used during authentication.

token = ->(r) { 'token' }
expect(AccessToken).to receive(:by_token).with('token')
Token.authenticate double, token
end

it 'revokes previous refresh_token if token was found' do
token = ->(r) { 'token' }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused block argument - r. If it's necessary, use _ or _r as an argument name to indicate that it won't be used. Also consider using a proc without arguments instead of a lambda if you want it to accept any arguments but don't care about them.

@Fredar
Copy link
Contributor Author

Fredar commented Jan 18, 2016

@tute ping 😉

double(Doorkeeper::AccessToken, accessible?: false, revoked?: false, expired?: false, includes_scope?: false, acceptable?: false)
double(Doorkeeper::AccessToken,
accessible?: false, revoked?: false, expired?: false, includes_scope?: false,
acceptable?: false, previous_refresh_token: "", revoke_previous_refresh_token!: true)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [96/80]

@Fredar
Copy link
Contributor Author

Fredar commented Apr 19, 2016

@tute Thanks for a quick review!
Updated with your comments. I have only fixed line length for specs that are modified / added by this PR. Also didnt update in two cases where it was 81/80.

@tute
Copy link
Contributor

tute commented Apr 20, 2016

Left a question around documentation for developers: how can they disable this option? Where should we document that?

Looking great, thanks for your work!


# If you have a `previous_refresh_token` column, refresh tokens will be revoked
# only after a generated access token is used.
# Remove `previous_refresh_token` column, if you would like to have them revoked

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [86/80]

@Fredar
Copy link
Contributor Author

Fredar commented Apr 20, 2016

Thanks again for your time 😉
Added a comment to migration template and responded to your question here

# If you have a `previous_refresh_token` column, refresh tokens
# will be revoked only after a generated access token is used.
# Remove `previous_refresh_token` column, if you would like
# to have them revoked as soon as a new access token is issued.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! Suggested rewording:

If there is a previous_refresh_token column, refresh tokens will be revoked after a related access token is used. If there is no previous_refresh_token column, previous tokens are revoked as soon as a new access token is created. Comment out this line if you'd rather have refresh tokens instantly revoked.

@tute
Copy link
Contributor

tute commented Apr 20, 2016

Two small comments, ready to squash commits together after those! Thank you again. :)

@Fredar Fredar force-pushed the feature/revoke-on-use branch 2 times, most recently from ae8faad to 1abd87b Compare April 20, 2016 20:33
@Fredar
Copy link
Contributor Author

Fredar commented Apr 20, 2016

@tute Updated migration comment, added news detail and squashed. Cheers!

require 'rails/generators/active_record'

module Doorkeeper
class PreviousRefreshTokenGenerator < Rails::Generators::Base
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Rails need a :: prefix? I got:

%   rails generate doorkeeper:previous_refresh_token
[WARNING] Could not load generator "generators/doorkeeper/previous_refresh_token_generator". Error: uninitialized constant Doorkeeper::Rails::Generators.
/Users/tutec/Sites/opensource/doorkeeper-gem/doorkeeper/lib/generators/doorkeeper/previous_refresh_token_generator.rb:4:in `<module:Doorkeeper>'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something must have changed since the time it was originally created.
Will move module directly into class definition.

@tute
Copy link
Contributor

tute commented Apr 20, 2016

The migration didn't run in my spec/dummy app.

Also, suggestion for the commit message:

Revoke refresh token after access token use

When AccessToken#previous_refresh_token attribute exists, it is populated with the refresh token that issues the access token. This refresh token will be revoked when the access token is authenticated for the first time.

If the attribute doesn't exist in the database, doorkeeper will revoke the refresh token as soon as it issues a new access token, regardless of when is it used.

When AccessToken#previous_refresh_token attribute exists, it is populated with the refresh token that issues the access token. This refresh token will be revoked when the access token is authenticated for the first time.

If the attribute doesn't exist in the database, doorkeeper will revoke the refresh token as soon as it issues a new access token, regardless of when is it used.
@Fredar
Copy link
Contributor Author

Fredar commented Apr 20, 2016

Indeed, the migration in dummy app was scheduled before the table creation 😉
I have fixed the generator and recreated the migration.

@tute tute merged commit 3d88a7b into doorkeeper-gem:master Apr 20, 2016
@tute
Copy link
Contributor

tute commented Apr 20, 2016

😃 🎉 ❤️❤️❤️

@groe
Copy link

groe commented Apr 22, 2016

Nice work – can't wait to use it in 4.0.0 stable! 👍

@kevinelliott
Copy link

I am attempting to use refresh_token_revoked_on_use in config/initializers/doorkeeper.rb but it is claiming that the setting does not exist. Thoughts here?

@nbulaj
Copy link
Member

nbulaj commented Mar 21, 2018

@kevinelliott all you need is just to add 'previous_refresh_token' column to Access Tokens (see Doorkeeper rake tasks, there must be a generator for migration).

@hickford
Copy link
Contributor

@Fredar @tute Is there any documentation for the refresh_token_revoked_on_use option? I couldn't find it in https://doorkeeper.gitbook.io/guides/

@Fredar
Copy link
Contributor Author

Fredar commented May 12, 2023

@hickford Dont think so, but it should be pretty straightforward to use.

Commit msg explains roughly how it works
https://github.com/doorkeeper-gem/doorkeeper/pull/769/commits

There is also a migration generator. (if you installed doorkeeper before it was part of default migration set)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants