Doorkeeper: Compatibilty with Ruby 3.0

Created on 4 Jan 2021  路  8Comments  路  Source: doorkeeper-gem/doorkeeper

Hi! I was trying to upgrade ruby from 2.7.1 to 3.0. Looks like the parameters for the find_in_batches call should change? Maybe it has something to do with the way option hashes or blocks should be passed? I can't figure it out where the problem arrises.

Steps to reproduce

Install the doorkeeper gem for a rails 6.1 or 6.0.3.4 project with ruby 3.0 and perform a oauth handshake with a consumer app.

Expected behavior

I would expect the oauth provider to perform an oauth handshake and redirect to the callback url of the consumer application.

Actual behavior

backend | ArgumentError (wrong number of arguments (given 1, expected 0)):
backend |   
backend | activerecord (6.1.0) lib/active_record/relation/batches.rb:128:in `find_in_batches'
backend | doorkeeper (5.4.0) lib/doorkeeper/models/access_token_mixin.rb:98:in `find_access_token_in_batches'
backend | doorkeeper (5.4.0) lib/doorkeeper/models/access_token_mixin.rb:127:in `find_matching_token'
backend | doorkeeper (5.4.0) lib/doorkeeper/models/access_token_mixin.rb:91:in `matching_token_for'
backend | doorkeeper (5.4.0) lib/doorkeeper/models/access_token_mixin.rb:184:in `find_or_create_for'
backend | doorkeeper (5.4.0) lib/doorkeeper/oauth/base_request.rb:31:in `find_or_create_access_token'
backend | doorkeeper (5.4.0) lib/doorkeeper/oauth/authorization_code_request.rb:41:in `block in before_successful_response'
backend | activerecord (6.1.0) lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `block in transaction'
backend | activerecord (6.1.0) lib/active_record/connection_adapters/abstract/transaction.rb:310:in `block in within_new_transaction'
backend | activesupport (6.1.0) lib/active_support/concurrency/load_interlock_aware_monitor.rb:26:in `block (2 levels) in synchronize'
backend | activesupport (6.1.0) lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
backend | activesupport (6.1.0) lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
backend | activesupport (6.1.0) lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
backend | activesupport (6.1.0) lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
backend | activerecord (6.1.0) lib/active_record/connection_adapters/abstract/transaction.rb:308:in `within_new_transaction'
backend | activerecord (6.1.0) lib/active_record/connection_adapters/abstract/database_statements.rb:320:in `transaction'
backend | activerecord (6.1.0) lib/active_record/transactions.rb:209:in `transaction'
backend | activerecord (6.1.0) lib/active_record/transactions.rb:288:in `transaction'
backend | doorkeeper (5.4.0) lib/doorkeeper/oauth/authorization_code_request.rb:29:in `

Doorkeeper initializer:

# config/initializers/doorkeeper.rb
Doorkeeper.configure do
  # ...
end

Ruby version: ``
3.0.0

Gemfile.lock:


Gemfile

  remote: https://rubygems.org/
  specs:
    actioncable (6.0.3.4)
      actionpack (= 6.0.3.4)
      nio4r (~> 2.0)
      websocket-driver (>= 0.6.1)
    actionmailbox (6.0.3.4)
      actionpack (= 6.0.3.4)
      activejob (= 6.0.3.4)
      activerecord (= 6.0.3.4)
      activestorage (= 6.0.3.4)
      activesupport (= 6.0.3.4)
      mail (>= 2.7.1)
    actionmailer (6.0.3.4)
      actionpack (= 6.0.3.4)
      actionview (= 6.0.3.4)
      activejob (= 6.0.3.4)
      mail (~> 2.5, >= 2.5.4)
      rails-dom-testing (~> 2.0)
    actionpack (6.0.3.4)
      actionview (= 6.0.3.4)
      activesupport (= 6.0.3.4)
      rack (~> 2.0, >= 2.0.8)
      rack-test (>= 0.6.3)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.0, >= 1.2.0)
    actiontext (6.0.3.4)
      actionpack (= 6.0.3.4)
      activerecord (= 6.0.3.4)
      activestorage (= 6.0.3.4)
      activesupport (= 6.0.3.4)
      nokogiri (>= 1.8.5)
    actionview (6.0.3.4)
      activesupport (= 6.0.3.4)
      builder (~> 3.1)
      erubi (~> 1.4)
      rails-dom-testing (~> 2.0)
      rails-html-sanitizer (~> 1.1, >= 1.2.0)
    activejob (6.0.3.4)
      activesupport (= 6.0.3.4)
      globalid (>= 0.3.6)
    activemodel (6.0.3.4)
      activesupport (= 6.0.3.4)
    activerecord (6.0.3.4)
      activemodel (= 6.0.3.4)
      activesupport (= 6.0.3.4)
    activestorage (6.0.3.4)
      actionpack (= 6.0.3.4)
      activejob (= 6.0.3.4)
      activerecord (= 6.0.3.4)
      marcel (~> 0.3.1)
    activesupport (6.0.3.4)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 0.7, < 2)
      minitest (~> 5.1)
      tzinfo (~> 1.1)
      zeitwerk (~> 2.2, >= 2.2.2)
    addressable (2.7.0)
      public_suffix (>= 2.0.2, < 5.0)
    ast (2.4.1)
    authy (3.0.0)
      httpclient (>= 2.5.3.3)
    bcrypt (3.1.16)
    bootsnap (1.5.1)
      msgpack (~> 1.0)
    brakeman (4.10.1)
    browser (5.2.0)
    builder (3.2.4)
    capybara (3.34.0)
      addressable
      mini_mime (>= 0.1.3)
      nokogiri (~> 1.8)
      rack (>= 1.6.0)
      rack-test (>= 0.6.3)
      regexp_parser (~> 1.5)
      xpath (~> 3.2)
    childprocess (3.0.0)
    coderay (1.1.3)
    concurrent-ruby (1.1.7)
    crass (1.0.6)
    devise (4.7.3)
      bcrypt (~> 3.0)
      orm_adapter (~> 0.1)
      railties (>= 4.1.0)
      responders
      warden (~> 1.2.3)
    devise-doorkeeper (1.1.2)
      devise
      doorkeeper
      rails
    devise-i18n (1.9.2)
      devise (>= 4.7.1)
    diff-lcs (1.4.4)
    domain_name (0.5.20190701)
      unf (>= 0.0.5, < 1.0.0)
    doorkeeper (5.4.0)
      railties (>= 5)
    doorkeeper-i18n (5.2.2)
      doorkeeper (>= 5.2)
    dotenv (2.7.6)
    dotenv-rails (2.7.6)
      dotenv (= 2.7.6)
      railties (>= 3.2)
    erubi (1.10.0)
    erubis (2.7.0)
    excon (0.78.1)
    factory_bot (6.1.0)
      activesupport (>= 5.0.0)
    factory_bot_rails (6.1.0)
      factory_bot (~> 6.1.0)
      railties (>= 5.0.0)
    faker (2.15.1)
      i18n (>= 1.6, < 2)
    faraday (1.3.0)
      faraday-net_http (~> 1.0)
      multipart-post (>= 1.2, < 3)
      ruby2_keywords
    faraday-net_http (1.0.0)
    ffi (1.14.2)
    gli (2.19.2)
    globalid (0.4.2)
      activesupport (>= 4.2.0)
    heroics (0.1.1)
      erubis (~> 2.0)
      excon
      moneta
      multi_json (>= 1.9.2)
    http-accept (1.7.0)
    http-cookie (1.0.3)
      domain_name (~> 0.5)
    http_accept_language (2.1.1)
    httpclient (2.8.3)
    i18n (1.8.7)
      concurrent-ruby (~> 1.0)
    i18n-docs (0.1.0)
      rake
    i18n-js (3.8.0)
      i18n (>= 0.6.6)
    invisible_captcha (1.1.0)
      rails (>= 4.2)
    jbuilder (2.10.1)
      activesupport (>= 5.0.0)
    json (2.5.1)
    launchy (2.5.0)
      addressable (~> 2.7)
    letter_opener (1.7.0)
      launchy (~> 2.2)
    listen (3.4.0)
      rb-fsevent (~> 0.10, >= 0.10.3)
      rb-inotify (~> 0.9, >= 0.9.10)
    localeapp (3.1.3)
      gli
      i18n (>= 0.7, < 2)
      json (>= 1.7.7)
      rest-client (>= 1.8.0)
    loofah (2.8.0)
      crass (~> 1.0.2)
      nokogiri (>= 1.5.9)
    mail (2.7.1)
      mini_mime (>= 0.1.1)
    marcel (0.3.3)
      mimemagic (~> 0.3.2)
    meta-tags (2.14.0)
      actionpack (>= 3.2.0, < 6.2)
    method_source (1.0.0)
    mime-types (3.3.1)
      mime-types-data (~> 3.2015)
    mime-types-data (3.2020.1104)
    mimemagic (0.3.5)
    mini_mime (1.0.2)
    mini_portile2 (2.5.0)
    minitest (5.14.2)
    moneta (1.0.0)
    msgpack (1.3.3)
    multi_json (1.15.0)
    multipart-post (2.1.1)
    netrc (0.11.0)
    nio4r (2.5.4)
    nokogiri (1.11.0)
      mini_portile2 (~> 2.5.0)
      racc (~> 1.4)
    orm_adapter (0.5.0)
    parallel (1.20.1)
    parser (3.0.0.0)
      ast (~> 2.4.1)
    pg (1.2.3)
    pgreset (0.1.1)
    platform-api (3.2.0)
      heroics (~> 0.1.1)
      moneta (~> 1.0.0)
      rate_throttle_client (~> 0.1.0)
    postmark (1.21.3)
      json
    postmark-rails (0.20.0)
      actionmailer (>= 3.0.0)
      postmark (~> 1.15)
    pry (0.13.1)
      coderay (~> 1.1)
      method_source (~> 1.0)
    pry-rails (0.3.9)
      pry (>= 0.10.4)
    public_suffix (4.0.6)
    puma (5.1.1)
      nio4r (~> 2.0)
    racc (1.5.2)
    rack (2.2.3)
    rack-proxy (0.6.5)
      rack
    rack-test (1.1.0)
      rack (>= 1.0, < 3)
    rails (6.0.3.4)
      actioncable (= 6.0.3.4)
      actionmailbox (= 6.0.3.4)
      actionmailer (= 6.0.3.4)
      actionpack (= 6.0.3.4)
      actiontext (= 6.0.3.4)
      actionview (= 6.0.3.4)
      activejob (= 6.0.3.4)
      activemodel (= 6.0.3.4)
      activerecord (= 6.0.3.4)
      activestorage (= 6.0.3.4)
      activesupport (= 6.0.3.4)
      bundler (>= 1.3.0)
      railties (= 6.0.3.4)
      sprockets-rails (>= 2.0.0)
    rails-dom-testing (2.0.3)
      activesupport (>= 4.2.0)
      nokogiri (>= 1.6)
    rails-html-sanitizer (1.3.0)
      loofah (~> 2.3)
    rails-i18n (6.0.0)
      i18n (>= 0.7, < 2)
      railties (>= 6.0.0, < 7)
    railties (6.0.3.4)
      actionpack (= 6.0.3.4)
      activesupport (= 6.0.3.4)
      method_source
      rake (>= 0.8.7)
      thor (>= 0.20.3, < 2.0)
    rainbow (3.0.0)
    rake (13.0.3)
    rate_throttle_client (0.1.2)
    rb-fsevent (0.10.4)
    rb-inotify (0.10.1)
      ffi (~> 1.0)
    regexp_parser (1.8.2)
    responders (3.0.1)
      actionpack (>= 5.0)
      railties (>= 5.0)
    rest-client (2.1.0)
      http-accept (>= 1.7.0, < 2.0)
      http-cookie (>= 1.0.2, < 2.0)
      mime-types (>= 1.16, < 4.0)
      netrc (~> 0.8)
    rexml (3.2.4)
    rspec-core (3.10.1)
      rspec-support (~> 3.10.0)
    rspec-expectations (3.10.1)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.10.0)
    rspec-mocks (3.10.1)
      diff-lcs (>= 1.2.0, < 2.0)
      rspec-support (~> 3.10.0)
    rspec-rails (4.0.2)
      actionpack (>= 4.2)
      activesupport (>= 4.2)
      railties (>= 4.2)
      rspec-core (~> 3.10)
      rspec-expectations (~> 3.10)
      rspec-mocks (~> 3.10)
      rspec-support (~> 3.10)
    rspec-support (3.10.1)
    rspec_junit_formatter (0.4.1)
      rspec-core (>= 2, < 4, != 2.12.0)
    rubocop (1.7.0)
      parallel (~> 1.10)
      parser (>= 2.7.1.5)
      rainbow (>= 2.2.2, < 4.0)
      regexp_parser (>= 1.8, < 3.0)
      rexml
      rubocop-ast (>= 1.2.0, < 2.0)
      ruby-progressbar (~> 1.7)
      unicode-display_width (>= 1.4.0, < 2.0)
    rubocop-ast (1.4.0)
      parser (>= 2.7.1.5)
    rubocop-performance (1.9.2)
      rubocop (>= 0.90.0, < 2.0)
      rubocop-ast (>= 0.4.0)
    rubocop-rails (2.9.1)
      activesupport (>= 4.2.0)
      rack (>= 1.1)
      rubocop (>= 0.90.0, < 2.0)
    rubocop-rspec (2.1.0)
      rubocop (~> 1.0)
      rubocop-ast (>= 1.1.0)
    ruby-progressbar (1.11.0)
    ruby2_keywords (0.0.2)
    rubyzip (2.3.0)
    seedbank (0.5.0)
      rake (>= 10.0)
    selenium-webdriver (3.142.7)
      childprocess (>= 0.5, < 4.0)
      rubyzip (>= 1.2.2)
    semantic_range (2.3.1)
    semver (1.0.1)
    sentry-raven (3.1.1)
      faraday (>= 1.0)
    slim (4.1.0)
      temple (>= 0.7.6, < 0.9)
      tilt (>= 2.0.6, < 2.1)
    slim-rails (3.2.0)
      actionpack (>= 3.1)
      railties (>= 3.1)
      slim (>= 3.0, < 5.0)
    slim_lint (0.20.2)
      rubocop (>= 0.78.0)
      slim (>= 3.0, < 5.0)
    spring (2.1.1)
    spring-commands-rspec (1.0.4)
      spring (>= 0.9.1)
    spring-commands-rubocop (0.2.0)
      spring (>= 1.0, < 3.0)
    spring-watcher-listen (2.0.1)
      listen (>= 2.7, < 4.0)
      spring (>= 1.2, < 3.0)
    sprockets (4.0.2)
      concurrent-ruby (~> 1.0)
      rack (> 1, < 3)
    sprockets-rails (3.2.2)
      actionpack (>= 4.0)
      activesupport (>= 4.0)
      sprockets (>= 3.0.0)
    temple (0.8.2)
    thor (1.0.1)
    thread_safe (0.3.6)
    tilt (2.0.10)
    tzinfo (1.2.9)
      thread_safe (~> 0.1)
    unf (0.1.4)
      unf_ext
    unf_ext (0.0.7.7)
    unicode-display_width (1.7.0)
    warden (1.2.9)
      rack (>= 2.0.9)
    webdrivers (4.4.2)
      nokogiri (~> 1.6)
      rubyzip (>= 1.3.0)
      selenium-webdriver (>= 3.0, < 4.0)
    webpacker (5.2.1)
      activesupport (>= 5.2)
      rack-proxy (>= 0.6.1)
      railties (>= 5.2)
      semantic_range (>= 2.3.0)
    websocket-driver (0.7.3)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.5)
    xpath (3.2.0)
      nokogiri (~> 1.8)
    zeitwerk (2.4.2)

bug

Most helpful comment

I stumbled upon this today when upgrading our project from ruby 2.5 to 2.7.1. It started giving me warnings like this:

/Users/dmytrosavochkin/.rvm/gems/ruby-2.7.1@.../gems/doorkeeper-5.4.0/lib/doorkeeper/models/access_token_mixin.rb:98: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/Users/dmytrosavochkin/.rvm/gems/ruby-2.7.1@.../gems/activerecord-6.1.0/lib/active_record/relation/batches.rb:128: warning: The called method `find_in_batches' is defined here

