devise 0.9.2 → 1.0.0

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 (54) hide show
  1. data/CHANGELOG.rdoc +11 -0
  2. data/README.rdoc +3 -2
  3. data/TODO +0 -1
  4. data/app/controllers/confirmations_controller.rb +18 -7
  5. data/app/controllers/passwords_controller.rb +18 -7
  6. data/app/controllers/registrations_controller.rb +55 -0
  7. data/app/controllers/sessions_controller.rb +17 -5
  8. data/app/controllers/unlocks_controller.rb +18 -7
  9. data/app/models/devise_mailer.rb +3 -2
  10. data/app/views/registrations/edit.html.erb +25 -0
  11. data/app/views/registrations/new.html.erb +17 -0
  12. data/app/views/sessions/new.html.erb +10 -12
  13. data/app/views/shared/_devise_links.erb +5 -1
  14. data/generators/devise_install/templates/devise.rb +3 -1
  15. data/lib/devise.rb +15 -8
  16. data/lib/devise/controllers/helpers.rb +1 -1
  17. data/lib/devise/controllers/internal_helpers.rb +15 -6
  18. data/lib/devise/controllers/url_helpers.rb +7 -7
  19. data/lib/devise/locales/en.yml +6 -0
  20. data/lib/devise/mapping.rb +9 -15
  21. data/lib/devise/models.rb +9 -16
  22. data/lib/devise/models/authenticatable.rb +38 -8
  23. data/lib/devise/models/lockable.rb +42 -24
  24. data/lib/devise/models/registerable.rb +8 -0
  25. data/lib/devise/models/timeoutable.rb +1 -1
  26. data/lib/devise/orm/active_record.rb +3 -2
  27. data/lib/devise/orm/data_mapper.rb +3 -3
  28. data/lib/devise/orm/mongo_mapper.rb +3 -3
  29. data/lib/devise/rails/routes.rb +9 -6
  30. data/lib/devise/strategies/authenticatable.rb +11 -1
  31. data/lib/devise/strategies/base.rb +5 -13
  32. data/lib/devise/strategies/http_authenticatable.rb +49 -0
  33. data/lib/devise/strategies/rememberable.rb +1 -1
  34. data/lib/devise/strategies/token_authenticatable.rb +9 -10
  35. data/lib/devise/version.rb +1 -1
  36. data/test/devise_test.rb +1 -1
  37. data/test/integration/authenticatable_test.rb +59 -43
  38. data/test/integration/http_authenticatable_test.rb +44 -0
  39. data/test/integration/registerable_test.rb +130 -0
  40. data/test/integration/token_authenticatable_test.rb +4 -4
  41. data/test/mailers/confirmation_instructions_test.rb +9 -0
  42. data/test/mapping_test.rb +14 -10
  43. data/test/models/authenticatable_test.rb +31 -9
  44. data/test/models/lockable_test.rb +8 -8
  45. data/test/models_test.rb +1 -1
  46. data/test/rails_app/app/active_record/admin.rb +1 -1
  47. data/test/rails_app/app/active_record/user.rb +4 -2
  48. data/test/rails_app/config/routes.rb +3 -2
  49. data/test/routes_test.rb +35 -0
  50. data/test/support/integration_tests_helper.rb +5 -1
  51. data/test/support/tests_helper.rb +35 -1
  52. metadata +9 -4
  53. data/lib/devise/controllers/common.rb +0 -24
  54. data/test/support/model_tests_helper.rb +0 -36
