loyal_devise 2.1.2

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.
Files changed (208) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +15 -0
  3. data/CHANGELOG.rdoc +881 -0
  4. data/CONTRIBUTING.md +12 -0
  5. data/Gemfile +31 -0
  6. data/Gemfile.lock +154 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +388 -0
  9. data/Rakefile +34 -0
  10. data/app/controllers/devise/confirmations_controller.rb +44 -0
  11. data/app/controllers/devise/omniauth_callbacks_controller.rb +31 -0
  12. data/app/controllers/devise/passwords_controller.rb +57 -0
  13. data/app/controllers/devise/registrations_controller.rb +120 -0
  14. data/app/controllers/devise/sessions_controller.rb +51 -0
  15. data/app/controllers/devise/unlocks_controller.rb +45 -0
  16. data/app/controllers/devise_controller.rb +193 -0
  17. data/app/helpers/devise_helper.rb +26 -0
  18. data/app/mailers/devise/mailer.rb +16 -0
  19. data/app/views/devise/_links.erb +3 -0
  20. data/app/views/devise/confirmations/new.html.erb +12 -0
  21. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  22. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  23. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  24. data/app/views/devise/passwords/edit.html.erb +16 -0
  25. data/app/views/devise/passwords/new.html.erb +12 -0
  26. data/app/views/devise/registrations/edit.html.erb +25 -0
  27. data/app/views/devise/registrations/new.html.erb +18 -0
  28. data/app/views/devise/sessions/new.html.erb +17 -0
  29. data/app/views/devise/shared/_links.erb +25 -0
  30. data/app/views/devise/unlocks/new.html.erb +12 -0
  31. data/config/locales/en.yml +59 -0
  32. data/devise.gemspec +26 -0
  33. data/gemfiles/Gemfile.rails-3.1.x +35 -0
  34. data/gemfiles/Gemfile.rails-3.1.x.lock +167 -0
  35. data/lib/devise/controllers/helpers.rb +273 -0
  36. data/lib/devise/controllers/rememberable.rb +53 -0
  37. data/lib/devise/controllers/scoped_views.rb +18 -0
  38. data/lib/devise/controllers/url_helpers.rb +68 -0
  39. data/lib/devise/delegator.rb +17 -0
  40. data/lib/devise/failure_app.rb +188 -0
  41. data/lib/devise/hooks/activatable.rb +12 -0
  42. data/lib/devise/hooks/forgetable.rb +10 -0
  43. data/lib/devise/hooks/lockable.rb +8 -0
  44. data/lib/devise/hooks/rememberable.rb +7 -0
  45. data/lib/devise/hooks/timeoutable.rb +26 -0
  46. data/lib/devise/hooks/trackable.rb +10 -0
  47. data/lib/devise/mailers/helpers.rb +92 -0
  48. data/lib/devise/mapping.rb +173 -0
  49. data/lib/devise/models/authenticatable.rb +269 -0
  50. data/lib/devise/models/confirmable.rb +271 -0
  51. data/lib/devise/models/database_authenticatable.rb +127 -0
  52. data/lib/devise/models/lockable.rb +194 -0
  53. data/lib/devise/models/omniauthable.rb +28 -0
  54. data/lib/devise/models/recoverable.rb +141 -0
  55. data/lib/devise/models/registerable.rb +26 -0
  56. data/lib/devise/models/rememberable.rb +126 -0
  57. data/lib/devise/models/timeoutable.rb +50 -0
  58. data/lib/devise/models/token_authenticatable.rb +90 -0
  59. data/lib/devise/models/trackable.rb +36 -0
  60. data/lib/devise/models/validatable.rb +67 -0
  61. data/lib/devise/models.rb +129 -0
  62. data/lib/devise/modules.rb +30 -0
  63. data/lib/devise/omniauth/config.rb +46 -0
  64. data/lib/devise/omniauth/url_helpers.rb +19 -0
  65. data/lib/devise/omniauth.rb +29 -0
  66. data/lib/devise/orm/active_record.rb +4 -0
  67. data/lib/devise/orm/mongoid.rb +4 -0
  68. data/lib/devise/param_filter.rb +42 -0
  69. data/lib/devise/rails/routes.rb +447 -0
  70. data/lib/devise/rails/warden_compat.rb +44 -0
  71. data/lib/devise/rails.rb +55 -0
  72. data/lib/devise/strategies/authenticatable.rb +177 -0
  73. data/lib/devise/strategies/base.rb +21 -0
  74. data/lib/devise/strategies/database_authenticatable.rb +21 -0
  75. data/lib/devise/strategies/rememberable.rb +56 -0
  76. data/lib/devise/strategies/token_authenticatable.rb +57 -0
  77. data/lib/devise/test_helpers.rb +132 -0
  78. data/lib/devise/time_inflector.rb +15 -0
  79. data/lib/devise/version.rb +4 -0
  80. data/lib/devise.rb +445 -0
  81. data/lib/generators/active_record/devise_generator.rb +80 -0
  82. data/lib/generators/active_record/templates/migration.rb +20 -0
  83. data/lib/generators/active_record/templates/migration_existing.rb +27 -0
  84. data/lib/generators/devise/devise_generator.rb +25 -0
  85. data/lib/generators/devise/install_generator.rb +25 -0
  86. data/lib/generators/devise/orm_helpers.rb +33 -0
  87. data/lib/generators/devise/views_generator.rb +117 -0
  88. data/lib/generators/mongoid/devise_generator.rb +58 -0
  89. data/lib/generators/templates/README +35 -0
  90. data/lib/generators/templates/devise.rb +241 -0
  91. data/lib/generators/templates/markerb/confirmation_instructions.markerb +5 -0
  92. data/lib/generators/templates/markerb/reset_password_instructions.markerb +8 -0
  93. data/lib/generators/templates/markerb/unlock_instructions.markerb +7 -0
  94. data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +15 -0
  95. data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +19 -0
  96. data/lib/generators/templates/simple_form_for/passwords/new.html.erb +15 -0
  97. data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +22 -0
  98. data/lib/generators/templates/simple_form_for/registrations/new.html.erb +17 -0
  99. data/lib/generators/templates/simple_form_for/sessions/new.html.erb +15 -0
  100. data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +15 -0
  101. data/test/controllers/custom_strategy_test.rb +63 -0
  102. data/test/controllers/helpers_test.rb +254 -0
  103. data/test/controllers/internal_helpers_test.rb +111 -0
  104. data/test/controllers/sessions_controller_test.rb +58 -0
  105. data/test/controllers/url_helpers_test.rb +60 -0
  106. data/test/delegator_test.rb +20 -0
  107. data/test/devise_test.rb +73 -0
  108. data/test/failure_app_test.rb +222 -0
  109. data/test/generators/active_record_generator_test.rb +76 -0
  110. data/test/generators/devise_generator_test.rb +40 -0
  111. data/test/generators/install_generator_test.rb +14 -0
  112. data/test/generators/mongoid_generator_test.rb +24 -0
  113. data/test/generators/views_generator_test.rb +53 -0
  114. data/test/helpers/devise_helper_test.rb +52 -0
  115. data/test/indifferent_hash.rb +34 -0
  116. data/test/integration/authenticatable_test.rb +634 -0
  117. data/test/integration/confirmable_test.rb +299 -0
  118. data/test/integration/database_authenticatable_test.rb +83 -0
  119. data/test/integration/http_authenticatable_test.rb +98 -0
  120. data/test/integration/lockable_test.rb +243 -0
  121. data/test/integration/omniauthable_test.rb +134 -0
  122. data/test/integration/recoverable_test.rb +307 -0
  123. data/test/integration/registerable_test.rb +346 -0
  124. data/test/integration/rememberable_test.rb +159 -0
  125. data/test/integration/timeoutable_test.rb +141 -0
  126. data/test/integration/token_authenticatable_test.rb +162 -0
  127. data/test/integration/trackable_test.rb +93 -0
  128. data/test/mailers/confirmation_instructions_test.rb +103 -0
  129. data/test/mailers/reset_password_instructions_test.rb +84 -0
  130. data/test/mailers/unlock_instructions_test.rb +78 -0
  131. data/test/mapping_test.rb +128 -0
  132. data/test/models/authenticatable_test.rb +8 -0
  133. data/test/models/confirmable_test.rb +392 -0
  134. data/test/models/database_authenticatable_test.rb +190 -0
  135. data/test/models/lockable_test.rb +274 -0
  136. data/test/models/omniauthable_test.rb +8 -0
  137. data/test/models/recoverable_test.rb +206 -0
  138. data/test/models/registerable_test.rb +8 -0
  139. data/test/models/rememberable_test.rb +175 -0
  140. data/test/models/serializable_test.rb +49 -0
  141. data/test/models/timeoutable_test.rb +47 -0
  142. data/test/models/token_authenticatable_test.rb +56 -0
  143. data/test/models/trackable_test.rb +14 -0
  144. data/test/models/validatable_test.rb +117 -0
  145. data/test/models_test.rb +180 -0
  146. data/test/omniauth/config_test.rb +58 -0
  147. data/test/omniauth/url_helpers_test.rb +52 -0
  148. data/test/orm/active_record.rb +10 -0
  149. data/test/orm/mongoid.rb +15 -0
  150. data/test/rails_app/Rakefile +10 -0
  151. data/test/rails_app/app/active_record/admin.rb +7 -0
  152. data/test/rails_app/app/active_record/shim.rb +3 -0
  153. data/test/rails_app/app/active_record/user.rb +7 -0
  154. data/test/rails_app/app/controllers/admins/sessions_controller.rb +7 -0
  155. data/test/rails_app/app/controllers/admins_controller.rb +12 -0
  156. data/test/rails_app/app/controllers/application_controller.rb +9 -0
  157. data/test/rails_app/app/controllers/home_controller.rb +26 -0
  158. data/test/rails_app/app/controllers/publisher/registrations_controller.rb +3 -0
  159. data/test/rails_app/app/controllers/publisher/sessions_controller.rb +3 -0
  160. data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +15 -0
  161. data/test/rails_app/app/controllers/users_controller.rb +24 -0
  162. data/test/rails_app/app/helpers/application_helper.rb +4 -0
  163. data/test/rails_app/app/mailers/users/mailer.rb +9 -0
  164. data/test/rails_app/app/mongoid/admin.rb +28 -0
  165. data/test/rails_app/app/mongoid/shim.rb +25 -0
  166. data/test/rails_app/app/mongoid/user.rb +43 -0
  167. data/test/rails_app/app/views/admins/index.html.erb +1 -0
  168. data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
  169. data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -0
  170. data/test/rails_app/app/views/home/index.html.erb +1 -0
  171. data/test/rails_app/app/views/home/join.html.erb +1 -0
  172. data/test/rails_app/app/views/home/private.html.erb +1 -0
  173. data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -0
  174. data/test/rails_app/app/views/layouts/application.html.erb +24 -0
  175. data/test/rails_app/app/views/users/index.html.erb +1 -0
  176. data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
  177. data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
  178. data/test/rails_app/config/application.rb +42 -0
  179. data/test/rails_app/config/boot.rb +9 -0
  180. data/test/rails_app/config/database.yml +18 -0
  181. data/test/rails_app/config/environment.rb +6 -0
  182. data/test/rails_app/config/environments/development.rb +19 -0
  183. data/test/rails_app/config/environments/production.rb +34 -0
  184. data/test/rails_app/config/environments/test.rb +34 -0
  185. data/test/rails_app/config/initializers/backtrace_silencers.rb +8 -0
  186. data/test/rails_app/config/initializers/devise.rb +179 -0
  187. data/test/rails_app/config/initializers/inflections.rb +3 -0
  188. data/test/rails_app/config/initializers/secret_token.rb +3 -0
  189. data/test/rails_app/config/routes.rb +101 -0
  190. data/test/rails_app/config.ru +4 -0
  191. data/test/rails_app/db/migrate/20100401102949_create_tables.rb +75 -0
  192. data/test/rails_app/db/schema.rb +53 -0
  193. data/test/rails_app/lib/shared_admin.rb +15 -0
  194. data/test/rails_app/lib/shared_user.rb +27 -0
  195. data/test/rails_app/public/404.html +26 -0
  196. data/test/rails_app/public/422.html +26 -0
  197. data/test/rails_app/public/500.html +26 -0
  198. data/test/rails_app/public/favicon.ico +0 -0
  199. data/test/rails_app/script/rails +10 -0
  200. data/test/routes_test.rb +249 -0
  201. data/test/support/assertions.rb +41 -0
  202. data/test/support/helpers.rb +92 -0
  203. data/test/support/integration.rb +93 -0
  204. data/test/support/locale/en.yml +4 -0
  205. data/test/support/webrat/integrations/rails.rb +25 -0
  206. data/test/test_helper.rb +28 -0
  207. data/test/test_helpers_test.rb +152 -0
  208. metadata +407 -0
