devise-jdguyot 1.2.rc → 1.2.rc2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +22 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +49 -60
- data/MIT-LICENSE +1 -1
- data/README.rdoc +11 -2
- data/Rakefile +1 -3
- data/app/controllers/devise/registrations_controller.rb +2 -2
- data/lib/devise/controllers/helpers.rb +13 -6
- data/lib/devise/failure_app.rb +15 -4
- data/lib/devise/hooks/timeoutable.rb +1 -1
- data/lib/devise/models/authenticatable.rb +1 -1
- data/lib/devise/models/confirmable.rb +3 -3
- data/lib/devise/models/database_authenticatable.rb +4 -2
- data/lib/devise/models/encryptable.rb +1 -1
- data/lib/devise/models/lockable.rb +7 -5
- data/lib/devise/models/recoverable.rb +1 -1
- data/lib/devise/models/registerable.rb +1 -1
- data/lib/devise/schema.rb +3 -2
- data/lib/devise/test_helpers.rb +2 -2
- data/lib/devise/version.rb +1 -1
- data/lib/devise.rb +22 -5
- data/lib/generators/devise/views_generator.rb +4 -84
- data/lib/generators/templates/devise.rb +6 -2
- data/test/controllers/helpers_test.rb +3 -0
- data/test/failure_app_test.rb +1 -1
- data/test/integration/registerable_test.rb +30 -0
- data/test/integration/rememberable_test.rb +10 -0
- data/test/integration/token_authenticatable_test.rb +26 -5
- data/test/models/confirmable_test.rb +20 -3
- data/test/models/encryptable_test.rb +1 -1
- data/test/models/lockable_test.rb +2 -2
- data/test/models/recoverable_test.rb +11 -2
- data/test/models/token_authenticatable_test.rb +1 -0
- data/test/rails_app/config/initializers/devise.rb +5 -2
- data/test/schema_test.rb +33 -0
- data/test/test_helpers_test.rb +16 -0
- metadata +6 -26
data/CHANGELOG.rdoc
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
* enhancements
|
2
|
-
*
|
2
|
+
* Make friendly_token 20 chars long
|
3
|
+
* Use secure_compare
|
3
4
|
|
4
5
|
* bug fix
|
5
6
|
* Fix an issue causing infinite redirects in production
|
6
7
|
* rails g destroy works properly with devise generators (by github.com/andmej)
|
7
8
|
* before_failure callbacks should work on test helpers (by github.com/twinge)
|
8
9
|
* rememberable cookie now is httponly by default (by github.com/JamesFerguson)
|
10
|
+
* Add missing confirmation_keys (by github.com/JohnPlummer)
|
11
|
+
* Ensure after_* hooks are called on RegistrationsController
|
12
|
+
* When using database_authenticatable Devise will now only create an email field when appropriate (if using default authentication_keys or custom authentication_keys with email included)
|
13
|
+
* Ensure stateless token does not trigger timeout (by github.com/pixelauthority)
|
14
|
+
* Implement handle_unverified_request for Rails 3.0.4 compatibility and improve FailureApp reliance on symbols
|
9
15
|
|
10
16
|
* deprecations
|
11
17
|
* Deprecated anybody_signed_in? in favor of signed_in? (by github.com/gavinhughes)
|
18
|
+
* Removed --haml and --slim view templates
|
12
19
|
|
13
20
|
== 1.2.rc
|
14
21
|
|
@@ -48,6 +55,20 @@
|
|
48
55
|
* Ensure namespaces has proper scoped views
|
49
56
|
* Ensure Devise does not set empty flash messages (by github.com/sxross)
|
50
57
|
|
58
|
+
== 1.1.6
|
59
|
+
|
60
|
+
* Use a more secure e-mail regexp
|
61
|
+
* Implement Rails 3.0.4 handle unverified request
|
62
|
+
* Use secure_compare to compare passwords
|
63
|
+
|
64
|
+
== 1.1.5
|
65
|
+
|
66
|
+
* bugfix
|
67
|
+
* Ensure to convert keys on indifferent hash
|
68
|
+
|
69
|
+
* defaults
|
70
|
+
* Set config.http_authenticatable to false to avoid confusion
|
71
|
+
|
51
72
|
== 1.1.4
|
52
73
|
|
53
74
|
* bugfix
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
devise (1.2.rc)
|
4
|
+
devise-jdguyot (1.2.rc)
|
5
5
|
bcrypt-ruby (~> 2.1.2)
|
6
6
|
orm_adapter (~> 0.0.3)
|
7
7
|
warden (~> 1.0.3)
|
@@ -10,58 +10,52 @@ GEM
|
|
10
10
|
remote: http://rubygems.org/
|
11
11
|
specs:
|
12
12
|
abstract (1.0.0)
|
13
|
-
actionmailer (3.0.
|
14
|
-
actionpack (= 3.0.
|
15
|
-
mail (~> 2.2.
|
16
|
-
actionpack (3.0.
|
17
|
-
activemodel (= 3.0.
|
18
|
-
activesupport (= 3.0.
|
13
|
+
actionmailer (3.0.4)
|
14
|
+
actionpack (= 3.0.4)
|
15
|
+
mail (~> 2.2.15)
|
16
|
+
actionpack (3.0.4)
|
17
|
+
activemodel (= 3.0.4)
|
18
|
+
activesupport (= 3.0.4)
|
19
19
|
builder (~> 2.1.2)
|
20
20
|
erubis (~> 2.6.6)
|
21
21
|
i18n (~> 0.4)
|
22
22
|
rack (~> 1.2.1)
|
23
23
|
rack-mount (~> 0.6.13)
|
24
|
-
rack-test (~> 0.5.
|
24
|
+
rack-test (~> 0.5.7)
|
25
25
|
tzinfo (~> 0.3.23)
|
26
|
-
activemodel (3.0.
|
27
|
-
activesupport (= 3.0.
|
26
|
+
activemodel (3.0.4)
|
27
|
+
activesupport (= 3.0.4)
|
28
28
|
builder (~> 2.1.2)
|
29
29
|
i18n (~> 0.4)
|
30
|
-
activerecord (3.0.
|
31
|
-
activemodel (= 3.0.
|
32
|
-
activesupport (= 3.0.
|
30
|
+
activerecord (3.0.4)
|
31
|
+
activemodel (= 3.0.4)
|
32
|
+
activesupport (= 3.0.4)
|
33
33
|
arel (~> 2.0.2)
|
34
34
|
tzinfo (~> 0.3.23)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
addressable (2.2.2)
|
44
|
-
arel (2.0.4)
|
45
|
-
bcrypt-ruby (2.1.2)
|
46
|
-
bson (1.1.2)
|
35
|
+
activeresource (3.0.4)
|
36
|
+
activemodel (= 3.0.4)
|
37
|
+
activesupport (= 3.0.4)
|
38
|
+
activesupport (3.0.4)
|
39
|
+
addressable (2.2.4)
|
40
|
+
arel (2.0.8)
|
41
|
+
bcrypt-ruby (2.1.4)
|
42
|
+
bson (1.2.2)
|
47
43
|
bson_ext (1.1.2)
|
48
44
|
builder (2.1.2)
|
49
45
|
erubis (2.6.6)
|
50
46
|
abstract (>= 1.0.0)
|
51
|
-
faraday (0.5.
|
52
|
-
addressable (~> 2.2.
|
53
|
-
multipart-post (~> 1.0
|
47
|
+
faraday (0.5.6)
|
48
|
+
addressable (~> 2.2.4)
|
49
|
+
multipart-post (~> 1.1.0)
|
54
50
|
rack (>= 1.1.0, < 2)
|
55
|
-
i18n (0.
|
56
|
-
|
57
|
-
mail (2.2.10)
|
51
|
+
i18n (0.5.0)
|
52
|
+
mail (2.2.15)
|
58
53
|
activesupport (>= 2.3.6)
|
59
|
-
i18n (
|
54
|
+
i18n (>= 0.4.0)
|
60
55
|
mime-types (~> 1.16)
|
61
56
|
treetop (~> 1.4.8)
|
62
57
|
mime-types (1.16)
|
63
|
-
mocha (0.9.
|
64
|
-
rake
|
58
|
+
mocha (0.9.12)
|
65
59
|
mongo (1.1.2)
|
66
60
|
bson (>= 1.1.1)
|
67
61
|
mongoid (2.0.0.beta.20)
|
@@ -70,10 +64,8 @@ GEM
|
|
70
64
|
tzinfo (~> 0.3.22)
|
71
65
|
will_paginate (~> 3.0.pre)
|
72
66
|
multi_json (0.0.5)
|
73
|
-
multipart-post (1.0
|
74
|
-
nokogiri (1.4.
|
75
|
-
nokogiri (1.4.3.1-java)
|
76
|
-
weakling (>= 0.0.3)
|
67
|
+
multipart-post (1.1.0)
|
68
|
+
nokogiri (1.4.4)
|
77
69
|
oa-core (0.1.6)
|
78
70
|
rack (~> 1.1)
|
79
71
|
oa-oauth (0.1.6)
|
@@ -87,10 +79,10 @@ GEM
|
|
87
79
|
rack-openid (~> 1.2.0)
|
88
80
|
ruby-openid-apps-discovery
|
89
81
|
oauth (0.4.4)
|
90
|
-
oauth2 (0.1.
|
82
|
+
oauth2 (0.1.1)
|
91
83
|
faraday (~> 0.5.0)
|
92
84
|
multi_json (~> 0.0.4)
|
93
|
-
orm_adapter (0.0.
|
85
|
+
orm_adapter (0.0.4)
|
94
86
|
polyglot (0.3.1)
|
95
87
|
rack (1.2.1)
|
96
88
|
rack-mount (0.6.13)
|
@@ -98,33 +90,34 @@ GEM
|
|
98
90
|
rack-openid (1.2.0)
|
99
91
|
rack (>= 1.1.0)
|
100
92
|
ruby-openid (>= 2.1.8)
|
101
|
-
rack-test (0.5.
|
93
|
+
rack-test (0.5.7)
|
102
94
|
rack (>= 1.0)
|
103
|
-
rails (3.0.
|
104
|
-
actionmailer (= 3.0.
|
105
|
-
actionpack (= 3.0.
|
106
|
-
activerecord (= 3.0.
|
107
|
-
activeresource (= 3.0.
|
108
|
-
activesupport (= 3.0.
|
95
|
+
rails (3.0.4)
|
96
|
+
actionmailer (= 3.0.4)
|
97
|
+
actionpack (= 3.0.4)
|
98
|
+
activerecord (= 3.0.4)
|
99
|
+
activeresource (= 3.0.4)
|
100
|
+
activesupport (= 3.0.4)
|
109
101
|
bundler (~> 1.0)
|
110
|
-
railties (= 3.0.
|
111
|
-
railties (3.0.
|
112
|
-
actionpack (= 3.0.
|
113
|
-
activesupport (= 3.0.
|
102
|
+
railties (= 3.0.4)
|
103
|
+
railties (3.0.4)
|
104
|
+
actionpack (= 3.0.4)
|
105
|
+
activesupport (= 3.0.4)
|
114
106
|
rake (>= 0.8.7)
|
115
107
|
thor (~> 0.14.4)
|
116
108
|
rake (0.8.7)
|
117
109
|
ruby-openid (2.1.8)
|
118
110
|
ruby-openid-apps-discovery (1.2.0)
|
119
111
|
ruby-openid (>= 2.1.7)
|
120
|
-
sqlite3
|
112
|
+
sqlite3 (1.3.3)
|
113
|
+
sqlite3-ruby (1.3.3)
|
114
|
+
sqlite3 (>= 1.3.3)
|
121
115
|
thor (0.14.6)
|
122
116
|
treetop (1.4.9)
|
123
117
|
polyglot (>= 0.3.1)
|
124
|
-
tzinfo (0.3.
|
118
|
+
tzinfo (0.3.24)
|
125
119
|
warden (1.0.3)
|
126
120
|
rack (>= 1.0.0)
|
127
|
-
weakling (0.0.4-java)
|
128
121
|
webrat (0.7.2)
|
129
122
|
nokogiri (>= 1.2.0)
|
130
123
|
rack (>= 1.0)
|
@@ -132,21 +125,17 @@ GEM
|
|
132
125
|
will_paginate (3.0.pre2)
|
133
126
|
|
134
127
|
PLATFORMS
|
135
|
-
java
|
136
128
|
ruby
|
137
129
|
|
138
130
|
DEPENDENCIES
|
139
131
|
activerecord-jdbcsqlite3-adapter
|
140
|
-
bcrypt-ruby (~> 2.1.2)
|
141
132
|
bson_ext (= 1.1.2)
|
142
|
-
devise!
|
133
|
+
devise-jdguyot!
|
143
134
|
mocha
|
144
135
|
mongo (= 1.1.2)
|
145
136
|
mongoid (= 2.0.0.beta.20)
|
146
137
|
oa-oauth
|
147
138
|
oa-openid
|
148
|
-
|
149
|
-
rails (~> 3.0.0)
|
139
|
+
rails (~> 3.0.4)
|
150
140
|
sqlite3-ruby
|
151
|
-
warden (~> 1.0.3)
|
152
141
|
webrat (= 0.7.2)
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright 2009 Plataforma Tecnologia. http://blog.plataformatec.com.br
|
1
|
+
Copyright 2009-2011 Plataforma Tecnologia. http://blog.plataformatec.com.br
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
data/README.rdoc
CHANGED
@@ -9,7 +9,7 @@ Devise is a flexible authentication solution for Rails based on Warden. It:
|
|
9
9
|
|
10
10
|
It's composed of 12 modules:
|
11
11
|
|
12
|
-
* Database Authenticatable: encrypts and stores a password in the database to validate the authenticity of
|
12
|
+
* Database Authenticatable: encrypts and stores a password in the database to validate the authenticity of a user while signing in. The authentication can be done both through POST requests or HTTP Basic Authentication.
|
13
13
|
* Token Authenticatable: signs in a user based on an authentication token (also known as "single access token"). The token can be given both through query string or HTTP Basic Authentication.
|
14
14
|
* Omniauthable: adds Omniauth (github.com/intridea/omniauth) support;
|
15
15
|
* Confirmable: sends emails with confirmation instructions and verifies whether an account is already confirmed during sign in.
|
@@ -90,6 +90,15 @@ Replace MODEL by the class name you want to add devise, like User, Admin, etc. T
|
|
90
90
|
|
91
91
|
Support for Rails 2.3.x can be found by installing Devise 1.0.x from the v1.0 branch.
|
92
92
|
|
93
|
+
== Starting with Rails?
|
94
|
+
|
95
|
+
If you are building your first Rails application, we recommend you to *not* use Devise. Devise requires a good understanding of the Rails Framework. In such cases, we advise you to start a simple authentication system from scratch, today we have two resources:
|
96
|
+
|
97
|
+
* Michael Hartl's online book: http://railstutorial.org/chapters/modeling-and-viewing-users-two#top
|
98
|
+
* Ryan Bates' Railscast: http://railscasts.com/episodes/250-authentication-from-scratch
|
99
|
+
|
100
|
+
Once you have solidified you understanding of Rails and authentication mechanisms, we assure you Devise will be very pleasant to work with. :)
|
101
|
+
|
93
102
|
== Getting started
|
94
103
|
|
95
104
|
This is a walkthrough with all steps you need to setup a devise resource, including model, migration, route files, and optional configuration.
|
@@ -209,7 +218,7 @@ Devise currently supports generating views for the following template engines (u
|
|
209
218
|
* Haml (http://github.com/nex3/haml)
|
210
219
|
* Slim (http://github.com/stonean/slim)
|
211
220
|
|
212
|
-
Note: If you are generating Haml or Slim templates, you will need to have a few dependencies such as `hpricot` (for both Haml and Slim) and `haml2slim` (for Slim) installed.
|
221
|
+
Note: If you are generating Haml or Slim templates, you will need to have a few dependencies such as `ruby_parser` (for Haml), `hpricot` (for both Haml and Slim) and `haml2slim` (for Slim) installed.
|
213
222
|
|
214
223
|
If you have more than one role in your application (such as "User" and "Admin"), you will notice that Devise uses the same views for all roles. Fortunately, Devise offers an easy way to customize views. All you need to do is set "config.scoped_views = true" inside "config/initializers/devise.rb".
|
215
224
|
|
data/Rakefile
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require 'rake'
|
4
3
|
require 'rake/testtask'
|
5
4
|
require 'rake/rdoctask'
|
6
|
-
require File.join(File.dirname(__FILE__), 'lib', 'devise', 'version')
|
7
5
|
|
8
6
|
desc 'Default: run tests for all ORMs.'
|
9
7
|
task :default => :pre_commit
|
@@ -33,4 +31,4 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
33
31
|
rdoc.options << '--line-numbers' << '--inline-source'
|
34
32
|
rdoc.rdoc_files.include('README.rdoc')
|
35
33
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
36
|
-
end
|
34
|
+
end
|
@@ -78,8 +78,8 @@ class Devise::RegistrationsController < ApplicationController
|
|
78
78
|
end
|
79
79
|
|
80
80
|
# Overwrite redirect_for_sign_in so it takes uses after_sign_up_path_for.
|
81
|
-
def
|
82
|
-
|
81
|
+
def redirect_location(scope, resource) #:nodoc:
|
82
|
+
stored_location_for(scope) || after_sign_up_path_for(resource)
|
83
83
|
end
|
84
84
|
|
85
85
|
# The path used after sign up for inactive accounts. You need to overwrite
|
@@ -21,7 +21,7 @@ module Devise
|
|
21
21
|
# Generated methods:
|
22
22
|
# authenticate_user! # Signs user in or redirect
|
23
23
|
# authenticate_admin! # Signs admin in or redirect
|
24
|
-
# user_signed_in? # Checks whether there is
|
24
|
+
# user_signed_in? # Checks whether there is a user signed in or not
|
25
25
|
# admin_signed_in? # Checks whether there is an admin signed in or not
|
26
26
|
# current_user # Current signed in user
|
27
27
|
# current_admin # Current signed in admin
|
@@ -86,7 +86,7 @@ module Devise
|
|
86
86
|
signed_in?
|
87
87
|
end
|
88
88
|
|
89
|
-
# Sign in
|
89
|
+
# Sign in a user that already was authenticated. This helper is useful for logging
|
90
90
|
# users in after sign up.
|
91
91
|
#
|
92
92
|
# All options given to sign_in is passed forward to the set_user method in warden.
|
@@ -117,7 +117,7 @@ module Devise
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
-
# Sign out a given user or scope. This helper is useful for signing out
|
120
|
+
# Sign out a given user or scope. This helper is useful for signing out a user
|
121
121
|
# after deleting accounts.
|
122
122
|
#
|
123
123
|
# Examples:
|
@@ -136,6 +136,7 @@ module Devise
|
|
136
136
|
# Sign out all active users or scopes. This helper is useful for signing out all roles
|
137
137
|
# in one click. This signs out ALL scopes in warden.
|
138
138
|
def sign_out_all_scopes
|
139
|
+
Devise.mappings.keys.each { |s| warden.user(s) }
|
139
140
|
warden.raw_session.inspect
|
140
141
|
warden.logout
|
141
142
|
end
|
@@ -184,7 +185,7 @@ module Devise
|
|
184
185
|
respond_to?(home_path, true) ? send(home_path) : root_path
|
185
186
|
end
|
186
187
|
|
187
|
-
# Method used by sessions controller to sign out
|
188
|
+
# Method used by sessions controller to sign out a user. You can overwrite
|
188
189
|
# it in your ApplicationController to provide a custom hook for a custom
|
189
190
|
# scope. Notice that differently from +after_sign_in_path_for+ this method
|
190
191
|
# receives a symbol with the scope, and not the resource.
|
@@ -194,7 +195,7 @@ module Devise
|
|
194
195
|
root_path
|
195
196
|
end
|
196
197
|
|
197
|
-
# Sign in
|
198
|
+
# Sign in a user and tries to redirect first to the stored location and
|
198
199
|
# then to the url specified by after_sign_in_path_for. It accepts the same
|
199
200
|
# parameters as the sign_in method.
|
200
201
|
def sign_in_and_redirect(resource_or_scope, *args)
|
@@ -209,7 +210,7 @@ module Devise
|
|
209
210
|
stored_location_for(scope) || after_sign_in_path_for(resource)
|
210
211
|
end
|
211
212
|
|
212
|
-
# Sign out
|
213
|
+
# Sign out a user and tries to redirect to the url specified by
|
213
214
|
# after_sign_out_path_for.
|
214
215
|
def sign_out_and_redirect(resource_or_scope)
|
215
216
|
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
@@ -222,6 +223,12 @@ module Devise
|
|
222
223
|
def expire_session_data_after_sign_in!
|
223
224
|
session.keys.grep(/^devise\./).each { |k| session.delete(k) }
|
224
225
|
end
|
226
|
+
|
227
|
+
# Overwrite Rails' handle unverified request to sign out all scopes.
|
228
|
+
def handle_unverified_request
|
229
|
+
sign_out_all_scopes
|
230
|
+
super # call the default behaviour which resets the session
|
231
|
+
end
|
225
232
|
end
|
226
233
|
end
|
227
234
|
end
|
data/lib/devise/failure_app.rb
CHANGED
@@ -64,7 +64,6 @@ module Devise
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def redirect_url
|
67
|
-
request_format = request.format.to_sym
|
68
67
|
if request_format == :html
|
69
68
|
send(:"new_#{scope}_session_path")
|
70
69
|
else
|
@@ -84,7 +83,7 @@ module Devise
|
|
84
83
|
if request.xhr?
|
85
84
|
Devise.http_authenticatable_on_xhr
|
86
85
|
else
|
87
|
-
!(
|
86
|
+
!(request_format && Devise.navigational_formats.include?(request_format))
|
88
87
|
end
|
89
88
|
end
|
90
89
|
|
@@ -95,8 +94,8 @@ module Devise
|
|
95
94
|
end
|
96
95
|
|
97
96
|
def http_auth_body
|
98
|
-
return i18n_message unless
|
99
|
-
method = "to_#{
|
97
|
+
return i18n_message unless request_format
|
98
|
+
method = "to_#{request_format}"
|
100
99
|
{}.respond_to?(method) ? { :error => i18n_message }.send(method) : i18n_message
|
101
100
|
end
|
102
101
|
|
@@ -128,5 +127,17 @@ module Devise
|
|
128
127
|
def store_location!
|
129
128
|
session["#{scope}_return_to"] = attempted_path if request.get? && !http_auth?
|
130
129
|
end
|
130
|
+
|
131
|
+
MIME_REFERENCES = Mime::HTML.respond_to?(:ref)
|
132
|
+
|
133
|
+
def request_format
|
134
|
+
@request_format ||= if request.format.respond_to?(:ref)
|
135
|
+
request.format.ref
|
136
|
+
elsif MIME_REFERENCES
|
137
|
+
request.format
|
138
|
+
else # Rails < 3.0.4
|
139
|
+
request.format.to_sym
|
140
|
+
end
|
141
|
+
end
|
131
142
|
end
|
132
143
|
end
|
@@ -6,7 +6,7 @@
|
|
6
6
|
Warden::Manager.after_set_user do |record, warden, options|
|
7
7
|
scope = options[:scope]
|
8
8
|
|
9
|
-
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope)
|
9
|
+
if record && record.respond_to?(:timedout?) && warden.authenticated?(scope) && options[:store] != false
|
10
10
|
last_request_at = warden.session(scope)['last_request_at']
|
11
11
|
|
12
12
|
if record.timedout?(last_request_at)
|
@@ -26,7 +26,7 @@ module Devise
|
|
26
26
|
#
|
27
27
|
# == Active?
|
28
28
|
#
|
29
|
-
# Before authenticating
|
29
|
+
# Before authenticating a user and in each request, Devise checks if your model is active by
|
30
30
|
# calling model.active?. This method is overwriten by other devise modules. For instance,
|
31
31
|
# :confirmable overwrites .active? to only return true if your model was confirmed.
|
32
32
|
#
|
@@ -56,7 +56,7 @@ module Devise
|
|
56
56
|
end
|
57
57
|
|
58
58
|
# Overwrites active? from Devise::Models::Activatable for confirmation
|
59
|
-
# by verifying whether
|
59
|
+
# by verifying whether a user is active to sign in or not. If the user
|
60
60
|
# is already confirmed, it should never be blocked. Otherwise we need to
|
61
61
|
# calculate if the confirm time has not expired for this user.
|
62
62
|
def active?
|
@@ -133,7 +133,7 @@ module Devise
|
|
133
133
|
# with an email not found error.
|
134
134
|
# Options must contain the user email
|
135
135
|
def send_confirmation_instructions(attributes={})
|
136
|
-
confirmable =
|
136
|
+
confirmable = find_or_initialize_with_errors(confirmation_keys, attributes, :not_found)
|
137
137
|
confirmable.resend_confirmation_token if confirmable.persisted?
|
138
138
|
confirmable
|
139
139
|
end
|
@@ -153,7 +153,7 @@ module Devise
|
|
153
153
|
generate_token(:confirmation_token)
|
154
154
|
end
|
155
155
|
|
156
|
-
Devise::Models.config(self, :confirm_within)
|
156
|
+
Devise::Models.config(self, :confirm_within, :confirmation_keys)
|
157
157
|
end
|
158
158
|
end
|
159
159
|
end
|
@@ -31,9 +31,11 @@ module Devise
|
|
31
31
|
self.encrypted_password = password_digest(@password) if @password.present?
|
32
32
|
end
|
33
33
|
|
34
|
-
# Verifies whether an
|
34
|
+
# Verifies whether an password (ie from sign in) is the user password.
|
35
35
|
def valid_password?(password)
|
36
|
-
::BCrypt::Password.new(self.encrypted_password)
|
36
|
+
bcrypt = ::BCrypt::Password.new(self.encrypted_password)
|
37
|
+
password = ::BCrypt::Engine.hash_secret("#{password}#{self.class.pepper}", bcrypt.salt)
|
38
|
+
Devise.secure_compare(password, self.encrypted_password)
|
37
39
|
end
|
38
40
|
|
39
41
|
# Set password and password confirmation to nil
|
@@ -36,7 +36,7 @@ module Devise
|
|
36
36
|
|
37
37
|
# Verifies whether an incoming_password (ie from sign in) is the user password.
|
38
38
|
def valid_password?(incoming_password)
|
39
|
-
password_digest(incoming_password)
|
39
|
+
Devise.secure_compare(password_digest(incoming_password), self.encrypted_password)
|
40
40
|
end
|
41
41
|
|
42
42
|
protected
|
@@ -22,7 +22,7 @@ module Devise
|
|
22
22
|
|
23
23
|
delegate :lock_strategy_enabled?, :unlock_strategy_enabled?, :to => "self.class"
|
24
24
|
|
25
|
-
# Lock
|
25
|
+
# Lock a user setting it's locked_at to actual time.
|
26
26
|
def lock_access!
|
27
27
|
self.locked_at = Time.now
|
28
28
|
|
@@ -34,7 +34,7 @@ module Devise
|
|
34
34
|
save(:validate => false)
|
35
35
|
end
|
36
36
|
|
37
|
-
# Unlock
|
37
|
+
# Unlock a user by cleaning locket_at and failed_attempts.
|
38
38
|
def unlock_access!
|
39
39
|
if_access_locked do
|
40
40
|
self.locked_at = nil
|
@@ -60,7 +60,7 @@ module Devise
|
|
60
60
|
end
|
61
61
|
|
62
62
|
# Overwrites active? from Devise::Models::Activatable for locking purposes
|
63
|
-
# by verifying whether
|
63
|
+
# by verifying whether a user is active to sign in or not based on locked?
|
64
64
|
def active?
|
65
65
|
super && !access_locked?
|
66
66
|
end
|
@@ -72,7 +72,7 @@ module Devise
|
|
72
72
|
end
|
73
73
|
|
74
74
|
# Overwrites valid_for_authentication? from Devise::Models::Authenticatable
|
75
|
-
# for verifying whether
|
75
|
+
# for verifying whether a user is allowed to sign in or not. If the user
|
76
76
|
# is locked, it should never be allowed.
|
77
77
|
def valid_for_authentication?
|
78
78
|
return super unless persisted? && lock_strategy_enabled?(:failed_attempts)
|
@@ -82,6 +82,7 @@ module Devise
|
|
82
82
|
return result
|
83
83
|
when TrueClass
|
84
84
|
self.failed_attempts = 0
|
85
|
+
save(:validate => false)
|
85
86
|
when FalseClass
|
86
87
|
# PostgreSQL uses nil as the default value for integer columns set to 0
|
87
88
|
self.failed_attempts ||= 0
|
@@ -89,10 +90,11 @@ module Devise
|
|
89
90
|
if attempts_exceeded?
|
90
91
|
lock_access!
|
91
92
|
return :locked
|
93
|
+
else
|
94
|
+
save(:validate => false)
|
92
95
|
end
|
93
96
|
end
|
94
97
|
|
95
|
-
save(:validate => false) if changed?
|
96
98
|
result
|
97
99
|
end
|
98
100
|
|
@@ -35,7 +35,7 @@ module Devise
|
|
35
35
|
|
36
36
|
# Resets reset password token and send reset password instructions by email
|
37
37
|
def send_reset_password_instructions
|
38
|
-
generate_reset_password_token! if self.
|
38
|
+
generate_reset_password_token! if self.reset_password_token.nil? or !reset_password_period_valid?
|
39
39
|
::Devise.mailer.reset_password_instructions(self).deliver
|
40
40
|
end
|
41
41
|
|
@@ -7,7 +7,7 @@ module Devise
|
|
7
7
|
|
8
8
|
module ClassMethods
|
9
9
|
# A convenience method that receives both parameters and session to
|
10
|
-
# initialize
|
10
|
+
# initialize a user. This can be used by OAuth, for example, to send
|
11
11
|
# in the user token and be stored on initialization.
|
12
12
|
#
|
13
13
|
# By default discards all information sent by the session by calling
|
data/lib/devise/schema.rb
CHANGED
@@ -3,7 +3,7 @@ module Devise
|
|
3
3
|
# and overwrite the apply_schema method.
|
4
4
|
module Schema
|
5
5
|
|
6
|
-
# Creates email, encrypted_password and password_salt.
|
6
|
+
# Creates email when enabled (on by default), encrypted_password and password_salt.
|
7
7
|
#
|
8
8
|
# == Options
|
9
9
|
# * :null - When true, allow columns to be null.
|
@@ -15,8 +15,9 @@ module Devise
|
|
15
15
|
def database_authenticatable(options={})
|
16
16
|
null = options[:null] || false
|
17
17
|
default = options.key?(:default) ? options[:default] : ("" if null == false)
|
18
|
+
include_email = !self.respond_to?(:authentication_keys) || self.authentication_keys.include?(:email)
|
18
19
|
|
19
|
-
apply_devise_schema :email, String, :null => null, :default => default
|
20
|
+
apply_devise_schema :email, String, :null => null, :default => default if include_email
|
20
21
|
apply_devise_schema :encrypted_password, String, :null => null, :default => default, :limit => 128
|
21
22
|
end
|
22
23
|
|
data/lib/devise/test_helpers.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Devise
|
2
2
|
# Devise::TestHelpers provides a facility to test controllers in isolation
|
3
3
|
# when using ActionController::TestCase allowing you to quickly sign_in or
|
4
|
-
# sign_out
|
4
|
+
# sign_out a user. Do not use Devise::TestHelpers in integration tests.
|
5
5
|
#
|
6
6
|
# Notice you should not test Warden specific behavior (like Warden callbacks)
|
7
7
|
# using Devise::TestHelpers since it is a stub of the actual behavior. Such
|
@@ -46,7 +46,7 @@ module Devise
|
|
46
46
|
env["warden.options"] = result
|
47
47
|
Warden::Manager._run_callbacks(:before_failure, env, result)
|
48
48
|
|
49
|
-
status, headers, body = Devise
|
49
|
+
status, headers, body = Devise.warden_config[:failure_app].call(env).to_a
|
50
50
|
@controller.send :render, :status => status, :text => body,
|
51
51
|
:content_type => headers["Content-Type"], :location => headers["Location"]
|
52
52
|
|
data/lib/devise/version.rb
CHANGED
data/lib/devise.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rails'
|
1
2
|
require 'active_support/core_ext/numeric/time'
|
2
3
|
require 'active_support/dependencies'
|
3
4
|
require 'orm_adapter'
|
@@ -68,9 +69,9 @@ module Devise
|
|
68
69
|
@@request_keys = []
|
69
70
|
|
70
71
|
# Keys that should be case-insensitive.
|
71
|
-
# Empty by default for backwards
|
72
|
+
# Empty by default for backwards compatibility.
|
72
73
|
mattr_accessor :case_insensitive_keys
|
73
|
-
@@case_insensitive_keys = [
|
74
|
+
@@case_insensitive_keys = []
|
74
75
|
|
75
76
|
# If http authentication is enabled by default.
|
76
77
|
mattr_accessor :http_authenticatable
|
@@ -117,6 +118,10 @@ module Devise
|
|
117
118
|
mattr_accessor :confirm_within
|
118
119
|
@@confirm_within = 0.days
|
119
120
|
|
121
|
+
# Defines which key will be used when confirming an account
|
122
|
+
mattr_accessor :confirmation_keys
|
123
|
+
@@confirmation_keys = [ :email ]
|
124
|
+
|
120
125
|
# Time interval to timeout the user session without activity.
|
121
126
|
mattr_accessor :timeout_in
|
122
127
|
@@timeout_in = 30.minutes
|
@@ -186,10 +191,11 @@ module Devise
|
|
186
191
|
@@stateless_token = false
|
187
192
|
|
188
193
|
# Which formats should be treated as navigational.
|
194
|
+
# We need both :"*/*" and "*/*" to work on different Rails versions.
|
189
195
|
mattr_accessor :navigational_formats
|
190
|
-
@@navigational_formats = [:"*/*", :html]
|
196
|
+
@@navigational_formats = [:"*/*", "*/*", :html]
|
191
197
|
|
192
|
-
# When set to true, signing out
|
198
|
+
# When set to true, signing out a user signs out all other scopes.
|
193
199
|
mattr_accessor :sign_out_all_scopes
|
194
200
|
@@sign_out_all_scopes = true
|
195
201
|
|
@@ -370,7 +376,18 @@ module Devise
|
|
370
376
|
|
371
377
|
# Generate a friendly string randomically to be used as token.
|
372
378
|
def self.friendly_token
|
373
|
-
ActiveSupport::SecureRandom.base64(
|
379
|
+
ActiveSupport::SecureRandom.base64(15).tr('+/=', 'xyz')
|
380
|
+
end
|
381
|
+
|
382
|
+
# constant-time comparison algorithm to prevent timing attacks
|
383
|
+
def self.secure_compare(a, b)
|
384
|
+
return false unless a.present? && b.present?
|
385
|
+
return false unless a.bytesize == b.bytesize
|
386
|
+
l = a.unpack "C#{a.bytesize}"
|
387
|
+
|
388
|
+
res = 0
|
389
|
+
b.each_byte { |byte| res |= byte ^ l.shift }
|
390
|
+
res == 0
|
374
391
|
end
|
375
392
|
end
|
376
393
|
|
@@ -13,94 +13,14 @@ module Devise
|
|
13
13
|
:desc => "Template engine for the views. Available options are 'erb', 'haml' and 'slim'."
|
14
14
|
|
15
15
|
def copy_views
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
create_and_copy_haml_views
|
21
|
-
when "slim"
|
22
|
-
verify_haml_existence
|
23
|
-
verify_haml_version
|
24
|
-
verify_haml2slim_existence
|
25
|
-
verify_haml2slim_version
|
26
|
-
create_and_copy_slim_views
|
16
|
+
template = options[:template_engine].to_s
|
17
|
+
case template
|
18
|
+
when "haml", "slim"
|
19
|
+
warn "#{template} templates have been removed from Devise gem"
|
27
20
|
else
|
28
21
|
directory "devise", "app/views/#{scope || :devise}"
|
29
22
|
end
|
30
23
|
end
|
31
|
-
|
32
|
-
protected
|
33
|
-
|
34
|
-
def verify_haml_existence
|
35
|
-
begin
|
36
|
-
require 'haml'
|
37
|
-
rescue LoadError
|
38
|
-
say "Haml is not installed, or it is not specified in your Gemfile."
|
39
|
-
exit
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def verify_haml2slim_existence
|
44
|
-
begin
|
45
|
-
require 'haml2slim'
|
46
|
-
rescue LoadError
|
47
|
-
say "Haml2Slim is not installed, or it is not specified in your Gemfile."
|
48
|
-
exit
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def verify_haml_version
|
53
|
-
unless Haml.version[:major] == 2 && Haml.version[:minor] >= 3 || Haml.version[:major] >= 3
|
54
|
-
say "To generate Haml or Slim templates, you need to have Haml 2.3 or above installed."
|
55
|
-
exit
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def verify_haml2slim_version
|
60
|
-
unless Haml2Slim::VERSION.to_f >= '0.4.0'.to_f
|
61
|
-
say "To generate Slim templates, you need to have Haml2Slim 0.4.0 or above installed."
|
62
|
-
exit
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def create_and_copy_haml_views
|
67
|
-
directory haml_tmp_root, "app/views/#{scope || :devise}"
|
68
|
-
FileUtils.rm_rf(haml_tmp_root)
|
69
|
-
end
|
70
|
-
|
71
|
-
def create_and_copy_slim_views
|
72
|
-
slim_tmp_root = Dir.mktmpdir("devise-slim.")
|
73
|
-
`haml2slim #{haml_tmp_root} #{slim_tmp_root}`
|
74
|
-
|
75
|
-
directory slim_tmp_root, "app/views/#{scope || :devise}"
|
76
|
-
|
77
|
-
FileUtils.rm_rf(haml_tmp_root)
|
78
|
-
FileUtils.rm_rf(slim_tmp_root)
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def create_haml_views
|
84
|
-
@haml_tmp_root ||= begin
|
85
|
-
html_root = "#{self.class.source_root}/devise"
|
86
|
-
haml_tmp_root = Dir.mktmpdir("devise-haml.")
|
87
|
-
|
88
|
-
Dir["#{html_root}/**/*"].each do |path|
|
89
|
-
relative_path = path.sub(html_root, "")
|
90
|
-
source_path = (haml_tmp_root + relative_path).sub(/erb$/, "haml")
|
91
|
-
|
92
|
-
if File.directory?(path)
|
93
|
-
FileUtils.mkdir_p(source_path)
|
94
|
-
else
|
95
|
-
`html2haml -r #{path} #{source_path}`
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
haml_tmp_root
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
alias :haml_tmp_root :create_haml_views
|
104
24
|
end
|
105
25
|
end
|
106
26
|
end
|
@@ -65,6 +65,9 @@ Devise.setup do |config|
|
|
65
65
|
# (ie 2 days).
|
66
66
|
# config.confirm_within = 2.days
|
67
67
|
|
68
|
+
# Defines which key will be used when confirming an account
|
69
|
+
# config.confirmation_keys = [ :email ]
|
70
|
+
|
68
71
|
# ==> Configuration for :rememberable
|
69
72
|
# The time the user will be remembered without asking for credentials again.
|
70
73
|
# config.remember_for = 2.weeks
|
@@ -163,8 +166,9 @@ Devise.setup do |config|
|
|
163
166
|
# If you have any extra navigational formats, like :iphone or :mobile, you
|
164
167
|
# should add them to the navigational formats lists.
|
165
168
|
#
|
166
|
-
# The :"*/*"
|
167
|
-
#
|
169
|
+
# The :"*/*" and "*/*" formats below is required to match Internet
|
170
|
+
# Explorer requests.
|
171
|
+
# config.navigational_formats = [:"*/*", "*/*", :html]
|
168
172
|
|
169
173
|
# The default HTTP method used to sign out a resource. Default is :get.
|
170
174
|
# config.sign_out_via = :get
|
@@ -136,11 +136,13 @@ class ControllerAuthenticatableTest < ActionController::TestCase
|
|
136
136
|
end
|
137
137
|
|
138
138
|
test 'sign out without args proxy to sign out all scopes' do
|
139
|
+
@mock_warden.expects(:user).times(Devise.mappings.size)
|
139
140
|
@mock_warden.expects(:logout).with().returns(true)
|
140
141
|
@controller.sign_out
|
141
142
|
end
|
142
143
|
|
143
144
|
test 'sign out everybody proxy to logout on warden' do
|
145
|
+
@mock_warden.expects(:user).times(Devise.mappings.size)
|
144
146
|
@mock_warden.expects(:logout).with().returns(true)
|
145
147
|
@controller.sign_out_all_scopes
|
146
148
|
end
|
@@ -224,6 +226,7 @@ class ControllerAuthenticatableTest < ActionController::TestCase
|
|
224
226
|
|
225
227
|
test 'sign out and redirect uses the configured after sign out path when signing out all scopes' do
|
226
228
|
swap Devise, :sign_out_all_scopes => true do
|
229
|
+
@mock_warden.expects(:user).times(Devise.mappings.size)
|
227
230
|
@mock_warden.expects(:logout).with().returns(true)
|
228
231
|
@controller.expects(:redirect_to).with(admin_root_path)
|
229
232
|
@controller.instance_eval "def after_sign_out_path_for(resource); admin_root_path; end"
|
data/test/failure_app_test.rb
CHANGED
@@ -13,7 +13,7 @@ class FailureTest < ActiveSupport::TestCase
|
|
13
13
|
'REQUEST_METHOD' => 'GET',
|
14
14
|
'warden.options' => { :scope => :user },
|
15
15
|
'rack.session' => {},
|
16
|
-
'action_dispatch.request.formats' => Array(env_params.delete('formats') ||
|
16
|
+
'action_dispatch.request.formats' => Array(env_params.delete('formats') || Mime::HTML),
|
17
17
|
'rack.input' => "",
|
18
18
|
'warden' => OpenStruct.new(:message => nil)
|
19
19
|
}.merge!(env_params)
|
@@ -15,11 +15,27 @@ class RegistrationTest < ActionController::IntegrationTest
|
|
15
15
|
|
16
16
|
assert_contain 'Welcome! You have signed up successfully.'
|
17
17
|
assert warden.authenticated?(:admin)
|
18
|
+
assert_current_url "/admin_area/home"
|
18
19
|
|
19
20
|
admin = Admin.last :order => "id"
|
20
21
|
assert_equal admin.email, 'new_user@test.com'
|
21
22
|
end
|
22
23
|
|
24
|
+
test 'a guest admin should be able to sign in and be redirected to a custom location' do
|
25
|
+
Devise::RegistrationsController.any_instance.stubs(:after_sign_up_path_for).returns("/?custom=1")
|
26
|
+
get new_admin_session_path
|
27
|
+
click_link 'Sign up'
|
28
|
+
|
29
|
+
fill_in 'email', :with => 'new_user@test.com'
|
30
|
+
fill_in 'password', :with => 'new_user123'
|
31
|
+
fill_in 'password confirmation', :with => 'new_user123'
|
32
|
+
click_button 'Sign up'
|
33
|
+
|
34
|
+
assert_contain 'Welcome! You have signed up successfully.'
|
35
|
+
assert warden.authenticated?(:admin)
|
36
|
+
assert_current_url "/?custom=1"
|
37
|
+
end
|
38
|
+
|
23
39
|
test 'a guest user should be able to sign up successfully and be blocked by confirmation' do
|
24
40
|
get new_user_registration_path
|
25
41
|
|
@@ -30,6 +46,7 @@ class RegistrationTest < ActionController::IntegrationTest
|
|
30
46
|
|
31
47
|
assert_contain 'You have signed up successfully. However, we could not sign you in because your account is unconfirmed.'
|
32
48
|
assert_not_contain 'You have to confirm your account before continuing'
|
49
|
+
assert_current_url "/"
|
33
50
|
|
34
51
|
assert_not warden.authenticated?(:user)
|
35
52
|
|
@@ -38,6 +55,19 @@ class RegistrationTest < ActionController::IntegrationTest
|
|
38
55
|
assert_not user.confirmed?
|
39
56
|
end
|
40
57
|
|
58
|
+
test 'a guest user should be blocked by confirmation and redirected to a custom path' do
|
59
|
+
Devise::RegistrationsController.any_instance.stubs(:after_inactive_sign_up_path_for).returns("/?custom=1")
|
60
|
+
get new_user_registration_path
|
61
|
+
|
62
|
+
fill_in 'email', :with => 'new_user@test.com'
|
63
|
+
fill_in 'password', :with => 'new_user123'
|
64
|
+
fill_in 'password confirmation', :with => 'new_user123'
|
65
|
+
click_button 'Sign up'
|
66
|
+
|
67
|
+
assert_current_url "/?custom=1"
|
68
|
+
assert_not warden.authenticated?(:user)
|
69
|
+
end
|
70
|
+
|
41
71
|
test 'a guest user cannot sign up with invalid information' do
|
42
72
|
get new_user_registration_path
|
43
73
|
|
@@ -72,6 +72,16 @@ class RememberMeTest < ActionController::IntegrationTest
|
|
72
72
|
assert_match /remember_user_token[^\n]*HttpOnly\n/, response.headers["Set-Cookie"], "Expected Set-Cookie header in response to set HttpOnly flag on remember_user_token cookie."
|
73
73
|
end
|
74
74
|
|
75
|
+
test 'cookies are destroyed on unverified requests' do
|
76
|
+
swap ApplicationController, :allow_forgery_protection => true do
|
77
|
+
user = create_user_and_remember
|
78
|
+
get users_path
|
79
|
+
assert warden.authenticated?(:user)
|
80
|
+
post root_path, :authenticity_token => 'INVALID'
|
81
|
+
assert_not warden.authenticated?(:user)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
75
85
|
test 'does not extend remember period through sign in' do
|
76
86
|
swap Devise, :extend_remember_period => true, :remember_for => 1.year do
|
77
87
|
user = create_user
|
@@ -76,15 +76,26 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
test 'authenticate with valid authentication token key and do not store if stateless and timeoutable are enabled' do
|
80
|
+
swap Devise, :token_authentication_key => :secret_token, :stateless_token => true, :timeout_in => (0.1).second do
|
81
|
+
user = sign_in_as_new_user_with_token
|
82
|
+
assert warden.authenticated?(:user)
|
83
|
+
|
84
|
+
# Expiring does not work because we are setting the session value when accessing it
|
85
|
+
sleep 0.3
|
86
|
+
|
87
|
+
get_users_path_as_existing_user(user)
|
88
|
+
assert warden.authenticated?(:user)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
79
92
|
private
|
80
93
|
|
81
94
|
def sign_in_as_new_user_with_token(options = {})
|
82
|
-
options
|
83
|
-
options[:auth_token] ||= VALID_AUTHENTICATION_TOKEN
|
95
|
+
user = options.delete(:user) || create_user_with_authentication_token(options)
|
84
96
|
|
85
|
-
|
86
|
-
user.authentication_token
|
87
|
-
user.save
|
97
|
+
options[:auth_token_key] ||= Devise.token_authentication_key
|
98
|
+
options[:auth_token] ||= user.authentication_token
|
88
99
|
|
89
100
|
if options[:http_auth]
|
90
101
|
header = "Basic #{ActiveSupport::Base64.encode64("#{VALID_AUTHENTICATION_TOKEN}:X")}"
|
@@ -96,4 +107,14 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
|
96
107
|
user
|
97
108
|
end
|
98
109
|
|
110
|
+
def create_user_with_authentication_token(options)
|
111
|
+
user = create_user(options)
|
112
|
+
user.authentication_token = VALID_AUTHENTICATION_TOKEN
|
113
|
+
user.save
|
114
|
+
user
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_users_path_as_existing_user(user)
|
118
|
+
sign_in_as_new_user_with_token(:user => user)
|
119
|
+
end
|
99
120
|
end
|
@@ -51,7 +51,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
51
51
|
assert_equal "was already confirmed, please try signing in", user.errors[:email].join
|
52
52
|
end
|
53
53
|
|
54
|
-
test 'should find and confirm
|
54
|
+
test 'should find and confirm a user automatically' do
|
55
55
|
user = create_user
|
56
56
|
confirmed_user = User.confirm_by_token(user.confirmation_token)
|
57
57
|
assert_equal confirmed_user, user
|
@@ -127,7 +127,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
127
127
|
User.send_confirmation_instructions(:email => user.email)
|
128
128
|
end
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
test 'should always have confirmation token when email is sent' do
|
132
132
|
user = new_user
|
133
133
|
user.instance_eval { def confirmation_required?; false end }
|
@@ -210,7 +210,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
210
210
|
user.save
|
211
211
|
assert_not user.reload.active?
|
212
212
|
end
|
213
|
-
|
213
|
+
|
214
214
|
test 'should be active without confirmation when confirmation is not required' do
|
215
215
|
user = create_user
|
216
216
|
user.instance_eval { def confirmation_required?; false end }
|
@@ -218,4 +218,21 @@ class ConfirmableTest < ActiveSupport::TestCase
|
|
218
218
|
user.save
|
219
219
|
assert user.reload.active?
|
220
220
|
end
|
221
|
+
|
222
|
+
test 'should find a user to send email instructions for the user confirm it\'s email by authentication_keys' do
|
223
|
+
swap Devise, :authentication_keys => [:username, :email] do
|
224
|
+
user = create_user
|
225
|
+
confirm_user = User.send_confirmation_instructions(:email => user.email, :username => user.username)
|
226
|
+
assert_equal confirm_user, user
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
test 'should require all confirmation_keys' do
|
231
|
+
swap Devise, :confirmation_keys => [:username, :email] do
|
232
|
+
user = create_user
|
233
|
+
confirm_user = User.send_confirmation_instructions(:email => user.email)
|
234
|
+
assert_not confirm_user.persisted?
|
235
|
+
assert_equal "can't be blank", confirm_user.errors[:username].join
|
236
|
+
end
|
237
|
+
end
|
221
238
|
end
|
@@ -31,7 +31,7 @@ class EncryptableTest < ActiveSupport::TestCase
|
|
31
31
|
|
32
32
|
test 'should generate a base64 hash using SecureRandom for password salt' do
|
33
33
|
swap_with_encryptor Admin, :sha1 do
|
34
|
-
ActiveSupport::SecureRandom.expects(:base64).with(
|
34
|
+
ActiveSupport::SecureRandom.expects(:base64).with(15).returns('friendly_token')
|
35
35
|
assert_equal 'friendly_token', create_admin.password_salt
|
36
36
|
end
|
37
37
|
end
|
@@ -55,7 +55,7 @@ class LockableTest < ActiveSupport::TestCase
|
|
55
55
|
assert_not user.active?
|
56
56
|
end
|
57
57
|
|
58
|
-
test "should unlock
|
58
|
+
test "should unlock a user by cleaning locked_at, falied_attempts and unlock_token" do
|
59
59
|
user = create_user
|
60
60
|
user.lock_access!
|
61
61
|
assert_not_nil user.reload.locked_at
|
@@ -141,7 +141,7 @@ class LockableTest < ActiveSupport::TestCase
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
-
test 'should find and unlock
|
144
|
+
test 'should find and unlock a user automatically' do
|
145
145
|
user = create_user
|
146
146
|
user.lock_access!
|
147
147
|
locked_user = User.unlock_access_by_token(user.unlock_token)
|
@@ -116,18 +116,27 @@ class RecoverableTest < ActiveSupport::TestCase
|
|
116
116
|
assert_equal reset_password_user, user
|
117
117
|
end
|
118
118
|
|
119
|
-
test 'should a new record with errors if no reset_password_token is found' do
|
119
|
+
test 'should return a new record with errors if no reset_password_token is found' do
|
120
120
|
reset_password_user = User.reset_password_by_token(:reset_password_token => 'invalid_token')
|
121
121
|
assert_not reset_password_user.persisted?
|
122
122
|
assert_equal "is invalid", reset_password_user.errors[:reset_password_token].join
|
123
123
|
end
|
124
124
|
|
125
|
-
test 'should a new record with errors if reset_password_token is blank' do
|
125
|
+
test 'should return a new record with errors if reset_password_token is blank' do
|
126
126
|
reset_password_user = User.reset_password_by_token(:reset_password_token => '')
|
127
127
|
assert_not reset_password_user.persisted?
|
128
128
|
assert_match "can't be blank", reset_password_user.errors[:reset_password_token].join
|
129
129
|
end
|
130
130
|
|
131
|
+
test 'should return a new record with errors if password is blank' do
|
132
|
+
user = create_user
|
133
|
+
user.send :generate_reset_password_token!
|
134
|
+
|
135
|
+
reset_password_user = User.reset_password_by_token(:reset_password_token => user.reset_password_token, :password => '')
|
136
|
+
assert_not reset_password_user.errors.empty?
|
137
|
+
assert_match "can't be blank", reset_password_user.errors[:password].join
|
138
|
+
end
|
139
|
+
|
131
140
|
test 'should reset successfully user password given the new password and confirmation' do
|
132
141
|
user = create_user
|
133
142
|
old_password = user.password
|
@@ -27,6 +27,7 @@ class TokenAuthenticatableTest < ActiveSupport::TestCase
|
|
27
27
|
end
|
28
28
|
|
29
29
|
test 'should return nil when authenticating an invalid user by authentication token' do
|
30
|
+
skip 'Currently raises an exception with Mongoid.' if DEVISE_ORM == :mongoid
|
30
31
|
user = create_user
|
31
32
|
user.ensure_authentication_token!
|
32
33
|
user.confirm!
|
@@ -15,9 +15,9 @@ Devise.setup do |config|
|
|
15
15
|
require "devise/orm/#{DEVISE_ORM}"
|
16
16
|
|
17
17
|
# ==> Configuration for any authentication mechanism
|
18
|
-
# Configure which keys are used when authenticating
|
18
|
+
# Configure which keys are used when authenticating a user. By default is
|
19
19
|
# just :email. You can configure it to use [:username, :subdomain], so for
|
20
|
-
# authenticating
|
20
|
+
# authenticating a user, both parameters are required. Remember that those
|
21
21
|
# parameters are used only when authenticating and not when retrieving from
|
22
22
|
# session. If you need permissions, you should implement that in a before filter.
|
23
23
|
# You can also supply hash where the value is a boolean expliciting if authentication
|
@@ -62,6 +62,9 @@ Devise.setup do |config|
|
|
62
62
|
# (ie 2 days).
|
63
63
|
# config.confirm_within = 2.days
|
64
64
|
|
65
|
+
# Defines which key will be used when confirming an account
|
66
|
+
# config.confirmation_keys = [ :email ]
|
67
|
+
|
65
68
|
# ==> Configuration for :rememberable
|
66
69
|
# The time the user will be remembered without asking for credentials again.
|
67
70
|
# config.remember_for = 2.weeks
|
data/test/schema_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
if DEVISE_ORM == :mongoid
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class User2
|
6
|
+
include Mongoid::Document
|
7
|
+
devise :database_authenticatable
|
8
|
+
end
|
9
|
+
|
10
|
+
class User3
|
11
|
+
include Mongoid::Document
|
12
|
+
devise :database_authenticatable, :authentication_keys => [:username, :email]
|
13
|
+
end
|
14
|
+
|
15
|
+
class User4
|
16
|
+
include Mongoid::Document
|
17
|
+
devise :database_authenticatable, :authentication_keys => [:username]
|
18
|
+
end
|
19
|
+
|
20
|
+
class SchemaTest < ActiveSupport::TestCase
|
21
|
+
test 'should create an email field if there are no custom authentication keys' do
|
22
|
+
assert_not_equal User2.fields['email'], nil
|
23
|
+
end
|
24
|
+
|
25
|
+
test 'should create an email field if there are custom authentication keys and they include email' do
|
26
|
+
assert_not_equal User3.fields['email'], nil
|
27
|
+
end
|
28
|
+
|
29
|
+
test 'should not create an email field if there are custom authentication keys they don\'t include email' do
|
30
|
+
assert_equal User4.fields['email'], nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/test/test_helpers_test.rb
CHANGED
@@ -4,6 +4,12 @@ class TestHelpersTest < ActionController::TestCase
|
|
4
4
|
tests UsersController
|
5
5
|
include Devise::TestHelpers
|
6
6
|
|
7
|
+
class CustomFailureApp < Devise::FailureApp
|
8
|
+
def redirect
|
9
|
+
self.status = 306
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
7
13
|
test "redirects if attempting to access a page unauthenticated" do
|
8
14
|
get :index
|
9
15
|
assert_redirected_to new_user_session_path
|
@@ -52,6 +58,16 @@ class TestHelpersTest < ActionController::TestCase
|
|
52
58
|
get :index
|
53
59
|
assert_redirected_to new_user_session_path
|
54
60
|
end
|
61
|
+
|
62
|
+
test "respects custom failure app" do
|
63
|
+
begin
|
64
|
+
Devise.warden_config.failure_app = CustomFailureApp
|
65
|
+
get :index
|
66
|
+
assert_response 306
|
67
|
+
ensure
|
68
|
+
Devise.warden_config.failure_app = Devise::FailureApp
|
69
|
+
end
|
70
|
+
end
|
55
71
|
|
56
72
|
test "defined Warden after_authentication callback should not be called when sign_in is called" do
|
57
73
|
begin
|
metadata
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise-jdguyot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 1
|
7
|
-
- 2
|
8
|
-
- rc
|
9
|
-
version: 1.2.rc
|
4
|
+
prerelease: 4
|
5
|
+
version: 1.2.rc2
|
10
6
|
platform: ruby
|
11
7
|
authors:
|
12
8
|
- "Jos\xC3\xA9 Valim"
|
@@ -15,7 +11,7 @@ autorequire:
|
|
15
11
|
bindir: bin
|
16
12
|
cert_chain: []
|
17
13
|
|
18
|
-
date: 2011-
|
14
|
+
date: 2011-02-22 00:00:00 +01:00
|
19
15
|
default_executable:
|
20
16
|
dependencies:
|
21
17
|
- !ruby/object:Gem::Dependency
|
@@ -26,10 +22,6 @@ dependencies:
|
|
26
22
|
requirements:
|
27
23
|
- - ~>
|
28
24
|
- !ruby/object:Gem::Version
|
29
|
-
segments:
|
30
|
-
- 1
|
31
|
-
- 0
|
32
|
-
- 3
|
33
25
|
version: 1.0.3
|
34
26
|
type: :runtime
|
35
27
|
version_requirements: *id001
|
@@ -41,10 +33,6 @@ dependencies:
|
|
41
33
|
requirements:
|
42
34
|
- - ~>
|
43
35
|
- !ruby/object:Gem::Version
|
44
|
-
segments:
|
45
|
-
- 0
|
46
|
-
- 0
|
47
|
-
- 3
|
48
36
|
version: 0.0.3
|
49
37
|
type: :runtime
|
50
38
|
version_requirements: *id002
|
@@ -56,10 +44,6 @@ dependencies:
|
|
56
44
|
requirements:
|
57
45
|
- - ~>
|
58
46
|
- !ruby/object:Gem::Version
|
59
|
-
segments:
|
60
|
-
- 2
|
61
|
-
- 1
|
62
|
-
- 2
|
63
47
|
version: 2.1.2
|
64
48
|
type: :runtime
|
65
49
|
version_requirements: *id003
|
@@ -249,6 +233,7 @@ files:
|
|
249
233
|
- test/rails_app/public/favicon.ico
|
250
234
|
- test/rails_app/script/rails
|
251
235
|
- test/routes_test.rb
|
236
|
+
- test/schema_test.rb
|
252
237
|
- test/support/assertions.rb
|
253
238
|
- test/support/helpers.rb
|
254
239
|
- test/support/integration.rb
|
@@ -270,23 +255,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
270
255
|
requirements:
|
271
256
|
- - ">="
|
272
257
|
- !ruby/object:Gem::Version
|
273
|
-
segments:
|
274
|
-
- 0
|
275
258
|
version: "0"
|
276
259
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
277
260
|
none: false
|
278
261
|
requirements:
|
279
262
|
- - ">"
|
280
263
|
- !ruby/object:Gem::Version
|
281
|
-
segments:
|
282
|
-
- 1
|
283
|
-
- 3
|
284
|
-
- 1
|
285
264
|
version: 1.3.1
|
286
265
|
requirements: []
|
287
266
|
|
288
267
|
rubyforge_project: devise
|
289
|
-
rubygems_version: 1.
|
268
|
+
rubygems_version: 1.5.2
|
290
269
|
signing_key:
|
291
270
|
specification_version: 3
|
292
271
|
summary: Flexible authentication solution for Rails with Warden
|
@@ -379,6 +358,7 @@ test_files:
|
|
379
358
|
- test/rails_app/public/favicon.ico
|
380
359
|
- test/rails_app/script/rails
|
381
360
|
- test/routes_test.rb
|
361
|
+
- test/schema_test.rb
|
382
362
|
- test/support/assertions.rb
|
383
363
|
- test/support/helpers.rb
|
384
364
|
- test/support/integration.rb
|