Skip to content

Define API for classes utilizing OmniAuth::Identity::Model #108

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

Merged
merged 6 commits into from
Mar 20, 2021

Conversation

pboling
Copy link
Member

@pboling pboling commented Mar 20, 2021

@btalbot - Working on a fix.

Fixes

  • Fix breaking changes introduced by #86's introduction of :on_validation

Added

  • Define #save, #persisted? and ::create on Omniauth::Identity::Model
  • Add @since YARD tags to interface methods
  • Refactor Omniauth::Strategies::Identity.registration_phase to support Omniauth::Identity::Model-inheriting classes that do not define #save.
    • This support will be dropped in v4.0.

@pboling pboling added the bug label Mar 20, 2021
@pboling pboling self-assigned this Mar 20, 2021
pboling referenced this pull request Mar 20, 2021
@pboling pboling merged commit 38fa977 into master Mar 20, 2021
@pboling pboling deleted the define-api branch March 20, 2021 03:46
@pboling
Copy link
Member Author

pboling commented Mar 20, 2021

@btalbot release 3.0.5 is out with the fix. Please let me know if there are any issues.

@btalbot
Copy link
Contributor

btalbot commented Mar 22, 2021

Hi @pboling

Thank you for the updates, they are much better than what existing previously. However, there are two issues I've run into while testing code with your changes.

  1. The previous model's initializer was never called by the strategy so the creator was free to use whatever arguments to the new method they wished. The updated strategy always attempts to call the model's new method with the attributes hash even if the strategy might later attempt to call ::create instead. This breaks old model implementations that do not expect their initializer to be called with a hash. I think that to remain backwards compatible the strategy must only use ::create and never expect to call the model initializer directly.
  2. The method #saving_instead_of_creating? will always return true for any model that extends the OmniAuth::Identity::Model since that model does define #save and #persisted? methods even if they do raise an NotImplementedError. Maybe just attempting to call the new #save method and then handling the NotImplementedError with the fallback method would work?
    def saving_instead_of_creating?
    @identity.respond_to?(:save) && @identity.respond_to?(:persisted?)
    end

@pboling
Copy link
Member Author

pboling commented Mar 24, 2021

Oops, I didn't see this before I released more fixes in 3.0.7. I will continue working on this @btalbot. Both of the points you make are valid, and haven't been fully resolved by the most recent release.

@pboling
Copy link
Member Author

pboling commented Mar 24, 2021

@btalbot The fix for both issues was fairly simple. It is impossible to use the options[:on_validation] unless also using new/save, so I just made the presence of that option the decider. If the option isn't set, then create works fine. I think that resolves the issues you found.

It just means that some implementations can't use options[:on_validation], which should surprise no-one.

@btalbot
Copy link
Contributor

btalbot commented Mar 24, 2021

That is simple and does seem to allow the ::create method to be used when #validating? is false. How should validation be configured to use the #save but without actually using the validation feature? Seems like we will need to create a valid on_validation block which just always returns true?

@pboling
Copy link
Member Author

pboling commented Mar 24, 2021

@btalbot No, the default for options[:on_validation] is nil. If it is provided by an implementation that implementation has always, since the introduction of the feature a few weeks ago, had to support new and save, so there is no change for those users.

@btalbot
Copy link
Contributor

btalbot commented Mar 24, 2021

What is expected config for an app to use new and save but with no (or default) on_validation?

@pboling
Copy link
Member Author

pboling commented Mar 24, 2021

They will not use new and save. Wasn't that the point of your initial issue? We can't introduce new and save in a breaking way for existing implementations. Introducing them as part of an entirely new feature, which on_valdiation is, is not breaking.

In this context, the only reason to use new and save instead of create is to validate before persisting. I also undeprecated create. We'll just keep this pattern for now.

@btalbot
Copy link
Contributor

btalbot commented Mar 24, 2021

Yes, the 3.0.8 release does resolve the backward compatibility issue and tests using existing implementations now pass. Thank you.

A future step is to remove the use of the deprecated create method and use new and save instead. When doing that, I'll just also add a lamba for on_validation = lamda { |_| true } to allow them to be used.

@btalbot
Copy link
Contributor

btalbot commented Mar 24, 2021

Also, future implementers will need to know that the on_validation call() provides a hash parameter and not env or req as most of the other blocks do.

For example

on_login = lambda { |env| puts "env is #{env}" }
on_validation = lambda { |args| puts "env is #{args[:env]}" }

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

Successfully merging this pull request may close these issues.

2 participants