Skip to content
This repository has been archived by the owner on Jul 28, 2021. It is now read-only.

Commit

Permalink
Merge 571f719 into fc82477
Browse files Browse the repository at this point in the history
  • Loading branch information
okapusta committed Oct 11, 2013
2 parents fc82477 + 571f719 commit 0b23237
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
24 changes: 21 additions & 3 deletions lib/casino_core/authenticator/activerecord.rb
@@ -1,6 +1,7 @@
require 'active_record'
require 'unix_crypt'
require 'bcrypt'
require 'digest/sha1'

class CASinoCore::Authenticator::ActiveRecord

Expand All @@ -23,10 +24,13 @@ class #{self.class.to_s}::#{@options[:table].classify} < AuthDatabase

def validate(username, password)
@model.verify_active_connections!
user = @model.send("find_by_#{@options[:username_column]}!", username)
user = @model.send("find_by_#{@options[:username_column]}", username)
unless user
user = @model.send("find_by_#{@options[:email_column]}!", username)
end
password_from_database = user.send(@options[:password_column])

if valid_password?(password, password_from_database)
if valid_password?(password, password_from_database, (user.salt if user.respond_to?(:salt)))
{ username: user.send(@options[:username_column]), extra_attributes: extra_attributes(user) }
else
false
Expand All @@ -37,12 +41,18 @@ def validate(username, password)
end

private
def valid_password?(password, password_from_database)
def secure_digest(*args)
Digest::SHA1.hexdigest(args.flatten.join('--'))
end

def valid_password?(password, password_from_database, salt=nil)
return false if password_from_database.blank?
magic = password_from_database.split('$')[1]
case magic
when /\A2a?\z/
valid_password_with_bcrypt?(password, password_from_database)
when /\Asha?\z/
valid_password_with_sha1_crypt?(password, password_from_database, salt)
else
valid_password_with_unix_crypt?(password, password_from_database)
end
Expand All @@ -57,6 +67,14 @@ def valid_password_with_unix_crypt?(password, password_from_database)
UnixCrypt.valid?(password, password_from_database)
end

def valid_password_with_sha1_crypt?(password, password_from_database, salt)
site_auth_key = digest = @options[:site_auth_key].to_s
10.times do
digest = secure_digest(digest, salt, password, site_auth_key)
end
digest == password_from_database.split('$')[2]
end

def extra_attributes(user)
attributes = {}
extra_attributes_option.each do |attribute_name, database_column|
Expand Down
32 changes: 32 additions & 0 deletions spec/casino_core/authenticator/activerecord_spec.rb
Expand Up @@ -5,6 +5,7 @@

let(:pepper) { nil }
let(:extra_attributes) {{ email: 'mail_address' }}
let(:site_auth_key) { '9df92c193273ae9adf804195641b50828dee0088' }
let(:options) do
{
connection: {
Expand All @@ -14,7 +15,9 @@
table: 'users',
username_column: 'username',
password_column: 'password',
email_column: 'email',
pepper: pepper,
site_auth_key: site_auth_key,
extra_attributes: extra_attributes
}
end
Expand All @@ -30,6 +33,8 @@
t.string :username
t.string :password
t.string :mail_address
t.string :salt
t.string :email
end
end
end
Expand Down Expand Up @@ -130,6 +135,33 @@
end
end

context 'support for sha1 restful-authentication' do
before do
CASinoCore::Authenticator::ActiveRecord::User.create!(
username: 'test4',
password: '$sha$2986d3bb945c0d03901fb7ec7e1405e5d9846271',
mail_address: 'mail@example.org',
salt: 'b1676d830c1558b584491089239f3ff448e5277e')
end

it 'is able to handle sha1 restful-authentication password hashes' do
@authenticator.validate('test4', 'password').should be_instance_of(Hash)
end
end

context 'support for login by username and/or email' do
before do
CASinoCore::Authenticator::ActiveRecord::User.create!(
username: 'test5',
password: '$2a$10$q9nu9AfeUCkwMeDaFlhOQ.2L0UK0tpYIq8JjJDzphO7qy1vdU9.Se',
email: 'test5@copper.io'
)
end
it 'allows login using email' do
@authenticator.validate('test5@copper.io', 'testpassword4').should be_instance_of(Hash)
end
end

end

end

0 comments on commit 0b23237

Please sign in to comment.