warden_strategies 0.1.0
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/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +48 -0
- data/lib/warden_strategies.rb +15 -0
- data/lib/warden_strategies/authlogic.rb +35 -0
- data/lib/warden_strategies/base.rb +14 -0
- data/lib/warden_strategies/bcrypt.rb +27 -0
- data/lib/warden_strategies/bcrypt/active_record.rb +28 -0
- data/lib/warden_strategies/bcrypt/base.rb +37 -0
- data/lib/warden_strategies/simple.rb +141 -0
- data/spec/helpers/request_helper.rb +10 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/warden_strategies/base_spec.rb +24 -0
- data/spec/warden_strategies/simple_spec.rb +169 -0
- metadata +83 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Daniel Neighman
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
= warden_strategies
|
2
|
+
|
3
|
+
A collection of warden strategies.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but
|
13
|
+
bump version in a commit by itself I can ignore when I pull)
|
14
|
+
* Send me a pull request. Bonus points for topic branches.
|
15
|
+
|
16
|
+
== Copyright
|
17
|
+
|
18
|
+
Copyright (c) 2009 Daniel Neighman. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "warden_strategies"
|
8
|
+
gem.summary = %Q{A collection of strategies for Warden}
|
9
|
+
gem.description = %Q{A collection of basic warden strategies}
|
10
|
+
gem.email = "has.sox@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/hassox/warden_strategies"
|
12
|
+
gem.authors = ["Daniel Neighman"]
|
13
|
+
gem.add_development_dependency "rspec"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'spec/rake/spectask'
|
21
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
22
|
+
spec.libs << 'lib' << 'spec'
|
23
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
24
|
+
end
|
25
|
+
|
26
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
27
|
+
spec.libs << 'lib' << 'spec'
|
28
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
29
|
+
spec.rcov = true
|
30
|
+
end
|
31
|
+
|
32
|
+
task :spec => :check_dependencies
|
33
|
+
|
34
|
+
task :default => :spec
|
35
|
+
|
36
|
+
require 'rake/rdoctask'
|
37
|
+
Rake::RDocTask.new do |rdoc|
|
38
|
+
if File.exist?('VERSION')
|
39
|
+
version = File.read('VERSION')
|
40
|
+
else
|
41
|
+
version = ""
|
42
|
+
end
|
43
|
+
|
44
|
+
rdoc.rdoc_dir = 'rdoc'
|
45
|
+
rdoc.title = "warden_strategies #{version}"
|
46
|
+
rdoc.rdoc_files.include('README*')
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'warden'
|
2
|
+
$:.push(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
module WardenStrategies
|
5
|
+
autoload :Base, "warden_strategies/base"
|
6
|
+
autoload :Simple, "warden_strategies/simple"
|
7
|
+
autoload :Bcrypt, "warden_strategies/bcrypt"
|
8
|
+
|
9
|
+
module Mixins
|
10
|
+
module Bcrypt
|
11
|
+
autoload :Base, "warden_strategies/bcrypt/base"
|
12
|
+
autoload :ActiveRecord, "warden_strategies/bcrypt/active_record"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
Rails.configuration.middleware.use RailsWarden::Manager do |manager|
|
2
|
+
manager.default_strategies :bcrypt
|
3
|
+
manager.failure_app = SessionsController
|
4
|
+
end
|
5
|
+
|
6
|
+
# Setup Session Serialization
|
7
|
+
Warden::Manager.serialize_into_session{ |user| [user.class, user.id] }
|
8
|
+
Warden::Manager.serialize_from_session{ |klass, id| klass.find(id) }
|
9
|
+
|
10
|
+
Warden::Strategies.add(:bcrypt) do
|
11
|
+
def valid?
|
12
|
+
params["username"] || params["password"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def authenticate!
|
16
|
+
return fail! unless user = User.find_by_login(params["username"])
|
17
|
+
|
18
|
+
if user.crypted_password == "#{params["password"]}#{user.password_salt}"
|
19
|
+
success!(user)
|
20
|
+
else
|
21
|
+
errors.add(:login, "Username or Password incorrect")
|
22
|
+
fail!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Warden::Manager.after_authentication do |user, auth, opts|
|
28
|
+
old_current = user.current_login_at
|
29
|
+
old_current ||= user.current_login_at = DateTime.now
|
30
|
+
user.last_login_at = old_current
|
31
|
+
user.current_login_at = DateTime.now
|
32
|
+
user.login_count = 0 if user.login_count.nil?
|
33
|
+
user.login_count += 1
|
34
|
+
user.save(false)
|
35
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module WardenStrategies
|
2
|
+
class Base < Warden::Strategies::Base
|
3
|
+
|
4
|
+
# Provides access to a user class.
|
5
|
+
# this should be overwritten in sub-classes to provde access
|
6
|
+
# to particular user classes
|
7
|
+
#
|
8
|
+
# @return A class to use as the "User" class for the request to use
|
9
|
+
# @api overwritable
|
10
|
+
def user_class
|
11
|
+
User
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module WardenStrategies
|
2
|
+
|
3
|
+
# Create a migration for the following fields:
|
4
|
+
# _crypted_password - String
|
5
|
+
# _password_salt - String
|
6
|
+
#
|
7
|
+
# Then include WardenStrategies::Bcrypt::Mixins::ActiveRecord
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# class MyClass < ActiveRecord::Base
|
11
|
+
# include WardenStrategies::Bcrypt::Mixins::ActiveRecord
|
12
|
+
# end
|
13
|
+
class Bcrypt < WardenStrategies::Simple
|
14
|
+
module Mixins
|
15
|
+
autoload :Base, "warden_strategies/bcrypt/base"
|
16
|
+
autoload :ActiveRecord, "warden_strategies/bcrypt/active_record"
|
17
|
+
end
|
18
|
+
|
19
|
+
config do |c|
|
20
|
+
c[:required_params] = [:login, :password]
|
21
|
+
c[:authenticate_method] = :authenticate_with_bcrypt
|
22
|
+
c[:error_message] = "Username or Password incorrect"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Warden::Strategies.add(:simple_bcypt, WardenStrategies::Bcrypt)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module WardenStrategies
|
2
|
+
class Bcrypt
|
3
|
+
|
4
|
+
module Mixins
|
5
|
+
module ActiveRecord
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
extend WardenStrategies::Bcrypt::Mixins::ActiveRecord::ClassMethods
|
9
|
+
include WardenStrategies::Bcrypt::Mixins::Base
|
10
|
+
|
11
|
+
attr_accessor :password, :password_confirmation
|
12
|
+
|
13
|
+
validates_presence_of :crypted_password, :on => :update, :if => :has_no_credentials?
|
14
|
+
validates_confirmation_of :password, :if => :password
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def authenticate_with_bcrypt(login, password)
|
20
|
+
user = self.find_by_login(login)
|
21
|
+
return nil unless user
|
22
|
+
user.crypted_password == "#{password}#{user.password_salt}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module WardenStrategies
|
2
|
+
class Bcypt
|
3
|
+
module Mixins
|
4
|
+
module Base
|
5
|
+
def password=(pass)
|
6
|
+
@password = pass
|
7
|
+
unless pass.blank?
|
8
|
+
self._crypted_password = pass.nil? ? nil : ::BCrypt::Password.create("#{pass}#{password_salt}", :cost => 10)
|
9
|
+
end
|
10
|
+
@password
|
11
|
+
end
|
12
|
+
|
13
|
+
def crypted_password
|
14
|
+
@crypted_password ||= begin
|
15
|
+
ep = _crypted_password
|
16
|
+
ep.nil? ? nil : ::BCrypt::Password.new(ep)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def password_salt
|
21
|
+
@password_salt ||= begin
|
22
|
+
pws = _password_salt
|
23
|
+
pws.nil? ? (self._password_salt = Digest::SHA512.hexdigest(unique_token)) : pws
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def has_no_credentials?
|
28
|
+
self._crypted_password.blank?
|
29
|
+
end
|
30
|
+
|
31
|
+
def unique_token
|
32
|
+
Time.now.to_s + (1..10).collect{ rand.to_s }.join
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module WardenStrategies
|
2
|
+
|
3
|
+
# The Simple strategy is a strategy that will accept a simple list of requried parameters, a user class
|
4
|
+
# an authenticate_method and an error message and use those to authenticate a "user"
|
5
|
+
#
|
6
|
+
# The following example will create a strategy that will check an account for a user login
|
7
|
+
# with the Account class using the authenitcate_account_holder method.
|
8
|
+
#
|
9
|
+
# for the given params "login" => "fred", "password => "sekrit", "account" => "main"
|
10
|
+
# The following would be called if all parameters are present
|
11
|
+
# Account.authenticate_account_holder("fred", "sekrit", "main")
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# class AccountStrategy < WardenStrategies::Base
|
15
|
+
# config.merge!(
|
16
|
+
# :user_class => Account,
|
17
|
+
# :authenticate_method => :authenticate_account_holder,
|
18
|
+
# :required_params => [:login, :password, :account]
|
19
|
+
# )
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Warden::Strategies.add(:account, AccountStrategy)
|
23
|
+
#
|
24
|
+
# # calls Account.authenticate_account_holder("login_param", "password_param", "account_param")
|
25
|
+
#
|
26
|
+
# @see WardenStrategies::Simple.config
|
27
|
+
class Simple < WardenStrategies::Base
|
28
|
+
|
29
|
+
# Sets the configuration for this strategy.
|
30
|
+
#
|
31
|
+
# The config will return and yeild a hash (if a block is given) with the configuration for this strategy.
|
32
|
+
# The following options are available
|
33
|
+
#
|
34
|
+
# :user_class
|
35
|
+
# :required_params
|
36
|
+
# :authenticate_method
|
37
|
+
# :error_message
|
38
|
+
#
|
39
|
+
# :user_class option will set the class for this strategy. If no user class is defined the super classes user_class method is called instead. Default - User
|
40
|
+
#
|
41
|
+
# :required_params is an array of required params that must be present for this strategy to run. Once the strategy is run, then these parameters are passed to the :authenticate_method in the order specified.
|
42
|
+
# The params can be specified as a symbol, a string, or a nested param. To specify a nested param seperate the string with a :
|
43
|
+
# Default []
|
44
|
+
#
|
45
|
+
# :authenticate_method specifies the method to call on the user_class when all the parameters are present
|
46
|
+
# Default :authenticate
|
47
|
+
#
|
48
|
+
# :error_message specifies the error message to call when the strategy fails (providing it's valid)
|
49
|
+
# Default "Could not login"
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# class MyStrategy < WardenStrategies::Simple
|
53
|
+
# config do |c|
|
54
|
+
# c[:required_params] = [:login, :password]
|
55
|
+
# c[:authenticate_method] = :authenticate_with_password
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# @api public
|
59
|
+
def self.config
|
60
|
+
@config ||= {
|
61
|
+
:authenticate_method => :authenticate,
|
62
|
+
:error_message => "Could not login"
|
63
|
+
}
|
64
|
+
yield @config if block_given?
|
65
|
+
@config
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the configured required_params for this class
|
69
|
+
# @api public
|
70
|
+
# @see WardenStrategies::Simple.config
|
71
|
+
def self.required_params
|
72
|
+
config[:required_params] ||= []
|
73
|
+
end
|
74
|
+
|
75
|
+
# Provides access to the required param for this class
|
76
|
+
# @see WardenStrategies::Simple.required_params
|
77
|
+
# @api public
|
78
|
+
def required_params
|
79
|
+
self.class.required_params
|
80
|
+
end
|
81
|
+
|
82
|
+
# Provides access to the User class for this strategy
|
83
|
+
# @see WardenStrategies::Simple.config
|
84
|
+
# @api public
|
85
|
+
def user_class
|
86
|
+
config[:user_class] || super
|
87
|
+
end
|
88
|
+
|
89
|
+
# Sets used in strategy selection. Returns true if all required_params are available in the request
|
90
|
+
# @return true if all valid params are returned false otherwise
|
91
|
+
# @see Warden::Strategy::Base#valid?
|
92
|
+
# @api private
|
93
|
+
def valid?
|
94
|
+
required_param_values.nil? ? false : !required_param_values.include?(nil)
|
95
|
+
end
|
96
|
+
|
97
|
+
# The workhorse. Will pass all requred_param_values to the configured authenticate_method
|
98
|
+
# @see WardenStrategies::Simple.config
|
99
|
+
# @see Warden::Strategy::Base#authenticate!
|
100
|
+
# @api private
|
101
|
+
def authenticate!
|
102
|
+
if u = user_class.send(config[:authenticate_method], *required_param_values)
|
103
|
+
success!(u)
|
104
|
+
else
|
105
|
+
fail!(config[:error_message])
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return the values of the required params for the required_params, or nil if one of the params is not found
|
110
|
+
# @api public
|
111
|
+
def required_param_values
|
112
|
+
result = required_params.map do |val|
|
113
|
+
r = extract_value_from_params(val)
|
114
|
+
break if r.nil?
|
115
|
+
r
|
116
|
+
end
|
117
|
+
result
|
118
|
+
end
|
119
|
+
|
120
|
+
# Provides access to the config hash for this strategy
|
121
|
+
def config
|
122
|
+
self.class.config
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
def extract_value_from_params(key)
|
127
|
+
case key
|
128
|
+
when String, Symbol
|
129
|
+
keys = key.to_s.split(":")
|
130
|
+
if keys.size == 1
|
131
|
+
params[keys.first]
|
132
|
+
else
|
133
|
+
keys.inject(params){|p,k| p[k]}
|
134
|
+
end
|
135
|
+
when Proc
|
136
|
+
instance_eval(&key)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module WardenStrategies
|
2
|
+
module Spec
|
3
|
+
def env_with_params(path = "/", params = {})
|
4
|
+
method = params.fetch(:method, "GET")
|
5
|
+
Rack::MockRequest.env_for(path, :input => Rack::Utils.build_query(params),
|
6
|
+
'HTTP_VERSION' => '1.1',
|
7
|
+
'REQUEST_METHOD' => "#{method}")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'rack'
|
4
|
+
require 'warden_strategies'
|
5
|
+
require 'spec'
|
6
|
+
require 'spec/autorun'
|
7
|
+
|
8
|
+
Dir[File.join(File.dirname(__FILE__), "helpers", "**/*.rb")].each do |f|
|
9
|
+
require f
|
10
|
+
end
|
11
|
+
|
12
|
+
Spec::Runner.configure do |config|
|
13
|
+
config.include(WardenStrategies::Spec)
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe WardenStrategies::Base do
|
4
|
+
before do
|
5
|
+
@env = Rack::MockRequest.env_for("/")
|
6
|
+
class ::User; end
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should allow me to get the User class by default" do
|
10
|
+
s = WardenStrategies::Base.new(@env, scope = :default)
|
11
|
+
s.user_class.should == User
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should allow me to get this in a subclass" do
|
15
|
+
class ::AStrategy < WardenStrategies::Base
|
16
|
+
end
|
17
|
+
|
18
|
+
s = AStrategy.new(@env)
|
19
|
+
s.user_class.should == User
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
+
|
3
|
+
describe WardenStrategies::Simple do
|
4
|
+
before do
|
5
|
+
@env = Rack::MockRequest.env_for("/", :input => Rack::Utils.build_query(
|
6
|
+
:name => "Homer", "foo[bar]" => "baz"
|
7
|
+
))
|
8
|
+
class ::User; end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should setup the spec correctly" do
|
12
|
+
req = Rack::Request.new(@env)
|
13
|
+
req.params["name"].should == "Homer"
|
14
|
+
req.params["foo"]["bar"].should == "baz"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should provide me with a configuration hash" do
|
18
|
+
WardenStrategies::Simple.config.should be_a_kind_of(Hash)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should allow me to specify the configuration via a block" do
|
22
|
+
WardenStrategies::Simple.config do |c|
|
23
|
+
c[:stuff] = :stuff
|
24
|
+
end
|
25
|
+
WardenStrategies::Simple.config[:stuff].should == :stuff
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "required params" do
|
29
|
+
before do
|
30
|
+
class SimpleFoo < WardenStrategies::Simple
|
31
|
+
config[:required_params] = [:login, :password]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should set simple symbol or string required params" do
|
36
|
+
SimpleFoo.config[:required_params] = [:login, "password"]
|
37
|
+
SimpleFoo.required_params.should == [:login, "password"]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should provide me with access to the required params at an instance level" do
|
41
|
+
SimpleFoo.config[:required_params] = [:login, "password"]
|
42
|
+
SimpleFoo.new(@env).required_params.should == [:login, "password"]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should provide the required param values from the required params" do
|
46
|
+
env = env_with_params("/", :login => "foo", :password => "bar")
|
47
|
+
SimpleFoo.config[:required_params] = [:login, "password"]
|
48
|
+
s = SimpleFoo.new(env).required_param_values.should == ["foo", "bar"]
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set nested_params with a single value" do
|
52
|
+
env = env_with_params("/", :login => "foo", "foo[bar]" => "baz")
|
53
|
+
SimpleFoo.config[:required_params] = [:login, "foo:bar"]
|
54
|
+
s = SimpleFoo.new(env).required_param_values.should == ["foo", "baz"]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should set deeply nested params" do
|
58
|
+
env = env_with_params("/", :login => "foo", "foo[bar][baz]" => "paz")
|
59
|
+
SimpleFoo.config[:required_params] = [:login, "foo:bar:baz"]
|
60
|
+
s = SimpleFoo.new(env).required_param_values.should == ["foo", "paz"]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should set rediculously deeply nested params" do
|
64
|
+
env = env_with_params("/", :login => "foo", "foo[bar][baz][paz][soz][kaz]" => "homer")
|
65
|
+
SimpleFoo.config[:required_params] = [:login, "foo:bar:baz:paz:soz:kaz"]
|
66
|
+
s = SimpleFoo.new(env).required_param_values.should == ["foo", "homer"]
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should set a nested param as a proc" do
|
70
|
+
env = env_with_params("/", :login => "foo", "sammy" => "barry")
|
71
|
+
SimpleFoo.config[:required_params] = [:login, Proc.new{ params["sammy"] }]
|
72
|
+
s = SimpleFoo.new(env).required_param_values.should == ["foo", "barry"]
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should be valid if all required params are found" do
|
76
|
+
env = env_with_params("/", :login => "foo", "sammy" => "barry")
|
77
|
+
SimpleFoo.config[:required_params] = [:login, :sammy]
|
78
|
+
s = SimpleFoo.new(env).should be_valid
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should be invalid if all required params are not found" do
|
82
|
+
env = env_with_params("/", :login => "foo")
|
83
|
+
SimpleFoo.config[:required_params] = [:login, :bar]
|
84
|
+
s = SimpleFoo.new(env).should_not be_valid
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should be valid with no required_params set" do
|
88
|
+
env = env_with_params("/")
|
89
|
+
SimpleFoo.config[:required_params] = nil
|
90
|
+
s = SimpleFoo.new(env).should be_valid
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should be valid with an emtpy array for a required_params" do
|
94
|
+
env = env_with_params("/")
|
95
|
+
SimpleFoo.config[:required_params] = []
|
96
|
+
s = SimpleFoo.new(env).should be_valid
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should be invalid with a nested param missing" do
|
100
|
+
env = env_with_params("/")
|
101
|
+
SimpleFoo.config[:required_params] = [:login, "foo:bar:baz"]
|
102
|
+
s = SimpleFoo.new(env).should_not be_valid
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "validating a strategy" do
|
107
|
+
before do
|
108
|
+
class SimpleFoo < WardenStrategies::Simple; end
|
109
|
+
class ::User
|
110
|
+
def self.authenticate(login)
|
111
|
+
login == "fred"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
app = lambda do |env|
|
116
|
+
env['warden'].authenticate!
|
117
|
+
Rack::Response.new("OK").finish
|
118
|
+
end
|
119
|
+
|
120
|
+
fail_app = lambda do |env|
|
121
|
+
Rack::Response.new("FAIL").finish
|
122
|
+
end
|
123
|
+
|
124
|
+
Warden::Strategies.add(:simple, SimpleFoo)
|
125
|
+
|
126
|
+
@app = Rack::Builder.new do
|
127
|
+
use Rack::Session::Cookie
|
128
|
+
use Warden::Manager do |manager|
|
129
|
+
manager.default_strategies :simple
|
130
|
+
manager.failure_app = fail_app
|
131
|
+
end
|
132
|
+
run app
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
after do
|
137
|
+
Warden::Strategies.clear!
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should validate a class by supplying the required params to the authenticate method" do
|
141
|
+
env = env_with_params("/", :login => "fred")
|
142
|
+
SimpleFoo.config[:required_params] = [:login]
|
143
|
+
s = SimpleFoo.new(env)
|
144
|
+
User.should_receive(:authenticate).with("fred").and_return("fred")
|
145
|
+
s.authenticate!
|
146
|
+
s.result.should == :success
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should fail the validation if the param is nil or false" do
|
150
|
+
env = env_with_params("/")
|
151
|
+
SimpleFoo.config[:required_params] = [:login]
|
152
|
+
s = SimpleFoo.new(env)
|
153
|
+
s.should_not be_valid
|
154
|
+
User.should_not_receive(:authenticate)
|
155
|
+
@app.call(env)
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should validate with a different return method" do
|
159
|
+
env = env_with_params("/", :login => "fred")
|
160
|
+
SimpleFoo.config[:required_params] = [:login]
|
161
|
+
SimpleFoo.config[:authenticate_method] = :authenticate_for_fred
|
162
|
+
User.should_receive(:authenticate_for_fred).and_return("fred")
|
163
|
+
s = SimpleFoo.new(env)
|
164
|
+
s.should be_valid
|
165
|
+
result = @app.call(env)
|
166
|
+
result[2].body.should include("OK")
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: warden_strategies
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Neighman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-25 00:00:00 +11:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: A collection of basic warden strategies
|
26
|
+
email: has.sox@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- .document
|
36
|
+
- .gitignore
|
37
|
+
- LICENSE
|
38
|
+
- README.rdoc
|
39
|
+
- Rakefile
|
40
|
+
- lib/warden_strategies.rb
|
41
|
+
- lib/warden_strategies/authlogic.rb
|
42
|
+
- lib/warden_strategies/base.rb
|
43
|
+
- lib/warden_strategies/bcrypt.rb
|
44
|
+
- lib/warden_strategies/bcrypt/active_record.rb
|
45
|
+
- lib/warden_strategies/bcrypt/base.rb
|
46
|
+
- lib/warden_strategies/simple.rb
|
47
|
+
- spec/helpers/request_helper.rb
|
48
|
+
- spec/spec_helper.rb
|
49
|
+
- spec/warden_strategies/base_spec.rb
|
50
|
+
- spec/warden_strategies/simple_spec.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://github.com/hassox/warden_strategies
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options:
|
57
|
+
- --charset=UTF-8
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: "0"
|
71
|
+
version:
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.3.5
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: A collection of strategies for Warden
|
79
|
+
test_files:
|
80
|
+
- spec/helpers/request_helper.rb
|
81
|
+
- spec/spec_helper.rb
|
82
|
+
- spec/warden_strategies/base_spec.rb
|
83
|
+
- spec/warden_strategies/simple_spec.rb
|