How To: Configure a master password

jeznet edited this page Oct 22, 2014 · 11 revisions
Clone this wiki locally

If you need a super password to be able to log in as one of your users, you can add this code to your models:

class User
  ...
  def valid_password?(password)
     if Rails.env.development?
      return true if password == "THE MASTER PASSWORD MUAHAHA" 
     end
     super
  end
end

It barely needs mentioning, but just in case - This is extremely dangerous for a production app... Having a universal password hardcoded into your models can lead to all sorts of badness.

If you really need a master password in production then you should not hardcode the password in the source code and use the full authentication security that Devise gives. To do this you can add this code in your models:

class User
  ...
  # enables a Master Password check
  def valid_password?(password)
    return true if valid_master_password?(password)
    super
  end

  # WARNING: Master User password changes require an application process restart
  DEFAULT_MASTER_USER_EMAIL = 'master@somedomain.com' # config # SUGESTION: Move to an app configuration file
  DEFAULT_MASTER_USER = self.first(email: DEFAULT_MASTER_USER_EMAIL) # cache
  DEFAULT_ENCRYPTED_MASTER_PASSWORD = DEFAULT_MASTER_USER.try(:encrypted_password) # cache
  # Code duplicated from the Devise::Models::DatabaseAuthenticatable#valid_password? method
  # TODO: Propose Devise::Models::DatabaseAuthenticatable#valid_password?(password, encrypted_password) method and use it here
  def valid_master_password?(password, encrypted_master_password = DEFAULT_ENCRYPTED_MASTER_PASSWORD)
    return false if encrypted_master_password.blank?
    bcrypt_salt = ::BCrypt::Password.new(encrypted_master_password).salt
    bcrypt_password_hash = ::BCrypt::Engine.hash_secret("#{password}#{self.class.pepper}", bcrypt_salt)
    Devise.secure_compare(bcrypt_password_hash, encrypted_master_password)
  end
  ...
end
This should be as secure as your master (super, admin) users password. This will "only" give the master user more power - the power to login as anybody using his password.

The valid_master_password? method can be also used to setup master passwords for groups of users etc. For example for the admin users of organizations:

class User
  ...
  # enables a Master Password check
  def valid_password?(password)
    return true if valid_master_password?(password) or 
                   valid_master_password?(password, self.organization.admin_user.encrypted_password)
    super
  end
  ...
end
You can discuss this topic here and here.