devise 2.0.6 → 2.1.0.rc

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of devise might be problematic. Click here for more details.

Files changed (68) hide show
  1. data/.travis.yml +0 -1
  2. data/CHANGELOG.rdoc +12 -6
  3. data/Gemfile.lock +3 -3
  4. data/README.md +9 -15
  5. data/app/controllers/devise_controller.rb +2 -3
  6. data/app/views/devise/_links.erb +3 -25
  7. data/app/views/devise/confirmations/new.html.erb +1 -1
  8. data/app/views/devise/passwords/edit.html.erb +1 -1
  9. data/app/views/devise/passwords/new.html.erb +1 -1
  10. data/app/views/devise/registrations/new.html.erb +1 -1
  11. data/app/views/devise/sessions/new.html.erb +1 -1
  12. data/app/views/devise/shared/_links.erb +25 -3
  13. data/app/views/devise/unlocks/new.html.erb +1 -1
  14. data/config/locales/en.yml +2 -2
  15. data/gemfiles/Gemfile.rails-3.1.x.lock +3 -3
  16. data/lib/devise.rb +1 -0
  17. data/lib/devise/controllers/helpers.rb +1 -1
  18. data/lib/devise/encryptors/base.rb +5 -1
  19. data/lib/devise/encryptors/bcrypt.rb +14 -0
  20. data/lib/devise/failure_app.rb +1 -0
  21. data/lib/devise/models.rb +32 -2
  22. data/lib/devise/models/authenticatable.rb +15 -10
  23. data/lib/devise/models/confirmable.rb +21 -1
  24. data/lib/devise/models/database_authenticatable.rb +11 -5
  25. data/lib/devise/models/encryptable.rb +17 -9
  26. data/lib/devise/models/lockable.rb +17 -1
  27. data/lib/devise/models/omniauthable.rb +4 -0
  28. data/lib/devise/models/recoverable.rb +4 -0
  29. data/lib/devise/models/registerable.rb +4 -0
  30. data/lib/devise/models/rememberable.rb +6 -2
  31. data/lib/devise/models/timeoutable.rb +4 -0
  32. data/lib/devise/models/token_authenticatable.rb +5 -0
  33. data/lib/devise/models/trackable.rb +4 -0
  34. data/lib/devise/models/validatable.rb +4 -0
  35. data/lib/devise/param_filter.rb +2 -1
  36. data/lib/devise/rails/routes.rb +3 -2
  37. data/lib/devise/strategies/authenticatable.rb +10 -4
  38. data/lib/devise/version.rb +1 -1
  39. data/lib/generators/devise/views_generator.rb +15 -6
  40. data/lib/generators/templates/devise.rb +1 -1
  41. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +1 -1
  42. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +1 -1
  43. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +1 -1
  44. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +1 -1
  45. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +1 -1
  46. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +1 -1
  47. data/test/generators/views_generator_test.rb +1 -1
  48. data/test/integration/omniauthable_test.rb +2 -2
  49. data/test/integration/recoverable_test.rb +9 -0
  50. data/test/models/authenticatable_test.rb +3 -5
  51. data/test/models/confirmable_test.rb +26 -0
  52. data/test/models/database_authenticatable_test.rb +29 -7
  53. data/test/models/encryptable_test.rb +6 -0
  54. data/test/models/lockable_test.rb +34 -0
  55. data/test/models/omniauthable_test.rb +7 -0
  56. data/test/models/recoverable_test.rb +8 -1
  57. data/test/models/registerable_test.rb +7 -0
  58. data/test/models/rememberable_test.rb +8 -1
  59. data/test/models/timeoutable_test.rb +4 -0
  60. data/test/models/token_authenticatable_test.rb +6 -0
  61. data/test/models/trackable_test.rb +9 -1
  62. data/test/models/validatable_test.rb +5 -1
  63. data/test/models_test.rb +70 -0
  64. data/test/rails_app/config/routes.rb +4 -0
  65. data/test/routes_test.rb +4 -0
  66. data/test/support/assertions.rb +15 -0
  67. data/test/support/helpers.rb +21 -0
  68. metadata +19 -34
