Created
March 4, 2010 05:05
-
-
Save plainlystated/321413 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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