NoamB / sorcery

Magical authentication for Rails 3 & 4
MIT License
2.31k stars 386 forks source link

Sorcery ActiveRecord Adapter always uses email attribute #762

Open chadwilken opened 8 years ago

chadwilken commented 8 years ago

I haven't changed any sorcery or user related code for a while but all of a sudden Sorcery is always trying to use the email attribute when performing find_by. My config is below and I confirmed that the configuration is being loaded. Not sure if you might have a solution for this other than adding an alias_attribute on the User class. I didn't update the gem just simply ran tests and it magically started failing. I attempted to remove the gem and reinstall to no change.

Update After some digging with Byebug, I have confirmed in the find_by_credentials method that it is getting email from the call to find_by_credentials. The output if I see what the sorcery_config has is:

#<Sorcery::Model::Config:0x007f9c2ac08550
 @after_config=[],
 @before_authenticate=[],
 @crypted_password_attribute_name=:crypted_password,
 @custom_encryption_provider=nil,
 @defaults=
  {:@submodules=>[],
   :@username_attribute_names=>[:email],
   :@password_attribute_name=>:password,
   :@downcase_username_before_authenticating=>false,
   :@email_attribute_name=>:email,
   :@crypted_password_attribute_name=>:crypted_password,
   :@encryption_algorithm=>:bcrypt,
   :@encryption_provider=>Sorcery::CryptoProviders::BCrypt,
   :@custom_encryption_provider=>nil,
   :@encryption_key=>nil,
   :@salt_join_token=>"",
   :@salt_attribute_name=>:salt,
   :@stretches=>nil,
   :@subclasses_inherit_config=>false,
   :@before_authenticate=>[],
   :@after_config=>[]},
 @downcase_username_before_authenticating=false,
 @email_attribute_name=:email,
 @encryption_algorithm=:bcrypt,
 @encryption_key=nil,
 @encryption_provider=Sorcery::CryptoProviders::BCrypt,
 @password_attribute_name=:password,
 @salt_attribute_name=:salt,
 @salt_join_token="",
 @stretches=nil,
 @subclasses_inherit_config=false,
 @submodules=[],
 @username_attribute_names=[:email]>

My config file:

require 'legacy_encryption_provider'
# The first thing you need to configure is which modules you need in your app.
# The default is nothing which will include only core features (password encryption, login/logout).
# Available submodules are: :user_activation, :http_basic_auth, :remember_me,
# :reset_password, :session_timeout, :brute_force_protection, :activity_logging, :external
Rails.application.config.sorcery.submodules = [:reset_password]

# Here you can configure each submodule's features.
Rails.application.config.sorcery.configure do |config|
  # --- user config ---
  config.user_config do |user|
    user.username_attribute_names = [:username, :email_address]
    user.downcase_username_before_authenticating = true
    user.email_attribute_name = :email_address
    user.crypted_password_attribute_name = :crypted_password
    user.salt_attribute_name = nil
    user.custom_encryption_provider = LegacyEncryptionProvider
    user.encryption_algorithm = :custom
    user.reset_password_token_attribute_name = :reset_password_token
    user.reset_password_mailer = UserMailer
  end

  # This line must come after the 'user config' block.
  # Define which model authenticates with sorcery.
  config.user_class = "User"
end
chadwilken commented 8 years ago

So it turns out if you use this in combination with rails_admin and modify the class in an initializer it will load the model class before sorcery can configure the properties and caused the error above. For the time being I removed my rails admin config.

arnvald commented 8 years ago

@chadwilken maybe simply loading the sorcery config before rails admin config is a solution? I think they're loaded alphabetically, so just rename one of them. That's far from perfect, but maybe having files like initializers/001_sorcery.rb and initializers/002_rails_admin.rb is't that bad it clearly suggest what needs to be loaded first

chadwilken commented 8 years ago

@arnvald not a bad idea as it is clear that one precedes the other. Ill mess with it a bit later.

chadwilken commented 8 years ago

@arnvald I gave it a try and now it complains that the password reset mailer must be provided. It is set but the module must not be loaded even if I add a require at the top.