devise 1.1.pre4 → 1.1.rc0
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/CHANGELOG.rdoc +31 -2
- data/Gemfile +15 -6
- data/README.rdoc +12 -16
- data/Rakefile +2 -2
- data/TODO +2 -1
- data/app/controllers/devise/confirmations_controller.rb +1 -1
- data/app/controllers/devise/passwords_controller.rb +2 -3
- data/app/controllers/devise/registrations_controller.rb +5 -5
- data/app/controllers/devise/sessions_controller.rb +5 -27
- data/app/controllers/devise/unlocks_controller.rb +9 -1
- data/app/models/devise/mailer.rb +17 -11
- data/app/views/devise/confirmations/new.html.erb +1 -1
- data/app/views/devise/passwords/edit.html.erb +1 -1
- data/app/views/devise/passwords/new.html.erb +1 -1
- data/app/views/devise/registrations/edit.html.erb +2 -2
- data/app/views/devise/registrations/new.html.erb +2 -2
- data/app/views/devise/sessions/new.html.erb +2 -2
- data/app/views/devise/shared/_links.erb +5 -5
- data/app/views/devise/unlocks/new.html.erb +1 -1
- data/config/locales/en.yml +4 -9
- data/lib/devise.rb +83 -42
- data/lib/devise/controllers/helpers.rb +6 -18
- data/lib/devise/controllers/internal_helpers.rb +11 -12
- data/lib/devise/controllers/scoped_views.rb +2 -2
- data/lib/devise/controllers/url_helpers.rb +1 -1
- data/lib/devise/failure_app.rb +56 -16
- data/lib/devise/hooks/activatable.rb +18 -6
- data/lib/devise/hooks/rememberable.rb +36 -27
- data/lib/devise/hooks/timeoutable.rb +1 -1
- data/lib/devise/hooks/trackable.rb +4 -2
- data/lib/devise/mapping.rb +19 -14
- data/lib/devise/models.rb +12 -3
- data/lib/devise/models/authenticatable.rb +19 -95
- data/lib/devise/models/confirmable.rb +14 -20
- data/lib/devise/models/database_authenticatable.rb +99 -0
- data/lib/devise/models/lockable.rb +53 -39
- data/lib/devise/models/recoverable.rb +3 -3
- data/lib/devise/models/rememberable.rb +5 -10
- data/lib/devise/models/token_authenticatable.rb +18 -25
- data/lib/devise/models/validatable.rb +14 -9
- data/lib/devise/modules.rb +7 -8
- data/lib/devise/orm/active_record.rb +1 -1
- data/lib/devise/orm/data_mapper.rb +20 -7
- data/lib/devise/orm/mongoid.rb +40 -0
- data/lib/devise/rails.rb +26 -3
- data/lib/devise/rails/routes.rb +18 -16
- data/lib/devise/rails/warden_compat.rb +2 -2
- data/lib/devise/schema.rb +45 -18
- data/lib/devise/strategies/authenticatable.rb +92 -21
- data/lib/devise/strategies/base.rb +6 -3
- data/lib/devise/strategies/database_authenticatable.rb +20 -0
- data/lib/devise/strategies/rememberable.rb +10 -6
- data/lib/devise/strategies/token_authenticatable.rb +28 -19
- data/lib/devise/test_helpers.rb +5 -1
- data/lib/devise/version.rb +1 -1
- data/lib/generators/devise/devise_generator.rb +15 -5
- data/lib/generators/devise/templates/migration.rb +2 -2
- data/lib/generators/devise_install/templates/devise.rb +37 -16
- data/lib/generators/devise_views/devise_views_generator.rb +51 -4
- data/test/controllers/helpers_test.rb +16 -8
- data/test/controllers/internal_helpers_test.rb +6 -1
- data/test/controllers/url_helpers_test.rb +10 -10
- data/test/devise_test.rb +13 -17
- data/test/encryptors_test.rb +2 -0
- data/test/failure_app_test.rb +72 -23
- data/test/integration/confirmable_test.rb +4 -4
- data/test/integration/{authenticatable_test.rb → database_authenticatable_test.rb} +35 -17
- data/test/integration/http_authenticatable_test.rb +3 -3
- data/test/integration/lockable_test.rb +28 -8
- data/test/integration/recoverable_test.rb +3 -3
- data/test/integration/registerable_test.rb +6 -4
- data/test/integration/rememberable_test.rb +11 -4
- data/test/integration/timeoutable_test.rb +4 -4
- data/test/integration/token_authenticatable_test.rb +46 -10
- data/test/integration/trackable_test.rb +2 -2
- data/test/mailers/confirmation_instructions_test.rb +5 -5
- data/test/mailers/reset_password_instructions_test.rb +5 -5
- data/test/mailers/unlock_instructions_test.rb +5 -5
- data/test/mapping_test.rb +15 -14
- data/test/models/confirmable_test.rb +9 -32
- data/test/models/{authenticatable_test.rb → database_authenticatable_test.rb} +2 -34
- data/test/models/lockable_test.rb +48 -66
- data/test/models/recoverable_test.rb +8 -8
- data/test/models/rememberable_test.rb +6 -28
- data/test/models/timeoutable_test.rb +1 -1
- data/test/models/token_authenticatable_test.rb +1 -8
- data/test/models/trackable_test.rb +1 -1
- data/test/models/validatable_test.rb +2 -2
- data/test/models_test.rb +16 -2
- data/test/orm/active_record.rb +1 -22
- data/test/orm/data_mapper.rb +1 -0
- data/test/orm/mongoid.rb +10 -0
- data/test/rails_app/app/active_record/admin.rb +1 -5
- data/test/rails_app/app/controllers/application_controller.rb +2 -0
- data/test/rails_app/app/controllers/sessions_controller.rb +1 -1
- data/test/rails_app/app/data_mapper/admin.rb +13 -0
- data/test/rails_app/app/data_mapper/user.rb +24 -0
- data/test/rails_app/app/mongoid/admin.rb +15 -0
- data/test/rails_app/app/mongoid/user.rb +21 -0
- data/test/rails_app/config/application.rb +10 -5
- data/test/rails_app/config/boot.rb +5 -1
- data/test/rails_app/config/initializers/devise.rb +1 -1
- data/test/rails_app/config/routes.rb +4 -1
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +27 -0
- data/test/rails_app/db/schema.rb +86 -0
- data/test/routes_test.rb +3 -3
- data/test/support/assertions.rb +2 -0
- data/test/support/helpers.rb +2 -0
- data/test/support/integration.rb +4 -7
- data/test/support/webrat/integrations/rails.rb +2 -1
- data/test/test_helper.rb +5 -2
- data/test/test_helpers_test.rb +4 -4
- metadata +36 -21
- data/lib/devise/models/http_authenticatable.rb +0 -19
- data/lib/devise/orm/mongo_mapper.rb +0 -49
- data/lib/devise/strategies/http_authenticatable.rb +0 -47
- data/test/models/http_authenticatable_test.rb +0 -19
- data/test/orm/mongo_mapper.rb +0 -12
- data/test/rails_app/app/mongo_mapper/admin.rb +0 -10
- data/test/rails_app/app/mongo_mapper/user.rb +0 -11
- data/test/rails_app/config/initializers/cookie_verification_secret.rb +0 -7
- data/test/rails_app/config/initializers/session_store.rb +0 -15
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Devise
|
|
2
|
+
module Orm
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Hook
|
|
5
|
+
def devise_modules_hook!
|
|
6
|
+
extend Schema
|
|
7
|
+
include ::Mongoid::Timestamps
|
|
8
|
+
include Compatibility
|
|
9
|
+
yield
|
|
10
|
+
return unless Devise.apply_schema
|
|
11
|
+
devise_modules.each { |m| send(m) if respond_to?(m, true) }
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Schema
|
|
16
|
+
include Devise::Schema
|
|
17
|
+
|
|
18
|
+
# Tell how to apply schema methods
|
|
19
|
+
def apply_schema(name, type, options={})
|
|
20
|
+
type = Time if type == DateTime
|
|
21
|
+
field name, { :type => type }.merge(options)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
module Compatibility
|
|
26
|
+
def save(validate = true)
|
|
27
|
+
if validate.is_a?(Hash) && validate.has_key?(:validate)
|
|
28
|
+
validate = validate[:validate]
|
|
29
|
+
end
|
|
30
|
+
super(validate)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Mongoid::Document::ClassMethods.class_eval do
|
|
38
|
+
include Devise::Models
|
|
39
|
+
include Devise::Orm::Mongoid::Hook
|
|
40
|
+
end
|
data/lib/devise/rails.rb
CHANGED
|
@@ -3,10 +3,33 @@ require 'devise/rails/warden_compat'
|
|
|
3
3
|
|
|
4
4
|
module Devise
|
|
5
5
|
class Engine < ::Rails::Engine
|
|
6
|
-
|
|
6
|
+
config.devise = Devise
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
initializer "devise.add_middleware" do |app|
|
|
9
|
+
app.config.middleware.use Warden::Manager do |config|
|
|
10
|
+
Devise.warden_config = config
|
|
11
|
+
config.failure_app = Devise::FailureApp
|
|
12
|
+
config.default_scope = Devise.default_scope
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
initializer "devise.add_url_helpers" do |app|
|
|
17
|
+
Devise::FailureApp.send :include, app.routes.url_helpers
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
config.after_initialize do
|
|
21
|
+
I18n.available_locales
|
|
22
|
+
flash = [:unauthenticated, :unconfirmed, :invalid, :invalid_token, :timeout, :inactive, :locked]
|
|
23
|
+
|
|
24
|
+
I18n.backend.send(:translations).each do |locale, translations|
|
|
25
|
+
keys = flash & (translations[:devise][:sessions].keys) rescue []
|
|
26
|
+
|
|
27
|
+
if keys.any?
|
|
28
|
+
ActiveSupport::Deprecation.warn "The following I18n messages in 'devise.sessions' " <<
|
|
29
|
+
"for locale '#{locale}' are deprecated: #{keys.to_sentence}. Please move them to " <<
|
|
30
|
+
"'devise.failure' instead."
|
|
31
|
+
end
|
|
32
|
+
end
|
|
10
33
|
end
|
|
11
34
|
end
|
|
12
35
|
end
|
data/lib/devise/rails/routes.rb
CHANGED
|
@@ -4,11 +4,9 @@ module ActionDispatch::Routing
|
|
|
4
4
|
# need devise_for mappings already declared to create filters and helpers.
|
|
5
5
|
def finalize_with_devise!
|
|
6
6
|
finalize_without_devise!
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
Devise.configure_warden!
|
|
9
8
|
ActionController::Base.send :include, Devise::Controllers::Helpers
|
|
10
9
|
ActionController::Base.send :include, Devise::Controllers::UrlHelpers
|
|
11
|
-
|
|
12
10
|
ActionView::Base.send :include, Devise::Controllers::UrlHelpers
|
|
13
11
|
end
|
|
14
12
|
alias_method_chain :finalize!, :devise
|
|
@@ -83,31 +81,35 @@ module ActionDispatch::Routing
|
|
|
83
81
|
#
|
|
84
82
|
# devise_for :users, :controllers => { :sessions => "users/sessions" }
|
|
85
83
|
#
|
|
84
|
+
# * :skip => tell which controller you want to skip routes from being created:
|
|
85
|
+
#
|
|
86
|
+
# devise_for :users, :skip => :sessions
|
|
87
|
+
#
|
|
86
88
|
def devise_for(*resources)
|
|
87
89
|
options = resources.extract_options!
|
|
88
90
|
resources.map!(&:to_sym)
|
|
89
91
|
|
|
90
92
|
resources.each do |resource|
|
|
91
|
-
mapping = Devise
|
|
93
|
+
mapping = Devise.register(resource, options)
|
|
92
94
|
|
|
93
95
|
unless mapping.to.respond_to?(:devise)
|
|
94
96
|
raise "#{mapping.to.name} does not respond to 'devise' method. This usually means you haven't " <<
|
|
95
|
-
"loaded your ORM file or it's being loaded
|
|
97
|
+
"loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' " <<
|
|
96
98
|
"inside 'config/initializers/devise.rb' or before your application definition in 'config/application.rb'"
|
|
97
99
|
end
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
+
routes = mapping.routes
|
|
102
|
+
routes -= Array(options.delete(:skip)).map { |s| s.to_s.singularize.to_sym }
|
|
101
103
|
|
|
102
|
-
|
|
103
|
-
send(mod, mapping, mapping.controllers)
|
|
104
|
+
routes.each do |mod|
|
|
105
|
+
send(:"devise_#{mod}", mapping, mapping.controllers)
|
|
104
106
|
end
|
|
105
107
|
end
|
|
106
108
|
end
|
|
107
109
|
|
|
108
110
|
protected
|
|
109
111
|
|
|
110
|
-
def
|
|
112
|
+
def devise_session(mapping, controllers)
|
|
111
113
|
scope mapping.path do
|
|
112
114
|
get mapping.path_names[:sign_in], :to => "#{controllers[:sessions]}#new", :as => :"new_#{mapping.name}_session"
|
|
113
115
|
post mapping.path_names[:sign_in], :to => "#{controllers[:sessions]}#create", :as => :"#{mapping.name}_session"
|
|
@@ -115,27 +117,27 @@ module ActionDispatch::Routing
|
|
|
115
117
|
end
|
|
116
118
|
end
|
|
117
119
|
|
|
118
|
-
def
|
|
120
|
+
def devise_password(mapping, controllers)
|
|
119
121
|
scope mapping.path, :name_prefix => mapping.name do
|
|
120
122
|
resource :password, :only => [:new, :create, :edit, :update], :as => mapping.path_names[:password], :controller => controllers[:passwords]
|
|
121
123
|
end
|
|
122
124
|
end
|
|
123
125
|
|
|
124
|
-
def
|
|
126
|
+
def devise_confirmation(mapping, controllers)
|
|
125
127
|
scope mapping.path, :name_prefix => mapping.name do
|
|
126
128
|
resource :confirmation, :only => [:new, :create, :show], :as => mapping.path_names[:confirmation], :controller => controllers[:confirmations]
|
|
127
129
|
end
|
|
128
130
|
end
|
|
129
131
|
|
|
130
|
-
def
|
|
132
|
+
def devise_unlock(mapping, controllers)
|
|
131
133
|
scope mapping.path, :name_prefix => mapping.name do
|
|
132
134
|
resource :unlock, :only => [:new, :create, :show], :as => mapping.path_names[:unlock], :controller => controllers[:unlocks]
|
|
133
135
|
end
|
|
134
136
|
end
|
|
135
137
|
|
|
136
|
-
def
|
|
137
|
-
scope :name_prefix => mapping.name do
|
|
138
|
-
resource :registration, :only => [:new, :create, :edit, :update, :destroy], :as =>
|
|
138
|
+
def devise_registration(mapping, controllers)
|
|
139
|
+
scope mapping.path[1..-1], :name_prefix => "#{mapping.name}_registration" do
|
|
140
|
+
resource :registration, :only => [:new, :create, :edit, :update, :destroy], :as => "",
|
|
139
141
|
:path_names => { :new => mapping.path_names[:sign_up] }, :controller => controllers[:registrations]
|
|
140
142
|
end
|
|
141
143
|
end
|
data/lib/devise/schema.rb
CHANGED
|
@@ -3,59 +3,86 @@ module Devise
|
|
|
3
3
|
# and overwrite the apply_schema method.
|
|
4
4
|
module Schema
|
|
5
5
|
|
|
6
|
+
def authenticatable(*args)
|
|
7
|
+
ActiveSupport::Deprecation.warn "t.authenticatable in migrations is deprecated. Please use t.database_authenticatable instead.", caller
|
|
8
|
+
database_authenticatable(*args)
|
|
9
|
+
end
|
|
10
|
+
|
|
6
11
|
# Creates email, encrypted_password and password_salt.
|
|
7
12
|
#
|
|
8
13
|
# == Options
|
|
9
14
|
# * :null - When true, allow columns to be null.
|
|
10
|
-
# * :
|
|
11
|
-
def
|
|
12
|
-
null
|
|
13
|
-
default
|
|
14
|
-
|
|
15
|
+
# * :default - Should be set to "" when :null is false.
|
|
16
|
+
def database_authenticatable(options={})
|
|
17
|
+
null = options[:null] || false
|
|
18
|
+
default = options[:default] || ""
|
|
19
|
+
|
|
20
|
+
if options.delete(:encryptor)
|
|
21
|
+
ActiveSupport::Deprecation.warn ":encryptor as option is deprecated, simply remove it."
|
|
22
|
+
end
|
|
15
23
|
|
|
16
24
|
apply_schema :email, String, :null => null, :default => default
|
|
17
|
-
apply_schema :encrypted_password, String, :null => null, :default => default, :limit =>
|
|
25
|
+
apply_schema :encrypted_password, String, :null => null, :default => default, :limit => 128
|
|
18
26
|
apply_schema :password_salt, String, :null => null, :default => default
|
|
19
|
-
end
|
|
27
|
+
end
|
|
20
28
|
|
|
21
29
|
# Creates authentication_token.
|
|
22
|
-
def token_authenticatable
|
|
23
|
-
apply_schema :authentication_token, String
|
|
30
|
+
def token_authenticatable(options={})
|
|
31
|
+
apply_schema :authentication_token, String
|
|
24
32
|
end
|
|
25
33
|
|
|
26
34
|
# Creates confirmation_token, confirmed_at and confirmation_sent_at.
|
|
27
35
|
def confirmable
|
|
28
|
-
apply_schema :confirmation_token, String
|
|
36
|
+
apply_schema :confirmation_token, String
|
|
29
37
|
apply_schema :confirmed_at, DateTime
|
|
30
38
|
apply_schema :confirmation_sent_at, DateTime
|
|
31
39
|
end
|
|
32
40
|
|
|
33
41
|
# Creates reset_password_token.
|
|
34
42
|
def recoverable
|
|
35
|
-
apply_schema :reset_password_token, String
|
|
43
|
+
apply_schema :reset_password_token, String
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
# Creates remember_token and remember_created_at.
|
|
39
47
|
def rememberable
|
|
40
|
-
apply_schema :remember_token, String
|
|
48
|
+
apply_schema :remember_token, String
|
|
41
49
|
apply_schema :remember_created_at, DateTime
|
|
42
50
|
end
|
|
43
51
|
|
|
44
52
|
# Creates sign_in_count, current_sign_in_at, last_sign_in_at,
|
|
45
53
|
# current_sign_in_ip, last_sign_in_ip.
|
|
46
54
|
def trackable
|
|
47
|
-
apply_schema :sign_in_count, Integer
|
|
55
|
+
apply_schema :sign_in_count, Integer, :default => 0
|
|
48
56
|
apply_schema :current_sign_in_at, DateTime
|
|
49
57
|
apply_schema :last_sign_in_at, DateTime
|
|
50
58
|
apply_schema :current_sign_in_ip, String
|
|
51
59
|
apply_schema :last_sign_in_ip, String
|
|
52
60
|
end
|
|
53
61
|
|
|
54
|
-
# Creates failed_attempts, unlock_token and locked_at
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
# Creates failed_attempts, unlock_token and locked_at depending on the options given.
|
|
63
|
+
#
|
|
64
|
+
# == Options
|
|
65
|
+
# * :unlock_strategy - The strategy used for unlock. Can be :time, :email, :both (default), :none.
|
|
66
|
+
# If :email or :both, creates a unlock_token field.
|
|
67
|
+
# * :lock_strategy - The strategy used for locking. Can be :failed_attempts (default) or :none.
|
|
68
|
+
def lockable(options={})
|
|
69
|
+
unlock_strategy = options[:unlock_strategy]
|
|
70
|
+
unlock_strategy ||= self.unlock_strategy if respond_to?(:unlock_strategy)
|
|
71
|
+
unlock_strategy ||= :both
|
|
72
|
+
|
|
73
|
+
lock_strategy = options[:lock_strategy]
|
|
74
|
+
lock_strategy ||= self.lock_strategy if respond_to?(:lock_strategy)
|
|
75
|
+
lock_strategy ||= :failed_attempts
|
|
76
|
+
|
|
77
|
+
if lock_strategy == :failed_attempts
|
|
78
|
+
apply_schema :failed_attempts, Integer, :default => 0
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
if [:both, :email].include?(unlock_strategy)
|
|
82
|
+
apply_schema :unlock_token, String
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
apply_schema :locked_at, DateTime
|
|
59
86
|
end
|
|
60
87
|
|
|
61
88
|
# Overwrite with specific modification to create your own schema.
|
|
@@ -2,35 +2,106 @@ require 'devise/strategies/base'
|
|
|
2
2
|
|
|
3
3
|
module Devise
|
|
4
4
|
module Strategies
|
|
5
|
-
#
|
|
6
|
-
#
|
|
5
|
+
# This strategy should be used as basis for authentication strategies. It retrieves
|
|
6
|
+
# parameters both from params or from http authorization headers. See database_authenticatable
|
|
7
|
+
# for an example.
|
|
7
8
|
class Authenticatable < Base
|
|
9
|
+
attr_accessor :authentication_hash, :password
|
|
10
|
+
|
|
8
11
|
def valid?
|
|
9
|
-
|
|
12
|
+
valid_for_http_auth? || valid_for_params_auth?
|
|
10
13
|
end
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
#
|
|
15
|
-
def
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# Simply invokes valid_for_authentication? with the given block and deal with the result.
|
|
18
|
+
def validate(resource, &block)
|
|
19
|
+
result = resource && resource.valid_for_authentication?(&block)
|
|
20
|
+
|
|
21
|
+
case result
|
|
22
|
+
when Symbol, String
|
|
23
|
+
fail!(result)
|
|
18
24
|
else
|
|
19
|
-
|
|
20
|
-
end
|
|
25
|
+
result
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Check if this is strategy is valid for http authentication.
|
|
30
|
+
def valid_for_http_auth?
|
|
31
|
+
http_authenticatable? && request.authorization && with_authentication_hash(http_auth_hash)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Check if this is strategy is valid for params authentication.
|
|
35
|
+
def valid_for_params_auth?
|
|
36
|
+
params_authenticatable? && valid_request? &&
|
|
37
|
+
valid_params? && with_authentication_hash(params_auth_hash)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Check if the model accepts this strategy as http authenticatable.
|
|
41
|
+
def http_authenticatable?
|
|
42
|
+
mapping.to.http_authenticatable?(authenticatable_name)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Check if the model accepts this strategy as params authenticatable.
|
|
46
|
+
def params_authenticatable?
|
|
47
|
+
mapping.to.params_authenticatable?(authenticatable_name)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Extract the appropriate subhash for authentication from params.
|
|
51
|
+
def params_auth_hash
|
|
52
|
+
params[scope]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Extract a hash with attributes:values from the http params.
|
|
56
|
+
def http_auth_hash
|
|
57
|
+
keys = [authentication_keys.first, :password]
|
|
58
|
+
Hash[*keys.zip(decode_credentials).flatten]
|
|
21
59
|
end
|
|
22
60
|
|
|
23
|
-
|
|
61
|
+
# By default, a request is valid if the controller is allowed and the VERB is POST.
|
|
62
|
+
def valid_request?
|
|
63
|
+
valid_controller? && valid_verb?
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Check if the controller is valid for params authentication.
|
|
67
|
+
def valid_controller?
|
|
68
|
+
mapping.controllers[:sessions] == params[:controller]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Check if the params_auth_hash is valid for params authentication.
|
|
72
|
+
def valid_verb?
|
|
73
|
+
request.post?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# If the request is valid, finally check if params_auth_hash returns a hash.
|
|
77
|
+
def valid_params?
|
|
78
|
+
params_auth_hash.is_a?(Hash)
|
|
79
|
+
end
|
|
24
80
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
81
|
+
# Helper to decode credentials from HTTP.
|
|
82
|
+
def decode_credentials
|
|
83
|
+
username_and_password = request.authorization.split(' ', 2).last || ''
|
|
84
|
+
ActiveSupport::Base64.decode64(username_and_password).split(/:/, 2)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Sets the authentication hash and the password from params_auth_hash or http_auth_hash.
|
|
88
|
+
def with_authentication_hash(hash)
|
|
89
|
+
self.authentication_hash = hash.slice(*authentication_keys)
|
|
90
|
+
self.password = hash[:password]
|
|
91
|
+
authentication_keys.all?{ |k| authentication_hash[k].present? }
|
|
92
|
+
end
|
|
28
93
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
94
|
+
# Holds the authentication keys.
|
|
95
|
+
def authentication_keys
|
|
96
|
+
@authentication_keys ||= mapping.to.authentication_keys
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Holds the authenticatable name for this class. Devise::Strategies::DatabaseAuthenticatable
|
|
100
|
+
# becomes simply :database.
|
|
101
|
+
def authenticatable_name
|
|
102
|
+
@authenticatable_name ||=
|
|
103
|
+
self.class.name.split("::").last.underscore.sub("_authenticatable", "").to_sym
|
|
104
|
+
end
|
|
32
105
|
end
|
|
33
106
|
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
Warden::Strategies.add(:authenticatable, Devise::Strategies::Authenticatable)
|
|
107
|
+
end
|
|
@@ -2,8 +2,7 @@ module Devise
|
|
|
2
2
|
module Strategies
|
|
3
3
|
# Base strategy for Devise. Responsible for verifying correct scope and mapping.
|
|
4
4
|
class Base < ::Warden::Strategies::Base
|
|
5
|
-
# Checks if a valid scope was given for devise and find mapping based on
|
|
6
|
-
# this scope.
|
|
5
|
+
# Checks if a valid scope was given for devise and find mapping based on this scope.
|
|
7
6
|
def mapping
|
|
8
7
|
@mapping ||= begin
|
|
9
8
|
mapping = Devise.mappings[scope]
|
|
@@ -11,6 +10,10 @@ module Devise
|
|
|
11
10
|
mapping
|
|
12
11
|
end
|
|
13
12
|
end
|
|
13
|
+
|
|
14
|
+
def succeeded?
|
|
15
|
+
@result == :success
|
|
16
|
+
end
|
|
14
17
|
end
|
|
15
18
|
end
|
|
16
|
-
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'devise/strategies/authenticatable'
|
|
2
|
+
|
|
3
|
+
module Devise
|
|
4
|
+
module Strategies
|
|
5
|
+
# Default strategy for signing in a user, based on his email and password in the database.
|
|
6
|
+
class DatabaseAuthenticatable < Authenticatable
|
|
7
|
+
def authenticate!
|
|
8
|
+
resource = mapping.to.find_for_database_authentication(authentication_hash)
|
|
9
|
+
|
|
10
|
+
if validate(resource){ resource.valid_password?(password) }
|
|
11
|
+
success!(resource)
|
|
12
|
+
else
|
|
13
|
+
fail(:invalid)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
Warden::Strategies.add(:database_authenticatable, Devise::Strategies::DatabaseAuthenticatable)
|