Skip to content

Piggyback Devise Basic Auth

Chris Hall edited this page Mar 9, 2020 · 6 revisions

Devise Compatible Database Lookup

In the Gemfile or geminabox.gemspec add

  s.add_dependency('mysql2')
  s.add_dependency('bcrypt-ruby')

You should then be able to just slap this into geminabox.rb

def self.secure_compare(a, b)
    return false if a == "" || b == "" || a.bytesize != b.bytesize
    l = a.unpack "C#{a.bytesize}"

    res = 0
    b.each_byte { |byte| res |= byte ^ l.shift }
    res == 0
  end

use Rack::Auth::Basic, "Restricted Area" do |username, password|
  # Lookup user in db
  client = Mysql2::Client.new(:host => "localhost", :username => "*DB USERNAME*", :password => "*DB PASSWORD*", :database => "*DATA BASE NAME*")
  pepper = "*PEPPER*"
  escaped = client.escape(username)
  valid = false
  results = client.query("SELECT * FROM users WHERE email='#{escaped}' LIMIT 1").each(:symbolize_keys => true) do |row|
    bcrypt   = ::BCrypt::Password.new(row[:encrypted_password])
    hash_pass = ::BCrypt::Engine.hash_secret("#{password}#{pepper}", bcrypt.salt)
    valid = secure_compare(hash_pass, row[:encrypted_password])
    break if valid
  end
  valid
end

This works great when you have an internal intranet app or a gitlab app that already uses devise.

This basically just grants users access based on those credentials.

If you use a pepper from devise you should place that in the pepper = "" variable, this can be found in config/intializers/devise.rb