@@ -1,3 +1,14 @@
1
+ == 1.0.0
2
+
3
+ * deprecation
4
+ * :old_password in update_with_password is deprecated, use :current_password instead
5
+
6
+ * enhancements
7
+ * Added Registerable
8
+ * Added Http Basic Authentication support
9
+ * Allow scoped_views to be customized per controller/mailer class
10
+ * [#99] Allow authenticatable to used in change_table statements
11
+
1
12
  == 0.9.2
2
13
 
3
14
  * bug fix
@@ -7,11 +7,12 @@ Devise is a flexible authentication solution for Rails based on Warden. It:
7
7
  * Allows you to have multiple roles (or models/scopes) signed in at the same time;
8
8
  * Is based on a modularity concept: use just what you really need.
9
9
 
10
- Right now it's composed of nine modules:
10
+ Right now it's composed of ten modules:
11
11
 
12
12
  * Authenticatable: responsible for encrypting password and validating authenticity of a user while signing in.
13
13
  * Confirmable: responsible for verifying whether an account is already confirmed to sign in, and to send emails with confirmation instructions.
14
14
  * Recoverable: takes care of reseting the user password and send reset instructions.
15
+ * Registerable: handles signing up users through a registration process.
15
16
  * Rememberable: manages generating and clearing token for remember the user from a saved cookie.
16
17
  * Trackable: tracks sign in count, timestamps and ip.
17
18
  * Validatable: creates all needed validations for email and password. It's totally optional, so you're able to to customize validations by yourself.
@@ -170,7 +171,7 @@ Since devise is an engine, it has all default views inside the gem. They are goo
170
171
 
171
172
  ruby script/generate devise_views
172
173
 
173
- By default Devise will use the same views for all roles you have. But what if you need so different views to each of them? Devise also has an easy way to accomplish it: just setup config.scoped_views to true inside "config/initializers/devise.rb".
174
+ By default Devise will use the same views for all roles you have. But what if you need so different views to each of them? Devise also has an easy way to accomplish it: just setup config.scoped_views to true inside "config/initializers/devise.rb".
174
175
 
175
176
  After doing so you will be able to have views based on the scope like 'sessions/users/new' and 'sessions/admin/new'. If no view is found within the scope, Devise will fallback to the default view.
176
177
 
data/TODO CHANGED
@@ -1,4 +1,3 @@
1
1
  * Make test run with DataMapper
2
2
  * Add Registerable support
3
- * Add http authentication support
4
3
  * Extract Activatable tests from Confirmable
@@ -1,6 +1,23 @@
1
1
  class ConfirmationsController < ApplicationController
2
2
  include Devise::Controllers::InternalHelpers
3
- include Devise::Controllers::Common
3
+
4
+ # GET /resource/confirmation/new
5
+ def new
6
+ build_resource
7
+ render_with_scope :new
8
+ end
9
+
10
+ # POST /resource/confirmation
11
+ def create
12
+ self.resource = resource_class.send_confirmation_instructions(params[resource_name])
13
+
14
+ if resource.errors.empty?
15
+ set_flash_message :notice, :send_instructions
16
+ redirect_to new_session_path(resource_name)
17
+ else
18
+ render_with_scope :new
19
+ end
20
+ end
4
21
 
5
22
  # GET /resource/confirmation?confirmation_token=abcdef
6
23
  def show
@@ -13,10 +30,4 @@ class ConfirmationsController < ApplicationController
13
30
  render_with_scope :new
14
31
  end
15
32
  end
16
-
17
- protected
18
-
19
- def send_instructions_with
20
- :send_confirmation_instructions
21
- end
22
33
  end
@@ -1,9 +1,26 @@
1
1
  class PasswordsController < ApplicationController
2
2
  include Devise::Controllers::InternalHelpers
3
- include Devise::Controllers::Common
4
3
 
5
4
  before_filter :require_no_authentication
6
5
 
6
+ # GET /resource/password/new
7
+ def new
8
+ build_resource
9
+ render_with_scope :new
10
+ end
11
+
12
+ # POST /resource/password
13
+ def create
14
+ self.resource = resource_class.send_reset_password_instructions(params[resource_name])
15
+
16
+ if resource.errors.empty?
17
+ set_flash_message :notice, :send_instructions
18
+ redirect_to new_session_path(resource_name)
19
+ else
20
+ render_with_scope :new
21
+ end
22
+ end
23
+
7
24
  # GET /resource/password/edit?reset_password_token=abcdef
8
25
  def edit
9
26
  self.resource = resource_class.new
@@ -22,10 +39,4 @@ class PasswordsController < ApplicationController
22
39
  render_with_scope :edit
23
40
  end
24
41
  end
25
-
26
- protected
27
-
28
- def send_instructions_with
29
- :send_reset_password_instructions
30
- end
31
42
  end
@@ -0,0 +1,55 @@
1
+ class RegistrationsController < ApplicationController
2
+ include Devise::Controllers::InternalHelpers
3
+
4
+ before_filter :require_no_authentication, :only => [ :new, :create ]
5
+ before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]
6
+
7
+ # GET /resource/sign_in
8
+ def new
9
+ build_resource
10
+ render_with_scope :new
11
+ end
12
+
13
+ # POST /resource/sign_up
14
+ def create
15
+ build_resource
16
+
17
+ if resource.save
18
+ flash[:"#{resource_name}_signed_up"] = true
19
+ set_flash_message :notice, :signed_up
20
+ sign_in_and_redirect(resource_name, resource)
21
+ else
22
+ render_with_scope :new
23
+ end
24
+ end
25
+
26
+ # GET /resource/edit
27
+ def edit
28
+ render_with_scope :edit
29
+ end
30
+
31
+ # PUT /resource
32
+ def update
33
+ if self.resource.update_with_password(params[resource_name])
34
+ set_flash_message :notice, :updated
35
+ redirect_to after_sign_in_path_for(self.resource)
36
+ else
37
+ render_with_scope :edit
38
+ end
39
+ end
40
+
41
+ # DELETE /resource
42
+ def destroy
43
+ self.resource.destroy
44
+ set_flash_message :notice, :destroyed
45
+ sign_out_and_redirect(self.resource)
46
+ end
47
+
48
+ protected
49
+
50
+ # Authenticates the current scope and dup the resource
51
+ def authenticate_scope!
52
+ send(:"authenticate_#{resource_name}!")
53
+ self.resource = send(:"current_#{resource_name}").dup
54
+ end
55
+ end
@@ -1,15 +1,18 @@
1
1
  class SessionsController < ApplicationController
