Search code examples
ruby-on-railsrubydevisecredentialssalt

Devise user created with Rails generator cannot sign in


I'm working on a Rails Engine which will depend on Devise.

I created an installer using Rails generator which you can find here. The installer creates the first credentials in order to access the administration panel later.

The problem is that I cannot sign in with those credentials. Weirdly then, if I delete the account and recreate it via Rails console, they do work. I think that's due to something happening during the installer.

Here a snippet of it:

# Binda installer generator ...

def setup_devise
  return if Rails.env.production?
  # Copy the initilializer on the application folder
  template 'config/initializers/devise.rb'
  # Add secret key
  inject_into_file 'config/initializers/devise.rb', after: "config.secret_key = '" do 
    SecureRandom.hex(64)
  end
  # Add pepper
  inject_into_file 'config/initializers/devise.rb', after: "config.pepper = '" do 
    SecureRandom.hex(64)
  end
  # some other code for mailer ...
end

def create_credentials
  @username = ask("What's your email? ['[email protected]']").presence || '[email protected]'
  @password = ask("What's your password? ['password']").presence || 'password'
  Binda::User.create( email: @username, password: @password, password_confirmation: @password )

# Binda installer generator continue ...

Here the full code.


More info

I found out that even if I modify devise.rb file the new configuration is not loaded until the end of the installer. This means the new salt/pepper isn't considered while creating the first user. How can I reload it before running the create_credentials method?


Solution

  • Sorted!

    The problem is that if you add salt/pepper configuration to the devise.rb of your application you need to reload the environment before being able to create a user with the new settings.

    To do that I moved the user creation into a task. This way the installer to reload the environment (and Devise config as weel) and is able to set the encrypted password correctly.

    Installer

    # lib/generators/myEngine/install/install_generator.rb
    def create_credentials
      rake 'binda_create_initial_user'
    end
    

    Task

    # lib/tasks/binda.rake
    desc "Create initial user"
    task :binda_create_initial_user => :environment do
      username = '[email protected]'
      password = 'password'
      Binda::User.create!( email: username, password: password, password_confirmation: password )
    end
    

    If you want to keep asking for mail and password:

    # lib/tasks/binda.rake
    desc "Create first user"
    task :binda_create_initial_user => :environment do
        STDOUT.puts "What is your email? [[email protected]]"
      username = STDIN.gets.strip
      username = '[email protected]' if username.blank?
        STDOUT.puts "What is your password? [password]"
      password = STDIN.gets.strip
      password = 'password' if password.blank?
      Binda::User.create!( email: username, password: password, password_confirmation: password )
    end