So it's probably not a ruby 3.0 issue. Why it wasn't caught in ruby 2.7.2 then? Probably because in 2.7.2 they disabled these warnings by default (https://www.ruby-lang.org/en/news/2020/10/02/ruby-2-7-2-released/). So the issue became clearly visible only with 3.0.0 release when these warnings became errors.

But it seems pretty easy to fix. I just changed

def find_access_token_in_batches(relation, *args, &block)
  relation.find_in_batches(*args, &block)
end

to

def find_access_token_in_batches(relation, **args, &block)
  relation.find_in_batches(**args, &block)
end

and my warnings went away. I created a local fix for my project and put it into config/initializers/doorkeeper.rb until this issue is fixed in Doorkeeper:

Doorkeeper::AccessTokenMixin::ClassMethods.module_eval do
  def find_access_token_in_batches(relation, **args, &block)
    relation.find_in_batches(**args, &block)
  end
end

Could someone please check it with ruby 3.0.0?

All 8 comments

I literally just hit this 5 mins ago myself!
ruby 3 / rails 6.0.3.4

file: lib/doorkeeper/models/access_token_mixin.rb

ruby def find_access_token_in_batches(relation, *args, &block) relation.find_in_batches(*args, &block) # <-------------------------- end
ArgumentError (wrong number of arguments (given 1, expected 0)):

I think this is an issue with rails handling &blocks with ruby 3.0.0

I would suggest rolling back to ruby 2.7.2

@freibuis I have searched the Rails repository for issues about blocks and parameters icw ruby 3.0, but nobody has experienced the same. It looks a bit like these kind of issue reports: https://github.com/rails/rails/issues/41001, which refer top the repository of the gem. The authors of the gem recently fixed some Ruby 2.7.1 deprecation warnings (which break in 3.0.0) concerning method calls with blocks: https://github.com/scoutapp/scout_apm_ruby/commit/f42b5243af0f0a188e4a97f5e50cc16be07dc34d

yerp,, read the same. I still think someone will drop an issue in the rails github, from what I looked at.. it might break.

here is the rails part... I dont think its listening to the block there. and therefor given 1 expected 0

    def find_in_batches(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil)
      relation = self
      unless block_given?
        return to_enum(:find_in_batches, start: start, finish: finish, batch_size: batch_size, error_on_ignore: error_on_ignore) do
          total = apply_limits(relation, start, finish).size
          (total - 1).div(batch_size) + 1
        end
      end

      in_batches(of: batch_size, start: start, finish: finish, load: true, error_on_ignore: error_on_ignore) do |batch|
        yield batch.to_a
      end
    end

my brain bleeds reading the ruby 3.0.0 changes related to blocks.

I stumbled upon this today when upgrading our project from ruby 2.5 to 2.7.1. It started giving me warnings like this:

/Users/dmytrosavochkin/.rvm/gems/ruby-2.7.1@.../gems/doorkeeper-5.4.0/lib/doorkeeper/models/access_token_mixin.rb:98: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/Users/dmytrosavochkin/.rvm/gems/ruby-2.7.1@.../gems/activerecord-6.1.0/lib/active_record/relation/batches.rb:128: warning: The called method `find_in_batches' is defined here

So it's probably not a ruby 3.0 issue. Why it wasn't caught in ruby 2.7.2 then? Probably because in 2.7.2 they disabled these warnings by default (https://www.ruby-lang.org/en/news/2020/10/02/ruby-2-7-2-released/). So the issue became clearly visible only with 3.0.0 release when these warnings became errors.

But it seems pretty easy to fix. I just changed

def find_access_token_in_batches(relation, *args, &block)
  relation.find_in_batches(*args, &block)
end

to

def find_access_token_in_batches(relation, **args, &block)
  relation.find_in_batches(**args, &block)
end

and my warnings went away. I created a local fix for my project and put it into config/initializers/doorkeeper.rb until this issue is fixed in Doorkeeper:

Doorkeeper::AccessTokenMixin::ClassMethods.module_eval do
  def find_access_token_in_batches(relation, **args, &block)
    relation.find_in_batches(**args, &block)
  end
end

Could someone please check it with ruby 3.0.0?

Yes, It works for me!!

-----my environment-----
ruby 3.0.0
rails 6.1.0
devise 4.7.3
doorkeeper 5.4

Hi @dmytro-savochkin . Would you mind propose a PR with a fix?
Also I've checked the mixin and see that it's already use **args :thinking:
https://github.com/doorkeeper-gem/doorkeeper/blob/master/lib/doorkeeper/models/access_token_mixin.rb#L97-L99

@nbulaj Ah, if it's already there then there is no need for a PR. I didn't see it was there because it had been added in 5.5.0.rc1 and I don't usually use "rc" versions :) So this issue should be solved by upgrading to 5.5.0.rc1 (or maybe by waiting for a next non-rc version if you are just like me).

Was this page helpful?
0 / 5 - 0 ratings