data/.travis.yml CHANGED
@@ -1,5 +1,4 @@
1
1
  script: "bundle exec rake test"
2
- before_install: gem update --system
3
2
  rvm:
4
3
  - 1.8.7
5
4
  - 1.9.2
data/CHANGELOG.rdoc CHANGED
@@ -1,16 +1,22 @@
1
- == 2.0.6
1
+ == 2.1.0.dev
2
2
 
3
- * bug fix
4
- * Do not confirm account after reset password
5
-
6
- == 2.0.5
3
+ * enhancements
4
+ * Add check_fields! method on Devise::Models to check if the model includes the fields that Devise uses
5
+ * Add `skip_reconfirmation!` to skip reconfirmation
7
6
 
8
7
  * bug fix
9
- * Require string conversion for all values
8
+ * Ensure after sign in hook is not called without a resource
9
+ * Fix a term: now on Omniauth related flash messages, we say that we're authenticating from an omniauth provider instead of authorizing
10
+
11
+ * deprecation
12
+ * All devise modules should have a required_fields(klass) module method to help gathering missing attributes
10
13
 
11
14
  == 2.0.4
12
15
 
16
+ Notes: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0
17
+
13
18
  * bug fix
19
+ * Fix when :host is used with devise_for (by @mreinsch)
14
20
  * Fix a regression that caused Warden to be initialized too late
15
21
 
16
22
  == 2.0.3 (yanked)
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- devise (2.0.6)
4
+ devise (2.0.4)
5
5
  bcrypt-ruby (~> 3.0)
6
6
  orm_adapter (~> 0.0.3)
7
7
  railties (~> 3.1)
@@ -39,7 +39,7 @@ GEM
39
39
  multi_json (~> 1.0)
40
40
  addressable (2.2.6)
41
41
  arel (3.0.0)
42
- bcrypt-ruby (3.1.1)
42
+ bcrypt-ruby (3.0.1)
43
43
  bson (1.5.1)
44
44
  bson_ext (1.3.1)
45
45
  builder (3.0.0)
@@ -87,7 +87,7 @@ GEM
87
87
  omniauth-openid (1.0.1)
88
88
  omniauth (~> 1.0)
89
89
  rack-openid (~> 1.3.1)
90
- orm_adapter (0.0.7)
90
+ orm_adapter (0.0.6)
91
91
  polyglot (0.3.3)
92
92
  rack (1.4.1)
93
93
  rack-cache (1.1)
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- *IMPORTANT:* Devise 2.0.0 is out. If you are upgrading, please read: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0
1
+ *IMPORTANT:* Devise 2.0 is out. If you are upgrading, please read: https://github.com/plataformatec/devise/wiki/How-To:-Upgrade-to-Devise-2.0
2
2
 
3
3
  ## Devise
4
4
 
@@ -109,6 +109,8 @@ rails generate devise MODEL
109
109
 
110
110
  Replace MODEL by the class name used for the applications users, it's frequently 'User' but could also be 'Admin'. This will create a model (if one does not exist) and configure it with default Devise modules. Next, you'll usually run "rake db:migrate" as the generator will have created a migration file (if your ORM supports them). This generator also configures your config/routes.rb file to point to Devise controller.
111
111
 
112
+ Note that you should re-start your app here if you've already started it. Otherwise you'll run into strange errors like users being unable to login and the route helpers being undefined.
113
+
112
114
  ### Controller filters and helpers
113
115
 
114
116
  Devise will create some helpers to use inside your controllers and views. To set up a controller with user authentication, just add this before_filter:
@@ -135,13 +137,13 @@ You can access the session for this scope:
135
137
  user_session
