Skip to content

Instantly share code, notes, and snippets.

@plainlystated
Created March 4, 2010 05:05
Show Gist options
  • Save plainlystated/321413 to your computer and use it in GitHub Desktop.
Save plainlystated/321413 to your computer and use it in GitHub Desktop.
require 'bcrypt'
module EasyAuth
# http://techspeak.plainlystated.com/2010/03/drop-dead-simple-authentication-for.html
# To generate a crypted password (in irb):
# require 'easy_auth'
# EasyAuth.encrypt_password('my_password') # Put returned array in AUTHORIZED_USERS
AUTHORIZED_USERS = {
'username' => ["encrypted_password", "salt"]
}
SALT_CHARS = ['.', '/', '0'..'9', 'A'..'Z', 'a'..'z'].collect do |set|
set.to_a
end.flatten
def self.encrypt_password(password, salt = nil)
if salt.nil?
salt = generate_salt
end
old_pass = password
password = BCrypt::Password.create(salt + password).to_s
[password, salt]
end
def self.generate_salt(length = 5)
salt = ""
length.times { salt << SALT_CHARS[rand(SALT_CHARS.length)] }
salt
end
def auth_key(username)
"#{_crypted_password(username)}::#{request.env['REMOTE_ADDR']}::#{request.env['HTTP_USER_AGENT']}"
end
def encrypt_password(username, password)
salt = _salt(username)
EasyAuth.encrypt_password(password, salt)[0]
end
def if_auth(username = request.cookies["username"], password = nil)
if AUTHORIZED_USERS.has_key?(username)
raise ArgumentError, "AUTHORIZED_USERS[#{username}] seems to have an invalid format. It should be the output of EasyAuth.encrypt_password('my_pass')" unless AUTHORIZED_USERS[username].size == 2
if password.nil?
authorized = valid_key?(username, request.cookies["key"])
else
if valid_password?(username, password)
authorized = true
crypted_key = encrypt_password(username, auth_key(username))
response.set_cookie("username", username)
response.set_cookie("key", crypted_key)
end
end
if authorized
return yield
end
end
@error = "Login failed"
erb :'/admin/login'
end
def valid_key?(username, key)
BCrypt::Password.new(key) == _salt(username) + auth_key(username)
end
def valid_password?(username, password)
BCrypt::Password.new(_crypted_password(username)) == _salt(username) + password
end
def _salt(username)
AUTHORIZED_USERS.fetch(username, []).last
end
def _crypted_password(username)
AUTHORIZED_USERS.fetch(username, []).first
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment