Giter Site home page Giter Site logo

Comments (18)

BobbyMcWho avatar BobbyMcWho commented on May 26, 2024 2

I think the biggest downstream consumer is devise, so we'd wanna look if/how devise uses the builder and try and at least keep backwards compatibility for that

from omniauth.

speckins avatar speckins commented on May 26, 2024 1

It's also not necessary to redefine #call since it's the same as the superclass.

https://github.com/rack/rack/blob/ab9cd7416c1b5253cd280d75704bafd87510c120/lib/rack/builder.rb#L261-L263

If OmniAuth::Builder is intended to be used as shown in the README, maybe overridding ::new would be a low-impact way of resolving this?

module OmniAuth
  class Builder < ::Rack::Builder
    def self.new(default_app = nil, &block)
      builder = super
      block ? builder.to_app : builder
    end
  end
end

from omniauth.

speckins avatar speckins commented on May 26, 2024 1

I searched the devise code. They don't use Builder. The only reference to "builder" is a form builder. I also ran their test suite against the code in the PR just in case, and everything passes.

from omniauth.

speckins avatar speckins commented on May 26, 2024 1

I opened another PR, with the Builder-as-a-module idea. I don't really have a preference between them, but the module version means there won't be an extra do-nothing piece of middleware in the stack since it just returns the built app.

from omniauth.

BobbyMcWho avatar BobbyMcWho commented on May 26, 2024 1

Thanks @speckins I will take a look as soon as I have some time, I've been very busy

from omniauth.

BobbyMcWho avatar BobbyMcWho commented on May 26, 2024

Thanks for the report, this is an area of the library I haven't looked much into. Would memoizing the to_app call be sufficient?

from omniauth.

ioquatix avatar ioquatix commented on May 26, 2024

I think you'd want to do it at build time because memoization is not thread safe.

from omniauth.

ioquatix avatar ioquatix commented on May 26, 2024
module OmniAuth
  module Builder
    def self.new(default_app = nil, &block)
      ::Rack::Builder.new(default_app, &block).to_app
    end
  end
end

maybe consider this???

from omniauth.

speckins avatar speckins commented on May 26, 2024

Except that OmniAuth::Builder adds a few methods of its own, of which, the #provider method is probably the main reason for using it.

def provider(klass, *args, **opts, &block)

What about this:

module OmniAuth
  class Builder < Rack::Builder
    def initialize default_app = nil, &block
      super
      @app = to_app if default_app
    end

    def call env
      (@app || to_app).call(env)
    end

    # The rest same as current OmniAuth::Builder class,
    # not duplicated here....
  end
end

It ought to cover people who are currently using it in both ways, as middleware as suggested in the docs or as Rack::Builder is expected to be used.

from omniauth.

ioquatix avatar ioquatix commented on May 26, 2024

I don't think side effects in #initialize are a good idea.

I like your original proposal: #1083 (comment)

I'd even suggest just doing it like this:

module OmniAuth
  module Builder
    def self.build(default_app = nil, &block)
      new(default_app, &block).to_app
    end

    # All the existing code.
  end
end

Then use OmniAuth::Builder.build(...).

from omniauth.

BobbyMcWho avatar BobbyMcWho commented on May 26, 2024

I'm not opposed to a major bump if need be, so the change can be as breaking as needed

from omniauth.

speckins avatar speckins commented on May 26, 2024

The problem is that omniauth has been telling people to use OmniAuth::Builder as middleware. E.g.,

use OmniAuth::Builder do
  provider :developer
end

Any Rack-like use(middleware, app, *args, &block) implementation is going to push those arguments onto a stack, and when it finally assembles the Rack app, it's going to call OmniAuth::Builder.new(app, *args, &block). So that means that OmniAuth has no control over which class method is called, and the only two places to fix this in existing applications written this way are ::new or #initialize. (And Rack::Builder already has a class method, ::app, that calls #to_app.)

What about...

module OmniAuth
  module Builder
    def self.new(app, *args, &block)
      builder = Rack::Builder.new(app).extend(self)
      builder.instance_eval(&block) if block_given?
      builder.to_app
    end

    def provider(klass, *args, **opts, &block)
      # ...
    end

    def options(options = false)
      # ...
    end

    # ...etc
  end
end

This would work for applications using OmniAuth::Builder as middleware with no changes needed. It would break for people (like me) who have been subclassing Builder, but at least it wouldn't be subtle (TypeError (superclass must be a Class (Module given))) and could be resolved by subclassing Rack::Builder and including the OmniAuth::Builder module.

It would break for people who have been instantiating Builder and using the instance directly, though.

from omniauth.

speckins avatar speckins commented on May 26, 2024

One more option -- rename the current Builder class to something else and define a new Builder to use it internally.

module OmniAuth
  class AuthBuilder < Rack::Builder
    # ...same as current OmniAuth::Builder, except no #call

    undef_method :call
  end

  class Builder
    def initialize app, &block
      @app = AuthBuilder.app(app, &block)
    end

    def call env
      @app.call(env)
    end
  end
end

from omniauth.

speckins avatar speckins commented on May 26, 2024

If you had a preference on how you wanted this resolved (or the priorities to take into consideration, e.g., what level of backward-compatibility, etc), I'd be willing to take a crack at it and submit a PR.

from omniauth.

ioquatix avatar ioquatix commented on May 26, 2024

If you want an easy way to test external dependencies, you might like https://github.com/ioquatix/bake-test-external

from omniauth.

jcmfernandes avatar jcmfernandes commented on May 26, 2024

I tripped on this earlier today. How can I help get #1094 merged?

from omniauth.

BobbyMcWho avatar BobbyMcWho commented on May 26, 2024

I've just not had the time to manage a large refactor at the moment, I'd love to be able to take care of a few different long standing issues w/ omniauth in the next major release, I just haven't had the time to work on OmniAuth outside of critical maintenance. Namely I'd like to resolve this issue, completely remove the hashie dependency, not dup the entire strategy w/ every request, and shortcircuit out of omniauth early when the request is not on a path that omniauth cares about.

from omniauth.

jcmfernandes avatar jcmfernandes commented on May 26, 2024

I've just not had the time to manage a large refactor at the moment, I'd love to be able to take care of a few different long standing issues w/ omniauth in the next major release, I just haven't had the time to work on OmniAuth outside of critical maintenance. Namely I'd like to resolve this issue, completely remove the hashie dependency, not dup the entire strategy w/ every request, and shortcircuit out of omniauth early when the request is not on a path that omniauth cares about.

Makes sense! What do you think of doing those changes incrementally? I can help.

from omniauth.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.