2
2
  include Devise::Controllers::InternalHelpers
3
- include Devise::Controllers::Common
4
3
 
5
4
  before_filter :require_no_authentication, :only => [ :new, :create ]
6
5
 
7
6
  # GET /resource/sign_in
8
7
  def new
9
- Devise::FLASH_MESSAGES.each do |message|
10
- set_now_flash_message :alert, message if params.try(:[], message) == "true"
8
+ unless resource_just_signed_up?
9
+ Devise::FLASH_MESSAGES.each do |message|
10
+ set_now_flash_message :alert, message if params.try(:[], message) == "true"
11
+ end
11
12
  end
12
- super
13
+
14
+ build_resource
15
+ render_with_scope :new
13
16
  end
14
17
 
15
18
  # POST /resource/sign_in
@@ -19,7 +22,7 @@ class SessionsController < ApplicationController
19
22
  sign_in_and_redirect(resource_name, resource, true)
20
23
  else
21
24
  set_now_flash_message :alert, (warden.message || :invalid)
22
- build_resource
25
+ clean_up_passwords(build_resource)
23
26
  render_with_scope :new
24
27
  end
25
28
  end
@@ -30,4 +33,13 @@ class SessionsController < ApplicationController
30
33
  sign_out_and_redirect(resource_name)
31
34
  end
32
35
 
36
+ protected
37
+
38
+ def resource_just_signed_up?
39
+ flash[:"#{resource_name}_signed_up"]
40
+ end
41
+
42
+ def clean_up_passwords(object)
43
+ object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
44
+ end
33
45
  end
@@ -1,6 +1,23 @@
1
1
  class UnlocksController < ApplicationController
2
2
  include Devise::Controllers::InternalHelpers
3
- include Devise::Controllers::Common
3
+
4
+ # GET /resource/unlock/new
5
+ def new
6
+ build_resource
7
+ render_with_scope :new
8
+ end
9
+
10
+ # POST /resource/unlock
11
+ def create
12
+ self.resource = resource_class.send_unlock_instructions(params[resource_name])
13
+
14
+ if resource.errors.empty?
15
+ set_flash_message :notice, :send_instructions
16
+ redirect_to new_session_path(resource_name)
17
+ else
18
+ render_with_scope :new
19
+ end
20
+ end
4
21
 
5
22
  # GET /resource/unlock?unlock_token=abcdef
6
23
  def show
@@ -13,10 +30,4 @@ class UnlocksController < ApplicationController
13
30
  render_with_scope :new
14
31
  end
15
32
  end
16
-
17
- protected
18
-
19
- def send_instructions_with
20
- :send_unlock_instructions
21
- end
22
33
  end
@@ -1,4 +1,5 @@
1
1
  class DeviseMailer < ::ActionMailer::Base
2
+ extend Devise::Controllers::InternalHelpers::ScopedViews
2
3
 
3
4
  # Deliver confirmation instructions when the user is created or its email is
4
5
  # updated, and also when confirmation is manually requested
@@ -31,7 +32,7 @@ class DeviseMailer < ::ActionMailer::Base
31
32
  end
32
33
 
33
34
  def render_with_scope(key, mapping, assigns)
34
- if Devise.scoped_views
35
+ if self.class.scoped_views
35
36
  begin
36
37
  render :file => "devise_mailer/#{mapping.as}/#{key}", :body => assigns
37
38
  rescue ActionView::MissingTemplate