136
138
  ```
137
139
 
138
- After signing in a user, confirming the account or updating the password, Devise will look for a scoped root path to redirect. Example: For a :user resource, it will use +user_root_path+ if it exists, otherwise default +root_path+ will be used. This means that you need to set the root inside your routes:
140
+ After signing in a user, confirming the account or updating the password, Devise will look for a scoped root path to redirect. Example: For a :user resource, it will use `user_root_path` if it exists, otherwise default `root_path` will be used. This means that you need to set the root inside your routes:
139
141
 
140
142
  ```ruby
141
143
  root :to => "home#index"
142
144
  ```
143
145
 
144
- You can also overwrite +after_sign_in_path_for+ and +after_sign_out_path_for+ to customize your redirect hooks.
146
+ You can also overwrite `after_sign_in_path_for` and `after_sign_out_path_for` to customize your redirect hooks.
145
147
 
146
148
  Finally, you need to set up default url options for the mailer in each environment. Here is the configuration for "config/environments/development.rb":
147
149
 
@@ -247,9 +249,9 @@ Devise also ships with default routes. If you need to customize them, you should
247
249
  devise_for :users, :path => "usuarios", :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification', :unlock => 'unblock', :registration => 'register', :sign_up => 'cmon_let_me_in' }
248
250
  ```
249
251
 
250
- Be sure to check +devise_for+ documentation for details.
252
+ Be sure to check `devise_for` documentation for details.
251
253
 
252
- If you have the need for more deep customization, for instance to also allow "/sign_in" besides "/users/sign_in", all you need to do is to create your routes normally and wrap them in a +devise_scope+ block in the router:
254
+ If you have the need for more deep customization, for instance to also allow "/sign_in" besides "/users/sign_in", all you need to do is to create your routes normally and wrap them in a `devise_scope` block in the router:
253
255
 
254
256
  ```ruby
255
257
  devise_scope :user do
@@ -257,15 +259,7 @@ devise_scope :user do
257
259
  end
258
260
  ```
259
261
 
260
- This way you tell devise to use the scope :user when "/sign_in" is accessed. Notice +devise_scope+ is also aliased as +as+ and you can also give a block to +devise_for+, resulting in the same behavior:
261
-
262
- ```ruby
263
- devise_for :users do
264
- get "sign_in", :to => "devise/sessions#new"
265
- end
266
- ```
267
-
268
- Feel free to choose the one you prefer!
262
+ This way you tell devise to use the scope :user when "/sign_in" is accessed. Notice `devise_scope` is also aliased as `as` in your router.
269
263
 
270
264
  ### I18n
271
265
 
@@ -327,7 +321,7 @@ class ActionController::TestCase
327
321
  end
328
322
  ```
329
323
 
330
- If you're using RSpec and want the helpers automatically included within all +describe+ blocks, add a file called spec/support/devise.rb with the following contents:
324
+ If you're using RSpec and want the helpers automatically included within all `describe` blocks, add a file called spec/support/devise.rb with the following contents:
331
325
 
332
326
  ```ruby
333
327
  RSpec.configure do |config|
@@ -89,8 +89,7 @@ MESSAGE
89
89
  warden.authenticated?(resource_name)
90
90
  end
91
91
 
92
- if authenticated
93
- resource = warden.user(resource_name)
92
+ if authenticated && resource = warden.user(resource_name)
94
93
  flash[:alert] = I18n.t("devise.failure.already_authenticated")
95
94
  redirect_to after_sign_in_path_for(resource)
96
95
  end
@@ -162,4 +161,4 @@ MESSAGE
162
161
  super
163
162
  end
164
163
  end
