merb-auth-more 1.0.15 → 1.1.0.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +46 -51
- data/lib/merb-auth-more.rb +3 -1
- data/lib/merb-auth-more/mixins/bcrypt_user.rb +72 -0
- data/lib/merb-auth-more/mixins/redirect_back.rb +1 -1
- data/lib/merb-auth-more/mixins/salted_user.rb +8 -8
- data/lib/merb-auth-more/mixins/salted_user/dm_salted_user.rb +5 -2
- data/lib/merb-auth-more/mixins/salted_user/relaxdb_salted_user.rb +5 -2
- data/lib/merb-auth-more/mixins/salted_user/sq_salted_user.rb +39 -18
- data/lib/merb-auth-more/strategies/basic/basic_auth.rb +1 -0
- data/lib/merb-auth-more/strategies/basic/openid.rb +1 -0
- data/lib/merb-auth-more/strategies/basic/password_form.rb +1 -0
- data/lib/merb-auth-more/version.rb +7 -0
- data/spec/mixins/dm_bcrypt_user_spec.rb +42 -0
- data/spec/mixins/dm_salted_user_spec.rb +42 -0
- data/spec/mixins/redirect_back_spec.rb +53 -32
- data/spec/mixins/sq_bcrypt_user_spec.rb +43 -0
- data/spec/mixins/sq_salted_user_spec.rb +44 -0
- data/spec/shared_user_spec.rb +117 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +29 -8
- metadata +55 -20
- data/spec/merb-auth-more_spec.rb +0 -4
- data/spec/mixins/salted_user_spec.rb +0 -105
data/Rakefile
CHANGED
|
@@ -1,59 +1,54 @@
|
|
|
1
|
-
require
|
|
2
|
-
|
|
3
|
-
RUBY_FORGE_PROJECT = "merb-auth"
|
|
4
|
-
GEM_NAME = "merb-auth-more"
|
|
5
|
-
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
|
6
|
-
GEM_VERSION = Merb::VERSION + PKG_BUILD
|
|
7
|
-
|
|
8
|
-
AUTHOR = "Daniel Neighman"
|
|
9
|
-
EMAIL = "has.sox@gmail.com"
|
|
10
|
-
HOMEPAGE = "http://merbivore.com/"
|
|
11
|
-
SUMMARY = "Additional resources for use with the merb-auth-core authentication framework."
|
|
12
|
-
|
|
13
|
-
spec = Gem::Specification.new do |s|
|
|
14
|
-
s.rubyforge_project = 'merb'
|
|
15
|
-
s.name = GEM_NAME
|
|
16
|
-
s.version = GEM_VERSION
|
|
17
|
-
s.platform = Gem::Platform::RUBY
|
|
18
|
-
s.has_rdoc = true
|
|
19
|
-
s.extra_rdoc_files = ["README.textile", "LICENSE", 'TODO']
|
|
20
|
-
s.summary = SUMMARY
|
|
21
|
-
s.description = s.summary
|
|
22
|
-
s.author = AUTHOR
|
|
23
|
-
s.email = EMAIL
|
|
24
|
-
s.homepage = HOMEPAGE
|
|
25
|
-
s.add_dependency("merb-auth-core", ">= #{Merb::VERSION}")
|
|
26
|
-
s.require_path = 'lib'
|
|
27
|
-
s.files = %w(LICENSE README.textile Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
|
|
28
|
-
|
|
29
|
-
end
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
30
3
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
end
|
|
4
|
+
# Load merb-auth-core version information
|
|
5
|
+
require File.expand_path('../../merb-auth-core/lib/merb-auth-core/version', __FILE__)
|
|
34
6
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
|
|
38
|
-
end
|
|
7
|
+
# Load this library's version information
|
|
8
|
+
require File.expand_path('../lib/merb-auth-more/version', __FILE__)
|
|
39
9
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
10
|
+
begin
|
|
11
|
+
|
|
12
|
+
gem 'jeweler', '~> 1.4'
|
|
13
|
+
require 'jeweler'
|
|
14
|
+
|
|
15
|
+
Jeweler::Tasks.new do |gemspec|
|
|
16
|
+
|
|
17
|
+
gemspec.version = Merb::Auth::More::VERSION.dup
|
|
18
|
+
|
|
19
|
+
gemspec.name = "merb-auth-more"
|
|
20
|
+
gemspec.description = "Addons for merb-auth-core"
|
|
21
|
+
gemspec.summary = "Additional resources for use with the merb-auth-core authentication framework."
|
|
22
|
+
|
|
23
|
+
gemspec.authors = [ "Daniel Neighman" ]
|
|
24
|
+
gemspec.email = "has.sox@gmail.com"
|
|
25
|
+
gemspec.homepage = "http://merbivore.com/"
|
|
26
|
+
|
|
27
|
+
gemspec.files = %w(LICENSE Rakefile README.textile TODO) + Dir['{lib,spec}/**/*']
|
|
28
|
+
|
|
29
|
+
# Runtime dependencies
|
|
30
|
+
gemspec.add_dependency 'merb-auth-core', "~> #{Merb::Auth::Core::VERSION}"
|
|
31
|
+
|
|
32
|
+
# Development dependencies
|
|
33
|
+
gemspec.add_development_dependency 'rspec', ">= 1.2.9"
|
|
44
34
|
|
|
45
|
-
desc "Create a gemspec file"
|
|
46
|
-
task :gemspec do
|
|
47
|
-
File.open("#{GEM_NAME}.gemspec", "w") do |file|
|
|
48
|
-
file.puts spec.to_ruby
|
|
49
35
|
end
|
|
36
|
+
|
|
37
|
+
Jeweler::GemcutterTasks.new
|
|
38
|
+
|
|
39
|
+
rescue LoadError
|
|
40
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
require 'spec/rake/spectask'
|
|
44
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
|
45
|
+
spec.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
|
|
46
|
+
spec.libs << 'lib' << 'spec'
|
|
47
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
|
50
48
|
end
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
t.rcov = false
|
|
57
|
-
t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
|
|
58
|
-
t.rcov_opts << '--only-uncovered'
|
|
50
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
|
51
|
+
spec.libs << 'lib' << 'spec'
|
|
52
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
|
53
|
+
spec.rcov = true
|
|
59
54
|
end
|
data/lib/merb-auth-more.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'merb-auth-core'
|
|
2
|
+
|
|
1
3
|
# make sure we're running inside Merb
|
|
2
4
|
if defined?(Merb::Plugins)
|
|
3
5
|
# Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
|
|
@@ -21,4 +23,4 @@ if defined?(Merb::Plugins)
|
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
Merb::Plugins.add_rakefiles "merb-auth-more/merbtasks"
|
|
24
|
-
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'bcrypt'
|
|
2
|
+
require 'merb-auth-more/strategies/abstract_password'
|
|
3
|
+
|
|
4
|
+
class Merb::Authentication
|
|
5
|
+
module Mixins
|
|
6
|
+
# This mixin provides basic salted user password encryption.
|
|
7
|
+
#
|
|
8
|
+
# Added properties:
|
|
9
|
+
# :crypted_password, String
|
|
10
|
+
#
|
|
11
|
+
# To use it simply require it and include it into your user class.
|
|
12
|
+
#
|
|
13
|
+
# class User
|
|
14
|
+
# include Merb::Authentication::Mixins::SaltedUser
|
|
15
|
+
#
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
module BCryptUser
|
|
19
|
+
|
|
20
|
+
def self.included(base)
|
|
21
|
+
base.class_eval do
|
|
22
|
+
attr_accessor :password, :password_confirmation
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
include Merb::Authentication::Mixins::BCryptUser::InstanceMethods
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
path = File.expand_path(File.dirname(__FILE__)) / "salted_user"
|
|
29
|
+
if defined?(DataMapper) && DataMapper::Resource > self
|
|
30
|
+
require path / "dm_salted_user"
|
|
31
|
+
extend(Merb::Authentication::Mixins::SaltedUser::DMClassMethods)
|
|
32
|
+
elsif defined?(ActiveRecord) && ancestors.include?(ActiveRecord::Base)
|
|
33
|
+
require path / "ar_salted_user"
|
|
34
|
+
extend(Merb::Authentication::Mixins::SaltedUser::ARClassMethods)
|
|
35
|
+
elsif defined?(Sequel) && ancestors.include?(Sequel::Model)
|
|
36
|
+
require path / "sq_salted_user"
|
|
37
|
+
extend(Merb::Authentication::Mixins::SaltedUser::SQClassMethods)
|
|
38
|
+
elsif defined?(RelaxDB) && ancestors.include?(RelaxDB::Document)
|
|
39
|
+
require path / "relaxdb_salted_user"
|
|
40
|
+
extend(Merb::Authentication::Mixins::SaltedUser::RDBClassMethods)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end # base.class_eval
|
|
44
|
+
end # self.included
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
module InstanceMethods
|
|
48
|
+
|
|
49
|
+
def authenticated?(password)
|
|
50
|
+
bcrypt_password == password
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def bcrypt_password
|
|
54
|
+
@bcrypt_password ||= BCrypt::Password.new(crypted_password)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def password_required?
|
|
58
|
+
crypted_password.blank? || !password.blank?
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def encrypt_password
|
|
62
|
+
return if password.blank?
|
|
63
|
+
cost = Merb::Plugins.config[:"merb-auth"][:bcrypt_cost] || BCrypt::Engine::DEFAULT_COST
|
|
64
|
+
self.crypted_password = BCrypt::Password.create(password, :cost => cost)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end # InstanceMethods
|
|
68
|
+
|
|
69
|
+
end # SaltedUser
|
|
70
|
+
end # Mixins
|
|
71
|
+
end # Merb::Authentication
|
|
72
|
+
|
|
@@ -51,7 +51,7 @@ module Merb::Authentication::Mixins
|
|
|
51
51
|
def _set_return_to
|
|
52
52
|
unless request.exceptions.blank?
|
|
53
53
|
session[:return_to] ||= []
|
|
54
|
-
session[:return_to] << request.uri
|
|
54
|
+
session[:return_to] << "#{Merb::Config[:path_prefix]}#{request.uri}"
|
|
55
55
|
session[:return_to]
|
|
56
56
|
end
|
|
57
57
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
require 'merb-auth-more/strategies/abstract_password'
|
|
3
3
|
|
|
4
4
|
class Merb::Authentication
|
|
5
5
|
module Mixins
|
|
@@ -25,18 +25,18 @@ class Merb::Authentication
|
|
|
25
25
|
include Merb::Authentication::Mixins::SaltedUser::InstanceMethods
|
|
26
26
|
extend Merb::Authentication::Mixins::SaltedUser::ClassMethods
|
|
27
27
|
|
|
28
|
-
path =
|
|
28
|
+
path = "merb-auth-more/mixins/salted_user"
|
|
29
29
|
if defined?(DataMapper) && DataMapper::Resource > self
|
|
30
|
-
require path
|
|
30
|
+
require "#{path}/dm_salted_user"
|
|
31
31
|
extend(Merb::Authentication::Mixins::SaltedUser::DMClassMethods)
|
|
32
32
|
elsif defined?(ActiveRecord) && ancestors.include?(ActiveRecord::Base)
|
|
33
|
-
require path
|
|
33
|
+
require "#{path}/ar_salted_user"
|
|
34
34
|
extend(Merb::Authentication::Mixins::SaltedUser::ARClassMethods)
|
|
35
35
|
elsif defined?(Sequel) && ancestors.include?(Sequel::Model)
|
|
36
|
-
require path
|
|
36
|
+
require "#{path}/sq_salted_user"
|
|
37
37
|
extend(Merb::Authentication::Mixins::SaltedUser::SQClassMethods)
|
|
38
38
|
elsif defined?(RelaxDB) && ancestors.include?(RelaxDB::Document)
|
|
39
|
-
require path
|
|
39
|
+
require "#{path}/relaxdb_salted_user"
|
|
40
40
|
extend(Merb::Authentication::Mixins::SaltedUser::RDBClassMethods)
|
|
41
41
|
end
|
|
42
42
|
|
|
@@ -66,7 +66,7 @@ class Merb::Authentication
|
|
|
66
66
|
|
|
67
67
|
def encrypt_password
|
|
68
68
|
return if password.blank?
|
|
69
|
-
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{Merb::Authentication::Strategies::Basic::Base.login_param}--") if
|
|
69
|
+
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{Merb::Authentication::Strategies::Basic::Base.login_param}--") if salt.blank?
|
|
70
70
|
self.crypted_password = encrypt(password)
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -4,9 +4,12 @@ class Merb::Authentication
|
|
|
4
4
|
module DMClassMethods
|
|
5
5
|
def self.extended(base)
|
|
6
6
|
base.class_eval do
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
property :crypted_password, String, :length => 60
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
if Merb::Authentication::Mixins::SaltedUser > base
|
|
11
|
+
property :salt, String
|
|
12
|
+
end
|
|
10
13
|
|
|
11
14
|
validates_present :password, :if => proc{|m| m.password_required?}
|
|
12
15
|
validates_is_confirmed :password, :if => proc{|m| m.password_required?}
|
|
@@ -1,21 +1,48 @@
|
|
|
1
|
+
require 'merb_sequel'
|
|
2
|
+
|
|
1
3
|
class Merb::Authentication
|
|
2
4
|
module Mixins
|
|
3
5
|
module SaltedUser
|
|
6
|
+
|
|
7
|
+
module SQ3Hooks
|
|
8
|
+
def before_save
|
|
9
|
+
return false if super == false
|
|
10
|
+
encrypt_password
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module SQ3Validations
|
|
15
|
+
def validate
|
|
16
|
+
validates_presence(:password) if password_required?
|
|
17
|
+
validates_presence(:password_confirmation) if password_required?
|
|
18
|
+
errors.add(:password, "Passwords are not the same") if password != password_confirmation
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
module SQInstanceMethods
|
|
23
|
+
unless Sequel::Model.instance_methods.include?(:new_record?)
|
|
24
|
+
def new_record?
|
|
25
|
+
self.new?
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
if Merb::Orms::Sequel.new_sequel?
|
|
30
|
+
include Merb::Authentication::Mixins::SaltedUser::SQ3Hooks
|
|
31
|
+
include Merb::Authentication::Mixins::SaltedUser::SQ3Validations
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
4
35
|
module SQClassMethods
|
|
5
|
-
|
|
6
36
|
def self.extended(base)
|
|
7
37
|
base.class_eval do
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
end # base.class_eval
|
|
18
|
-
|
|
38
|
+
unless Merb::Orms::Sequel.new_sequel?
|
|
39
|
+
before_save :encrypt_password
|
|
40
|
+
validates_presence_of :password, :if => :password_required?
|
|
41
|
+
validates_presence_of :password_confirmation, :if => :password_required?
|
|
42
|
+
validates_confirmation_of :password, :if => :password_required?
|
|
43
|
+
end
|
|
44
|
+
include Merb::Authentication::Mixins::SaltedUser::SQInstanceMethods
|
|
45
|
+
end
|
|
19
46
|
end # self.extended
|
|
20
47
|
|
|
21
48
|
def authenticate(login, password)
|
|
@@ -24,12 +51,6 @@ class Merb::Authentication
|
|
|
24
51
|
end
|
|
25
52
|
end # SQClassMethods
|
|
26
53
|
|
|
27
|
-
module SQInstanceMethods
|
|
28
|
-
def new_record?
|
|
29
|
-
new?
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
54
|
end # SaltedUser
|
|
34
55
|
end # Mixins
|
|
35
56
|
end # Merb::Authentication
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'dm-core'
|
|
3
|
+
require 'dm-validations'
|
|
4
|
+
require 'merb-auth-more/mixins/bcrypt_user'
|
|
5
|
+
|
|
6
|
+
describe "A DataMapper Bcrypt User" do
|
|
7
|
+
|
|
8
|
+
include UserHelper
|
|
9
|
+
|
|
10
|
+
before(:all) do
|
|
11
|
+
|
|
12
|
+
DataMapper.setup(:default, "sqlite3::memory:")
|
|
13
|
+
|
|
14
|
+
class DataMapperBcryptUser
|
|
15
|
+
|
|
16
|
+
include DataMapper::Resource
|
|
17
|
+
include Merb::Authentication::Mixins::BCryptUser
|
|
18
|
+
|
|
19
|
+
property :id, Serial
|
|
20
|
+
property :email, String
|
|
21
|
+
property :login, String
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
DataMapper.auto_migrate!
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
before(:each) do
|
|
30
|
+
@user_class = DataMapperBcryptUser
|
|
31
|
+
@user_class.create(valid_user_params)
|
|
32
|
+
@new_user = @user_class.new(valid_user_params)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
after(:each) do
|
|
36
|
+
DataMapperBcryptUser.all.destroy!
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it_should_behave_like 'every encrypted user'
|
|
40
|
+
it_should_behave_like 'every bcrypt user'
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'dm-core'
|
|
3
|
+
require 'dm-validations'
|
|
4
|
+
require 'merb-auth-more/mixins/salted_user'
|
|
5
|
+
|
|
6
|
+
describe "A DataMapper Salted User" do
|
|
7
|
+
|
|
8
|
+
include UserHelper
|
|
9
|
+
|
|
10
|
+
before(:all) do
|
|
11
|
+
|
|
12
|
+
DataMapper.setup(:default, "sqlite3::memory:")
|
|
13
|
+
|
|
14
|
+
class DataMapperSaltedUser
|
|
15
|
+
|
|
16
|
+
include DataMapper::Resource
|
|
17
|
+
include Merb::Authentication::Mixins::SaltedUser
|
|
18
|
+
|
|
19
|
+
property :id, Serial
|
|
20
|
+
property :email, String
|
|
21
|
+
property :login, String
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
DataMapper.auto_migrate!
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
before(:each) do
|
|
30
|
+
@user_class = DataMapperSaltedUser
|
|
31
|
+
@user_class.create(valid_user_params)
|
|
32
|
+
@new_user = @user_class.new(valid_user_params)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
after(:each) do
|
|
36
|
+
DataMapperSaltedUser.all.destroy!
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it_should_behave_like 'every encrypted user'
|
|
40
|
+
it_should_behave_like 'every salted user'
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -1,5 +1,43 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'merb-auth-more/mixins/redirect_back'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
describe "every call to redirect_back", :shared => true do
|
|
6
|
+
|
|
7
|
+
it "should set the return_to in the session when sent to the exceptions controller from a failed login" do
|
|
8
|
+
r = request("/go_back")
|
|
9
|
+
r.status.should == Merb::Controller::Unauthenticated.status
|
|
10
|
+
r2 = login
|
|
11
|
+
r2.should redirect_to(@return_to_after_failed_login)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should not set the return_to in the session when deliberately going to unauthenticated" do
|
|
15
|
+
r = login
|
|
16
|
+
r.should redirect_to("/")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should still redirect to the original even if it's failed many times" do
|
|
20
|
+
request("/go_back")
|
|
21
|
+
request("/login", :method => "put", :params => {:pass_auth => false})
|
|
22
|
+
request("/login", :method => "put", :params => {:pass_auth => false})
|
|
23
|
+
request("/login", :method => "put", :params => {:pass_auth => false})
|
|
24
|
+
r = login
|
|
25
|
+
r.should redirect_to(@return_to_after_failed_login)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should not redirect back to a previous redirect back after being logged out" do
|
|
29
|
+
request("/go_back")
|
|
30
|
+
request("/login", :method => "put", :params => {:pass_auth => false})
|
|
31
|
+
request("/login", :method => "put", :params => {:pass_auth => false})
|
|
32
|
+
request("/login", :method => "put", :params => {:pass_auth => false})
|
|
33
|
+
r = login
|
|
34
|
+
r.should redirect_to(@return_to_after_failed_login)
|
|
35
|
+
request("/logout", :method => "delete")
|
|
36
|
+
r = login
|
|
37
|
+
r.should redirect_to("/")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
3
41
|
|
|
4
42
|
describe "redirect_back" do
|
|
5
43
|
|
|
@@ -60,38 +98,21 @@ describe "redirect_back" do
|
|
|
60
98
|
def login
|
|
61
99
|
request("/login", :method => "put", :params => {:pass_auth => true})
|
|
62
100
|
end
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
it "should not set the return_to in the session when deliberately going to unauthenticated" do
|
|
72
|
-
r = login
|
|
73
|
-
r.should redirect_to("/")
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
it "should still redirect to the original even if it's failed many times" do
|
|
77
|
-
request("/go_back")
|
|
78
|
-
request("/login", :method => "put", :params => {:pass_auth => false})
|
|
79
|
-
request("/login", :method => "put", :params => {:pass_auth => false})
|
|
80
|
-
request("/login", :method => "put", :params => {:pass_auth => false})
|
|
81
|
-
r = login
|
|
82
|
-
r.should redirect_to("/go_back")
|
|
101
|
+
|
|
102
|
+
describe "without Merb::Config[:path_prefix]" do
|
|
103
|
+
before(:all) do
|
|
104
|
+
Merb::Config[:path_prefix] = nil
|
|
105
|
+
@return_to_after_failed_login = '/go_back'
|
|
106
|
+
end
|
|
107
|
+
it_should_behave_like 'every call to redirect_back'
|
|
83
108
|
end
|
|
84
109
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
r.should redirect_to("/go_back")
|
|
92
|
-
request("/logout", :method => "delete")
|
|
93
|
-
r = login
|
|
94
|
-
r.should redirect_to("/")
|
|
110
|
+
describe "without Merb::Config[:path_prefix]" do
|
|
111
|
+
before(:all) do
|
|
112
|
+
Merb::Config[:path_prefix] = '/myapp'
|
|
113
|
+
@return_to_after_failed_login = '/myapp/go_back'
|
|
114
|
+
end
|
|
115
|
+
it_should_behave_like 'every call to redirect_back'
|
|
95
116
|
end
|
|
96
117
|
|
|
97
118
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'sequel'
|
|
3
|
+
require 'merb_sequel'
|
|
4
|
+
require 'merb-auth-more/mixins/bcrypt_user'
|
|
5
|
+
|
|
6
|
+
DB = Sequel.sqlite unless Object.const_defined?('DB')
|
|
7
|
+
|
|
8
|
+
describe "A Sequel Bcrypt User" do
|
|
9
|
+
|
|
10
|
+
include UserHelper
|
|
11
|
+
|
|
12
|
+
before(:all) do
|
|
13
|
+
|
|
14
|
+
DB.drop_table(:users) if DB.table_exists? :users
|
|
15
|
+
DB.create_table :users do
|
|
16
|
+
primary_key :id
|
|
17
|
+
column :email, :string
|
|
18
|
+
column :login, :string
|
|
19
|
+
column :crypted_password, :string
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class SequelBcryptUser < Sequel::Model
|
|
23
|
+
set_dataset :users
|
|
24
|
+
plugin(:validation_helpers) if Merb::Orms::Sequel.new_sequel?
|
|
25
|
+
include Merb::Authentication::Mixins::BCryptUser
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
before(:each) do
|
|
31
|
+
@user_class = SequelBcryptUser
|
|
32
|
+
@user_class.create(valid_user_params)
|
|
33
|
+
@new_user = @user_class.new(valid_user_params)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
after(:each) do
|
|
37
|
+
SequelBcryptUser.delete
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it_should_behave_like 'every encrypted user'
|
|
41
|
+
it_should_behave_like 'every bcrypt user'
|
|
42
|
+
|
|
43
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'sequel'
|
|
3
|
+
require 'merb_sequel'
|
|
4
|
+
require 'merb-auth-more/mixins/salted_user'
|
|
5
|
+
|
|
6
|
+
DB = Sequel.sqlite unless Object.const_defined?('DB')
|
|
7
|
+
|
|
8
|
+
describe "A Sequel Salted User" do
|
|
9
|
+
|
|
10
|
+
include UserHelper
|
|
11
|
+
|
|
12
|
+
before(:all) do
|
|
13
|
+
|
|
14
|
+
DB.drop_table(:users) if DB.table_exists? :users
|
|
15
|
+
DB.create_table :users do
|
|
16
|
+
primary_key :id
|
|
17
|
+
column :email, :string
|
|
18
|
+
column :login, :string
|
|
19
|
+
column :crypted_password, :string
|
|
20
|
+
column :salt, :string
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class SequelSaltedUser < Sequel::Model
|
|
24
|
+
set_dataset :users
|
|
25
|
+
plugin(:validation_helpers) if Merb::Orms::Sequel.new_sequel?
|
|
26
|
+
include Merb::Authentication::Mixins::SaltedUser
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
before(:each) do
|
|
32
|
+
@user_class = SequelSaltedUser
|
|
33
|
+
@user_class.create(valid_user_params)
|
|
34
|
+
@new_user = @user_class.new(valid_user_params)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
after(:each) do
|
|
38
|
+
SequelSaltedUser.delete
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it_should_behave_like 'every encrypted user'
|
|
42
|
+
it_should_behave_like 'every salted user'
|
|
43
|
+
|
|
44
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module UserHelper
|
|
4
|
+
|
|
5
|
+
def valid_login
|
|
6
|
+
'fred'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def valid_email
|
|
10
|
+
'fred@example.com'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def valid_password
|
|
14
|
+
'sekrit'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def valid_user_params
|
|
18
|
+
{
|
|
19
|
+
:login => valid_login,
|
|
20
|
+
:email => valid_email,
|
|
21
|
+
:password => valid_password,
|
|
22
|
+
:password_confirmation => valid_password
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "every encrypted user", :shared => true do
|
|
29
|
+
|
|
30
|
+
describe "class" do
|
|
31
|
+
|
|
32
|
+
it "should authenticate valid credentials" do
|
|
33
|
+
@user_class.authenticate(valid_login, valid_password).should_not be_nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should not authenticate an invalid login and an existing password" do
|
|
37
|
+
@user_class.authenticate("not_the_login", valid_password).should be_nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should not authenticate a valid login and an invalid password" do
|
|
41
|
+
@user_class.authenticate(valid_login, "not_the_password").should be_nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should not authenticate an invalid login and an unknown password" do
|
|
45
|
+
@user_class.authenticate("i_dont_exist", "not_the_password").should be_nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe "instance" do
|
|
51
|
+
|
|
52
|
+
it { @new_user.should respond_to(:password) }
|
|
53
|
+
it { @new_user.should respond_to(:password_confirmation) }
|
|
54
|
+
it { @new_user.should respond_to(:crypted_password) }
|
|
55
|
+
|
|
56
|
+
it "should require a password if a #password_required? returns true" do
|
|
57
|
+
@new_user.password = nil
|
|
58
|
+
@new_user.password_required?.should be_true
|
|
59
|
+
@new_user.should_not be_valid
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should require a password_confirmation if #password_required? returns true" do
|
|
63
|
+
@new_user.password_confirmation = nil
|
|
64
|
+
@new_user.password_required?.should be_true
|
|
65
|
+
@new_user.should_not be_valid
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should not require a password when saving an existing user" do
|
|
69
|
+
user = @user_class.first(:login => valid_login)
|
|
70
|
+
user.password.should be_nil
|
|
71
|
+
user.password_confirmation.should be_nil
|
|
72
|
+
user.login = "some_different_login_to_allow_saving"
|
|
73
|
+
user.save
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should authenticate a user instance against a valid password" do
|
|
77
|
+
@user_class.first(:login => valid_login).should be_authenticated(valid_password)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
describe 'every salted user', :shared => true do
|
|
85
|
+
|
|
86
|
+
it { @new_user.should respond_to(:salt) }
|
|
87
|
+
|
|
88
|
+
it "should set the salt" do
|
|
89
|
+
@new_user.salt.should be_nil
|
|
90
|
+
@new_user.send(:encrypt_password)
|
|
91
|
+
@new_user.salt.should_not be_nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "should set the salt even when user is not new record but salt is blank" do
|
|
95
|
+
@new_user.save
|
|
96
|
+
@new_user.salt = nil
|
|
97
|
+
@new_user.send(:encrypt_password)
|
|
98
|
+
@new_user.salt.should_not be_nil
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe 'every bcrypt user', :shared => true do
|
|
104
|
+
|
|
105
|
+
it "should create a valid Bcrypt password" do
|
|
106
|
+
lambda { @new_user.bcrypt_password }.should raise_error(BCrypt::Errors::InvalidHash)
|
|
107
|
+
@new_user.send(:encrypt_password)
|
|
108
|
+
lambda { @new_user.bcrypt_password }.should_not raise_error(BCrypt::Errors::InvalidHash)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should use the cost set in Merb::Plugins.config[:'merb-auth'][:bcrypt_cost]" do
|
|
112
|
+
Merb::Plugins.config[:'merb-auth'][:bcrypt_cost] = 6
|
|
113
|
+
@new_user.send(:encrypt_password)
|
|
114
|
+
@new_user.bcrypt_password.cost.should == 6
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
CHANGED
|
@@ -1,17 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
|
1
|
+
require "rubygems"
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
# Use current merb-core sources if running from a typical dev checkout.
|
|
4
|
+
lib = File.expand_path('../../../../merb/merb-core/lib', __FILE__)
|
|
5
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib)
|
|
5
6
|
require 'merb-core'
|
|
6
7
|
require 'merb-core/test'
|
|
7
8
|
require 'merb-core/dispatch/session'
|
|
8
|
-
|
|
9
|
+
|
|
10
|
+
# Use current merb-auth-core sources if running from a typical dev checkout.
|
|
11
|
+
lib = File.expand_path('../../../merb-auth-core/lib', __FILE__)
|
|
12
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib)
|
|
9
13
|
require 'merb-auth-core'
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
# Use current merb_sequel sources if running from a typical dev checkout.
|
|
16
|
+
lib = File.expand_path('../../../../merb_sequel/lib', __FILE__)
|
|
17
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib)
|
|
18
|
+
require 'merb_sequel'
|
|
19
|
+
|
|
20
|
+
# The lib under test
|
|
21
|
+
require "merb-auth-more"
|
|
22
|
+
|
|
23
|
+
# Satisfies Autotest and anyone else not using the Rake tasks
|
|
24
|
+
require 'spec'
|
|
25
|
+
|
|
26
|
+
require 'shared_user_spec'
|
|
27
|
+
|
|
28
|
+
$TESTING=true
|
|
29
|
+
|
|
30
|
+
Merb.start(
|
|
31
|
+
:environment => "test",
|
|
32
|
+
:adapter => "runner",
|
|
33
|
+
:session_store => "cookie",
|
|
34
|
+
:session_secret_key => "d3a6e6f99a25004da82b71af8b9ed0ab71d3ea21"
|
|
35
|
+
)
|
|
15
36
|
|
|
16
37
|
module StrategyHelper
|
|
17
38
|
def clear_strategies!
|
metadata
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: merb-auth-more
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
4
|
+
prerelease: true
|
|
5
|
+
segments:
|
|
6
|
+
- 1
|
|
7
|
+
- 1
|
|
8
|
+
- 0
|
|
9
|
+
- pre
|
|
10
|
+
version: 1.1.0.pre
|
|
5
11
|
platform: ruby
|
|
6
12
|
authors:
|
|
7
13
|
- Daniel Neighman
|
|
@@ -9,75 +15,104 @@ autorequire:
|
|
|
9
15
|
bindir: bin
|
|
10
16
|
cert_chain: []
|
|
11
17
|
|
|
12
|
-
date:
|
|
18
|
+
date: 2010-02-21 00:00:00 +00:00
|
|
13
19
|
default_executable:
|
|
14
20
|
dependencies:
|
|
15
21
|
- !ruby/object:Gem::Dependency
|
|
16
22
|
name: merb-auth-core
|
|
23
|
+
prerelease: false
|
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ~>
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
segments:
|
|
29
|
+
- 1
|
|
30
|
+
- 1
|
|
31
|
+
- 0
|
|
32
|
+
- pre
|
|
33
|
+
version: 1.1.0.pre
|
|
17
34
|
type: :runtime
|
|
18
|
-
|
|
19
|
-
|
|
35
|
+
version_requirements: *id001
|
|
36
|
+
- !ruby/object:Gem::Dependency
|
|
37
|
+
name: rspec
|
|
38
|
+
prerelease: false
|
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
20
40
|
requirements:
|
|
21
41
|
- - ">="
|
|
22
42
|
- !ruby/object:Gem::Version
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
43
|
+
segments:
|
|
44
|
+
- 1
|
|
45
|
+
- 2
|
|
46
|
+
- 9
|
|
47
|
+
version: 1.2.9
|
|
48
|
+
type: :development
|
|
49
|
+
version_requirements: *id002
|
|
50
|
+
description: Addons for merb-auth-core
|
|
26
51
|
email: has.sox@gmail.com
|
|
27
52
|
executables: []
|
|
28
53
|
|
|
29
54
|
extensions: []
|
|
30
55
|
|
|
31
56
|
extra_rdoc_files:
|
|
32
|
-
- README.textile
|
|
33
57
|
- LICENSE
|
|
58
|
+
- README.textile
|
|
34
59
|
- TODO
|
|
35
60
|
files:
|
|
36
61
|
- LICENSE
|
|
37
62
|
- README.textile
|
|
38
63
|
- Rakefile
|
|
39
64
|
- TODO
|
|
65
|
+
- lib/merb-auth-more.rb
|
|
40
66
|
- lib/merb-auth-more/merbtasks.rb
|
|
67
|
+
- lib/merb-auth-more/mixins/bcrypt_user.rb
|
|
41
68
|
- lib/merb-auth-more/mixins/redirect_back.rb
|
|
69
|
+
- lib/merb-auth-more/mixins/salted_user.rb
|
|
42
70
|
- lib/merb-auth-more/mixins/salted_user/ar_salted_user.rb
|
|
43
71
|
- lib/merb-auth-more/mixins/salted_user/dm_salted_user.rb
|
|
44
72
|
- lib/merb-auth-more/mixins/salted_user/relaxdb_salted_user.rb
|
|
45
73
|
- lib/merb-auth-more/mixins/salted_user/sq_salted_user.rb
|
|
46
|
-
- lib/merb-auth-more/mixins/salted_user.rb
|
|
47
74
|
- lib/merb-auth-more/strategies/abstract_password.rb
|
|
48
75
|
- lib/merb-auth-more/strategies/basic/basic_auth.rb
|
|
49
76
|
- lib/merb-auth-more/strategies/basic/openid.rb
|
|
50
77
|
- lib/merb-auth-more/strategies/basic/password_form.rb
|
|
51
|
-
- lib/merb-auth-more.rb
|
|
52
|
-
- spec/
|
|
78
|
+
- lib/merb-auth-more/version.rb
|
|
79
|
+
- spec/mixins/dm_bcrypt_user_spec.rb
|
|
80
|
+
- spec/mixins/dm_salted_user_spec.rb
|
|
53
81
|
- spec/mixins/redirect_back_spec.rb
|
|
54
|
-
- spec/mixins/
|
|
82
|
+
- spec/mixins/sq_bcrypt_user_spec.rb
|
|
83
|
+
- spec/mixins/sq_salted_user_spec.rb
|
|
84
|
+
- spec/shared_user_spec.rb
|
|
85
|
+
- spec/spec.opts
|
|
55
86
|
- spec/spec_helper.rb
|
|
56
87
|
has_rdoc: true
|
|
57
88
|
homepage: http://merbivore.com/
|
|
58
89
|
licenses: []
|
|
59
90
|
|
|
60
91
|
post_install_message:
|
|
61
|
-
rdoc_options:
|
|
62
|
-
|
|
92
|
+
rdoc_options:
|
|
93
|
+
- --charset=UTF-8
|
|
63
94
|
require_paths:
|
|
64
95
|
- lib
|
|
65
96
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
66
97
|
requirements:
|
|
67
98
|
- - ">="
|
|
68
99
|
- !ruby/object:Gem::Version
|
|
100
|
+
segments:
|
|
101
|
+
- 0
|
|
69
102
|
version: "0"
|
|
70
|
-
version:
|
|
71
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
104
|
requirements:
|
|
73
|
-
- - "
|
|
105
|
+
- - ">"
|
|
74
106
|
- !ruby/object:Gem::Version
|
|
75
|
-
|
|
76
|
-
|
|
107
|
+
segments:
|
|
108
|
+
- 1
|
|
109
|
+
- 3
|
|
110
|
+
- 1
|
|
111
|
+
version: 1.3.1
|
|
77
112
|
requirements: []
|
|
78
113
|
|
|
79
|
-
rubyforge_project:
|
|
80
|
-
rubygems_version: 1.3.
|
|
114
|
+
rubyforge_project:
|
|
115
|
+
rubygems_version: 1.3.6
|
|
81
116
|
signing_key:
|
|
82
117
|
specification_version: 3
|
|
83
118
|
summary: Additional resources for use with the merb-auth-core authentication framework.
|
data/spec/merb-auth-more_spec.rb
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
require File.join(File.dirname(__FILE__), "..", 'spec_helper.rb')
|
|
2
|
-
require 'dm-core'
|
|
3
|
-
require 'dm-validations'
|
|
4
|
-
require File.join(File.expand_path(File.dirname(__FILE__)), "..", ".." ,"lib", "merb-auth-more", "strategies", "abstract_password")
|
|
5
|
-
require File.join(File.expand_path(File.dirname(__FILE__)), "..", ".." ,"lib", "merb-auth-more", "mixins", "salted_user")
|
|
6
|
-
|
|
7
|
-
describe "A Salted User" do
|
|
8
|
-
|
|
9
|
-
before(:all) do
|
|
10
|
-
DataMapper.setup(:default, "sqlite3::memory:")
|
|
11
|
-
|
|
12
|
-
class Utilisateur
|
|
13
|
-
include DataMapper::Resource
|
|
14
|
-
include Merb::Authentication::Mixins::SaltedUser
|
|
15
|
-
|
|
16
|
-
property :id, Serial
|
|
17
|
-
property :email, String
|
|
18
|
-
property :login, String
|
|
19
|
-
end
|
|
20
|
-
Utilisateur.auto_migrate!
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
after(:each) do
|
|
24
|
-
Utilisateur.all.destroy!
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def default_user_params
|
|
28
|
-
{:login => "fred", :email => "fred@example.com", :password => "sekrit", :password_confirmation => "sekrit"}
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "should authenticate a user using a class method" do
|
|
32
|
-
user = Utilisateur.new(default_user_params)
|
|
33
|
-
user.save
|
|
34
|
-
user.should_not be_new_record
|
|
35
|
-
Utilisateur.authenticate("fred", "sekrit").should_not be_nil
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it "should not authenticate a user using the wrong password" do
|
|
39
|
-
user = Utilisateur.new(default_user_params)
|
|
40
|
-
user.save
|
|
41
|
-
Utilisateur.authenticate("fred", "not_the_password").should be_nil
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "should not authenticate a user using the wrong login" do
|
|
45
|
-
user = Utilisateur.create(default_user_params)
|
|
46
|
-
Utilisateur.authenticate("not_the_login@blah.com", "sekrit").should be_nil
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it "should not authenticate a user that does not exist" do
|
|
50
|
-
Utilisateur.authenticate("i_dont_exist", "password").should be_nil
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
describe "passwords" do
|
|
54
|
-
before(:each) do
|
|
55
|
-
@user = Utilisateur.new(default_user_params)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
it{@user.should respond_to(:password)}
|
|
59
|
-
it{@user.should respond_to(:password_confirmation)}
|
|
60
|
-
it{@user.should respond_to(:crypted_password)}
|
|
61
|
-
|
|
62
|
-
it "should require password if password is required" do
|
|
63
|
-
user = Utilisateur.new(:login => "fred", :email => "fred@example.com")
|
|
64
|
-
user.stub!(:password_required?).and_return(true)
|
|
65
|
-
user.valid?
|
|
66
|
-
user.errors.on(:password).should_not be_nil
|
|
67
|
-
user.errors.on(:password).should_not be_empty
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it "should set the salt" do
|
|
71
|
-
@user.salt.should be_nil
|
|
72
|
-
@user.send(:encrypt_password)
|
|
73
|
-
@user.salt.should_not be_nil
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
it "should require the password on create" do
|
|
77
|
-
user = Utilisateur.new(:login => "fred", :email => "fred@example.com")
|
|
78
|
-
user.save
|
|
79
|
-
user.errors.on(:password).should_not be_nil
|
|
80
|
-
user.errors.on(:password).should_not be_empty
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it "should require password_confirmation if the password_required?" do
|
|
84
|
-
user = Utilisateur.new(:login => "fred", :email => "fred@example.com", :password => "sekrit")
|
|
85
|
-
user.save
|
|
86
|
-
(user.errors.on(:password) || user.errors.on(:password_confirmation)).should_not be_nil
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "should autenticate against a password" do
|
|
90
|
-
@user.save
|
|
91
|
-
@user.should be_authenticated("sekrit")
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
it "should not require a password when saving an existing user" do
|
|
95
|
-
@user.save
|
|
96
|
-
@user.should_not be_a_new_record
|
|
97
|
-
@user = Utilisateur.first(:login => "fred")
|
|
98
|
-
@user.password.should be_nil
|
|
99
|
-
@user.password_confirmation.should be_nil
|
|
100
|
-
@user.login = "some_different_login_to_allow_saving"
|
|
101
|
-
(@user.save).should be_true
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
end
|
|
105
|
-
end
|