@@ -45,7 +46,7 @@ class DeviseMailer < ::ActionMailer::Base
45
46
  def mailer_sender(mapping)
46
47
  if Devise.mailer_sender.is_a?(Proc)
47
48
  block_args = mapping.name if Devise.mailer_sender.arity > 0
48
- Devise.mailer_sender.call(*block_args)
49
+ Devise.mailer_sender.call(block_args)
49
50
  else
50
51
  Devise.mailer_sender
51
52
  end
@@ -0,0 +1,25 @@
1
+ <h2>Edit <%= resource_name.to_s.humanize %></h2>
2
+
3
+ <% form_for resource_name, resource, :url => registration_path(resource_name), :html => { :method => :put } do |f| -%>
4
+ <%= f.error_messages %>
5
+
6
+ <p><%= f.label :email %></p>
7
+ <p><%= f.text_field :email %></p>
8
+
9
+ <p><%= f.label :password %> <i>(leave blank if you don't want to change it)</i></p>
10
+ <p><%= f.password_field :password %></p>
11
+
12
+ <p><%= f.label :password_confirmation %></p>
13
+ <p><%= f.password_field :password_confirmation %></p>
14
+
15
+ <p><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i></p>
16
+ <p><%= f.password_field :current_password %></p>
17
+
18
+ <p><%= f.submit "Update" %></p>
19
+ <% end -%>
20
+
21
+ <h3>Cancel my account</h3>
22
+
23
+ <p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete %>.</p>
24
+
25
+ <%= render :partial => "shared/devise_links" %>
@@ -0,0 +1,17 @@
1
+ <h2>Sign up</h2>
2
+
3
+ <% form_for resource_name, resource, :url => registration_path(resource_name) do |f| -%>
4
+ <%= f.error_messages %>
5
+ <p><%= f.label :email %></p>
6
+ <p><%= f.text_field :email %></p>
7
+
8
+ <p><%= f.label :password %></p>
9
+ <p><%= f.password_field :password %></p>
10
+
11
+ <p><%= f.label :password_confirmation %></p>
12
+ <p><%= f.password_field :password_confirmation %></p>
13
+
14
+ <p><%= f.submit "Sign up" %></p>
15
+ <% end -%>
16
+
17
+ <%= render :partial => "shared/devise_links" %>
@@ -1,19 +1,17 @@
1
1
  <h2>Sign in</h2>
2
2
 
3
- <%- if devise_mapping.authenticatable? %>
4
- <% form_for resource_name, resource, :url => session_path(resource_name) do |f| -%>
5
- <p><%= f.label :email %></p>
6
- <p><%= f.text_field :email %></p>
3
+ <% form_for resource_name, resource, :url => session_path(resource_name) do |f| -%>
4
+ <p><%= f.label :email %></p>
5
+ <p><%= f.text_field :email %></p>
7
6
 
8
- <p><%= f.label :password %></p>
9
- <p><%= f.password_field :password %></p>
7
+ <p><%= f.label :password %></p>
8
+ <p><%= f.password_field :password %></p>
10
9
 
11
- <% if devise_mapping.rememberable? -%>
12
- <p><%= f.check_box :remember_me %> <%= f.label :remember_me %></p>
13
- <% end -%>
14
-
15
- <p><%= f.submit "Sign in" %></p>
10
+ <% if devise_mapping.rememberable? -%>
11
+ <p><%= f.check_box :remember_me %> <%= f.label :remember_me %></p>
16
12
  <% end -%>
17
- <% end%>
13
+
14
+ <p><%= f.submit "Sign in" %></p>
15
+ <% end -%>
18
16
 
19
17
  <%= render :partial => "shared/devise_links" %>
@@ -2,6 +2,10 @@
2
2
  <%= link_to t('devise.sessions.link'), new_session_path(resource_name) %><br />
3
3
  <% end -%>
4
4
 
5
+ <%- if devise_mapping.registerable? && controller_name != 'registrations' %>
6
+ <%= link_to t('devise.registrations.link'), new_registration_path(resource_name) %><br />
7
+ <% end -%>
8
+
5
9
  <%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
6
10
  <%= link_to t('devise.passwords.link'), new_password_path(resource_name) %><br />
7
11
  <% end -%>
@@ -12,4 +16,4 @@
12
16
 
13
17
  <%- if devise_mapping.lockable? && controller_name != 'unlocks' %>
14
18
  <%= link_to t('devise.unlocks.link'), new_unlock_path(resource_name) %><br />
15
- <% end -%>
19
+ <% end -%>
@@ -26,6 +26,9 @@ Devise.setup do |config|
26
26
  # session. If you need permissions, you should implement that in a before filter.
27
27
  # config.authentication_keys = [ :email ]
28
28
 
29
+ # The realm used in Http Basic Authentication
30
+ # config.http_authentication_realm = "Application"
31
+
29
32
  # ==> Configuration for :confirmable
30
33
  # The time you want give to your user to confirm his account. During this time
31
34
  # he will be able to access your application without confirming. Default is nil.
@@ -93,7 +96,6 @@ Devise.setup do |config|
93
96
 
94
97
  # Configure default_url_options if you are using dynamic segments in :path_prefix
95
98
  # for devise_for.
96
- #
97
99
  # config.default_url_options do
98
100
  # { :locale => I18n.locale }
99
101
  # end
@@ -4,7 +4,6 @@ module Devise
4
4
  autoload :TestHelpers, 'devise/test_helpers'
5
5
 
6
6
  module Controllers
7
- autoload :Common, 'devise/controllers/common'
8
7
  autoload :Helpers, 'devise/controllers/helpers'
9
8
  autoload :InternalHelpers, 'devise/controllers/internal_helpers'
10
9
  autoload :UrlHelpers, 'devise/controllers/url_helpers'
@@ -32,7 +31,7 @@ module Devise
32
31
  ALL.push :authenticatable, :token_authenticatable, :rememberable
33
32
 
34
33
  # Misc after
35
- ALL.push :recoverable, :validatable
34
+ ALL.push :recoverable, :registerable, :validatable
36
35
 
37
36
  # The ones which can sign out after
38
37
  ALL.push :activatable, :confirmable, :lockable, :timeoutable
@@ -40,20 +39,24 @@ module Devise
40
39
  # Stats for last, so we make sure the user is really signed in
41
40
  ALL.push :trackable
42
41
 
43
- # Maps controller names to devise modules
42
+ # Maps controller names to devise modules.
44
43
  CONTROLLERS = {
45
44
  :sessions => [:authenticatable, :token_authenticatable],
46
45
  :passwords => [:recoverable],
47
46
  :confirmations => [:confirmable],
47
+ :registrations => [:registerable],
48
48
  :unlocks => [:lockable]
49
49
  }
50
50
 
51
- STRATEGIES = [:rememberable, :token_authenticatable, :authenticatable]
51
+ # Routes for generating url helpers.
52
+ ROUTES = [:session, :password, :confirmation, :registration, :unlock]
53
+
54
+ STRATEGIES = [:rememberable, :http_authenticatable, :token_authenticatable, :authenticatable]
52
55
 
53
56
  TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']
54
57
 
55
58
  # Maps the messages types that are used in flash message.
56
- FLASH_MESSAGES = [ :unauthenticated, :unconfirmed, :invalid, :invalid_token, :timeout, :inactive, :locked ]
59
+ FLASH_MESSAGES = [:unauthenticated, :unconfirmed, :invalid, :invalid_token, :timeout, :inactive, :locked]
57
60
 
58
61
  # Declare encryptors length which are used in migrations.
59
62
  ENCRYPTORS_LENGTH = {
@@ -133,7 +136,7 @@ module Devise
133
136
 
134
137
  # Tell when to use the default scope, if one cannot be found from routes.
135
138
  mattr_accessor :use_default_scope
136
- @@use_default_scope
139
+ @@use_default_scope = false
137
140
 
138
141
  # The default scope which is used by warden.
139
142
  mattr_accessor :default_scope
@@ -141,12 +144,16 @@ module Devise
141
144
 
142
145
  # Address which sends Devise e-mails.
143
146
  mattr_accessor :mailer_sender
144
- @@mailer_sender
147
+ @@mailer_sender = nil
145
148
 
146
149
  # Authentication token params key name of choice. E.g. /users/sign_in?some_key=...
147
150
  mattr_accessor :token_authentication_key
148
151
  @@token_authentication_key = :auth_token
149
152
 
153
+ # The realm used in Http Basic Authentication
154
+ mattr_accessor :http_authentication_realm
155
+ @@http_authentication_realm = "Application"
156
+
150
157
  class << self
151
158
  # Default way to setup Devise. Run script/generate devise_install to create
152
159
  # a fresh initializer with all configuration values.
@@ -242,4 +249,4 @@ rescue
242
249
  end
243
250
 
244
251
  require 'devise/mapping'
245
- require 'devise/rails'
252
+ require 'devise/rails'