165
- end
164
+ end
@@ -1,25 +1,3 @@
1
- <%- if controller_name != 'sessions' %>
2
- <%= link_to "Sign in", new_session_path(resource_name) %><br />
3
- <% end -%>
4
-
5
- <%- if devise_mapping.registerable? && controller_name != 'registrations' %>
6
- <%= link_to "Sign up", new_registration_path(resource_name) %><br />
7
- <% end -%>
8
-
9
- <%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
10
- <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
11
- <% end -%>
12
-
13
- <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
14
- <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
15
- <% end -%>
16
-
17
- <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
18
- <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
19
- <% end -%>
20
-
21
- <%- if devise_mapping.omniauthable? %>
22
- <%- resource_class.omniauth_providers.each do |provider| %>
23
- <%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
24
- <% end -%>
25
- <% end -%>
1
+ <% ActiveSupport::Deprecation.warn "Rendering partials devise/_links.erb is deprecated" \
2
+ "please use devise/shared/_links.erb instead."%>
3
+ <%= render "shared/links" %>
@@ -9,4 +9,4 @@
9
9
  <div><%= f.submit "Resend confirmation instructions" %></div>
10
10
  <% end %>
11
11
 
12
- <%= render "links" %>
12
+ <%= render :partial => "devise/shared/links" %>
@@ -13,4 +13,4 @@
13
13
  <div><%= f.submit "Change my password" %></div>
14
14
  <% end %>
15
15
 
16
- <%= render "links" %>
16
+ <%= render :partial => "devise/shared/links" %>
@@ -9,4 +9,4 @@
9
9
  <div><%= f.submit "Send me reset password instructions" %></div>
10
10
  <% end %>
11
11
 
12
- <%= render "links" %>
12
+ <%= render :partial => "devise/shared/links" %>
@@ -15,4 +15,4 @@
15
15
  <div><%= f.submit "Sign up" %></div>
16
16
  <% end %>
17
17
 
18
- <%= render "links" %>
18
+ <%= render :partial => "devise/shared/links" %>
@@ -14,4 +14,4 @@
14
14
  <div><%= f.submit "Sign in" %></div>
15
15
  <% end %>
16
16
 
17
- <%= render "links" %>
17
+ <%= render :partial => "devise/shared/links" %>
@@ -1,3 +1,25 @@
1
- <% ActiveSupport::Deprecation.warn "Rendering partials devise/shared/_links.erb is deprecated" \
2
- "please use devise/_links.erb instead." %>
3
- <%= render "links" %>
1
+ <%- if controller_name != 'sessions' %>
2
+ <%= link_to "Sign in", new_session_path(resource_name) %><br />
3
+ <% end -%>
4
+
5
+ <%- if devise_mapping.registerable? && controller_name != 'registrations' %>
6
+ <%= link_to "Sign up", new_registration_path(resource_name) %><br />
7
+ <% end -%>
8
+
9
+ <%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
10
+ <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
11
+ <% end -%>
12
+
13
+ <%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
14
+ <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
15
+ <% end -%>
16
+
17
+ <%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
18
+ <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
19
+ <% end -%>
20
+
21
+ <%- if devise_mapping.omniauthable? %>
22
+ <%- resource_class.omniauth_providers.each do |provider| %>
23
+ <%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
24
+ <% end -%>
25
+ <% end -%>
@@ -9,4 +9,4 @@
9
9
  <div><%= f.submit "Resend unlock instructions" %></div>
10
10
  <% end %>
11
11
 
12
- <%= render "links" %>
12
+ <%= render :partial => "devise/shared/links" %>
@@ -46,8 +46,8 @@ en:
46
46
  unlocked: 'Your account has been unlocked successfully. Please sign in to continue.'
47
47
  send_paranoid_instructions: 'If your account exists, you will receive an email with instructions about how to unlock it in a few minutes.'
48
48
  omniauth_callbacks:
49
- success: 'Successfully authorized from %{kind} account.'
50
- failure: 'Could not authorize you from %{kind} because "%{reason}".'
49
+ success: 'Successfully authenticated from %{kind} account.'
50
+ failure: 'Could not authenticate you from %{kind} because "%{reason}".'
51
51
  mailer:
52
52
  confirmation_instructions:
53
53
  subject: 'Confirmation instructions'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- devise (2.0.6)
4
+ devise (2.0.2)
5
5
  bcrypt-ruby (~> 3.0)
6
6
  orm_adapter (~> 0.0.3)
7
7
  railties (~> 3.1)
@@ -40,7 +40,7 @@ GEM
40
40
  multi_json (~> 1.0)
41
41
  addressable (2.2.7)
42
42
  arel (2.2.1)
43
- bcrypt-ruby (3.1.1)
43
+ bcrypt-ruby (3.0.1)
44
44
  bson (1.5.2)
45
45
  bson_ext (1.3.1)
46
46
  builder (3.0.0)
@@ -87,7 +87,7 @@ GEM
87
87
  omniauth-openid (1.0.1)
88
88
  omniauth (~> 1.0)
89
89
  rack-openid (~> 1.3.1)
90
- orm_adapter (0.0.7)
90
+ orm_adapter (0.0.6)
91
91
  polyglot (0.3.3)
92
92
  rack (1.3.6)
93
93
  rack-cache (1.1)
data/lib/devise.rb CHANGED
@@ -23,6 +23,7 @@ module Devise
23
23
  module Encryptors
24
24
  autoload :Base, 'devise/encryptors/base'
25
25
  autoload :AuthlogicSha512, 'devise/encryptors/authlogic_sha512'
26
+ autoload :BCrypt, 'devise/encryptors/bcrypt'
26
27
  autoload :ClearanceSha1, 'devise/encryptors/clearance_sha1'
27
28
  autoload :RestfulAuthenticationSha1, 'devise/encryptors/restful_authentication_sha1'
28
29
  autoload :Sha512, 'devise/encryptors/sha512'
@@ -208,7 +208,7 @@ module Devise
208
208
  # if resource.is_a?(User) && resource.can_publish?
209
209
  # publisher_url
210
210
  # else
211
- # signed_in_root_path(resource)
211
+ # super
212
212
  # end
213
213
  # end
214
214
  #
@@ -15,6 +15,10 @@ module Devise
15
15
  def self.salt(stretches)
16
16
  Devise.friendly_token[0,20]
17
17
  end
18
+
19
+ def self.compare(encrypted_password, password, stretches, salt, pepper)
20
+ Devise.secure_compare(encrypted_password, digest(password, stretches, salt, pepper))
21
+ end
18
22
  end
19
23
  end
20
- end
24
+ end
@@ -0,0 +1,14 @@
1
+ module Devise
2
+ module Encryptors
3
+ class BCrypt < Base
4
+ def self.digest(password, stretches, salt, pepper)
5
+ ::BCrypt::Engine.hash_secret("#{password}#{pepper}",salt, stretches)
6
+ end
7
+
8
+ def self.compare(encrypted_password, password, stretches, salt, pepper)
9
+ salt = ::BCrypt::Password.new(encrypted_password).salt
10
+ Devise.secure_compare(encrypted_password, digest(password, stretches, salt, pepper))
11
+ end
12
+ end
13
+ end
14
+ end
@@ -88,6 +88,7 @@ module Devise
88
88
  opts = {}
89
89
  route = :"new_#{scope}_session_path"
90
90
  opts[:format] = request_format unless skip_format?
91
+ opts[:script_name] = nil
91
92
 
92
93
  context = send(Devise.available_router_name)
93
94
 
data/lib/devise/models.rb CHANGED
@@ -1,5 +1,15 @@
1
1
  module Devise
2
2
  module Models
3
+ class MissingAttribute < StandardError
4
+ def initialize(attributes)
5
+ @attributes = attributes
6
+ end
7
+
8
+ def message
9
+ "The following attribute(s) is (are) missing on your model: #{@attributes.join(", ")}"
10
+ end
11
+ end
12
+
3
13
  # Creates configuration values for Devise and for the given module.
