af-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.
- data/.gitignore +10 -0
- data/.travis.yml +15 -0
- data/CHANGELOG.rdoc +885 -0
- data/CONTRIBUTING.md +14 -0
- data/Gemfile +29 -0
- data/Gemfile.lock +155 -0
- data/MIT-LICENSE +20 -0
- data/README.md +394 -0
- data/Rakefile +34 -0
- data/app/controllers/devise/confirmations_controller.rb +43 -0
- data/app/controllers/devise/omniauth_callbacks_controller.rb +30 -0
- data/app/controllers/devise/passwords_controller.rb +65 -0
- data/app/controllers/devise/registrations_controller.rb +119 -0
- data/app/controllers/devise/sessions_controller.rb +50 -0
- data/app/controllers/devise/unlocks_controller.rb +44 -0
- data/app/controllers/devise_controller.rb +184 -0
- data/app/helpers/devise_helper.rb +25 -0
- data/app/mailers/devise/mailer.rb +15 -0
- data/app/views/devise/_links.erb +3 -0
- data/app/views/devise/confirmations/new.html.erb +12 -0
- data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
- data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
- data/app/views/devise/passwords/edit.html.erb +16 -0
- data/app/views/devise/passwords/new.html.erb +12 -0
- data/app/views/devise/registrations/edit.html.erb +25 -0
- data/app/views/devise/registrations/new.html.erb +18 -0
- data/app/views/devise/sessions/new.html.erb +17 -0
- data/app/views/devise/shared/_links.erb +25 -0
- data/app/views/devise/unlocks/new.html.erb +12 -0
- data/config/locales/en.yml +59 -0
- data/devise.gemspec +25 -0
- data/gemfiles/Gemfile.rails-3.1.x +35 -0
- data/gemfiles/Gemfile.rails-3.1.x.lock +167 -0
- data/lib/devise.rb +444 -0
- data/lib/devise/controllers/helpers.rb +285 -0
- data/lib/devise/controllers/rememberable.rb +52 -0
- data/lib/devise/controllers/scoped_views.rb +17 -0
- data/lib/devise/controllers/url_helpers.rb +67 -0
- data/lib/devise/delegator.rb +16 -0
- data/lib/devise/failure_app.rb +187 -0
- data/lib/devise/hooks/activatable.rb +11 -0
- data/lib/devise/hooks/forgetable.rb +9 -0
- data/lib/devise/hooks/lockable.rb +7 -0
- data/lib/devise/hooks/rememberable.rb +6 -0
- data/lib/devise/hooks/timeoutable.rb +25 -0
- data/lib/devise/hooks/trackable.rb +9 -0
- data/lib/devise/mailers/helpers.rb +91 -0
- data/lib/devise/mapping.rb +172 -0
- data/lib/devise/models.rb +128 -0
- data/lib/devise/models/authenticatable.rb +268 -0
- data/lib/devise/models/confirmable.rb +270 -0
- data/lib/devise/models/database_authenticatable.rb +127 -0
- data/lib/devise/models/lockable.rb +193 -0
- data/lib/devise/models/omniauthable.rb +27 -0
- data/lib/devise/models/recoverable.rb +140 -0
- data/lib/devise/models/registerable.rb +25 -0
- data/lib/devise/models/rememberable.rb +125 -0
- data/lib/devise/models/timeoutable.rb +49 -0
- data/lib/devise/models/token_authenticatable.rb +89 -0
- data/lib/devise/models/trackable.rb +35 -0
- data/lib/devise/models/validatable.rb +66 -0
- data/lib/devise/modules.rb +29 -0
- data/lib/devise/omniauth.rb +28 -0
- data/lib/devise/omniauth/config.rb +45 -0
- data/lib/devise/omniauth/url_helpers.rb +18 -0
- data/lib/devise/orm/active_record.rb +3 -0
- data/lib/devise/orm/mongoid.rb +3 -0
- data/lib/devise/param_filter.rb +41 -0
- data/lib/devise/rails.rb +54 -0
- data/lib/devise/rails/routes.rb +446 -0
- data/lib/devise/rails/warden_compat.rb +43 -0
- data/lib/devise/strategies/authenticatable.rb +176 -0
- data/lib/devise/strategies/base.rb +20 -0
- data/lib/devise/strategies/database_authenticatable.rb +20 -0
- data/lib/devise/strategies/rememberable.rb +55 -0
- data/lib/devise/strategies/token_authenticatable.rb +56 -0
- data/lib/devise/test_helpers.rb +131 -0
- data/lib/devise/time_inflector.rb +14 -0
- data/lib/devise/version.rb +3 -0
- data/lib/generators/active_record/devise_generator.rb +79 -0
- data/lib/generators/active_record/templates/migration.rb +19 -0
- data/lib/generators/active_record/templates/migration_existing.rb +26 -0
- data/lib/generators/devise/devise_generator.rb +24 -0
- data/lib/generators/devise/install_generator.rb +24 -0
- data/lib/generators/devise/orm_helpers.rb +32 -0
- data/lib/generators/devise/views_generator.rb +116 -0
- data/lib/generators/mongoid/devise_generator.rb +57 -0
- data/lib/generators/templates/README +35 -0
- data/lib/generators/templates/devise.rb +240 -0
- data/lib/generators/templates/markerb/confirmation_instructions.markerb +5 -0
- data/lib/generators/templates/markerb/reset_password_instructions.markerb +8 -0
- data/lib/generators/templates/markerb/unlock_instructions.markerb +7 -0
- data/lib/generators/templates/simple_form_for/confirmations/new.html.erb +15 -0
- data/lib/generators/templates/simple_form_for/passwords/edit.html.erb +19 -0
- data/lib/generators/templates/simple_form_for/passwords/new.html.erb +15 -0
- data/lib/generators/templates/simple_form_for/registrations/edit.html.erb +22 -0
- data/lib/generators/templates/simple_form_for/registrations/new.html.erb +17 -0
- data/lib/generators/templates/simple_form_for/sessions/new.html.erb +15 -0
- data/lib/generators/templates/simple_form_for/unlocks/new.html.erb +15 -0
- data/test/controllers/custom_strategy_test.rb +62 -0
- data/test/controllers/helpers_test.rb +253 -0
- data/test/controllers/internal_helpers_test.rb +110 -0
- data/test/controllers/sessions_controller_test.rb +85 -0
- data/test/controllers/url_helpers_test.rb +59 -0
- data/test/delegator_test.rb +19 -0
- data/test/devise_test.rb +72 -0
- data/test/failure_app_test.rb +221 -0
- data/test/generators/active_record_generator_test.rb +75 -0
- data/test/generators/devise_generator_test.rb +39 -0
- data/test/generators/install_generator_test.rb +13 -0
- data/test/generators/mongoid_generator_test.rb +23 -0
- data/test/generators/views_generator_test.rb +52 -0
- data/test/helpers/devise_helper_test.rb +51 -0
- data/test/integration/authenticatable_test.rb +633 -0
- data/test/integration/confirmable_test.rb +298 -0
- data/test/integration/database_authenticatable_test.rb +82 -0
- data/test/integration/http_authenticatable_test.rb +97 -0
- data/test/integration/lockable_test.rb +242 -0
- data/test/integration/omniauthable_test.rb +133 -0
- data/test/integration/recoverable_test.rb +334 -0
- data/test/integration/registerable_test.rb +345 -0
- data/test/integration/rememberable_test.rb +158 -0
- data/test/integration/timeoutable_test.rb +140 -0
- data/test/integration/token_authenticatable_test.rb +161 -0
- data/test/integration/trackable_test.rb +92 -0
- data/test/mailers/confirmation_instructions_test.rb +102 -0
- data/test/mailers/reset_password_instructions_test.rb +83 -0
- data/test/mailers/unlock_instructions_test.rb +77 -0
- data/test/mapping_test.rb +127 -0
- data/test/models/authenticatable_test.rb +7 -0
- data/test/models/confirmable_test.rb +391 -0
- data/test/models/database_authenticatable_test.rb +196 -0
- data/test/models/lockable_test.rb +273 -0
- data/test/models/omniauthable_test.rb +7 -0
- data/test/models/recoverable_test.rb +205 -0
- data/test/models/registerable_test.rb +7 -0
- data/test/models/rememberable_test.rb +174 -0
- data/test/models/serializable_test.rb +49 -0
- data/test/models/timeoutable_test.rb +46 -0
- data/test/models/token_authenticatable_test.rb +55 -0
- data/test/models/trackable_test.rb +13 -0
- data/test/models/validatable_test.rb +117 -0
- data/test/models_test.rb +179 -0
- data/test/omniauth/config_test.rb +57 -0
- data/test/omniauth/url_helpers_test.rb +51 -0
- data/test/orm/active_record.rb +9 -0
- data/test/orm/mongoid.rb +13 -0
- data/test/rails_app/Rakefile +10 -0
- data/test/rails_app/app/active_record/admin.rb +6 -0
- data/test/rails_app/app/active_record/shim.rb +2 -0
- data/test/rails_app/app/active_record/user.rb +6 -0
- data/test/rails_app/app/controllers/admins/sessions_controller.rb +6 -0
- data/test/rails_app/app/controllers/admins_controller.rb +11 -0
- data/test/rails_app/app/controllers/application_controller.rb +8 -0
- data/test/rails_app/app/controllers/home_controller.rb +25 -0
- data/test/rails_app/app/controllers/publisher/registrations_controller.rb +2 -0
- data/test/rails_app/app/controllers/publisher/sessions_controller.rb +2 -0
- data/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +14 -0
- data/test/rails_app/app/controllers/users_controller.rb +23 -0
- data/test/rails_app/app/helpers/application_helper.rb +3 -0
- data/test/rails_app/app/mailers/users/mailer.rb +8 -0
- data/test/rails_app/app/mongoid/admin.rb +29 -0
- data/test/rails_app/app/mongoid/shim.rb +24 -0
- data/test/rails_app/app/mongoid/user.rb +42 -0
- data/test/rails_app/app/views/admins/index.html.erb +1 -0
- data/test/rails_app/app/views/admins/sessions/new.html.erb +2 -0
- data/test/rails_app/app/views/home/admin_dashboard.html.erb +1 -0
- data/test/rails_app/app/views/home/index.html.erb +1 -0
- data/test/rails_app/app/views/home/join.html.erb +1 -0
- data/test/rails_app/app/views/home/private.html.erb +1 -0
- data/test/rails_app/app/views/home/user_dashboard.html.erb +1 -0
- data/test/rails_app/app/views/layouts/application.html.erb +24 -0
- data/test/rails_app/app/views/users/index.html.erb +1 -0
- data/test/rails_app/app/views/users/mailer/confirmation_instructions.erb +1 -0
- data/test/rails_app/app/views/users/sessions/new.html.erb +1 -0
- data/test/rails_app/config.ru +4 -0
- data/test/rails_app/config/application.rb +41 -0
- data/test/rails_app/config/boot.rb +8 -0
- data/test/rails_app/config/database.yml +18 -0
- data/test/rails_app/config/environment.rb +5 -0
- data/test/rails_app/config/environments/development.rb +18 -0
- data/test/rails_app/config/environments/production.rb +33 -0
- data/test/rails_app/config/environments/test.rb +33 -0
- data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_app/config/initializers/devise.rb +178 -0
- data/test/rails_app/config/initializers/inflections.rb +2 -0
- data/test/rails_app/config/initializers/secret_token.rb +2 -0
- data/test/rails_app/config/routes.rb +100 -0
- data/test/rails_app/db/migrate/20100401102949_create_tables.rb +74 -0
- data/test/rails_app/db/schema.rb +52 -0
- data/test/rails_app/lib/shared_admin.rb +14 -0
- data/test/rails_app/lib/shared_user.rb +26 -0
- data/test/rails_app/public/404.html +26 -0
- data/test/rails_app/public/422.html +26 -0
- data/test/rails_app/public/500.html +26 -0
- data/test/rails_app/public/favicon.ico +0 -0
- data/test/rails_app/script/rails +10 -0
- data/test/routes_test.rb +248 -0
- data/test/support/assertions.rb +40 -0
- data/test/support/helpers.rb +91 -0
- data/test/support/integration.rb +92 -0
- data/test/support/locale/en.yml +4 -0
- data/test/support/webrat/integrations/rails.rb +24 -0
- data/test/test_helper.rb +27 -0
- data/test/test_helpers_test.rb +151 -0
- metadata +421 -0
data/Rakefile
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require "bundler/gem_tasks"
|
|
3
|
+
require 'rake/testtask'
|
|
4
|
+
require 'rdoc/task'
|
|
5
|
+
|
|
6
|
+
desc 'Default: run tests for all ORMs.'
|
|
7
|
+
task :default => :test
|
|
8
|
+
|
|
9
|
+
desc 'Run Devise tests for all ORMs.'
|
|
10
|
+
task :pre_commit do
|
|
11
|
+
Dir[File.join(File.dirname(__FILE__), 'test', 'orm', '*.rb')].each do |file|
|
|
12
|
+
orm = File.basename(file).split(".").first
|
|
13
|
+
# "Some day, my son, rake's inner wisdom will reveal itself. Until then,
|
|
14
|
+
# take this `system` -- may its brute force protect you well."
|
|
15
|
+
exit 1 unless system "rake test DEVISE_ORM=#{orm}"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
desc 'Run Devise unit tests.'
|
|
20
|
+
Rake::TestTask.new(:test) do |t|
|
|
21
|
+
t.libs << 'lib'
|
|
22
|
+
t.libs << 'test'
|
|
23
|
+
t.pattern = 'test/**/*_test.rb'
|
|
24
|
+
t.verbose = true
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
desc 'Generate documentation for Devise.'
|
|
28
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
29
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
30
|
+
rdoc.title = 'Devise'
|
|
31
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
|
32
|
+
rdoc.rdoc_files.include('README.md')
|
|
33
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
34
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
class Devise::ConfirmationsController < DeviseController
|
|
2
|
+
# GET /resource/confirmation/new
|
|
3
|
+
def new
|
|
4
|
+
build_resource({})
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# POST /resource/confirmation
|
|
8
|
+
def create
|
|
9
|
+
self.resource = resource_class.send_confirmation_instructions(resource_params)
|
|
10
|
+
|
|
11
|
+
if successfully_sent?(resource)
|
|
12
|
+
respond_with({}, :location => after_resending_confirmation_instructions_path_for(resource_name))
|
|
13
|
+
else
|
|
14
|
+
respond_with(resource)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# GET /resource/confirmation?confirmation_token=abcdef
|
|
19
|
+
def show
|
|
20
|
+
self.resource = resource_class.confirm_by_token(params[:confirmation_token])
|
|
21
|
+
|
|
22
|
+
if resource.errors.empty?
|
|
23
|
+
set_flash_message(:notice, :confirmed) if is_navigational_format?
|
|
24
|
+
sign_in(resource_name, resource)
|
|
25
|
+
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
|
|
26
|
+
else
|
|
27
|
+
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
# The path used after resending confirmation instructions.
|
|
34
|
+
def after_resending_confirmation_instructions_path_for(resource_name)
|
|
35
|
+
new_session_path(resource_name)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# The path used after confirmation.
|
|
39
|
+
def after_confirmation_path_for(resource_name, resource)
|
|
40
|
+
after_sign_in_path_for(resource)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
class Devise::OmniauthCallbacksController < DeviseController
|
|
2
|
+
prepend_before_filter { request.env["devise.skip_timeout"] = true }
|
|
3
|
+
|
|
4
|
+
def passthru
|
|
5
|
+
render :status => 404, :text => "Not found. Authentication passthru."
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def failure
|
|
9
|
+
set_flash_message :alert, :failure, :kind => OmniAuth::Utils.camelize(failed_strategy.name), :reason => failure_message
|
|
10
|
+
redirect_to after_omniauth_failure_path_for(resource_name)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
protected
|
|
14
|
+
|
|
15
|
+
def failed_strategy
|
|
16
|
+
env["omniauth.error.strategy"]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def failure_message
|
|
20
|
+
exception = env["omniauth.error"]
|
|
21
|
+
error = exception.error_reason if exception.respond_to?(:error_reason)
|
|
22
|
+
error ||= exception.error if exception.respond_to?(:error)
|
|
23
|
+
error ||= env["omniauth.error.type"].to_s
|
|
24
|
+
error.to_s.humanize if error
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def after_omniauth_failure_path_for(scope)
|
|
28
|
+
new_session_path(scope)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
class Devise::PasswordsController < DeviseController
|
|
2
|
+
prepend_before_filter :require_no_authentication
|
|
3
|
+
# Render the #edit only if coming from a reset password email link
|
|
4
|
+
append_before_filter :assert_reset_token_passed, :only => :edit
|
|
5
|
+
|
|
6
|
+
# GET /resource/password/new
|
|
7
|
+
def new
|
|
8
|
+
build_resource({})
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# POST /resource/password
|
|
12
|
+
def create
|
|
13
|
+
self.resource = resource_class.send_reset_password_instructions(resource_params)
|
|
14
|
+
|
|
15
|
+
if successfully_sent?(resource)
|
|
16
|
+
respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name))
|
|
17
|
+
else
|
|
18
|
+
respond_with(resource)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# GET /resource/password/edit?reset_password_token=abcdef
|
|
23
|
+
def edit
|
|
24
|
+
self.resource = resource_class.new
|
|
25
|
+
resource.reset_password_token = params[:reset_password_token]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# PUT /resource/password
|
|
29
|
+
def update
|
|
30
|
+
self.resource = resource_class.reset_password_by_token(resource_params)
|
|
31
|
+
|
|
32
|
+
if resource.errors.empty?
|
|
33
|
+
resource.unlock_access! if unlockable?(resource)
|
|
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
|
+
|
|
58
|
+
# Check if proper Lockable module methods are present & unlock strategy
|
|
59
|
+
# allows to unlock resource on password reset
|
|
60
|
+
def unlockable?(resource)
|
|
61
|
+
resource.respond_to?(:unlock_access!) &&
|
|
62
|
+
resource.respond_to?(:unlock_strategy_enabled?) &&
|
|
63
|
+
resource.unlock_strategy_enabled?(:email)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
class Devise::RegistrationsController < DeviseController
|
|
2
|
+
prepend_before_filter :require_no_authentication, :only => [ :new, :create, :cancel ]
|
|
3
|
+
prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]
|
|
4
|
+
|
|
5
|
+
# GET /resource/sign_up
|
|
6
|
+
def new
|
|
7
|
+
resource = build_resource({})
|
|
8
|
+
respond_with resource
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# POST /resource
|
|
12
|
+
def create
|
|
13
|
+
build_resource
|
|
14
|
+
|
|
15
|
+
if resource.save
|
|
16
|
+
if resource.active_for_authentication?
|
|
17
|
+
set_flash_message :notice, :signed_up if is_navigational_format?
|
|
18
|
+
sign_up(resource_name, resource)
|
|
19
|
+
respond_with resource, :location => after_sign_up_path_for(resource)
|
|
20
|
+
else
|
|
21
|
+
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
|
|
22
|
+
expire_session_data_after_sign_in!
|
|
23
|
+
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
clean_up_passwords resource
|
|
27
|
+
respond_with resource
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# GET /resource/edit
|
|
32
|
+
def edit
|
|
33
|
+
render :edit
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# PUT /resource
|
|
37
|
+
# We need to use a copy of the resource because we don't want to change
|
|
38
|
+
# the current user in place.
|
|
39
|
+
def update
|
|
40
|
+
self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
|
|
41
|
+
prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)
|
|
42
|
+
|
|
43
|
+
if resource.update_with_password(resource_params)
|
|
44
|
+
if is_navigational_format?
|
|
45
|
+
flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
|
|
46
|
+
:update_needs_confirmation : :updated
|
|
47
|
+
set_flash_message :notice, flash_key
|
|
48
|
+
end
|
|
49
|
+
sign_in resource_name, resource, :bypass => true
|
|
50
|
+
respond_with resource, :location => after_update_path_for(resource)
|
|
51
|
+
else
|
|
52
|
+
clean_up_passwords resource
|
|
53
|
+
respond_with resource
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# DELETE /resource
|
|
58
|
+
def destroy
|
|
59
|
+
resource.destroy
|
|
60
|
+
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
|
|
61
|
+
set_flash_message :notice, :destroyed if is_navigational_format?
|
|
62
|
+
respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# GET /resource/cancel
|
|
66
|
+
# Forces the session data which is usually expired after sign
|
|
67
|
+
# in to be expired now. This is useful if the user wants to
|
|
68
|
+
# cancel oauth signing in/up in the middle of the process,
|
|
69
|
+
# removing all OAuth session data.
|
|
70
|
+
def cancel
|
|
71
|
+
expire_session_data_after_sign_in!
|
|
72
|
+
redirect_to new_registration_path(resource_name)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
protected
|
|
76
|
+
|
|
77
|
+
def update_needs_confirmation?(resource, previous)
|
|
78
|
+
resource.respond_to?(:pending_reconfirmation?) &&
|
|
79
|
+
resource.pending_reconfirmation? &&
|
|
80
|
+
previous != resource.unconfirmed_email
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Build a devise resource passing in the session. Useful to move
|
|
84
|
+
# temporary session data to the newly created user.
|
|
85
|
+
def build_resource(hash=nil)
|
|
86
|
+
hash ||= resource_params || {}
|
|
87
|
+
self.resource = resource_class.new_with_session(hash, session)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Signs in a user on sign up. You can overwrite this method in your own
|
|
91
|
+
# RegistrationsController.
|
|
92
|
+
def sign_up(resource_name, resource)
|
|
93
|
+
sign_in(resource_name, resource)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# The path used after sign up. You need to overwrite this method
|
|
97
|
+
# in your own RegistrationsController.
|
|
98
|
+
def after_sign_up_path_for(resource)
|
|
99
|
+
after_sign_in_path_for(resource)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# The path used after sign up for inactive accounts. You need to overwrite
|
|
103
|
+
# this method in your own RegistrationsController.
|
|
104
|
+
def after_inactive_sign_up_path_for(resource)
|
|
105
|
+
respond_to?(:root_path) ? root_path : "/"
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# The default url to be used after updating a resource. You need to overwrite
|
|
109
|
+
# this method in your own RegistrationsController.
|
|
110
|
+
def after_update_path_for(resource)
|
|
111
|
+
signed_in_root_path(resource)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Authenticates the current scope and gets the current resource from the session.
|
|
115
|
+
def authenticate_scope!
|
|
116
|
+
send(:"authenticate_#{resource_name}!", :force => true)
|
|
117
|
+
self.resource = send(:"current_#{resource_name}")
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
class Devise::SessionsController < DeviseController
|
|
2
|
+
prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
|
|
3
|
+
prepend_before_filter :allow_params_authentication!, :only => :create
|
|
4
|
+
prepend_before_filter { request.env["devise.skip_timeout"] = true }
|
|
5
|
+
|
|
6
|
+
# GET /resource/sign_in
|
|
7
|
+
def new
|
|
8
|
+
self.resource = build_resource(nil, :unsafe => true)
|
|
9
|
+
clean_up_passwords(resource)
|
|
10
|
+
respond_with(resource, serialize_options(resource))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# POST /resource/sign_in
|
|
14
|
+
def create
|
|
15
|
+
self.resource = warden.authenticate!(auth_options)
|
|
16
|
+
set_flash_message(:notice, :signed_in) if is_navigational_format?
|
|
17
|
+
sign_in(resource_name, resource)
|
|
18
|
+
respond_with resource, :location => after_sign_in_path_for(resource)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# DELETE /resource/sign_out
|
|
22
|
+
def destroy
|
|
23
|
+
redirect_path = after_sign_out_path_for(resource_name)
|
|
24
|
+
signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
|
|
25
|
+
set_flash_message :notice, :signed_out if signed_out && is_navigational_format?
|
|
26
|
+
|
|
27
|
+
# We actually need to hardcode this as Rails default responder doesn't
|
|
28
|
+
# support returning empty response on GET request
|
|
29
|
+
respond_to do |format|
|
|
30
|
+
format.any(*navigational_formats) { redirect_to redirect_path }
|
|
31
|
+
format.all do
|
|
32
|
+
head :no_content
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
|
|
39
|
+
def serialize_options(resource)
|
|
40
|
+
methods = resource_class.authentication_keys.dup
|
|
41
|
+
methods = methods.keys if methods.is_a?(Hash)
|
|
42
|
+
methods << :password if resource.respond_to?(:password)
|
|
43
|
+
{ :methods => methods, :only => [:password] }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def auth_options
|
|
47
|
+
{ :scope => resource_name, :recall => "#{controller_path}#new" }
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
class Devise::UnlocksController < DeviseController
|
|
2
|
+
prepend_before_filter :require_no_authentication
|
|
3
|
+
|
|
4
|
+
# GET /resource/unlock/new
|
|
5
|
+
def new
|
|
6
|
+
build_resource({})
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# POST /resource/unlock
|
|
10
|
+
def create
|
|
11
|
+
self.resource = resource_class.send_unlock_instructions(resource_params)
|
|
12
|
+
|
|
13
|
+
if successfully_sent?(resource)
|
|
14
|
+
respond_with({}, :location => after_sending_unlock_instructions_path_for(resource))
|
|
15
|
+
else
|
|
16
|
+
respond_with(resource)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# GET /resource/unlock?unlock_token=abcdef
|
|
21
|
+
def show
|
|
22
|
+
self.resource = resource_class.unlock_access_by_token(params[:unlock_token])
|
|
23
|
+
|
|
24
|
+
if resource.errors.empty?
|
|
25
|
+
set_flash_message :notice, :unlocked if is_navigational_format?
|
|
26
|
+
respond_with_navigational(resource){ redirect_to after_unlock_path_for(resource) }
|
|
27
|
+
else
|
|
28
|
+
respond_with_navigational(resource.errors, :status => :unprocessable_entity){ render :new }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
protected
|
|
33
|
+
|
|
34
|
+
# The path used after sending unlock password instructions
|
|
35
|
+
def after_sending_unlock_instructions_path_for(resource)
|
|
36
|
+
new_session_path(resource)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# The path used after unlocking the resource
|
|
40
|
+
def after_unlock_path_for(resource)
|
|
41
|
+
new_session_path(resource)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# All Devise controllers are inherited from here.
|
|
2
|
+
class DeviseController < Devise.parent_controller.constantize
|
|
3
|
+
include Devise::Controllers::ScopedViews
|
|
4
|
+
|
|
5
|
+
helper DeviseHelper
|
|
6
|
+
|
|
7
|
+
helpers = %w(resource scope_name resource_name signed_in_resource
|
|
8
|
+
resource_class resource_params devise_mapping)
|
|
9
|
+
hide_action *helpers
|
|
10
|
+
helper_method *helpers
|
|
11
|
+
|
|
12
|
+
prepend_before_filter :assert_is_devise_resource!
|
|
13
|
+
respond_to *Mime::SET.map(&:to_sym) if mimes_for_respond_to.empty?
|
|
14
|
+
|
|
15
|
+
# Gets the actual resource stored in the instance variable
|
|
16
|
+
def resource
|
|
17
|
+
instance_variable_get(:"@#{resource_name}")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Proxy to devise map name
|
|
21
|
+
def resource_name
|
|
22
|
+
devise_mapping.name
|
|
23
|
+
end
|
|
24
|
+
alias :scope_name :resource_name
|
|
25
|
+
|
|
26
|
+
# Proxy to devise map class
|
|
27
|
+
def resource_class
|
|
28
|
+
devise_mapping.to
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def resource_params
|
|
32
|
+
params[resource_name]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns a signed in resource from session (if one exists)
|
|
36
|
+
def signed_in_resource
|
|
37
|
+
warden.authenticate(:scope => resource_name)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Attempt to find the mapped route for devise based on request path
|
|
41
|
+
def devise_mapping
|
|
42
|
+
@devise_mapping ||= request.env["devise.mapping"]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Override prefixes to consider the scoped view.
|
|
46
|
+
# Notice we need to check for the request due to a bug in
|
|
47
|
+
# Action Controller tests that forces _prefixes to be
|
|
48
|
+
# loaded before even having a request object.
|
|
49
|
+
def _prefixes #:nodoc:
|
|
50
|
+
@_prefixes ||= if self.class.scoped_views? && request && devise_mapping
|
|
51
|
+
super.unshift("#{devise_mapping.scoped_path}/#{controller_name}")
|
|
52
|
+
else
|
|
53
|
+
super
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
hide_action :_prefixes
|
|
58
|
+
|
|
59
|
+
protected
|
|
60
|
+
|
|
61
|
+
# Checks whether it's a devise mapped resource or not.
|
|
62
|
+
def assert_is_devise_resource! #:nodoc:
|
|
63
|
+
unknown_action! <<-MESSAGE unless devise_mapping
|
|
64
|
+
Could not find devise mapping for path #{request.fullpath.inspect}.
|
|
65
|
+
This may happen for two reasons:
|
|
66
|
+
|
|
67
|
+
1) You forgot to wrap your route inside the scope block. For example:
|
|
68
|
+
|
|
69
|
+
devise_scope :user do
|
|
70
|
+
match "/some/route" => "some_devise_controller"
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
2) You are testing a Devise controller bypassing the router.
|
|
74
|
+
If so, you can explicitly tell Devise which mapping to use:
|
|
75
|
+
|
|
76
|
+
@request.env["devise.mapping"] = Devise.mappings[:user]
|
|
77
|
+
|
|
78
|
+
MESSAGE
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Returns real navigational formats which are supported by Rails
|
|
82
|
+
def navigational_formats
|
|
83
|
+
@navigational_formats ||= Devise.navigational_formats.select { |format| Mime::EXTENSION_LOOKUP[format.to_s] }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def unknown_action!(msg)
|
|
87
|
+
logger.debug "[Devise] #{msg}" if logger
|
|
88
|
+
raise AbstractController::ActionNotFound, msg
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Sets the resource creating an instance variable
|
|
92
|
+
def resource=(new_resource)
|
|
93
|
+
instance_variable_set(:"@#{resource_name}", new_resource)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Build a devise resource.
|
|
97
|
+
# Assignment bypasses attribute protection when :unsafe option is passed
|
|
98
|
+
def build_resource(hash = nil, options = {})
|
|
99
|
+
hash ||= resource_params || {}
|
|
100
|
+
|
|
101
|
+
if options[:unsafe]
|
|
102
|
+
self.resource = resource_class.new.tap do |resource|
|
|
103
|
+
hash.each do |key, value|
|
|
104
|
+
setter = :"#{key}="
|
|
105
|
+
resource.send(setter, value) if resource.respond_to?(setter)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
else
|
|
109
|
+
self.resource = resource_class.new(hash)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Helper for use in before_filters where no authentication is required.
|
|
114
|
+
#
|
|
115
|
+
# Example:
|
|
116
|
+
# before_filter :require_no_authentication, :only => :new
|
|
117
|
+
def require_no_authentication
|
|
118
|
+
assert_is_devise_resource!
|
|
119
|
+
return unless is_navigational_format?
|
|
120
|
+
no_input = devise_mapping.no_input_strategies
|
|
121
|
+
|
|
122
|
+
authenticated = if no_input.present?
|
|
123
|
+
args = no_input.dup.push :scope => resource_name
|
|
124
|
+
warden.authenticate?(*args)
|
|
125
|
+
else
|
|
126
|
+
warden.authenticated?(resource_name)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
if authenticated && resource = warden.user(resource_name)
|
|
130
|
+
flash[:alert] = I18n.t("devise.failure.already_authenticated")
|
|
131
|
+
redirect_to after_sign_in_path_for(resource)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Helper for use after calling send_*_instructions methods on a resource.
|
|
136
|
+
# If we are in paranoid mode, we always act as if the resource was valid
|
|
137
|
+
# and instructions were sent.
|
|
138
|
+
def successfully_sent?(resource)
|
|
139
|
+
notice = if Devise.paranoid
|
|
140
|
+
resource.errors.clear
|
|
141
|
+
:send_paranoid_instructions
|
|
142
|
+
elsif resource.errors.empty?
|
|
143
|
+
:send_instructions
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
if notice
|
|
147
|
+
set_flash_message :notice, notice if is_navigational_format?
|
|
148
|
+
true
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Sets the flash message with :key, using I18n. By default you are able
|
|
153
|
+
# to setup your messages using specific resource scope, and if no one is
|
|
154
|
+
# found we look to default scope.
|
|
155
|
+
# Example (i18n locale file):
|
|
156
|
+
#
|
|
157
|
+
# en:
|
|
158
|
+
# devise:
|
|
159
|
+
# passwords:
|
|
160
|
+
# #default_scope_messages - only if resource_scope is not found
|
|
161
|
+
# user:
|
|
162
|
+
# #resource_scope_messages
|
|
163
|
+
#
|
|
164
|
+
# Please refer to README or en.yml locale file to check what messages are
|
|
165
|
+
# available.
|
|
166
|
+
def set_flash_message(key, kind, options={})
|
|
167
|
+
options[:scope] = "devise.#{controller_name}"
|
|
168
|
+
options[:default] = Array(options[:default]).unshift(kind.to_sym)
|
|
169
|
+
options[:resource_name] = resource_name
|
|
170
|
+
options = devise_i18n_options(options) if respond_to?(:devise_i18n_options, true)
|
|
171
|
+
message = I18n.t("#{options[:resource_name]}.#{kind}", options)
|
|
172
|
+
flash[key] = message if message.present?
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def clean_up_passwords(object)
|
|
176
|
+
object.clean_up_passwords if object.respond_to?(:clean_up_passwords)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def respond_with_navigational(*args, &block)
|
|
180
|
+
respond_with(*args) do |format|
|
|
181
|
+
format.any(*navigational_formats, &block)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|