@@ -0,0 +1,31 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class Devise::OmniauthCallbacksController < DeviseController
3
+ prepend_before_filter { request.env["devise.skip_timeout"] = true }
4
+
5
+ def passthru
6
+ render :status => 404, :text => "Not found. Authentication passthru."
7
+ end
8
+
9
+ def failure
10
+ set_flash_message :alert, :failure, :kind => OmniAuth::Utils.camelize(failed_strategy.name), :reason => failure_message
11
+ redirect_to after_omniauth_failure_path_for(resource_name)
12
+ end
13
+
14
+ protected
15
+
16
+ def failed_strategy
17
+ env["omniauth.error.strategy"]
18
+ end
19
+
20
+ def failure_message
21
+ exception = env["omniauth.error"]
22
+ error = exception.error_reason if exception.respond_to?(:error_reason)
23
+ error ||= exception.error if exception.respond_to?(:error)
24
+ error ||= env["omniauth.error.type"].to_s
25
+ error.to_s.humanize if error
26
+ end
27
+
28
+ def after_omniauth_failure_path_for(scope)
29
+ new_session_path(scope)
30
+ end
31
+ end
@@ -0,0 +1,57 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class Devise::PasswordsController < DeviseController
3
+ prepend_before_filter :require_no_authentication
4
+ # Render the #edit only if coming from a reset password email link
5
+ append_before_filter :assert_reset_token_passed, :only => :edit
6
+
7
+ # GET /resource/password/new
8
+ def new
9
+ build_resource({})
10
+ end
11
+
12
+ # POST /resource/password
13
+ def create
14
+ self.resource = resource_class.send_reset_password_instructions(resource_params)
15
+
16
+ if successfully_sent?(resource)
17
+ respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name))
18
+ else
19
+ respond_with(resource)
20
+ end
21
+ end
22
+
23
+ # GET /resource/password/edit?reset_password_token=abcdef
24
+ def edit
25
+ self.resource = resource_class.new
26
+ resource.reset_password_token = params[:reset_password_token]
27
+ end
28
+
29
+ # PUT /resource/password
30
+ def update
31
+ self.resource = resource_class.reset_password_by_token(resource_params)
32
+
33
+ if resource.errors.empty?
34
+ flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
35
+ set_flash_message(:notice, flash_message) if is_navigational_format?
36
+ sign_in(resource_name, resource)
37
+ respond_with resource, :location => after_sign_in_path_for(resource)
38
+ else
39
+ respond_with resource
40
+ end
41
+ end
42
+
43
+ protected
44
+
45
+ # The path used after sending reset password instructions
46
+ def after_sending_reset_password_instructions_path_for(resource_name)
47
+ new_session_path(resource_name)
48
+ end
49
+
50
+ # Check if a reset_password_token is provided in the request
51
+ def assert_reset_token_passed
52
+ if params[:reset_password_token].blank?
53
+ set_flash_message(:error, :no_token)
54
+ redirect_to new_session_path(resource_name)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,120 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class Devise::RegistrationsController < DeviseController
3
+ prepend_before_filter :require_no_authentication, :only => [ :new, :create, :cancel ]
4
+ prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]
5
+
6
+ # GET /resource/sign_up
7
+ def new
8
+ resource = build_resource({})
9
+ respond_with resource
10
+ end
11
+
12
+ # POST /resource
13
+ def create
14
+ build_resource
15
+
16
+ if resource.save
17
+ if resource.active_for_authentication?
18
+ set_flash_message :notice, :signed_up if is_navigational_format?
19
+ sign_up(resource_name, resource)
20
+ respond_with resource, :location => after_sign_up_path_for(resource)
21
+ else
22
+ set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
23
+ expire_session_data_after_sign_in!
24
+ respond_with resource, :location => after_inactive_sign_up_path_for(resource)
25
+ end
26
+ else
27
+ clean_up_passwords resource
28
+ respond_with resource
29
+ end
30
+ end
31
+
32
+ # GET /resource/edit
33
+ def edit
34
+ render :edit
35
+ end
36
+
37
+ # PUT /resource
38
+ # We need to use a copy of the resource because we don't want to change
39
+ # the current user in place.
40
+ def update
41
+ self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
42
+ prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
43
+
44
+ if resource.update_with_password(resource_params)
45
+ if is_navigational_format?
46
+ flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
47
+ :update_needs_confirmation : :updated
48
+ set_flash_message :notice, flash_key
49
+ end
50
+ sign_in resource_name, resource, :bypass => true
51
+ respond_with resource, :location => after_update_path_for(resource)
52
+ else
53
+ clean_up_passwords resource
54
+ respond_with resource
55
+ end
56
+ end
57
+
58
+ # DELETE /resource
59
+ def destroy
60
+ resource.destroy
61
+ Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
62
+ set_flash_message :notice, :destroyed if is_navigational_format?
63
+ respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
64
+ end
65
+
66
+ # GET /resource/cancel
67
+ # Forces the session data which is usually expired after sign
68
+ # in to be expired now. This is useful if the user wants to
69
+ # cancel oauth signing in/up in the middle of the process,
70
+ # removing all OAuth session data.
71
+ def cancel
72
+ expire_session_data_after_sign_in!
73
+ redirect_to new_registration_path(resource_name)
74
+ end
75
+
76
+ protected
77
+
78
+ def update_needs_confirmation?(resource, previous)
79
+ resource.respond_to?(:pending_reconfirmation?) &&
80
+ resource.pending_reconfirmation? &&
81
+ previous != resource.unconfirmed_email
82
+ end
83
+
84
+ # Build a devise resource passing in the session. Useful to move
85
+ # temporary session data to the newly created user.
86
+ def build_resource(hash=nil)
87
+ hash ||= resource_params || {}
88
+ self.resource = resource_class.new_with_session(hash, session)
89
+ end
90
+
91
+ # Signs in a user on sign up. You can overwrite this method in your own
92
+ # RegistrationsController.
93
+ def sign_up(resource_name, resource)
94
+ sign_in(resource_name, resource)
95
+ end
96
+
97
+ # The path used after sign up. You need to overwrite this method
98
+ # in your own RegistrationsController.
99
+ def after_sign_up_path_for(resource)
100
+ after_sign_in_path_for(resource)
101
+ end
102
+
103
+ # The path used after sign up for inactive accounts. You need to overwrite
104
+ # this method in your own RegistrationsController.
105
+ def after_inactive_sign_up_path_for(resource)
106
+ respond_to?(:root_path) ? root_path : "/"
107
+ end
108
+
109
+ # The default url to be used after updating a resource. You need to overwrite
110
+ # this method in your own RegistrationsController.
111
+ def after_update_path_for(resource)
112
+ signed_in_root_path(resource)
113
+ end
114
+
115
+ # Authenticates the current scope and gets the current resource from the session.
116
+ def authenticate_scope!
117
+ send(:"authenticate_#{resource_name}!", :force => true)
118
+ self.resource = send(:"current_#{resource_name}")
119
+ end
120
+ end
@@ -0,0 +1,51 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class Devise::SessionsController < DeviseController
3
+ prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
4
+ prepend_before_filter :allow_params_authentication!, :only => :create
5
+ prepend_before_filter { request.env["devise.skip_timeout"] = true }
6
+
7
+ # GET /resource/sign_in
8
+ def new
9
+ self.resource = build_resource(nil, :unsafe => true)
10
+ clean_up_passwords(resource)
11
+ respond_with(resource, serialize_options(resource))
12
+ end
13
+
14
+ # POST /resource/sign_in
15
+ def create
16
+ self.resource = warden.authenticate!(auth_options)
17
+ set_flash_message(:notice, :signed_in) if is_navigational_format?
18
+ sign_in(resource_name, resource)
19
+ respond_with resource, :location => after_sign_in_path_for(resource)
20
+ end
21
+
22
+ # DELETE /resource/sign_out
23
+ def destroy
24
+ redirect_path = after_sign_out_path_for(resource_name)
25
+ signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
26
+ set_flash_message :notice, :signed_out if signed_out && is_navigational_format?
27
+
28
+ # We actually need to hardcode this as Rails default responder doesn't
29
+ # support returning empty response on GET request
30
+ respond_to do |format|
31
+ format.any(*navigational_formats) { redirect_to redirect_path }
32
+ format.all do
33
+ head :no_content
34
+ end
35
+ end
36
+ end
37
+
38
+ protected
39
+
40
+ def serialize_options(resource)
41
+ methods = resource_class.authentication_keys.dup
42
+ methods = methods.keys if methods.is_a?(Hash)
43
+ methods << :password if resource.respond_to?(:password)
44
+ { :methods => methods, :only => [:password] }
45
+ end
46
+
47
+ def auth_options
48
+ { :scope => resource_name, :recall => "#{controller_path}#new" }
49
+ end
50
+ end
51
+
@@ -0,0 +1,45 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class Devise::UnlocksController < DeviseController
3
+ prepend_before_filter :require_no_authentication
4
+
5
+ # GET /resource/unlock/new
6
+ def new
7
+ build_resource({})
8
+ end
9
+
10
+ # POST /resource/unlock
11
+ def create
12
+ self.resource = resource_class.send_unlock_instructions(resource_params)
13
+
14
+ if successfully_sent?(resource)
15
+ respond_with({}, :location => after_sending_unlock_instructions_path_for(resource))
16
+ else
17
+ respond_with(resource)
18
+ end
19
+ end
20
+
21
+ # GET /resource/unlock?unlock_token=abcdef
22
+ def show
23
+ self.resource = resource_class.unlock_access_by_token(params[:unlock_token])
24
+
25
+ if resource.errors.empty?
26
+ set_flash_message :notice, :unlocked if is_navigational_format?
27
+ respond_with_navigational(resource){ redirect_to after_unlock_path_for(resource) }
28
+ else
29
+ respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
30
+ end
31
+ end
32
+
33
+ protected
34
+
35
+ # The path used after sending unlock password instructions
36
+ def after_sending_unlock_instructions_path_for(resource)
37
+ new_session_path(resource)
38
+ end
39
+
40
+ # The path used after unlocking the resource
41
+ def after_unlock_path_for(resource)
42
+ new_session_path(resource)
43
+ end
44
+
45
+ end
@@ -0,0 +1,193 @@
1
+ # -*- encoding : utf-8 -*-
2
+ # All Devise controllers are inherited from here.
3
+ class DeviseController < Devise.parent_controller.constantize
4
+ include Devise::Controllers::ScopedViews
5
+
6
+ helper DeviseHelper
7
+
8
+ helpers = %w(resource scope_name resource_name signed_in_resource
9
+ resource_class resource_params devise_mapping)
10
+ hide_action *helpers
11
+ helper_method *helpers
12
+
13
+ prepend_before_filter :assert_is_devise_resource!
14
+ respond_to *Mime::SET.map(&:to_sym) if mimes_for_respond_to.empty?
15
+
16
+ # Gets the actual resource stored in the instance variable
17
+ def resource
18
+ instance_variable_get(:"@#{resource_name}")
19
+ end
20
+
21
+ # Proxy to devise map name
22
+ def resource_name
23
+ devise_mapping.name
24
+ end
25
+ alias :scope_name :resource_name
26
+
27
+ # Proxy to devise map class
28
+ def resource_class
29
+ devise_mapping.to
30
+ end
31
+
32
+ def resource_params
33
+ params[resource_name]
34
+ end
35
+
36
+ # Returns a signed in resource from session (if one exists)
37
+ def signed_in_resource
38
+ warden.authenticate(:scope => resource_name)
39
+ end
40
+
41
+ # Attempt to find the mapped route for devise based on request path
42
+ def devise_mapping
43
+ @devise_mapping ||= request.env["devise.mapping"]
44
+ end
45
+
46
+ # Override prefixes to consider the scoped view.
47
+ # Notice we need to check for the request due to a bug in
48
+ # Action Controller tests that forces _prefixes to be
49
+ # loaded before even having a request object.
50
+ def _prefixes #:nodoc:
51
+ @_prefixes ||= if self.class.scoped_views? && request && devise_mapping
52
+ super.unshift("#{devise_mapping.scoped_path}/#{controller_name}")
53
+ else
54
+ super
55
+ end
56
+ end
57
+
58
+ hide_action :_prefixes
59
+
60
+ protected
61
+
62
+ # Checks whether it's a devise mapped resource or not.
63
+ def assert_is_devise_resource! #:nodoc:
64
+ unknown_action! <<-MESSAGE unless devise_mapping
65
+ Could not find devise mapping for path #{request.fullpath.inspect}.
66
+ This may happen for two reasons:
67
+
68
+ 1) You forgot to wrap your route inside the scope block. For example:
69
+
70
+ devise_scope :user do
71
+ match "/some/route" => "some_devise_controller"
72
+ end
73
+
74
+ 2) You are testing a Devise controller bypassing the router.
75
+ If so, you can explicitly tell Devise which mapping to use:
76
+
77
+ @request.env["devise.mapping"] = Devise.mappings[:user]
78
+
79
+ MESSAGE
80
+ end
81
+
82
+ # Returns real navigational formats which are supported by Rails
83
+ def navigational_formats
84
+ @navigational_formats ||= Devise.navigational_formats.select { |format| Mime::EXTENSION_LOOKUP[format.to_s] }
85
+ end
86
+
87
+ def unknown_action!(msg)
88
+ logger.debug "[Devise] #{msg}" if logger
89
+ raise AbstractController::ActionNotFound, msg
90
+ end
91
+
92
+ # Sets the resource creating an instance variable
93
+ def resource=(new_resource)
94
+ instance_variable_set(:"@#{resource_name}", new_resource)
95
+ end
96
+
97
+ # Build a devise resource.
98
+ # Assignment bypasses attribute protection when :unsafe option is passed
99
+ def build_resource(hash = nil, options = {})
100
+ hash ||= resource_params || {}
101
+
102
+ if options[:unsafe]
103
+ self.resource = resource_class.new.tap do |resource|
104
+ hash.each do |key, value|
105
+ setter = :"#{key}="
106
+ resource.send(setter, value) if resource.respond_to?(setter)
107
+ end
108
+ end
109
+ else
110
+ self.resource = resource_class.new(hash)
111
+ end
112
+ end
113
+
114
+ # Helper for use in before_filters where no authentication is required.
115
+ #
116
+ # Example:
117
+ # before_filter :require_no_authentication, :only => :new
118
+ def require_no_authentication
119
+ assert_is_devise_resource!
120
+ return unless is_navigational_format?
121
+ no_input = devise_mapping.no_input_strategies
122
+
123
+ authenticated = if no_input.present?
124
+ args = no_input.dup.push :scope => resource_name
125
+ warden.authenticate?(*args)
126
+ else
127
+ warden.authenticated?(resource_name)
128
+ end
129
+
130
+ if authenticated && resource = warden.user(resource_name)
131
+ flash[:alert] = I18n.t("devise.failure.already_authenticated")
132
+ redirect_to after_sign_in_path_for(resource)
133
+ end
134
+ end
135
+
136
+ # Helper for use after calling send_*_instructions methods on a resource.
137
+ # If we are in paranoid mode, we always act as if the resource was valid
138
+ # and instructions were sent.
139
+ def successfully_sent?(resource)
140
+ notice = if Devise.paranoid
141
+ resource.errors.clear
142
+ :send_paranoid_instructions
143
+ elsif resource.errors.empty?
144
+ :send_instructions
145
+ end
146
+
147
+ if notice
148
+ set_flash_message :notice, notice if is_navigational_format?
149
+ true
150
+ end
151
+ end
152
+
153
+ # Sets the flash message with :key, using I18n. By default you are able
154
+ # to setup your messages using specific resource scope, and if no one is
155
+ # found we look to default scope.
156
+ # Example (i18n locale file):
157
+ #
158
+ # en:
159
+ # devise:
160
+ # passwords:
161
+ # #default_scope_messages - only if resource_scope is not found
162
+ # user:
163
+ # #resource_scope_messages
164
+ #
165
+ # Please refer to README or en.yml locale file to check what messages are
166
+ # available.
167
+ def set_flash_message(key, kind, options={})
168
+ options[:scope] = "devise.#{controller_name}"
169
+ options[:default] = Array(options[:default]).unshift(kind.to_sym)
170
+ options[:resource_name] = resource_name
171
+ options = devise_i18n_options(options) if respond_to?(:devise_i18n_options, true)
172
+ message = I18n.t("#{options[:resource_name]}.#{kind}", options)
173
+ flash[key] = message if message.present?
174
+ end
175
+
176
+ def clean_up_passwords(object)
177
+ object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
178
+ end
179
+
180
+ def respond_with_navigational(*args, &block)
181
+ respond_with(*args) do |format|
182
+ format.any(*navigational_formats, &block)
183
+ end
184
+ end
185
+
186
+ def request_format
187
+ @request_format ||= request.format.try(:ref)
188
+ end
189
+
190
+ def is_navigational_format?
191
+ Devise.navigational_formats.include?(request_format)
192
+ end
193
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding : utf-8 -*-
2
+ module DeviseHelper
3
+ # A simple way to show error messages for the current devise resource. If you need
4
+ # to customize this method, you can either overwrite it in your application helpers or
5
+ # copy the views to your application.
6
+ #
7
+ # This method is intended to stay simple and it is unlikely that we are going to change
8
+ # it to add more behavior or options.
9
+ def devise_error_messages!
10
+ return "" if resource.errors.empty?
11
+
12
+ messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
13
+ sentence = I18n.t("errors.messages.not_saved",
14
+ :count => resource.errors.count,
15
+ :resource => resource.class.model_name.human.downcase)
16
+
17
+ html = <<-HTML
18
+ <div id="error_explanation">
19
+ <h2>#{sentence}</h2>
20
+ <ul>#{messages}</ul>
21
+ </div>
22
+ HTML
23
+
24
+ html.html_safe
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ # -*- encoding : utf-8 -*-
2
+ class Devise::Mailer < ::ActionMailer::Base
3
+ include Devise::Mailers::Helpers
4
+
5
+ def confirmation_instructions(record)
6
+ devise_mail(record, :confirmation_instructions)
7
+ end
8
+
9
+ def reset_password_instructions(record)
10
+ devise_mail(record, :reset_password_instructions)
11
+ end
12
+
13
+ def unlock_instructions(record)
14
+ devise_mail(record, :unlock_instructions)
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ <% ActiveSupport::Deprecation.warn "Rendering partials devise/_links.erb is deprecated" \
2
+ "please use devise/shared/_links.erb instead."%>
3
+ <%= render "shared/links" %>
@@ -0,0 +1,12 @@
1
+ <h2>Resend confirmation instructions</h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email, :autofocus => true %></div>
8
+
9
+ <div><%= f.submit "Resend confirmation instructions" %></div>
10
+ <% end %>
11
+
12
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,5 @@
1
+ <p>Welcome <%= @resource.email %>!</p>
2
+
3
+ <p>You can confirm your account email through the link below:</p>
4
+
5
+ <p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>
@@ -0,0 +1,8 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>Someone has requested a link to change your password, and you can do this through the link below.</p>
4
+
5
+ <p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %></p>
6
+
7
+ <p>If you didn't request this, please ignore this email.</p>
8
+ <p>Your password won't change until you access the link above and create a new one.</p>
@@ -0,0 +1,7 @@
1
+ <p>Hello <%= @resource.email %>!</p>
2
+
3
+ <p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
4
+
5
+ <p>Click the link below to unlock your account:</p>
6
+
7
+ <p><%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %></p>
@@ -0,0 +1,16 @@
1
+ <h2>Change your password</h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+ <%= f.hidden_field :reset_password_token %>
6
+
7
+ <div><%= f.label :password, "New password" %><br />
8
+ <%= f.password_field :password, :autofocus => true %></div>
9
+
10
+ <div><%= f.label :password_confirmation, "Confirm new password" %><br />
11
+ <%= f.password_field :password_confirmation %></div>
12
+
13
+ <div><%= f.submit "Change my password" %></div>
14
+ <% end %>
15
+
16
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,12 @@
1
+ <h2>Forgot your password?</h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email, :autofocus => true %></div>
8
+
9
+ <div><%= f.submit "Send me reset password instructions" %></div>
10
+ <% end %>
11
+
12
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,25 @@
1
+ <h2>Edit <%= resource_name.to_s.humanize %></h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email, :autofocus => true %></div>
8
+
9
+ <div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
10
+ <%= f.password_field :password, :autocomplete => "off" %></div>
11
+
12
+ <div><%= f.label :password_confirmation %><br />
13
+ <%= f.password_field :password_confirmation %></div>
14
+
15
+ <div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
16
+ <%= f.password_field :current_password %></div>
17
+
18
+ <div><%= f.submit "Update" %></div>
19
+ <% end %>
20
+
21
+ <h3>Cancel my account</h3>
22
+
23
+ <p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), :data => { :confirm => "Are you sure?" }, :method => :delete %>.</p>
24
+
25
+ <%= link_to "Back", :back %>
@@ -0,0 +1,18 @@
1
+ <h2>Sign up</h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
4
+ <%= devise_error_messages! %>
5
+
6
+ <div><%= f.label :email %><br />
7
+ <%= f.email_field :email, :autofocus => true %></div>
8
+
9
+ <div><%= f.label :password %><br />
10
+ <%= f.password_field :password %></div>
11
+
12
+ <div><%= f.label :password_confirmation %><br />
13
+ <%= f.password_field :password_confirmation %></div>
14
+
15
+ <div><%= f.submit "Sign up" %></div>
16
+ <% end %>
17
+
18
+ <%= render "devise/shared/links" %>
@@ -0,0 +1,17 @@
1
+ <h2>Sign in</h2>
2
+
3
+ <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
4
+ <div><%= f.label :email %><br />
5
+ <%= f.email_field :email, :autofocus => true %></div>
6
+
7
+ <div><%= f.label :password %><br />
8
+ <%= f.password_field :password %></div>
9
+
10
+ <% if devise_mapping.rememberable? -%>
11
+ <div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
12
+ <% end -%>
13
+
14
+ <div><%= f.submit "Sign in" %></div>
15
+ <% end %>
16
+
17
+ <%= render "devise/shared/links" %>