4
14
  #
5
15
  # Devise::Models.config(Devise::Authenticatable, :stretches, 10)
@@ -39,6 +49,26 @@ module Devise
39
49
  end
40
50
  end
41
51
 
52
+ def self.check_fields!(klass)
53
+ failed_attributes = []
54
+
55
+ klass.devise_modules.each do |mod|
56
+ instance = klass.new
57
+
58
+ if const_get(mod.to_s.classify).respond_to?(:required_fields)
59
+ const_get(mod.to_s.classify).required_fields(klass).each do |field|
60
+ failed_attributes << field unless instance.respond_to?(field)
61
+ end
62
+ else
63
+ ActiveSupport::Deprecation.warn "The module #{mod} doesn't implement self.required_fields(klass). Devise uses required_fields to warn developers of any missing fields in their models. Please implement #{mod}.required_fields(klass) that returns an array of symbols with the required fields."
64
+ end
65
+ end
66
+
67
+ if failed_attributes.any?
68
+ fail Devise::Models::MissingAttribute.new(failed_attributes)
69
+ end
70
+ end
71
+
42
72
  # Include the chosen devise modules in your model:
43
73
  #
44
74
  # devise :database_authenticatable, :confirmable, :recoverable
@@ -66,7 +96,7 @@ module Devise
66
96
  if class_mod.respond_to?(:available_configs)
67
97
  available_configs = class_mod.available_configs
68
98
  available_configs.each do |config|
69
- next unless options.key?(config)
99
+ next unless options.key?(config)
70
100
  send(:"#{config}=", options.delete(config))
71
101
  end
72
102
  end
@@ -88,4 +118,4 @@ module Devise
88
118
  end
89
119
  end
90
120
 
91
- require 'devise/models/authenticatable'
121
+ require 'devise/models/authenticatable'
@@ -64,6 +64,10 @@ module Devise
64
64
  before_validation :strip_whitespace
65
65
  end
66
66
 
67
+ def self.required_fields(klass)
68
+ []
69
+ end
70
+
67
71
  # Check if the current object is valid for authentication. This method and
68
72
  # find_for_authentication are the methods used in a Warden::Strategy to check
69
73
  # if a model should be signed in or not.
@@ -74,6 +78,10 @@ module Devise
74
78
  block_given? ? yield : true
75
79
  end
76
80
 
81
+ def unauthenticated_message
82
+ :invalid
83
+ end
84
+
77
85
  def active_for_authentication?
78
86
  true
79
87
  end
@@ -154,20 +162,17 @@ module Devise
154
162
  # namedscope to filter records while authenticating.
155
163
  # Example:
156
164
  #
157
- # def self.find_for_authentication(tainted_conditions)
158
- # find_first_by_auth_conditions(tainted_conditions, :active => true)
165
+ # def self.find_for_authentication(conditions={})
166
+ # conditions[:active] = true
167
+ # super
159
168
  # end
160
169
  #
161
- # Finally, notice that Devise also queries for users in other scenarios
162
- # besides authentication, for example when retrieving an user to send
163
- # an e-mail for password reset. In such cases, find_for_authentication
164
- # is not called.
165
- def find_for_authentication(tainted_conditions)
166
- find_first_by_auth_conditions(tainted_conditions)
170
+ def find_for_authentication(conditions)
171
+ find_first_by_auth_conditions(conditions)
167
172
  end
168
173
 
169
- def find_first_by_auth_conditions(tainted_conditions, opts={})
170
- to_adapter.find_first(devise_param_filter.filter(tainted_conditions).merge(opts))
174
+ def find_first_by_auth_conditions(conditions)
175
+ to_adapter.find_first devise_param_filter.filter(conditions)
171
176
  end
172
177
 
173
178
  # Find an initialize a record setting an error if it can't be found.