mirror of
https://github.com/heartcombo/devise.git
synced 2026-01-09 23:58:06 -05:00
Compare commits
113 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e0d517cdb | ||
|
|
17cd4b0c85 | ||
|
|
1d85f389a0 | ||
|
|
e358f8256b | ||
|
|
12ba8603a5 | ||
|
|
2b123f3017 | ||
|
|
5396b04202 | ||
|
|
acac9b43a7 | ||
|
|
6e020af959 | ||
|
|
c3983d7807 | ||
|
|
4803d5d6b1 | ||
|
|
d8dedec1f8 | ||
|
|
b328655f0f | ||
|
|
0dd921c460 | ||
|
|
c2feed6b3e | ||
|
|
dea0f68291 | ||
|
|
5fc2c2e6f5 | ||
|
|
3bba7edc4f | ||
|
|
36906a03f3 | ||
|
|
d6af3d7dc6 | ||
|
|
767331657b | ||
|
|
55860675c2 | ||
|
|
da3af3f341 | ||
|
|
0f46ed3a33 | ||
|
|
8d33e8f313 | ||
|
|
fb1e9bc8a7 | ||
|
|
4310ad798c | ||
|
|
8def06e1a6 | ||
|
|
3b0aaaaae8 | ||
|
|
cb83c66139 | ||
|
|
2104397bee | ||
|
|
374948cf4b | ||
|
|
7c51ec0742 | ||
|
|
ed05225dd5 | ||
|
|
c32cb3da6c | ||
|
|
70c32e48fc | ||
|
|
522219e5db | ||
|
|
a843b74c86 | ||
|
|
56834284bd | ||
|
|
5b762ff85a | ||
|
|
73822fe109 | ||
|
|
85a4aa2afa | ||
|
|
c49fe8c6d7 | ||
|
|
a59e20e3bb | ||
|
|
5ef88a8fe6 | ||
|
|
9ab64c53f4 | ||
|
|
c5999c8f61 | ||
|
|
680f2612f4 | ||
|
|
81620fecab | ||
|
|
2939a61a49 | ||
|
|
058d433f28 | ||
|
|
5aeb8cf1cf | ||
|
|
abfd7e5a4b | ||
|
|
869c658e3b | ||
|
|
5e64699a5f | ||
|
|
aecc014d33 | ||
|
|
55fd7e3b0a | ||
|
|
b4794e041b | ||
|
|
4f6113ab68 | ||
|
|
05d23f1a00 | ||
|
|
e567c00dd8 | ||
|
|
ebe3e791d6 | ||
|
|
2602ef41cf | ||
|
|
a87bc4a861 | ||
|
|
eca511a8f2 | ||
|
|
9c5ff02ff1 | ||
|
|
9f29ca480b | ||
|
|
b9df42c350 | ||
|
|
bd0e2a3180 | ||
|
|
750560ae87 | ||
|
|
e2a4ebce4a | ||
|
|
77b7692b57 | ||
|
|
ae6322efb5 | ||
|
|
238226e33a | ||
|
|
96a9c88420 | ||
|
|
dd612753f9 | ||
|
|
35923c9c69 | ||
|
|
f54013a181 | ||
|
|
1cf77028c1 | ||
|
|
7774accb6c | ||
|
|
6c49b428b3 | ||
|
|
7113dfe93a | ||
|
|
4083d679d4 | ||
|
|
7a1adbb61e | ||
|
|
18cccae82f | ||
|
|
e9fbb3d7ef | ||
|
|
04c25539c2 | ||
|
|
55bc0ace5a | ||
|
|
421256d294 | ||
|
|
8e3ef2a620 | ||
|
|
aefcd53765 | ||
|
|
0eb9208503 | ||
|
|
8824b767f3 | ||
|
|
2103a673f0 | ||
|
|
78e7642bd2 | ||
|
|
8526056bde | ||
|
|
4b272767d6 | ||
|
|
84c34ff0c4 | ||
|
|
4db3ac820b | ||
|
|
503d27f2e1 | ||
|
|
2475faf9c7 | ||
|
|
819db39263 | ||
|
|
f864259f1e | ||
|
|
12ae21117c | ||
|
|
1a224c7486 | ||
|
|
f10b747f7f | ||
|
|
8370006591 | ||
|
|
1924a915a8 | ||
|
|
7a45043bc8 | ||
|
|
ad63e25c89 | ||
|
|
895a7a4951 | ||
|
|
b8c2bbe73c | ||
|
|
b76bf10203 |
@@ -1,3 +1,79 @@
|
||||
== 1.1.9
|
||||
|
||||
* bugfix
|
||||
* double check if warden has not halted
|
||||
|
||||
== 1.1.8
|
||||
|
||||
* bugfix
|
||||
* Ensure you can't inject Mongoid queries using token authenticatable
|
||||
|
||||
== 1.1.7
|
||||
|
||||
* bugfix
|
||||
* Fix a backward incompatible change with versions prior to Rails 3.0.4
|
||||
|
||||
== 1.1.6
|
||||
|
||||
* bugfix
|
||||
* Use a more secure e-mail regexp
|
||||
* Implement Rails 3.0.4 handle unverified request
|
||||
* Use secure_compare to compare passwords
|
||||
|
||||
== 1.1.5
|
||||
|
||||
* bugfix
|
||||
* Ensure to convert keys on indifferent hash
|
||||
|
||||
* defaults
|
||||
* Set config.http_authenticatable to false to avoid confusion
|
||||
|
||||
== 1.1.4
|
||||
|
||||
* bugfix
|
||||
* Avoid session fixation attacks
|
||||
|
||||
== 1.1.3
|
||||
|
||||
* bugfix
|
||||
* Add reply-to to e-mail headers by default
|
||||
* Updated the views generator to respect the rails :template_engine option (by github.com/fredwu)
|
||||
* Check the type of HTTP Authentication before using Basic headers
|
||||
* Avoid invalid_salt errors by checking salt presence (by github.com/thibaudgg)
|
||||
* Forget user deletes the right cookie before logout, not remembering the user anymore (by github.com/emtrane)
|
||||
* Fix for failed first-ever logins on PostgreSQL where column default is nil (by github.com/bensie)
|
||||
* :default options is now honored in migrations
|
||||
|
||||
== 1.1.2
|
||||
|
||||
* bugfix
|
||||
* Compatibility with latest Rails routes schema
|
||||
|
||||
== 1.1.1
|
||||
|
||||
* bugfix
|
||||
* Fix a small bug where generated locale file was empty on devise:install
|
||||
|
||||
== 1.1.0
|
||||
|
||||
* enhancements
|
||||
* Rememberable module allows user to be remembered across browsers and is enabled by default (by github.com/trevorturk)
|
||||
* Rememberable module allows you to activate the period the remember me token is extended (by github.com/trevorturk)
|
||||
* devise_for can now be used together with scope method in routes but with a few limitations (check the documentation)
|
||||
* Support `as` or `devise_scope` in the router to specify controller access scope
|
||||
* HTTP Basic Auth can now be disabled/enabled for xhr(ajax) requests using http_authenticatable_on_xhr option (by github.com/pellja)
|
||||
|
||||
* bug fix
|
||||
* Fix a bug in Devise::TestHelpers where current_user was returning a Response object for non active accounts
|
||||
* Devise should respect script_name and path_info contracts
|
||||
* Fix a bug when accessing a path with (.:format) (by github.com/klacointe)
|
||||
* Do not add unlock routes unless unlock strategy is email or both
|
||||
* Email should be case insensitive
|
||||
* Store classes as string in session, to avoid serialization and stale data issues
|
||||
|
||||
* deprecations
|
||||
* use_default_scope is deprecated and has no effect. Use :as or :devise_scope in the router instead
|
||||
|
||||
== 1.1.rc2
|
||||
|
||||
* enhancements
|
||||
@@ -16,7 +92,7 @@
|
||||
* devise.mailer.user.confirmations_instructions now should be devise.mailer.confirmations_instructions.user_subject
|
||||
* Generators now use Rails 3 syntax (devise:install) instead of devise_install
|
||||
|
||||
== 1.1.rc
|
||||
== 1.1.rc1
|
||||
|
||||
* enhancements
|
||||
* Rails 3 compatibility
|
||||
@@ -29,7 +105,7 @@
|
||||
* E-mails now use any template available in the filesystem. Easy to create multipart e-mails
|
||||
* E-mails asks headers_for in the model to set the proper headers
|
||||
* Allow to specify haml in devise_views
|
||||
* Compatibility with Datamapper and Mongoid
|
||||
* Compatibility with Mongoid
|
||||
* Make config.devise available on config/application.rb
|
||||
* TokenAuthenticatable now works with HTTP Basic Auth
|
||||
* Allow :unlock_strategy to be :none and add :lock_strategy which can be :failed_attempts or none. Setting those values to :none means that you want to handle lock and unlocking by yourself
|
||||
|
||||
40
Gemfile
40
Gemfile
@@ -1,29 +1,27 @@
|
||||
source "http://rubygems.org"
|
||||
|
||||
# Need to install Rails from source
|
||||
gem "rails", "3.0.0.beta4"
|
||||
gem "warden", "0.10.7"
|
||||
gem "sqlite3-ruby"
|
||||
gem "webrat", "0.7.0"
|
||||
gem "mocha", :require => false
|
||||
gem "bcrypt-ruby", :require => "bcrypt"
|
||||
gemspec
|
||||
|
||||
if RUBY_VERSION < '1.9'
|
||||
gem "ruby-debug", ">= 0.10.3"
|
||||
gem "rails", "~> 3.0.4"
|
||||
|
||||
group :test do
|
||||
gem "webrat", "0.7.2", :require => false
|
||||
gem "mocha", :require => false
|
||||
end
|
||||
|
||||
group :mongoid do
|
||||
gem "mongo"
|
||||
gem "mongoid", :git => "git://github.com/durran/mongoid.git"
|
||||
gem "bson_ext"
|
||||
platforms :jruby do
|
||||
gem 'activerecord-jdbcsqlite3-adapter'
|
||||
end
|
||||
|
||||
group :data_mapper do
|
||||
gem 'dm-core', '~> 1.0.0', :git => 'git://github.com/datamapper/dm-core'
|
||||
gem 'dm-migrations', '~> 1.0.0', :git => 'git://github.com/datamapper/dm-migrations'
|
||||
gem 'dm-sqlite-adapter', '~> 1.0.0', :git => 'git://github.com/datamapper/dm-sqlite-adapter'
|
||||
gem 'dm-validations', '~> 1.0.0', :git => 'git://github.com/datamapper/dm-validations'
|
||||
gem 'dm-serializer', '~> 1.0.0', :git => 'git://github.com/datamapper/dm-serializer'
|
||||
gem 'dm-timestamps', '~> 1.0.0', :git => 'git://github.com/datamapper/dm-timestamps'
|
||||
gem 'dm-rails', '~> 1.0.0', :git => 'git://github.com/datamapper/dm-rails'
|
||||
platforms :ruby do
|
||||
group :test do
|
||||
gem "sqlite3-ruby"
|
||||
gem "ruby-debug", ">= 0.10.3" if RUBY_VERSION < '1.9'
|
||||
end
|
||||
|
||||
group :mongoid do
|
||||
gem "mongo", "1.1.2"
|
||||
gem "mongoid", "2.0.0.beta.20"
|
||||
gem "bson_ext", "1.1.2"
|
||||
end
|
||||
end
|
||||
|
||||
115
Gemfile.lock
Normal file
115
Gemfile.lock
Normal file
@@ -0,0 +1,115 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
devise (1.1.8)
|
||||
bcrypt-ruby (~> 2.1.2)
|
||||
warden (~> 1.0.2)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
abstract (1.0.0)
|
||||
actionmailer (3.0.4)
|
||||
actionpack (= 3.0.4)
|
||||
mail (~> 2.2.15)
|
||||
actionpack (3.0.4)
|
||||
activemodel (= 3.0.4)
|
||||
activesupport (= 3.0.4)
|
||||
builder (~> 2.1.2)
|
||||
erubis (~> 2.6.6)
|
||||
i18n (~> 0.4)
|
||||
rack (~> 1.2.1)
|
||||
rack-mount (~> 0.6.13)
|
||||
rack-test (~> 0.5.7)
|
||||
tzinfo (~> 0.3.23)
|
||||
activemodel (3.0.4)
|
||||
activesupport (= 3.0.4)
|
||||
builder (~> 2.1.2)
|
||||
i18n (~> 0.4)
|
||||
activerecord (3.0.4)
|
||||
activemodel (= 3.0.4)
|
||||
activesupport (= 3.0.4)
|
||||
arel (~> 2.0.2)
|
||||
tzinfo (~> 0.3.23)
|
||||
activeresource (3.0.4)
|
||||
activemodel (= 3.0.4)
|
||||
activesupport (= 3.0.4)
|
||||
activesupport (3.0.4)
|
||||
arel (2.0.8)
|
||||
bcrypt-ruby (2.1.4)
|
||||
bson (1.1.2)
|
||||
bson_ext (1.1.2)
|
||||
builder (2.1.2)
|
||||
columnize (0.3.2)
|
||||
erubis (2.6.6)
|
||||
abstract (>= 1.0.0)
|
||||
i18n (0.5.0)
|
||||
linecache (0.43)
|
||||
mail (2.2.15)
|
||||
activesupport (>= 2.3.6)
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
mime-types (1.16)
|
||||
mocha (0.9.9)
|
||||
rake
|
||||
mongo (1.1.2)
|
||||
bson (>= 1.1.1)
|
||||
mongoid (2.0.0.beta.20)
|
||||
activemodel (~> 3.0)
|
||||
mongo (~> 1.1)
|
||||
tzinfo (~> 0.3.22)
|
||||
will_paginate (~> 3.0.pre)
|
||||
nokogiri (1.4.4)
|
||||
polyglot (0.3.1)
|
||||
rack (1.2.1)
|
||||
rack-mount (0.6.13)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (0.5.7)
|
||||
rack (>= 1.0)
|
||||
rails (3.0.4)
|
||||
actionmailer (= 3.0.4)
|
||||
actionpack (= 3.0.4)
|
||||
activerecord (= 3.0.4)
|
||||
activeresource (= 3.0.4)
|
||||
activesupport (= 3.0.4)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.0.4)
|
||||
railties (3.0.4)
|
||||
actionpack (= 3.0.4)
|
||||
activesupport (= 3.0.4)
|
||||
rake (>= 0.8.7)
|
||||
thor (~> 0.14.4)
|
||||
rake (0.8.7)
|
||||
ruby-debug (0.10.4)
|
||||
columnize (>= 0.1)
|
||||
ruby-debug-base (~> 0.10.4.0)
|
||||
ruby-debug-base (0.10.4)
|
||||
linecache (>= 0.3)
|
||||
sqlite3-ruby (1.3.2)
|
||||
thor (0.14.6)
|
||||
treetop (1.4.9)
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.24)
|
||||
warden (1.0.3)
|
||||
rack (>= 1.0.0)
|
||||
webrat (0.7.2)
|
||||
nokogiri (>= 1.2.0)
|
||||
rack (>= 1.0)
|
||||
rack-test (>= 0.5.3)
|
||||
will_paginate (3.0.pre2)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
activerecord-jdbcsqlite3-adapter
|
||||
bson_ext (= 1.1.2)
|
||||
devise!
|
||||
mocha
|
||||
mongo (= 1.1.2)
|
||||
mongoid (= 2.0.0.beta.20)
|
||||
rails (~> 3.0.4)
|
||||
ruby-debug (>= 0.10.3)
|
||||
sqlite3-ruby
|
||||
webrat (= 0.7.2)
|
||||
28
README.rdoc
28
README.rdoc
@@ -22,19 +22,11 @@ Right now it's composed of 11 modules:
|
||||
|
||||
== Installation
|
||||
|
||||
=== Rails 3 beta 4
|
||||
Devise 1.1 supports Rails 3 and is NOT backward compatible. You can use the latest Rails 3 beta gem with Devise latest gem:
|
||||
|
||||
To use Devise with Rails 3 beta 4, please use it straight from the git repository, by adding it to your Gemfile:
|
||||
gem install devise --version=1.1.7
|
||||
|
||||
gem "devise", :git => "git://github.com/plataformatec/devise.git"
|
||||
|
||||
Then follow the same steps as below.
|
||||
|
||||
=== Rails 3 beta 3
|
||||
|
||||
Devise master branch now supports Rails 3 and is NOT backward compatible. You can use the latest Rails 3 beta gem with Devise latest gem:
|
||||
|
||||
gem install devise --version=1.1.rc1
|
||||
If you want to use Rails master (from git repository) you need to use Devise from git repository and vice-versa.
|
||||
|
||||
After you install Devise and add it to your Gemfile, you need to run the generator:
|
||||
|
||||
@@ -46,11 +38,11 @@ The generator will install an initializer which describes ALL Devise's configura
|
||||
|
||||
Replace MODEL by the class name you want to add devise, like User, Admin, etc. This will create a model (if one does not exist) and configure it with default Devise modules. The generator will also create a migration file (if your ORM support them) and configure your routes. Continue reading this file to understand exactly what the generator produces and how to use it.
|
||||
|
||||
=== Rails 2.3
|
||||
== Rails 2.3
|
||||
|
||||
If you want to use the Rails 2.3.x version, you should do:
|
||||
|
||||
gem install devise --version=1.0.7
|
||||
gem install devise --version=1.0.10
|
||||
|
||||
And please check the README at the v1.0 branch since this one is based on Rails 3:
|
||||
|
||||
@@ -283,6 +275,16 @@ Please consult their respective documentation for more information and requireme
|
||||
|
||||
Please refer to TODO file.
|
||||
|
||||
== Security
|
||||
|
||||
Needless to say, security is extremely important to Devise. If you find yourself in a possible security issue with Devise, please go through the following steps, trying to reproduce the bug:
|
||||
|
||||
1) Look at the source code a bit to find out whether your assumptions are correct;
|
||||
2) If possible, provide a way to reproduce the bug: a small app on Github or a step-by-step to reproduce;
|
||||
3) E-mail us or send a Github private message instead of using the normal issues;
|
||||
|
||||
Being able to reproduce the bug is the first step to fix it. Thanks for your understanding.
|
||||
|
||||
== Maintainers
|
||||
|
||||
* José Valim (http://github.com/josevalim)
|
||||
|
||||
2
Rakefile
2
Rakefile
@@ -45,7 +45,7 @@ begin
|
||||
s.authors = ['José Valim', 'Carlos Antônio']
|
||||
s.files = FileList["[A-Z]*", "{app,config,lib}/**/*"]
|
||||
s.extra_rdoc_files = FileList["[A-Z]*"] - %w(Gemfile Rakefile)
|
||||
s.add_dependency("warden", "~> 0.10.7")
|
||||
s.add_dependency("warden", "~> 1.0.2")
|
||||
s.add_dependency("bcrypt-ruby", "~> 2.1.2")
|
||||
end
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class Devise::RegistrationsController < ApplicationController
|
||||
render_with_scope :new
|
||||
end
|
||||
|
||||
# POST /resource/sign_up
|
||||
# POST /resource
|
||||
def create
|
||||
build_resource
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
class Devise::UnlocksController < ApplicationController
|
||||
prepend_before_filter :ensure_email_as_unlock_strategy
|
||||
prepend_before_filter :require_no_authentication
|
||||
include Devise::Controllers::InternalHelpers
|
||||
|
||||
@@ -32,10 +31,4 @@ class Devise::UnlocksController < ApplicationController
|
||||
render_with_scope :new
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def ensure_email_as_unlock_strategy
|
||||
raise ActionController::UnknownAction unless resource_class.unlock_strategy_enabled?(:email)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,14 +22,11 @@ class Devise::Mailer < ::ActionMailer::Base
|
||||
@devise_mapping = Devise.mappings[@scope_name]
|
||||
@resource = instance_variable_set("@#{@devise_mapping.name}", record)
|
||||
|
||||
template_path = ["devise/mailer"]
|
||||
template_path.unshift "#{@devise_mapping.plural}/mailer" if self.class.scoped_views?
|
||||
|
||||
headers = {
|
||||
:subject => translate(@devise_mapping, action),
|
||||
:from => mailer_sender(@devise_mapping),
|
||||
:to => record.email,
|
||||
:template_path => template_path
|
||||
:template_path => template_paths
|
||||
}
|
||||
|
||||
headers.merge!(record.headers_for(action)) if record.respond_to?(:headers_for)
|
||||
@@ -44,6 +41,12 @@ class Devise::Mailer < ::ActionMailer::Base
|
||||
end
|
||||
end
|
||||
|
||||
def template_paths
|
||||
template_path = [self.class.mailer_name]
|
||||
template_path.unshift "#{@devise_mapping.plural}/mailer" if self.class.scoped_views?
|
||||
template_path
|
||||
end
|
||||
|
||||
# Setup a subject doing an I18n lookup. At first, it attemps to set a subject
|
||||
# based on the current mapping:
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<h2>Resend confirmation instructions</h2>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name)) do |f| %>
|
||||
<%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<p><%= f.label :email %><br />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<h2>Forgot your password?</h2>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name)) do |f| %>
|
||||
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<p><%= f.label :email %><br />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<h2>Resend unlock instructions</h2>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name)) do |f| %>
|
||||
<%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %>
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<p><%= f.label :email %><br />
|
||||
|
||||
322
devise.gemspec
322
devise.gemspec
@@ -1,197 +1,197 @@
|
||||
# Generated by jeweler
|
||||
# DO NOT EDIT THIS FILE DIRECTLY
|
||||
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
||||
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = %q{devise}
|
||||
s.version = "1.1.rc2"
|
||||
s.version = "1.1.9"
|
||||
|
||||
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||
s.authors = ["Jos\303\251 Valim", "Carlos Ant\303\264nio"]
|
||||
s.date = %q{2010-06-23}
|
||||
s.date = %q{2011-03-25}
|
||||
s.description = %q{Flexible authentication solution for Rails with Warden}
|
||||
s.email = %q{contact@plataformatec.com.br}
|
||||
s.extra_rdoc_files = [
|
||||
"CHANGELOG.rdoc",
|
||||
"MIT-LICENSE",
|
||||
"README.rdoc",
|
||||
"TODO"
|
||||
"Gemfile.lock",
|
||||
"MIT-LICENSE",
|
||||
"README.rdoc",
|
||||
"TODO"
|
||||
]
|
||||
s.files = [
|
||||
"CHANGELOG.rdoc",
|
||||
"Gemfile",
|
||||
"MIT-LICENSE",
|
||||
"README.rdoc",
|
||||
"Rakefile",
|
||||
"TODO",
|
||||
"app/controllers/devise/confirmations_controller.rb",
|
||||
"app/controllers/devise/passwords_controller.rb",
|
||||
"app/controllers/devise/registrations_controller.rb",
|
||||
"app/controllers/devise/sessions_controller.rb",
|
||||
"app/controllers/devise/unlocks_controller.rb",
|
||||
"app/helpers/devise_helper.rb",
|
||||
"app/mailers/devise/mailer.rb",
|
||||
"app/views/devise/confirmations/new.html.erb",
|
||||
"app/views/devise/mailer/confirmation_instructions.html.erb",
|
||||
"app/views/devise/mailer/reset_password_instructions.html.erb",
|
||||
"app/views/devise/mailer/unlock_instructions.html.erb",
|
||||
"app/views/devise/passwords/edit.html.erb",
|
||||
"app/views/devise/passwords/new.html.erb",
|
||||
"app/views/devise/registrations/edit.html.erb",
|
||||
"app/views/devise/registrations/new.html.erb",
|
||||
"app/views/devise/sessions/new.html.erb",
|
||||
"app/views/devise/shared/_links.erb",
|
||||
"app/views/devise/unlocks/new.html.erb",
|
||||
"config/locales/en.yml",
|
||||
"lib/devise.rb",
|
||||
"lib/devise/controllers/helpers.rb",
|
||||
"lib/devise/controllers/internal_helpers.rb",
|
||||
"lib/devise/controllers/scoped_views.rb",
|
||||
"lib/devise/controllers/url_helpers.rb",
|
||||
"lib/devise/encryptors/authlogic_sha512.rb",
|
||||
"lib/devise/encryptors/base.rb",
|
||||
"lib/devise/encryptors/bcrypt.rb",
|
||||
"lib/devise/encryptors/clearance_sha1.rb",
|
||||
"lib/devise/encryptors/restful_authentication_sha1.rb",
|
||||
"lib/devise/encryptors/sha1.rb",
|
||||
"lib/devise/encryptors/sha512.rb",
|
||||
"lib/devise/failure_app.rb",
|
||||
"lib/devise/hooks/activatable.rb",
|
||||
"lib/devise/hooks/forgetable.rb",
|
||||
"lib/devise/hooks/rememberable.rb",
|
||||
"lib/devise/hooks/timeoutable.rb",
|
||||
"lib/devise/hooks/trackable.rb",
|
||||
"lib/devise/mapping.rb",
|
||||
"lib/devise/models.rb",
|
||||
"lib/devise/models/authenticatable.rb",
|
||||
"lib/devise/models/confirmable.rb",
|
||||
"lib/devise/models/database_authenticatable.rb",
|
||||
"lib/devise/models/lockable.rb",
|
||||
"lib/devise/models/recoverable.rb",
|
||||
"lib/devise/models/registerable.rb",
|
||||
"lib/devise/models/rememberable.rb",
|
||||
"lib/devise/models/timeoutable.rb",
|
||||
"lib/devise/models/token_authenticatable.rb",
|
||||
"lib/devise/models/trackable.rb",
|
||||
"lib/devise/models/validatable.rb",
|
||||
"lib/devise/modules.rb",
|
||||
"lib/devise/orm/active_record.rb",
|
||||
"lib/devise/orm/data_mapper.rb",
|
||||
"lib/devise/orm/mongoid.rb",
|
||||
"lib/devise/path_checker.rb",
|
||||
"lib/devise/rails.rb",
|
||||
"lib/devise/rails/routes.rb",
|
||||
"lib/devise/rails/warden_compat.rb",
|
||||
"lib/devise/schema.rb",
|
||||
"lib/devise/strategies/authenticatable.rb",
|
||||
"lib/devise/strategies/base.rb",
|
||||
"lib/devise/strategies/database_authenticatable.rb",
|
||||
"lib/devise/strategies/rememberable.rb",
|
||||
"lib/devise/strategies/token_authenticatable.rb",
|
||||
"lib/devise/test_helpers.rb",
|
||||
"lib/devise/version.rb",
|
||||
"lib/generators/devise/devise/devise_generator.rb",
|
||||
"lib/generators/devise/devise/templates/migration.rb",
|
||||
"lib/generators/devise/install/install_generator.rb",
|
||||
"lib/generators/devise/install/templates/README",
|
||||
"lib/generators/devise/install/templates/devise.rb",
|
||||
"lib/generators/devise/views/views_generator.rb",
|
||||
"lib/generators/devise_generator.rb",
|
||||
"lib/generators/devise_install_generator.rb",
|
||||
"lib/generators/devise_views_generator.rb"
|
||||
"Gemfile",
|
||||
"Gemfile.lock",
|
||||
"MIT-LICENSE",
|
||||
"README.rdoc",
|
||||
"Rakefile",
|
||||
"TODO",
|
||||
"app/controllers/devise/confirmations_controller.rb",
|
||||
"app/controllers/devise/passwords_controller.rb",
|
||||
"app/controllers/devise/registrations_controller.rb",
|
||||
"app/controllers/devise/sessions_controller.rb",
|
||||
"app/controllers/devise/unlocks_controller.rb",
|
||||
"app/helpers/devise_helper.rb",
|
||||
"app/mailers/devise/mailer.rb",
|
||||
"app/views/devise/confirmations/new.html.erb",
|
||||
"app/views/devise/mailer/confirmation_instructions.html.erb",
|
||||
"app/views/devise/mailer/reset_password_instructions.html.erb",
|
||||
"app/views/devise/mailer/unlock_instructions.html.erb",
|
||||
"app/views/devise/passwords/edit.html.erb",
|
||||
"app/views/devise/passwords/new.html.erb",
|
||||
"app/views/devise/registrations/edit.html.erb",
|
||||
"app/views/devise/registrations/new.html.erb",
|
||||
"app/views/devise/sessions/new.html.erb",
|
||||
"app/views/devise/shared/_links.erb",
|
||||
"app/views/devise/unlocks/new.html.erb",
|
||||
"config/locales/en.yml",
|
||||
"lib/devise.rb",
|
||||
"lib/devise/controllers/helpers.rb",
|
||||
"lib/devise/controllers/internal_helpers.rb",
|
||||
"lib/devise/controllers/scoped_views.rb",
|
||||
"lib/devise/controllers/url_helpers.rb",
|
||||
"lib/devise/encryptors/authlogic_sha512.rb",
|
||||
"lib/devise/encryptors/base.rb",
|
||||
"lib/devise/encryptors/bcrypt.rb",
|
||||
"lib/devise/encryptors/clearance_sha1.rb",
|
||||
"lib/devise/encryptors/restful_authentication_sha1.rb",
|
||||
"lib/devise/encryptors/sha1.rb",
|
||||
"lib/devise/encryptors/sha512.rb",
|
||||
"lib/devise/failure_app.rb",
|
||||
"lib/devise/hooks/activatable.rb",
|
||||
"lib/devise/hooks/forgetable.rb",
|
||||
"lib/devise/hooks/rememberable.rb",
|
||||
"lib/devise/hooks/timeoutable.rb",
|
||||
"lib/devise/hooks/trackable.rb",
|
||||
"lib/devise/mapping.rb",
|
||||
"lib/devise/models.rb",
|
||||
"lib/devise/models/authenticatable.rb",
|
||||
"lib/devise/models/confirmable.rb",
|
||||
"lib/devise/models/database_authenticatable.rb",
|
||||
"lib/devise/models/lockable.rb",
|
||||
"lib/devise/models/recoverable.rb",
|
||||
"lib/devise/models/registerable.rb",
|
||||
"lib/devise/models/rememberable.rb",
|
||||
"lib/devise/models/timeoutable.rb",
|
||||
"lib/devise/models/token_authenticatable.rb",
|
||||
"lib/devise/models/trackable.rb",
|
||||
"lib/devise/models/validatable.rb",
|
||||
"lib/devise/modules.rb",
|
||||
"lib/devise/orm/active_record.rb",
|
||||
"lib/devise/orm/mongoid.rb",
|
||||
"lib/devise/path_checker.rb",
|
||||
"lib/devise/rails.rb",
|
||||
"lib/devise/rails/routes.rb",
|
||||
"lib/devise/rails/warden_compat.rb",
|
||||
"lib/devise/schema.rb",
|
||||
"lib/devise/strategies/authenticatable.rb",
|
||||
"lib/devise/strategies/base.rb",
|
||||
"lib/devise/strategies/database_authenticatable.rb",
|
||||
"lib/devise/strategies/rememberable.rb",
|
||||
"lib/devise/strategies/token_authenticatable.rb",
|
||||
"lib/devise/test_helpers.rb",
|
||||
"lib/devise/version.rb",
|
||||
"lib/generators/active_record/devise_generator.rb",
|
||||
"lib/generators/active_record/templates/migration.rb",
|
||||
"lib/generators/devise/devise_generator.rb",
|
||||
"lib/generators/devise/install_generator.rb",
|
||||
"lib/generators/devise/orm_helpers.rb",
|
||||
"lib/generators/devise/views_generator.rb",
|
||||
"lib/generators/devise_install_generator.rb",
|
||||
"lib/generators/devise_views_generator.rb",
|
||||
"lib/generators/mongoid/devise_generator.rb",
|
||||
"lib/generators/templates/README",
|
||||
"lib/generators/templates/devise.rb"
|
||||
]
|
||||
s.homepage = %q{http://github.com/plataformatec/devise}
|
||||
s.rdoc_options = ["--charset=UTF-8"]
|
||||
s.require_paths = ["lib"]
|
||||
s.rubygems_version = %q{1.3.7}
|
||||
s.summary = %q{Flexible authentication solution for Rails with Warden}
|
||||
s.test_files = [
|
||||
"test/controllers/helpers_test.rb",
|
||||
"test/controllers/internal_helpers_test.rb",
|
||||
"test/controllers/url_helpers_test.rb",
|
||||
"test/devise_test.rb",
|
||||
"test/encryptors_test.rb",
|
||||
"test/failure_app_test.rb",
|
||||
"test/integration/authenticatable_test.rb",
|
||||
"test/integration/confirmable_test.rb",
|
||||
"test/integration/database_authenticatable_test.rb",
|
||||
"test/integration/http_authenticatable_test.rb",
|
||||
"test/integration/lockable_test.rb",
|
||||
"test/integration/recoverable_test.rb",
|
||||
"test/integration/registerable_test.rb",
|
||||
"test/integration/rememberable_test.rb",
|
||||
"test/integration/timeoutable_test.rb",
|
||||
"test/integration/token_authenticatable_test.rb",
|
||||
"test/integration/trackable_test.rb",
|
||||
"test/mailers/confirmation_instructions_test.rb",
|
||||
"test/mailers/reset_password_instructions_test.rb",
|
||||
"test/mailers/unlock_instructions_test.rb",
|
||||
"test/mapping_test.rb",
|
||||
"test/models/confirmable_test.rb",
|
||||
"test/models/database_authenticatable_test.rb",
|
||||
"test/models/lockable_test.rb",
|
||||
"test/models/recoverable_test.rb",
|
||||
"test/models/rememberable_test.rb",
|
||||
"test/models/timeoutable_test.rb",
|
||||
"test/models/token_authenticatable_test.rb",
|
||||
"test/models/trackable_test.rb",
|
||||
"test/models/validatable_test.rb",
|
||||
"test/models_test.rb",
|
||||
"test/orm/active_record.rb",
|
||||
"test/orm/data_mapper.rb",
|
||||
"test/orm/mongoid.rb",
|
||||
"test/rails_app/app/active_record/admin.rb",
|
||||
"test/rails_app/app/active_record/shim.rb",
|
||||
"test/rails_app/app/active_record/user.rb",
|
||||
"test/rails_app/app/controllers/admins_controller.rb",
|
||||
"test/rails_app/app/controllers/application_controller.rb",
|
||||
"test/rails_app/app/controllers/home_controller.rb",
|
||||
"test/rails_app/app/controllers/sessions_controller.rb",
|
||||
"test/rails_app/app/controllers/users_controller.rb",
|
||||
"test/rails_app/app/data_mapper/admin.rb",
|
||||
"test/rails_app/app/data_mapper/shim.rb",
|
||||
"test/rails_app/app/data_mapper/user.rb",
|
||||
"test/rails_app/app/helpers/application_helper.rb",
|
||||
"test/rails_app/app/mongoid/admin.rb",
|
||||
"test/rails_app/app/mongoid/shim.rb",
|
||||
"test/rails_app/app/mongoid/user.rb",
|
||||
"test/rails_app/config/application.rb",
|
||||
"test/rails_app/config/boot.rb",
|
||||
"test/rails_app/config/environment.rb",
|
||||
"test/rails_app/config/environments/development.rb",
|
||||
"test/rails_app/config/environments/production.rb",
|
||||
"test/rails_app/config/environments/test.rb",
|
||||
"test/rails_app/config/initializers/backtrace_silencers.rb",
|
||||
"test/rails_app/config/initializers/devise.rb",
|
||||
"test/rails_app/config/initializers/inflections.rb",
|
||||
"test/rails_app/config/initializers/secret_token.rb",
|
||||
"test/rails_app/config/routes.rb",
|
||||
"test/rails_app/db/migrate/20100401102949_create_tables.rb",
|
||||
"test/rails_app/db/schema.rb",
|
||||
"test/routes_test.rb",
|
||||
"test/support/assertions.rb",
|
||||
"test/support/helpers.rb",
|
||||
"test/support/integration.rb",
|
||||
"test/support/test_silencer.rb",
|
||||
"test/support/webrat/integrations/rails.rb",
|
||||
"test/test_helper.rb",
|
||||
"test/test_helpers_test.rb"
|
||||
"test/controllers/internal_helpers_test.rb",
|
||||
"test/controllers/url_helpers_test.rb",
|
||||
"test/devise_test.rb",
|
||||
"test/encryptors_test.rb",
|
||||
"test/failure_app_test.rb",
|
||||
"test/indifferent_hash.rb",
|
||||
"test/integration/authenticatable_test.rb",
|
||||
"test/integration/confirmable_test.rb",
|
||||
"test/integration/database_authenticatable_test.rb",
|
||||
"test/integration/http_authenticatable_test.rb",
|
||||
"test/integration/lockable_test.rb",
|
||||
"test/integration/recoverable_test.rb",
|
||||
"test/integration/registerable_test.rb",
|
||||
"test/integration/rememberable_test.rb",
|
||||
"test/integration/timeoutable_test.rb",
|
||||
"test/integration/token_authenticatable_test.rb",
|
||||
"test/integration/trackable_test.rb",
|
||||
"test/mailers/confirmation_instructions_test.rb",
|
||||
"test/mailers/reset_password_instructions_test.rb",
|
||||
"test/mailers/unlock_instructions_test.rb",
|
||||
"test/mapping_test.rb",
|
||||
"test/models/confirmable_test.rb",
|
||||
"test/models/database_authenticatable_test.rb",
|
||||
"test/models/lockable_test.rb",
|
||||
"test/models/recoverable_test.rb",
|
||||
"test/models/rememberable_test.rb",
|
||||
"test/models/timeoutable_test.rb",
|
||||
"test/models/token_authenticatable_test.rb",
|
||||
"test/models/trackable_test.rb",
|
||||
"test/models/validatable_test.rb",
|
||||
"test/models_test.rb",
|
||||
"test/orm/active_record.rb",
|
||||
"test/orm/mongoid.rb",
|
||||
"test/rails_app/app/active_record/admin.rb",
|
||||
"test/rails_app/app/active_record/shim.rb",
|
||||
"test/rails_app/app/active_record/user.rb",
|
||||
"test/rails_app/app/controllers/admins_controller.rb",
|
||||
"test/rails_app/app/controllers/application_controller.rb",
|
||||
"test/rails_app/app/controllers/home_controller.rb",
|
||||
"test/rails_app/app/controllers/publisher/registrations_controller.rb",
|
||||
"test/rails_app/app/controllers/publisher/sessions_controller.rb",
|
||||
"test/rails_app/app/controllers/sessions_controller.rb",
|
||||
"test/rails_app/app/controllers/users_controller.rb",
|
||||
"test/rails_app/app/helpers/application_helper.rb",
|
||||
"test/rails_app/app/mongoid/admin.rb",
|
||||
"test/rails_app/app/mongoid/shim.rb",
|
||||
"test/rails_app/app/mongoid/user.rb",
|
||||
"test/rails_app/config/application.rb",
|
||||
"test/rails_app/config/boot.rb",
|
||||
"test/rails_app/config/environment.rb",
|
||||
"test/rails_app/config/environments/development.rb",
|
||||
"test/rails_app/config/environments/production.rb",
|
||||
"test/rails_app/config/environments/test.rb",
|
||||
"test/rails_app/config/initializers/backtrace_silencers.rb",
|
||||
"test/rails_app/config/initializers/devise.rb",
|
||||
"test/rails_app/config/initializers/inflections.rb",
|
||||
"test/rails_app/config/initializers/secret_token.rb",
|
||||
"test/rails_app/config/routes.rb",
|
||||
"test/rails_app/db/migrate/20100401102949_create_tables.rb",
|
||||
"test/rails_app/db/schema.rb",
|
||||
"test/routes_test.rb",
|
||||
"test/support/assertions.rb",
|
||||
"test/support/helpers.rb",
|
||||
"test/support/integration.rb",
|
||||
"test/support/test_silencer.rb",
|
||||
"test/support/webrat/integrations/rails.rb",
|
||||
"test/test_helper.rb",
|
||||
"test/test_helpers_test.rb"
|
||||
]
|
||||
|
||||
if s.respond_to? :specification_version then
|
||||
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
||||
s.specification_version = 3
|
||||
|
||||
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
||||
s.add_runtime_dependency(%q<warden>, ["~> 0.10.7"])
|
||||
s.add_runtime_dependency(%q<warden>, ["~> 1.0.2"])
|
||||
s.add_runtime_dependency(%q<bcrypt-ruby>, ["~> 2.1.2"])
|
||||
else
|
||||
s.add_dependency(%q<warden>, ["~> 0.10.7"])
|
||||
s.add_dependency(%q<warden>, ["~> 1.0.2"])
|
||||
s.add_dependency(%q<bcrypt-ruby>, ["~> 2.1.2"])
|
||||
end
|
||||
else
|
||||
s.add_dependency(%q<warden>, ["~> 0.10.7"])
|
||||
s.add_dependency(%q<warden>, ["~> 1.0.2"])
|
||||
s.add_dependency(%q<bcrypt-ruby>, ["~> 2.1.2"])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -67,7 +67,11 @@ module Devise
|
||||
|
||||
# If http authentication is enabled by default.
|
||||
mattr_accessor :http_authenticatable
|
||||
@@http_authenticatable = true
|
||||
@@http_authenticatable = false
|
||||
|
||||
# If http authentication is used for ajax requests. True by default.
|
||||
mattr_accessor :http_authenticatable_on_xhr
|
||||
@@http_authenticatable_on_xhr = true
|
||||
|
||||
# If params authenticatable is enabled by default.
|
||||
mattr_accessor :params_authenticatable
|
||||
@@ -79,16 +83,24 @@ module Devise
|
||||
|
||||
# Email regex used to validate email formats. Adapted from authlogic.
|
||||
mattr_accessor :email_regexp
|
||||
@@email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
|
||||
@@email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
|
||||
|
||||
# Range validation for password length
|
||||
mattr_accessor :password_length
|
||||
@@password_length = 6..20
|
||||
|
||||
# Time interval where the remember me token is valid.
|
||||
# The time the user will be remembered without asking for credentials again.
|
||||
mattr_accessor :remember_for
|
||||
@@remember_for = 2.weeks
|
||||
|
||||
# If true, a valid remember token can be re-used between multiple browsers.
|
||||
mattr_accessor :remember_across_browsers
|
||||
@@remember_across_browsers = true
|
||||
|
||||
# If true, extends the user's remember period when remembered via cookie.
|
||||
mattr_accessor :extend_remember_period
|
||||
@@extend_remember_period = false
|
||||
|
||||
# Time interval you can access your account before confirming your account.
|
||||
mattr_accessor :confirm_within
|
||||
@@confirm_within = 0.days
|
||||
@@ -133,10 +145,6 @@ module Devise
|
||||
mattr_accessor :unlock_in
|
||||
@@unlock_in = 1.hour
|
||||
|
||||
# Tell when to use the default scope, if one cannot be found from routes.
|
||||
mattr_accessor :use_default_scope
|
||||
@@use_default_scope = false
|
||||
|
||||
# The default scope which is used by warden.
|
||||
mattr_accessor :default_scope
|
||||
@@default_scope = nil
|
||||
@@ -149,6 +157,7 @@ module Devise
|
||||
mattr_accessor :token_authentication_key
|
||||
@@token_authentication_key = :auth_token
|
||||
|
||||
# Which formats should be treated as navigational.
|
||||
mattr_accessor :navigational_formats
|
||||
@@navigational_formats = [:html]
|
||||
|
||||
@@ -157,6 +166,17 @@ module Devise
|
||||
@@warden_config = nil
|
||||
@@warden_config_block = nil
|
||||
|
||||
# When set to true, signing out an user signs out all other scopes.
|
||||
mattr_accessor :sign_out_all_scopes
|
||||
@@sign_out_all_scopes = false
|
||||
|
||||
def self.use_default_scope=(*)
|
||||
ActiveSupport::Deprecation.warn "config.use_default_scope is deprecated and removed from Devise. " <<
|
||||
"If you are using non conventional routes in Devise, all you need to do is to pass the devise " <<
|
||||
"scope in the router DSL:\n\n as :user do\n get \"sign_in\", :to => \"devise/sessions\"\n end\n\n" <<
|
||||
"The method :as is also aliased to :devise_scope. Choose the one you prefer.", caller
|
||||
end
|
||||
|
||||
# Default way to setup Devise. Run rails generate devise_install to create
|
||||
# a fresh initializer with all configuration values.
|
||||
def self.setup
|
||||
@@ -174,10 +194,8 @@ module Devise
|
||||
end
|
||||
self.mailer = "Devise::Mailer"
|
||||
|
||||
# Register a model in Devise. You can call this manually if you don't want
|
||||
# to use devise routes. Check devise_for in routes to know which options
|
||||
# are available.
|
||||
def self.add_model(resource, options)
|
||||
# Small method that adds a mapping to Devise.
|
||||
def self.add_mapping(resource, options)
|
||||
mapping = Devise::Mapping.new(resource, options)
|
||||
self.mappings[mapping.name] = mapping
|
||||
self.default_scope ||= mapping.name
|
||||
@@ -247,6 +265,11 @@ module Devise
|
||||
@@warden_config_block = block
|
||||
end
|
||||
|
||||
# Returns true if Rails version is bigger than 3.0.x
|
||||
def self.rack_session?
|
||||
Rails::VERSION::STRING[0,3] != "3.0"
|
||||
end
|
||||
|
||||
# A method used internally to setup warden manager from the Rails initialize
|
||||
# block.
|
||||
def self.configure_warden! #:nodoc:
|
||||
@@ -267,6 +290,17 @@ module Devise
|
||||
def self.friendly_token
|
||||
ActiveSupport::SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
|
||||
end
|
||||
|
||||
# constant-time comparison algorithm to prevent timing attacks
|
||||
def self.secure_compare(a, b)
|
||||
return false unless a.present? && b.present?
|
||||
return false unless a.bytesize == b.bytesize
|
||||
l = a.unpack "C#{a.bytesize}"
|
||||
|
||||
res = 0
|
||||
b.each_byte { |byte| res |= byte ^ l.shift }
|
||||
res == 0
|
||||
end
|
||||
end
|
||||
|
||||
require 'warden'
|
||||
|
||||
@@ -64,6 +64,16 @@ module Devise
|
||||
warden.logout(scope)
|
||||
end
|
||||
|
||||
# Sign out all active users or scopes. This helper is useful for signing out all roles
|
||||
# in one click.
|
||||
def sign_out_all_scopes
|
||||
# Not "warden.logout" since we need to sign_out only devise-defined scopes.
|
||||
scopes = Devise.mappings.keys
|
||||
scopes.each { |scope| warden.user(scope) }
|
||||
warden.raw_session.inspect
|
||||
warden.logout(*scopes)
|
||||
end
|
||||
|
||||
# Returns and delete the url stored in the session for the given scope. Useful
|
||||
# for giving redirect backs after sign up:
|
||||
#
|
||||
@@ -73,7 +83,7 @@ module Devise
|
||||
#
|
||||
def stored_location_for(resource_or_scope)
|
||||
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
||||
session.delete(:"#{scope}_return_to")
|
||||
session.delete("#{scope}_return_to")
|
||||
end
|
||||
|
||||
# The default url to be used after signing in. This is used by all Devise
|
||||
@@ -86,13 +96,13 @@ module Devise
|
||||
#
|
||||
# map.user_root '/users', :controller => 'users' # creates user_root_path
|
||||
#
|
||||
# map.resources :users do |users|
|
||||
# users.root # creates user_root_path
|
||||
# map.namespace :user do |user|
|
||||
# user.root :controller => 'users' # creates user_root_path
|
||||
# end
|
||||
#
|
||||
#
|
||||
# If none of these are defined, root_path is used. However, if this default
|
||||
# is not enough, you can customize it, for example:
|
||||
# If the resource root path is not defined, root_path is used. However,
|
||||
# if this default is not enough, you can customize it, for example:
|
||||
#
|
||||
# def after_sign_in_path_for(resource)
|
||||
# if resource.is_a?(User) && resource.can_publish?
|
||||
@@ -104,7 +114,7 @@ module Devise
|
||||
#
|
||||
def after_sign_in_path_for(resource_or_scope)
|
||||
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
||||
home_path = :"#{scope}_root_path"
|
||||
home_path = "#{scope}_root_path"
|
||||
respond_to?(home_path, true) ? send(home_path) : root_path
|
||||
end
|
||||
|
||||
@@ -164,10 +174,20 @@ module Devise
|
||||
# after_sign_out_path_for.
|
||||
def sign_out_and_redirect(resource_or_scope)
|
||||
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
||||
sign_out(scope)
|
||||
if Devise.sign_out_all_scopes
|
||||
sign_out_all_scopes
|
||||
else
|
||||
sign_out(scope)
|
||||
end
|
||||
redirect_to after_sign_out_path_for(scope)
|
||||
end
|
||||
|
||||
# Override Rails' handle unverified request to sign out all scopes.
|
||||
def handle_unverified_request
|
||||
sign_out_all_scopes
|
||||
super # call the default behaviour which resets the session
|
||||
end
|
||||
|
||||
# Define authentication filters and accessor helpers based on mappings.
|
||||
# These filters should be used inside the controllers as before_filters,
|
||||
# so you can control the scope of the user who should be signed in to
|
||||
|
||||
@@ -8,7 +8,6 @@ module Devise
|
||||
include Devise::Controllers::ScopedViews
|
||||
|
||||
included do
|
||||
unloadable
|
||||
helper DeviseHelper
|
||||
|
||||
helpers = %w(resource scope_name resource_name
|
||||
@@ -38,11 +37,7 @@ module Devise
|
||||
|
||||
# Attempt to find the mapped route for devise based on request path
|
||||
def devise_mapping
|
||||
@devise_mapping ||= begin
|
||||
mapping = Devise::Mapping.find_by_path(request.path)
|
||||
mapping ||= Devise.mappings[Devise.default_scope] if Devise.use_default_scope
|
||||
mapping
|
||||
end
|
||||
@devise_mapping ||= request.env["devise.mapping"]
|
||||
end
|
||||
|
||||
# Overwrites devise_controller? to return true
|
||||
@@ -54,8 +49,7 @@ module Devise
|
||||
|
||||
# Checks whether it's a devise mapped resource or not.
|
||||
def is_devise_resource? #:nodoc:
|
||||
raise ActionController::UnknownAction unless devise_mapping &&
|
||||
devise_mapping.allowed_controllers.include?(controller_path)
|
||||
raise ActionController::UnknownAction unless devise_mapping
|
||||
end
|
||||
|
||||
# Sets the resource creating an instance variable
|
||||
|
||||
@@ -12,7 +12,7 @@ module Devise
|
||||
raise NotImplemented
|
||||
end
|
||||
|
||||
def self.salt
|
||||
def self.salt(stretches)
|
||||
Devise.friendly_token
|
||||
end
|
||||
end
|
||||
|
||||
@@ -11,8 +11,8 @@ module Devise
|
||||
::BCrypt::Engine.hash_secret([password, pepper].join, salt, stretches)
|
||||
end
|
||||
|
||||
def self.salt
|
||||
::BCrypt::Engine.generate_salt
|
||||
def self.salt(stretches)
|
||||
::BCrypt::Engine.generate_salt(stretches)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,7 +47,7 @@ module Devise
|
||||
def redirect
|
||||
store_location!
|
||||
flash[:alert] = i18n_message unless flash[:notice]
|
||||
redirect_to send(:"new_#{scope}_session_path")
|
||||
redirect_to redirect_url
|
||||
end
|
||||
|
||||
protected
|
||||
@@ -63,12 +63,16 @@ module Devise
|
||||
end
|
||||
end
|
||||
|
||||
def redirect_url
|
||||
send(:"new_#{scope}_session_path")
|
||||
end
|
||||
|
||||
def http_auth?
|
||||
!Devise.navigational_formats.include?(request.format.to_sym) || request.xhr?
|
||||
!Devise.navigational_formats.include?(request_format) || (request.xhr? && Devise.http_authenticatable_on_xhr)
|
||||
end
|
||||
|
||||
def http_auth_body
|
||||
method = :"to_#{request.format.to_sym}"
|
||||
method = :"to_#{request_format}"
|
||||
{}.respond_to?(method) ? { :error => i18n_message }.send(method) : i18n_message
|
||||
end
|
||||
|
||||
@@ -99,5 +103,17 @@ module Devise
|
||||
def store_location!
|
||||
session[:"#{scope}_return_to"] = attempted_path if request.get? && !http_auth?
|
||||
end
|
||||
|
||||
MIME_REFERENCES = Mime::HTML.respond_to?(:ref)
|
||||
|
||||
def request_format
|
||||
@request_format ||= if request.format.respond_to?(:ref)
|
||||
request.format.ref
|
||||
elsif MIME_REFERENCES
|
||||
request.format
|
||||
else # Rails < 3.0.4
|
||||
request.format.to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
Warden::Manager.before_logout do |record, warden, options|
|
||||
if record.respond_to?(:forget_me!)
|
||||
record.forget_me! unless record.frozen?
|
||||
options = record.cookie_domain? ? { :domain => record.cookie_domain } : {}
|
||||
warden.cookies.delete("remember_#{options[:scope]}_token", options)
|
||||
cookie_options = record.cookie_domain? ? { :domain => record.cookie_domain } : {}
|
||||
warden.cookies.delete("remember_#{options[:scope]}_token", cookie_options)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,7 +9,7 @@ module Devise
|
||||
super
|
||||
|
||||
if succeeded? && resource.respond_to?(:remember_me!) && remember_me?
|
||||
resource.remember_me!
|
||||
resource.remember_me!(extend_remember_period?)
|
||||
|
||||
configuration = {
|
||||
:value => resource.class.serialize_into_cookie(resource),
|
||||
@@ -24,6 +24,14 @@ module Devise
|
||||
|
||||
protected
|
||||
|
||||
def succeeded?
|
||||
@result == :success
|
||||
end
|
||||
|
||||
def extend_remember_period?
|
||||
false
|
||||
end
|
||||
|
||||
def remember_me?
|
||||
valid_params? && Devise::TRUE_VALUES.include?(params_auth_hash[:remember_me])
|
||||
end
|
||||
|
||||
@@ -22,19 +22,9 @@ module Devise
|
||||
# # is the modules included in the class
|
||||
#
|
||||
class Mapping #:nodoc:
|
||||
attr_reader :singular, :plural, :path, :controllers, :path_names, :path_prefix, :class_name
|
||||
attr_reader :singular, :plural, :path, :controllers, :path_names, :class_name
|
||||
alias :name :singular
|
||||
|
||||
# Loop through all mappings looking for a map that matches with the requested
|
||||
# path (ie /users/sign_in). If a path prefix is given, it's taken into account.
|
||||
def self.find_by_path(path)
|
||||
Devise.mappings.each_value do |mapping|
|
||||
route = path.split("/")[mapping.segment_position]
|
||||
return mapping if route && mapping.path == route.to_sym
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
# Receives an object and find a scope for it. If a scope cannot be found,
|
||||
# raises an error. If a symbol is given, it's considered to be the scope.
|
||||
def self.find_scope!(duck)
|
||||
@@ -51,31 +41,22 @@ module Devise
|
||||
end
|
||||
|
||||
def initialize(name, options) #:nodoc:
|
||||
if as = options.delete(:as)
|
||||
ActiveSupport::Deprecation.warn ":as is deprecated, please use :path instead."
|
||||
options[:path] ||= as
|
||||
end
|
||||
@plural = (options[:as] ? "#{options[:as]}_#{name}" : name).to_sym
|
||||
@singular = (options[:singular] || @plural.to_s.singularize).to_sym
|
||||
|
||||
if scope = options.delete(:scope)
|
||||
ActiveSupport::Deprecation.warn ":scope is deprecated, please use :singular instead."
|
||||
options[:singular] ||= scope
|
||||
end
|
||||
|
||||
@plural = name.to_sym
|
||||
@path = (options.delete(:path) || name).to_sym
|
||||
@singular = (options.delete(:singular) || name.to_s.singularize).to_sym
|
||||
|
||||
@class_name = (options.delete(:class_name) || name.to_s.classify).to_s
|
||||
@class_name = (options[:class_name] || name.to_s.classify).to_s
|
||||
@ref = ActiveSupport::Dependencies.ref(@class_name)
|
||||
|
||||
@path_prefix = "/#{options.delete(:path_prefix)}/".squeeze("/")
|
||||
@path = (options[:path] || name).to_s
|
||||
@path_prefix = options[:path_prefix]
|
||||
|
||||
@controllers = Hash.new { |h,k| h[k] = "devise/#{k}" }
|
||||
@controllers.merge!(options.delete(:controllers) || {})
|
||||
mod = options[:module] || "devise"
|
||||
@controllers = Hash.new { |h,k| h[k] = "#{mod}/#{k}" }
|
||||
@controllers.merge!(options[:controllers] || {})
|
||||
|
||||
@path_names = Hash.new { |h,k| h[k] = k.to_s }
|
||||
@path_names = Hash.new { |h,k| h[k] = k.to_s }
|
||||
@path_names.merge!(:registration => "")
|
||||
@path_names.merge!(options.delete(:path_names) || {})
|
||||
@path_names.merge!(options[:path_names] || {})
|
||||
end
|
||||
|
||||
# Return modules for the mapping.
|
||||
@@ -96,30 +77,14 @@ module Devise
|
||||
@routes ||= ROUTES.values_at(*self.modules).compact.uniq
|
||||
end
|
||||
|
||||
# Keep a list of allowed controllers for this mapping. It's useful to ensure
|
||||
# that an Admin cannot access the registrations controller unless it has
|
||||
# :registerable in the model.
|
||||
def allowed_controllers
|
||||
@allowed_controllers ||= begin
|
||||
canonical = CONTROLLERS.values_at(*self.modules).compact
|
||||
@controllers.values_at(*canonical)
|
||||
end
|
||||
end
|
||||
|
||||
# Return in which position in the path prefix devise should find the as mapping.
|
||||
def segment_position
|
||||
self.path_prefix.count("/")
|
||||
end
|
||||
|
||||
# Returns the raw path using path_prefix and as.
|
||||
def full_path
|
||||
path_prefix + path.to_s
|
||||
end
|
||||
|
||||
def authenticatable?
|
||||
@authenticatable ||= self.modules.any? { |m| m.to_s =~ /authenticatable/ }
|
||||
end
|
||||
|
||||
def fullpath
|
||||
"#{@path_prefix}/#{@path}".squeeze("/")
|
||||
end
|
||||
|
||||
# Create magic predicates for verifying what module is activated by this map.
|
||||
# Example:
|
||||
#
|
||||
|
||||
@@ -90,6 +90,7 @@ module Devise
|
||||
# end
|
||||
#
|
||||
def find_for_authentication(conditions)
|
||||
filter_auth_params(conditions)
|
||||
find(:first, :conditions => conditions)
|
||||
end
|
||||
|
||||
@@ -112,6 +113,23 @@ module Devise
|
||||
|
||||
record
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Force keys to be string to avoid injection on mongoid related database.
|
||||
def filter_auth_params(conditions)
|
||||
conditions.each do |k, v|
|
||||
conditions[k] = v.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Generate a token by looping and ensuring does not already exist.
|
||||
def generate_token(column)
|
||||
loop do
|
||||
token = Devise.friendly_token
|
||||
break token unless find(:first, :conditions => { column => token })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -45,12 +45,12 @@ module Devise
|
||||
|
||||
# Verifies whether a user is confirmed or not
|
||||
def confirmed?
|
||||
persisted? && !confirmed_at.nil?
|
||||
!!confirmed_at
|
||||
end
|
||||
|
||||
# Send confirmation instructions by email
|
||||
def send_confirmation_instructions
|
||||
generate_confirmation_token if self.confirmation_token.nil?
|
||||
generate_confirmation_token! if self.confirmation_token.nil?
|
||||
::Devise.mailer.confirmation_instructions(self).deliver
|
||||
end
|
||||
|
||||
@@ -75,15 +75,14 @@ module Devise
|
||||
# If you don't want confirmation to be sent on create, neither a code
|
||||
# to be generated, call skip_confirmation!
|
||||
def skip_confirmation!
|
||||
self.confirmed_at = Time.now
|
||||
@skip_confirmation = true
|
||||
self.confirmed_at = Time.now
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Callback to overwrite if confirmation is required or not.
|
||||
def confirmation_required?
|
||||
!@skip_confirmation
|
||||
!confirmed?
|
||||
end
|
||||
|
||||
# Checks if the confirmation for the user is within the limit time.
|
||||
@@ -128,6 +127,10 @@ module Devise
|
||||
self.confirmation_sent_at = Time.now.utc
|
||||
end
|
||||
|
||||
def generate_confirmation_token!
|
||||
generate_confirmation_token && save(:validate => false)
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Attempt to find a user by it's email. If a record is found, send new
|
||||
# confirmation instructions to it. If not user is found, returns a new user
|
||||
@@ -149,8 +152,9 @@ module Devise
|
||||
confirmable
|
||||
end
|
||||
|
||||
# Generate a token checking if one does not already exist in the database.
|
||||
def confirmation_token
|
||||
Devise.friendly_token
|
||||
generate_token(:confirmation_token)
|
||||
end
|
||||
|
||||
Devise::Models.config(self, :confirm_within)
|
||||
|
||||
@@ -37,14 +37,14 @@ module Devise
|
||||
@password = new_password
|
||||
|
||||
if @password.present?
|
||||
self.password_salt = self.class.encryptor_class.salt
|
||||
self.password_salt = self.class.password_salt
|
||||
self.encrypted_password = password_digest(@password)
|
||||
end
|
||||
end
|
||||
|
||||
# Verifies whether an incoming_password (ie from sign in) is the user password.
|
||||
def valid_password?(incoming_password)
|
||||
password_digest(incoming_password) == self.encrypted_password
|
||||
Devise.secure_compare(password_digest(incoming_password), self.encrypted_password)
|
||||
end
|
||||
|
||||
# Set password and password confirmation to nil
|
||||
@@ -82,7 +82,9 @@ module Devise
|
||||
|
||||
# Digests the password using the configured encryptor.
|
||||
def password_digest(password)
|
||||
self.class.encryptor_class.digest(password, self.class.stretches, self.password_salt, self.class.pepper)
|
||||
if self.password_salt.present?
|
||||
self.class.encryptor_class.digest(password, self.class.stretches, self.password_salt, self.class.pepper)
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
@@ -93,6 +95,14 @@ module Devise
|
||||
@encryptor_class ||= ::Devise::Encryptors.const_get(encryptor.to_s.classify)
|
||||
end
|
||||
|
||||
def password_salt
|
||||
self.encryptor_class.salt(self.stretches)
|
||||
end
|
||||
|
||||
# We assume this method already gets the sanitized values from the
|
||||
# DatabaseAuthenticatable strategy. If you are using this method on
|
||||
# your own, be sure to sanitize the conditions hash to only include
|
||||
# the proper fields.
|
||||
def find_for_database_authentication(conditions)
|
||||
find_for_authentication(conditions)
|
||||
end
|
||||
|
||||
@@ -81,6 +81,8 @@ module Devise
|
||||
when TrueClass
|
||||
self.failed_attempts = 0
|
||||
when FalseClass
|
||||
# PostgreSQL uses nil as the default value for integer columns set to 0
|
||||
self.failed_attempts ||= 0
|
||||
self.failed_attempts += 1
|
||||
if attempts_exceeded?
|
||||
lock_access!
|
||||
|
||||
@@ -35,7 +35,7 @@ module Devise
|
||||
|
||||
# Generates a new random token for reset password
|
||||
def generate_reset_password_token
|
||||
self.reset_password_token = Devise.friendly_token
|
||||
self.reset_password_token = self.class.reset_password_token
|
||||
end
|
||||
|
||||
# Resets the reset password token with and save the record without
|
||||
@@ -60,6 +60,11 @@ module Devise
|
||||
recoverable
|
||||
end
|
||||
|
||||
# Generate a token checking if one does not already exist in the database.
|
||||
def reset_password_token
|
||||
generate_token(:reset_password_token)
|
||||
end
|
||||
|
||||
# Attempt to find a user by it's reset_password_token to reset it's
|
||||
# password. If a user is found, reset it's password and automatically
|
||||
# try saving the record. If not user is found, returns a new user
|
||||
|
||||
@@ -18,7 +18,15 @@ module Devise
|
||||
# blocked and will have to enter his credentials again.
|
||||
# This configuration is also used to calculate the expires
|
||||
# time for the cookie created to remember the user.
|
||||
# By default remember_for is 2.weeks.
|
||||
# 2.weeks by default.
|
||||
#
|
||||
# remember_across_browsers: if true, a valid remember token can be
|
||||
# re-used between multiple browsers.
|
||||
# True by default.
|
||||
#
|
||||
# extend_remember_period: if true, extends the user's remember period
|
||||
# when remembered via cookie.
|
||||
# False by default.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
@@ -38,10 +46,11 @@ module Devise
|
||||
attr_accessor :remember_me
|
||||
end
|
||||
|
||||
# Generate a new remember token and save the record without validations.
|
||||
def remember_me!
|
||||
self.remember_token = Devise.friendly_token
|
||||
self.remember_created_at = Time.now.utc
|
||||
# Generate a new remember token and save the record without validations
|
||||
# unless remember_across_browsers is true and the user already has a valid token.
|
||||
def remember_me!(extend_period=false)
|
||||
self.remember_token = self.class.remember_token if generate_remember_token?
|
||||
self.remember_created_at = Time.now.utc if generate_remember_timestamp?(extend_period)
|
||||
save(:validate => false)
|
||||
end
|
||||
|
||||
@@ -57,7 +66,7 @@ module Devise
|
||||
|
||||
# Remember token should be expired if expiration time not overpass now.
|
||||
def remember_expired?
|
||||
remember_expires_at <= Time.now.utc
|
||||
remember_created_at && (remember_expires_at <= Time.now.utc)
|
||||
end
|
||||
|
||||
# Remember token expires at created time + remember_for configuration
|
||||
@@ -73,6 +82,20 @@ module Devise
|
||||
self.class.cookie_domain != false
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Generate a token unless remember_across_browsers is true and there is
|
||||
# an existing remember_token or the existing remember_token has expried.
|
||||
def generate_remember_token? #:nodoc:
|
||||
!(self.class.remember_across_browsers && remember_token) || remember_expired?
|
||||
end
|
||||
|
||||
# Generate a timestamp if extend_remember_period is true, if no remember_token
|
||||
# exists, or if an existing remember token has expired.
|
||||
def generate_remember_timestamp?(extend_period) #:nodoc:
|
||||
extend_period || remember_created_at.nil? || remember_expired?
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Create the cookie key using the record id and remember_token
|
||||
def serialize_into_cookie(record)
|
||||
@@ -86,7 +109,13 @@ module Devise
|
||||
record if record && !record.remember_expired?
|
||||
end
|
||||
|
||||
Devise::Models.config(self, :remember_for, :cookie_domain)
|
||||
# Generate a token checking if one does not already exist in the database.
|
||||
def remember_token
|
||||
generate_token(:remember_token)
|
||||
end
|
||||
|
||||
Devise::Models.config(self, :remember_for, :remember_across_browsers,
|
||||
:extend_remember_period, :cookie_domain)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -44,16 +44,16 @@ module Devise
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
::Devise::Models.config(self, :token_authentication_key)
|
||||
|
||||
def find_for_token_authentication(conditions)
|
||||
conditions[:authentication_token] ||= conditions.delete(token_authentication_key)
|
||||
find_for_authentication(conditions)
|
||||
find_for_authentication(:authentication_token => conditions[token_authentication_key])
|
||||
end
|
||||
|
||||
# Generate a token checking if one does not already exist in the database.
|
||||
def authentication_token
|
||||
::Devise.friendly_token
|
||||
generate_token(:authentication_token)
|
||||
end
|
||||
|
||||
::Devise::Models.config(self, :token_authentication_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,7 +16,7 @@ module Devise
|
||||
|
||||
base.class_eval do
|
||||
validates_presence_of :email
|
||||
validates_uniqueness_of :email, :scope => authentication_keys[1..-1], :allow_blank => true
|
||||
validates_uniqueness_of :email, :scope => authentication_keys[1..-1], :case_sensitive => false, :allow_blank => true
|
||||
validates_format_of :email, :with => email_regexp, :allow_blank => true
|
||||
|
||||
with_options :if => :password_required? do |v|
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
module Devise
|
||||
module Orm
|
||||
module DataMapper
|
||||
module Hook
|
||||
def devise_modules_hook!
|
||||
extend Schema
|
||||
include Compatibility
|
||||
yield
|
||||
return unless Devise.apply_schema
|
||||
devise_modules.each { |m| send(m) if respond_to?(m, true) }
|
||||
end
|
||||
end
|
||||
|
||||
module Schema
|
||||
include Devise::Schema
|
||||
|
||||
SCHEMA_OPTIONS = {
|
||||
:null => :required,
|
||||
:limit => :length
|
||||
}
|
||||
|
||||
# Tell how to apply schema methods. This automatically maps :limit to
|
||||
# :length and :null to :required.
|
||||
def apply_devise_schema(name, type, options={})
|
||||
SCHEMA_OPTIONS.each do |old_key, new_key|
|
||||
next unless options.key?(old_key)
|
||||
options[new_key] = options.delete(old_key)
|
||||
end
|
||||
|
||||
options.delete(:default) if options[:default].nil?
|
||||
property name, type, options
|
||||
end
|
||||
end
|
||||
|
||||
module Compatibility
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
module ClassMethods
|
||||
# Hooks for confirmable
|
||||
def before_create(*args)
|
||||
wrap_hook(:before, :create, *args)
|
||||
end
|
||||
|
||||
def after_create(*args)
|
||||
wrap_hook(:after, :create, *args)
|
||||
end
|
||||
|
||||
def before_save(*args)
|
||||
wrap_hook(:before, :save, *args)
|
||||
end
|
||||
|
||||
def wrap_hook(action, method, *args)
|
||||
options = args.extract_options!
|
||||
|
||||
args.each do |callback|
|
||||
send action, method, callback
|
||||
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
||||
def #{callback}
|
||||
super if #{options[:if] || true}
|
||||
end
|
||||
METHOD
|
||||
end
|
||||
end
|
||||
|
||||
# Add ActiveRecord like finder
|
||||
def find(*args)
|
||||
case args.first
|
||||
when :first, :all
|
||||
send(args.shift, *args)
|
||||
else
|
||||
get(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def changed?
|
||||
dirty?
|
||||
end
|
||||
|
||||
def save(options=nil)
|
||||
if options.is_a?(Hash) && options[:validate] == false
|
||||
save!
|
||||
else
|
||||
super()
|
||||
end
|
||||
end
|
||||
|
||||
def update_attributes(*args)
|
||||
update(*args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
DataMapper::Model.append_extensions(Devise::Models)
|
||||
DataMapper::Model.append_extensions(Devise::Orm::DataMapper::Hook)
|
||||
@@ -2,12 +2,17 @@ module Devise
|
||||
class PathChecker
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
def self.default_url_options(*args)
|
||||
ApplicationController.default_url_options(*args)
|
||||
end
|
||||
|
||||
def initialize(env, scope)
|
||||
@env, @scope = env, scope
|
||||
@current_path = "/#{env["SCRIPT_NAME"]}/#{env["PATH_INFO"]}".squeeze("/")
|
||||
@scope = scope
|
||||
end
|
||||
|
||||
def signing_out?
|
||||
@env["PATH_INFO"] == send("destroy_#{@scope}_session_path")
|
||||
@current_path == send("destroy_#{@scope}_session_path")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -20,11 +20,16 @@ module Devise
|
||||
Devise.encryptor ||= begin
|
||||
warn "[WARNING] config.encryptor is not set in your config/initializers/devise.rb. " \
|
||||
"Devise will then set it to :bcrypt. If you were using the previous default " \
|
||||
"encryptor, please add config.encryptor = :sha1 to your configuration file."
|
||||
"encryptor, please add config.encryptor = :sha1 to your configuration file." if Devise.mailer_sender
|
||||
:bcrypt
|
||||
end
|
||||
end
|
||||
|
||||
initializer "devise.add_filters" do |app|
|
||||
app.config.filter_parameters += [:password, :password_confirmation]
|
||||
app.config.filter_parameters.uniq
|
||||
end
|
||||
|
||||
unless Rails.env.production?
|
||||
config.after_initialize do
|
||||
actions = [:confirmation_instructions, :reset_password_instructions, :unlock_instructions]
|
||||
|
||||
@@ -15,9 +15,10 @@ module ActionDispatch::Routing
|
||||
# generate all needed routes for devise, based on what modules you have
|
||||
# defined in your model.
|
||||
#
|
||||
# Examples: Let's say you have an User model configured to use
|
||||
# authenticatable, confirmable and recoverable modules. After creating this
|
||||
# inside your routes:
|
||||
# ==== Examples
|
||||
#
|
||||
# Let's say you have an User model configured to use authenticatable,
|
||||
# confirmable and recoverable modules. After creating this inside your routes:
|
||||
#
|
||||
# devise_for :users
|
||||
#
|
||||
@@ -25,20 +26,22 @@ module ActionDispatch::Routing
|
||||
# needed routes:
|
||||
#
|
||||
# # Session routes for Authenticatable (default)
|
||||
# new_user_session GET /users/sign_in {:controller=>"sessions", :action=>"new"}
|
||||
# user_session POST /users/sign_in {:controller=>"sessions", :action=>"create"}
|
||||
# destroy_user_session GET /users/sign_out {:controller=>"sessions", :action=>"destroy"}
|
||||
# new_user_session GET /users/sign_in {:controller=>"devise/sessions", :action=>"new"}
|
||||
# user_session POST /users/sign_in {:controller=>"devise/sessions", :action=>"create"}
|
||||
# destroy_user_session GET /users/sign_out {:controller=>"devise/sessions", :action=>"destroy"}
|
||||
#
|
||||
# # Password routes for Recoverable, if User model has :recoverable configured
|
||||
# new_user_password GET /users/password/new(.:format) {:controller=>"passwords", :action=>"new"}
|
||||
# edit_user_password GET /users/password/edit(.:format) {:controller=>"passwords", :action=>"edit"}
|
||||
# user_password PUT /users/password(.:format) {:controller=>"passwords", :action=>"update"}
|
||||
# POST /users/password(.:format) {:controller=>"passwords", :action=>"create"}
|
||||
# new_user_password GET /users/password/new(.:format) {:controller=>"devise/passwords", :action=>"new"}
|
||||
# edit_user_password GET /users/password/edit(.:format) {:controller=>"devise/passwords", :action=>"edit"}
|
||||
# user_password PUT /users/password(.:format) {:controller=>"devise/passwords", :action=>"update"}
|
||||
# POST /users/password(.:format) {:controller=>"devise/passwords", :action=>"create"}
|
||||
#
|
||||
# # Confirmation routes for Confirmable, if User model has :confirmable configured
|
||||
# new_user_confirmation GET /users/confirmation/new(.:format) {:controller=>"confirmations", :action=>"new"}
|
||||
# user_confirmation GET /users/confirmation(.:format) {:controller=>"confirmations", :action=>"show"}
|
||||
# POST /users/confirmation(.:format) {:controller=>"confirmations", :action=>"create"}
|
||||
# new_user_confirmation GET /users/confirmation/new(.:format) {:controller=>"devise/confirmations", :action=>"new"}
|
||||
# user_confirmation GET /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"show"}
|
||||
# POST /users/confirmation(.:format) {:controller=>"devise/confirmations", :action=>"create"}
|
||||
#
|
||||
# ==== Options
|
||||
#
|
||||
# You can configure your routes with some options:
|
||||
#
|
||||
@@ -62,37 +65,84 @@ module ActionDispatch::Routing
|
||||
#
|
||||
# devise_for :users, :path_names => { :sign_in => 'login', :sign_out => 'logout', :password => 'secret', :confirmation => 'verification' }
|
||||
#
|
||||
# * :path_prefix => the path prefix to be used in all routes.
|
||||
#
|
||||
# devise_for :users, :path_prefix => "/:locale"
|
||||
#
|
||||
# If you are using a dynamic prefix, like :locale above, you need to configure default_url_options in your ApplicationController
|
||||
# class level, so Devise can pick it:
|
||||
#
|
||||
# class ApplicationController < ActionController::Base
|
||||
# def self.default_url_options
|
||||
# { :locale => I18n.locale }
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# * :controllers => the controller which should be used. All routes by default points to Devise controllers.
|
||||
# However, if you want them to point to custom controller, you should do:
|
||||
#
|
||||
# devise_for :users, :controllers => { :sessions => "users/sessions" }
|
||||
#
|
||||
# * :module => the namespace to find controlers. By default, devise will access devise/sessions,
|
||||
# devise/registrations and so on. If you want to namespace all at once, use module:
|
||||
#
|
||||
# devise_for :users, :module => "users"
|
||||
#
|
||||
# Notice that whenever you use namespace in the router DSL, it automatically sets the module.
|
||||
# So the following setup:
|
||||
#
|
||||
# namespace :publisher
|
||||
# devise_for :account
|
||||
# end
|
||||
#
|
||||
# Will use publisher/sessions controller instead of devise/sessions controller. You can revert
|
||||
# this by providing the :module option to devise_for.
|
||||
#
|
||||
# * :skip => tell which controller you want to skip routes from being created:
|
||||
#
|
||||
# devise_for :users, :skip => :sessions
|
||||
#
|
||||
# ==== Scoping
|
||||
#
|
||||
# Following Rails 3 routes DSL, you can nest devise_for calls inside a scope:
|
||||
#
|
||||
# scope "/my" do
|
||||
# devise_for :users
|
||||
# end
|
||||
#
|
||||
# However, since Devise uses the request path to retrieve the current user, it has one caveats.
|
||||
# If you are using a dynamic segment, as below:
|
||||
#
|
||||
# scope ":locale" do
|
||||
# devise_for :users
|
||||
# end
|
||||
#
|
||||
# You are required to configure default_url_options in your ApplicationController class level, so
|
||||
# Devise can pick it:
|
||||
#
|
||||
# class ApplicationController < ActionController::Base
|
||||
# def self.default_url_options
|
||||
# { :locale => I18n.locale }
|
||||
# end
|
||||
# end
|
||||
#
|
||||
def devise_for(*resources)
|
||||
options = resources.extract_options!
|
||||
|
||||
if as = options.delete(:as)
|
||||
ActiveSupport::Deprecation.warn ":as is deprecated, please use :path instead."
|
||||
options[:path] ||= as
|
||||
end
|
||||
|
||||
if scope = options.delete(:scope)
|
||||
ActiveSupport::Deprecation.warn ":scope is deprecated, please use :singular instead."
|
||||
options[:singular] ||= scope
|
||||
end
|
||||
|
||||
options[:as] ||= @scope[:as] if @scope[:as].present?
|
||||
options[:module] ||= @scope[:module] if @scope[:module].present?
|
||||
options[:path_prefix] ||= @scope[:path] if @scope[:path].present?
|
||||
options[:path_names] = (@scope[:path_names] || {}).merge(options[:path_names] || {})
|
||||
|
||||
resources.map!(&:to_sym)
|
||||
|
||||
resources.each do |resource|
|
||||
mapping = Devise.add_model(resource, options)
|
||||
mapping = Devise.add_mapping(resource, options)
|
||||
|
||||
begin
|
||||
raise_no_devise_method_error!(mapping.class_name) unless mapping.to.respond_to?(:devise)
|
||||
rescue NameError => e
|
||||
raise unless mapping.class_name == resource.to_s.classify
|
||||
warn "[WARNING] You provided devise_for #{resource.inspect} but there is " <<
|
||||
"no model #{mapping.class_name} defined in your application"
|
||||
next
|
||||
rescue NoMethodError => e
|
||||
raise unless e.message.include?("undefined method `devise'")
|
||||
raise_no_devise_method_error!(mapping.class_name)
|
||||
@@ -101,12 +151,21 @@ module ActionDispatch::Routing
|
||||
routes = mapping.routes
|
||||
routes -= Array(options.delete(:skip)).map { |s| s.to_s.singularize.to_sym }
|
||||
|
||||
routes.each do |mod|
|
||||
send(:"devise_#{mod}", mapping, mapping.controllers)
|
||||
devise_scope mapping.name do
|
||||
yield if block_given?
|
||||
with_devise_exclusive_scope mapping.fullpath, mapping.name do
|
||||
routes.each { |mod| send(:"devise_#{mod}", mapping, mapping.controllers) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Allow you to add authentication request from the router:
|
||||
#
|
||||
# authenticate(:user) do
|
||||
# resources :post
|
||||
# end
|
||||
#
|
||||
def authenticate(scope)
|
||||
constraint = lambda do |request|
|
||||
request.env["warden"].authenticate!(:scope => scope)
|
||||
@@ -117,42 +176,70 @@ module ActionDispatch::Routing
|
||||
end
|
||||
end
|
||||
|
||||
# Sets the devise scope to be used in the controller. If you have custom routes,
|
||||
# you are required to call this method (also aliased as :as) in order to specify
|
||||
# to which controller it is targetted.
|
||||
#
|
||||
# as :user do
|
||||
# get "sign_in", :to => "devise/sessions#new"
|
||||
# end
|
||||
#
|
||||
# Notice you cannot have two scopes mapping to the same URL. And remember, if
|
||||
# you try to access a devise controller without specifying a scope, it will
|
||||
# raise ActionNotFound error.
|
||||
def devise_scope(scope)
|
||||
constraint = lambda do |request|
|
||||
request.env["devise.mapping"] = Devise.mappings[scope]
|
||||
true
|
||||
end
|
||||
|
||||
constraints(constraint) do
|
||||
yield
|
||||
end
|
||||
end
|
||||
alias :as :devise_scope
|
||||
|
||||
protected
|
||||
|
||||
def devise_session(mapping, controllers)
|
||||
scope mapping.full_path do
|
||||
get mapping.path_names[:sign_in], :to => "#{controllers[:sessions]}#new", :as => :"new_#{mapping.name}_session"
|
||||
post mapping.path_names[:sign_in], :to => "#{controllers[:sessions]}#create", :as => :"#{mapping.name}_session"
|
||||
get mapping.path_names[:sign_out], :to => "#{controllers[:sessions]}#destroy", :as => :"destroy_#{mapping.name}_session"
|
||||
def devise_session(mapping, controllers) #:nodoc:
|
||||
resource :session, :only => [], :controller => controllers[:sessions], :path => "" do
|
||||
get :new, :path => mapping.path_names[:sign_in], :as => "new"
|
||||
post :create, :path => mapping.path_names[:sign_in]
|
||||
get :destroy, :path => mapping.path_names[:sign_out], :as => "destroy"
|
||||
end
|
||||
end
|
||||
|
||||
def devise_password(mapping, controllers)
|
||||
scope mapping.full_path, :name_prefix => mapping.name do
|
||||
resource :password, :only => [:new, :create, :edit, :update], :path => mapping.path_names[:password], :controller => controllers[:passwords]
|
||||
end
|
||||
def devise_password(mapping, controllers) #:nodoc:
|
||||
resource :password, :only => [:new, :create, :edit, :update],
|
||||
:path => mapping.path_names[:password], :controller => controllers[:passwords]
|
||||
end
|
||||
|
||||
def devise_confirmation(mapping, controllers)
|
||||
scope mapping.full_path, :name_prefix => mapping.name do
|
||||
resource :confirmation, :only => [:new, :create, :show], :path => mapping.path_names[:confirmation], :controller => controllers[:confirmations]
|
||||
end
|
||||
def devise_confirmation(mapping, controllers) #:nodoc:
|
||||
resource :confirmation, :only => [:new, :create, :show],
|
||||
:path => mapping.path_names[:confirmation], :controller => controllers[:confirmations]
|
||||
end
|
||||
|
||||
def devise_unlock(mapping, controllers)
|
||||
scope mapping.full_path, :name_prefix => mapping.name do
|
||||
resource :unlock, :only => [:new, :create, :show], :path => mapping.path_names[:unlock], :controller => controllers[:unlocks]
|
||||
def devise_unlock(mapping, controllers) #:nodoc:
|
||||
if mapping.to.unlock_strategy_enabled?(:email)
|
||||
resource :unlock, :only => [:new, :create, :show],
|
||||
:path => mapping.path_names[:unlock], :controller => controllers[:unlocks]
|
||||
end
|
||||
end
|
||||
|
||||
def devise_registration(mapping, controllers)
|
||||
scope mapping.full_path[1..-1], :name_prefix => mapping.name do
|
||||
resource :registration, :only => [:new, :create, :edit, :update, :destroy], :path => mapping.path_names[:registration],
|
||||
:path_names => { :new => mapping.path_names[:sign_up] }, :controller => controllers[:registrations]
|
||||
end
|
||||
def devise_registration(mapping, controllers) #:nodoc:
|
||||
resource :registration, :only => [:new, :create, :edit, :update, :destroy], :path => mapping.path_names[:registration],
|
||||
:path_names => { :new => mapping.path_names[:sign_up] }, :controller => controllers[:registrations]
|
||||
end
|
||||
|
||||
def raise_no_devise_method_error!(klass)
|
||||
def with_devise_exclusive_scope(new_path, new_as) #:nodoc:
|
||||
old_as, old_path, old_module = @scope[:as], @scope[:path], @scope[:module]
|
||||
@scope[:as], @scope[:path], @scope[:module] = new_as, new_path, nil
|
||||
yield
|
||||
ensure
|
||||
@scope[:as], @scope[:path], @scope[:module] = old_as, old_path, old_module
|
||||
end
|
||||
|
||||
def raise_no_devise_method_error!(klass) #:nodoc:
|
||||
raise "#{klass} does not respond to 'devise' method. This usually means you haven't " <<
|
||||
"loaded your ORM file or it's being loaded too late. To fix it, be sure to require 'devise/orm/YOUR_ORM' " <<
|
||||
"inside 'config/initializers/devise.rb' or before your application definition in 'config/application.rb'"
|
||||
|
||||
@@ -15,11 +15,108 @@ end
|
||||
|
||||
class Warden::SessionSerializer
|
||||
def serialize(record)
|
||||
[record.class, record.id]
|
||||
[record.class.name, record.id]
|
||||
end
|
||||
|
||||
def deserialize(keys)
|
||||
klass, id = keys
|
||||
klass.find(:first, :conditions => { :id => id })
|
||||
|
||||
if klass.is_a?(Class)
|
||||
raise "Devise changed how it stores objects in session. If you are seeing this message, " <<
|
||||
"you can fix it by changing one character in your cookie secret, forcing all previous " <<
|
||||
"cookies to expire, or cleaning up your database sessions if you are using a db store."
|
||||
end
|
||||
|
||||
klass.constantize.find(:first, :conditions => { :id => id })
|
||||
rescue NameError => e
|
||||
if e.message =~ /uninitialized constant/
|
||||
Rails.logger.debug "Trying to deserialize invalid class #{klass}"
|
||||
nil
|
||||
else
|
||||
raise
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
unless Devise.rack_session?
|
||||
# We cannot use Rails Indifferent Hash because it messes up the flash object.
|
||||
class Devise::IndifferentHash < Hash
|
||||
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
||||
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
||||
|
||||
def [](key)
|
||||
super(convert_key(key))
|
||||
end
|
||||
|
||||
def []=(key, value)
|
||||
regular_writer(convert_key(key), value)
|
||||
end
|
||||
|
||||
alias_method :store, :[]=
|
||||
|
||||
def update(other_hash)
|
||||
other_hash.each_pair { |key, value| regular_writer(convert_key(key), value) }
|
||||
self
|
||||
end
|
||||
|
||||
alias_method :merge!, :update
|
||||
|
||||
def key?(key)
|
||||
super(convert_key(key))
|
||||
end
|
||||
|
||||
alias_method :include?, :key?
|
||||
alias_method :has_key?, :key?
|
||||
alias_method :member?, :key?
|
||||
|
||||
def fetch(key, *extras)
|
||||
super(convert_key(key), *extras)
|
||||
end
|
||||
|
||||
def values_at(*indices)
|
||||
indices.collect {|key| self[convert_key(key)]}
|
||||
end
|
||||
|
||||
def merge(hash)
|
||||
self.dup.update(hash)
|
||||
end
|
||||
|
||||
def delete(key)
|
||||
super(convert_key(key))
|
||||
end
|
||||
|
||||
def stringify_keys!; self end
|
||||
def stringify_keys; dup end
|
||||
|
||||
undef :symbolize_keys!
|
||||
def symbolize_keys; to_hash.symbolize_keys end
|
||||
|
||||
def to_options!; self end
|
||||
def to_hash; Hash.new.update(self) end
|
||||
|
||||
protected
|
||||
|
||||
def convert_key(key)
|
||||
key.kind_of?(Symbol) ? key.to_s : key
|
||||
end
|
||||
end
|
||||
|
||||
class ActionDispatch::Request
|
||||
def reset_session
|
||||
session.destroy if session && session.respond_to?(:destroy)
|
||||
self.session = {}
|
||||
@env['action_dispatch.request.flash_hash'] = nil
|
||||
end
|
||||
end
|
||||
|
||||
Warden::Manager.after_set_user :event => [:set_user, :authentication] do |record, warden, options|
|
||||
if options[:scope] && warden.authenticated?(options[:scope])
|
||||
request, flash = warden.request, warden.env['action_dispatch.request.flash_hash']
|
||||
backup = request.session.to_hash
|
||||
backup.delete("session_id")
|
||||
request.reset_session
|
||||
warden.env['action_dispatch.request.flash_hash'] = flash
|
||||
request.session = Devise::IndifferentHash.new.update(backup)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -19,7 +19,7 @@ module Devise
|
||||
# encrypter password field in 128 characters.
|
||||
def database_authenticatable(options={})
|
||||
null = options[:null] || false
|
||||
default = options[:default] || ""
|
||||
default = options.key?(:default) ? options[:default] : ("" if null == false)
|
||||
|
||||
if options.delete(:encryptor)
|
||||
ActiveSupport::Deprecation.warn ":encryptor as option is deprecated, simply remove it."
|
||||
|
||||
@@ -14,6 +14,19 @@ module Devise
|
||||
|
||||
private
|
||||
|
||||
# Simply invokes valid_for_authentication? with the given block and deal with the result.
|
||||
def validate(resource, &block)
|
||||
result = resource && resource.valid_for_authentication?(&block)
|
||||
|
||||
case result
|
||||
when Symbol, String
|
||||
fail!(result)
|
||||
false
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
# Check if this is strategy is valid for http authentication by:
|
||||
#
|
||||
# * Validating if the model allows params authentication;
|
||||
@@ -84,8 +97,8 @@ module Devise
|
||||
|
||||
# Helper to decode credentials from HTTP.
|
||||
def decode_credentials
|
||||
username_and_password = request.authorization.split(' ', 2).last || ''
|
||||
ActiveSupport::Base64.decode64(username_and_password).split(/:/, 2)
|
||||
return [] unless request.authorization && request.authorization =~ /^Basic (.*)/
|
||||
ActiveSupport::Base64.decode64($1).split(/:/, 2)
|
||||
end
|
||||
|
||||
# Sets the authentication hash and the password from params_auth_hash or http_auth_hash.
|
||||
|
||||
@@ -10,24 +10,6 @@ module Devise
|
||||
mapping
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def succeeded?
|
||||
@result == :success
|
||||
end
|
||||
|
||||
# Simply invokes valid_for_authentication? with the given block and deal with the result.
|
||||
def validate(resource, &block)
|
||||
result = resource && resource.valid_for_authentication?(&block)
|
||||
|
||||
case result
|
||||
when Symbol, String
|
||||
fail!(result)
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@ module Devise
|
||||
if validate(resource){ resource.valid_password?(password) }
|
||||
resource.after_database_authentication
|
||||
success!(resource)
|
||||
else
|
||||
elsif !halted?
|
||||
fail(:invalid)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,7 +6,7 @@ module Devise
|
||||
# to verify whether there is a cookie with the remember token, and to
|
||||
# recreate the user from this cookie if it exists. Must be called *before*
|
||||
# authenticatable.
|
||||
class Rememberable < Devise::Strategies::Base
|
||||
class Rememberable < Authenticatable
|
||||
# A valid strategy for rememberable needs a remember token in the cookies.
|
||||
def valid?
|
||||
remember_cookie.present?
|
||||
@@ -20,7 +20,7 @@ module Devise
|
||||
|
||||
if validate(resource)
|
||||
success!(resource)
|
||||
else
|
||||
elsif !halted?
|
||||
cookies.delete(remember_key)
|
||||
pass
|
||||
end
|
||||
@@ -28,10 +28,18 @@ module Devise
|
||||
|
||||
private
|
||||
|
||||
def remember_me?
|
||||
true
|
||||
end
|
||||
|
||||
def remember_key
|
||||
"remember_#{scope}_token"
|
||||
end
|
||||
|
||||
def extend_remember_period?
|
||||
mapping.to.extend_remember_period
|
||||
end
|
||||
|
||||
# Accessor for remember cookie
|
||||
def remember_cookie
|
||||
@remember_cookie ||= cookies.signed[remember_key]
|
||||
|
||||
@@ -16,7 +16,7 @@ module Devise
|
||||
if validate(resource)
|
||||
resource.after_token_authentication
|
||||
success!(resource)
|
||||
else
|
||||
elsif !halted?
|
||||
fail(:invalid_token)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,6 +42,8 @@ module Devise
|
||||
status, headers, body = Devise::FailureApp.call(env).to_a
|
||||
@controller.send :render, :status => status, :text => body,
|
||||
:content_type => headers["Content-Type"], :location => headers["Location"]
|
||||
|
||||
nil
|
||||
else
|
||||
result
|
||||
end
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module Devise
|
||||
VERSION = "1.1.rc2".freeze
|
||||
VERSION = "1.1.9".freeze
|
||||
end
|
||||
|
||||
28
lib/generators/active_record/devise_generator.rb
Normal file
28
lib/generators/active_record/devise_generator.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
require 'rails/generators/active_record'
|
||||
require 'generators/devise/orm_helpers'
|
||||
|
||||
module ActiveRecord
|
||||
module Generators
|
||||
class DeviseGenerator < ActiveRecord::Generators::Base
|
||||
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
||||
|
||||
include Devise::Generators::OrmHelpers
|
||||
source_root File.expand_path("../templates", __FILE__)
|
||||
|
||||
def generate_model
|
||||
invoke "active_record:model", [name], :migration => false unless model_exists?
|
||||
end
|
||||
|
||||
def copy_devise_migration
|
||||
migration_template "migration.rb", "db/migrate/devise_create_#{table_name}"
|
||||
end
|
||||
|
||||
def inject_devise_content
|
||||
inject_into_class model_path, class_name, model_contents + <<-CONTENT
|
||||
# Setup accessible (or protected) attributes for your model
|
||||
attr_accessible :email, :password, :password_confirmation, :remember_me
|
||||
CONTENT
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,6 +10,10 @@ class DeviseCreate<%= table_name.camelize %> < ActiveRecord::Migration
|
||||
# t.lockable :lock_strategy => :<%= Devise.lock_strategy %>, :unlock_strategy => :<%= Devise.unlock_strategy %>
|
||||
# t.token_authenticatable
|
||||
|
||||
<% for attribute in attributes -%>
|
||||
t.<%= attribute.type %> :<%= attribute.name %>
|
||||
<% end -%>
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
require 'rails/generators/migration'
|
||||
|
||||
module Devise
|
||||
module Generators
|
||||
class DeviseGenerator < Rails::Generators::NamedBase
|
||||
include Rails::Generators::Migration
|
||||
|
||||
source_root File.expand_path("../templates", __FILE__)
|
||||
namespace "devise"
|
||||
|
||||
desc "Generates a model with the given NAME (if one does not exist) with devise " <<
|
||||
"configuration plus a migration file and devise routes."
|
||||
|
||||
def self.orm_has_migration?
|
||||
Rails::Generators.options[:rails][:orm] == :active_record
|
||||
end
|
||||
|
||||
def self.next_migration_number(path)
|
||||
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
||||
end
|
||||
|
||||
class_option :orm
|
||||
class_option :migration, :type => :boolean, :default => orm_has_migration?
|
||||
|
||||
def invoke_orm_model
|
||||
return unless behavior == :invoke
|
||||
|
||||
if model_exists?
|
||||
say "* Model already exists. Adding Devise behavior."
|
||||
elsif options[:orm].present?
|
||||
invoke "model", [name], :migration => false, :orm => options[:orm]
|
||||
|
||||
unless model_exists?
|
||||
abort "Tried to invoke the model generator for '#{options[:orm]}' but could not find it.\n" <<
|
||||
"Please create your model by hand before calling `rails g devise #{name}`."
|
||||
end
|
||||
else
|
||||
abort "Cannot create a devise model because config.generators.orm is blank.\n" <<
|
||||
"Please create your model by hand or configure your generators orm before calling `rails g devise #{name}`."
|
||||
end
|
||||
end
|
||||
|
||||
def inject_devise_config_into_model
|
||||
devise_class_setup = <<-CONTENT
|
||||
|
||||
# Include default devise modules. Others available are:
|
||||
# :token_authenticatable, :confirmable, :lockable and :timeoutable
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :trackable, :validatable
|
||||
|
||||
CONTENT
|
||||
|
||||
case options[:orm].to_s
|
||||
when "mongoid"
|
||||
inject_into_file model_path, devise_class_setup, :after => "include Mongoid::Document\n"
|
||||
when "data_mapper"
|
||||
inject_into_file model_path, devise_class_setup, :after => "include DataMapper::Resource\n"
|
||||
when "active_record"
|
||||
inject_into_class model_path, class_name, devise_class_setup + <<-CONTENT
|
||||
# Setup accessible (or protected) attributes for your model
|
||||
attr_accessible :email, :password, :password_confirmation
|
||||
CONTENT
|
||||
end
|
||||
end
|
||||
|
||||
def copy_migration_template
|
||||
return unless options.migration?
|
||||
migration_template "migration.rb", "db/migrate/devise_create_#{table_name}"
|
||||
end
|
||||
|
||||
def add_devise_routes
|
||||
route "devise_for :#{table_name}"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def model_exists?
|
||||
File.exists?(File.join(destination_root, model_path))
|
||||
end
|
||||
|
||||
def model_path
|
||||
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
17
lib/generators/devise/devise_generator.rb
Normal file
17
lib/generators/devise/devise_generator.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
module Devise
|
||||
module Generators
|
||||
class DeviseGenerator < Rails::Generators::NamedBase
|
||||
namespace "devise"
|
||||
source_root File.expand_path("../templates", __FILE__)
|
||||
|
||||
desc "Generates a model with the given NAME (if one does not exist) with devise " <<
|
||||
"configuration plus a migration file and devise routes."
|
||||
|
||||
hook_for :orm
|
||||
|
||||
def add_devise_routes
|
||||
route "devise_for :#{table_name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,7 +3,7 @@ require 'active_support/secure_random'
|
||||
module Devise
|
||||
module Generators
|
||||
class InstallGenerator < Rails::Generators::Base
|
||||
source_root File.expand_path("../templates", __FILE__)
|
||||
source_root File.expand_path("../../templates", __FILE__)
|
||||
|
||||
desc "Creates a Devise initializer and copy locale files to your application."
|
||||
class_option :orm
|
||||
@@ -13,11 +13,11 @@ module Devise
|
||||
end
|
||||
|
||||
def copy_locale
|
||||
copy_file "../../../../../config/locales/en.yml", "config/locales/devise.en.yml"
|
||||
copy_file "../../../config/locales/en.yml", "config/locales/devise.en.yml"
|
||||
end
|
||||
|
||||
def show_readme
|
||||
readme "README"
|
||||
readme "README" if behavior == :invoke
|
||||
end
|
||||
end
|
||||
end
|
||||
23
lib/generators/devise/orm_helpers.rb
Normal file
23
lib/generators/devise/orm_helpers.rb
Normal file
@@ -0,0 +1,23 @@
|
||||
module Devise
|
||||
module Generators
|
||||
module OrmHelpers
|
||||
def model_contents
|
||||
<<-CONTENT
|
||||
# Include default devise modules. Others available are:
|
||||
# :token_authenticatable, :confirmable, :lockable and :timeoutable
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :trackable, :validatable
|
||||
|
||||
CONTENT
|
||||
end
|
||||
|
||||
def model_exists?
|
||||
File.exists?(File.join(destination_root, model_path))
|
||||
end
|
||||
|
||||
def model_path
|
||||
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,17 +1,17 @@
|
||||
module Devise
|
||||
module Generators
|
||||
class ViewsGenerator < Rails::Generators::Base
|
||||
source_root File.expand_path("../../../../../app/views", __FILE__)
|
||||
source_root File.expand_path("../../../../app/views", __FILE__)
|
||||
desc "Copies all Devise views to your application."
|
||||
|
||||
argument :scope, :required => false, :default => nil,
|
||||
:desc => "The scope to copy views to"
|
||||
|
||||
class_option :template_engine, :type => :string, :aliases => "-t", :default => "erb",
|
||||
class_option :template_engine, :type => :string, :aliases => "-t",
|
||||
:desc => "Template engine for the views. Available options are 'erb' and 'haml'."
|
||||
|
||||
def copy_views
|
||||
case options[:template_engine]
|
||||
case options[:template_engine].to_s
|
||||
when "haml"
|
||||
verify_haml_existence
|
||||
verify_haml_version
|
||||
@@ -1,2 +0,0 @@
|
||||
# Remove this file on next rails release
|
||||
require "generators/devise/devise/devise_generator"
|
||||
17
lib/generators/mongoid/devise_generator.rb
Normal file
17
lib/generators/mongoid/devise_generator.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
require 'generators/devise/orm_helpers'
|
||||
|
||||
module Mongoid
|
||||
module Generators
|
||||
class DeviseGenerator < Rails::Generators::NamedBase
|
||||
include Devise::Generators::OrmHelpers
|
||||
|
||||
def generate_model
|
||||
invoke "mongoid:model", [name] unless model_exists?
|
||||
end
|
||||
|
||||
def inject_devise_content
|
||||
inject_into_file model_path, model_contents, :after => "include Mongoid::Document\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,8 +9,9 @@ Devise.setup do |config|
|
||||
# config.mailer = "Devise::Mailer"
|
||||
|
||||
# ==> ORM configuration
|
||||
# Load and configure the ORM. Supports :active_record (default), :mongoid
|
||||
# (bson_ext recommended) and :data_mapper (experimental).
|
||||
# Load and configure the ORM. Supports :active_record (default) and
|
||||
# :mongoid (bson_ext recommended) by default. Other ORMs may be
|
||||
# available as additional gems.
|
||||
require 'devise/orm/<%= options[:orm] %>'
|
||||
|
||||
# ==> Configuration for any authentication mechanism
|
||||
@@ -24,8 +25,11 @@ Devise.setup do |config|
|
||||
# Tell if authentication through request.params is enabled. True by default.
|
||||
# config.params_authenticatable = true
|
||||
|
||||
# Tell if authentication through HTTP Basic Auth is enabled. True by default.
|
||||
# config.http_authenticatable = true
|
||||
# Tell if authentication through HTTP Basic Auth is enabled. False by default.
|
||||
# config.http_authenticatable = false
|
||||
|
||||
# Set this to true to use Basic Auth for AJAX requests. True by default.
|
||||
# config.http_authenticatable_on_xhr = true
|
||||
|
||||
# The realm used in Http Basic Authentication
|
||||
# config.http_authentication_realm = "Application"
|
||||
@@ -57,12 +61,18 @@ Devise.setup do |config|
|
||||
# The time the user will be remembered without asking for credentials again.
|
||||
# config.remember_for = 2.weeks
|
||||
|
||||
# If true, a valid remember token can be re-used between multiple browsers.
|
||||
# config.remember_across_browsers = true
|
||||
|
||||
# If true, extends the user's remember period when remembered via cookie.
|
||||
# config.extend_remember_period = false
|
||||
|
||||
# ==> Configuration for :validatable
|
||||
# Range for password length
|
||||
# config.password_length = 6..20
|
||||
|
||||
# Regex to use to validate the email address
|
||||
# config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
|
||||
# config.email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
|
||||
|
||||
# ==> Configuration for :timeoutable
|
||||
# The time you want to timeout the user session without activity. After this
|
||||
@@ -95,22 +105,19 @@ Devise.setup do |config|
|
||||
|
||||
# ==> Scopes configuration
|
||||
# Turn scoped views on. Before rendering "sessions/new", it will first check for
|
||||
# "sessions/users/new". It's turned off by default because it's slower if you
|
||||
# "users/sessions/new". It's turned off by default because it's slower if you
|
||||
# are using only default views.
|
||||
# config.scoped_views = true
|
||||
|
||||
# By default, devise detects the role accessed based on the url. So whenever
|
||||
# accessing "/users/sign_in", it knows you are accessing an User. This makes
|
||||
# routes as "/sign_in" not possible, unless you tell Devise to use the default
|
||||
# scope, setting true below.
|
||||
# Note that devise does not generate default routes. You also have to
|
||||
# specify them in config/routes.rb
|
||||
# config.use_default_scope = true
|
||||
|
||||
# Configure the default scope used by Devise. By default it's the first devise
|
||||
# role declared in your routes.
|
||||
# Configure the default scope given to Warden. By default it's the first
|
||||
# devise role declared in your routes.
|
||||
# config.default_scope = :user
|
||||
|
||||
# Configure sign_out behavior.
|
||||
# By default sign_out is scoped (i.e. /users/sign_out affects only :user scope).
|
||||
# In case of sign_out_all_scopes set to true any logout action will sign out all active scopes.
|
||||
# config.sign_out_all_scopes = false
|
||||
|
||||
# ==> Navigation configuration
|
||||
# Lists the formats that should be treated as navigational. Formats like
|
||||
# :html, should redirect to the sign in page when the user does not have
|
||||
@@ -60,26 +60,36 @@ class ControllerAuthenticableTest < ActionController::TestCase
|
||||
@controller.anybody_signed_in?
|
||||
end
|
||||
|
||||
test 'proxy current_admin to authenticate with admin scope' do
|
||||
@mock_warden.expects(:authenticate).with(:scope => :admin)
|
||||
@controller.current_admin
|
||||
end
|
||||
|
||||
test 'proxy current_user to authenticate with user scope' do
|
||||
@mock_warden.expects(:authenticate).with(:scope => :user)
|
||||
@controller.current_user
|
||||
end
|
||||
|
||||
test 'proxy user_authenticate! to authenticate with user scope' do
|
||||
test 'proxy current_admin to authenticate with admin scope' do
|
||||
@mock_warden.expects(:authenticate).with(:scope => :admin)
|
||||
@controller.current_admin
|
||||
end
|
||||
|
||||
test 'proxy current_publisher_account to authenticate with namespaced publisher account scope' do
|
||||
@mock_warden.expects(:authenticate).with(:scope => :publisher_account)
|
||||
@controller.current_publisher_account
|
||||
end
|
||||
|
||||
test 'proxy authenticate_user! to authenticate with user scope' do
|
||||
@mock_warden.expects(:authenticate!).with(:scope => :user)
|
||||
@controller.authenticate_user!
|
||||
end
|
||||
|
||||
test 'proxy admin_authenticate! to authenticate with admin scope' do
|
||||
test 'proxy authenticate_admin! to authenticate with admin scope' do
|
||||
@mock_warden.expects(:authenticate!).with(:scope => :admin)
|
||||
@controller.authenticate_admin!
|
||||
end
|
||||
|
||||
test 'proxy authenticate_publisher_account! to authenticate with namespaced publisher account scope' do
|
||||
@mock_warden.expects(:authenticate!).with(:scope => :publisher_account)
|
||||
@controller.authenticate_publisher_account!
|
||||
end
|
||||
|
||||
test 'proxy user_signed_in? to authenticate? with user scope' do
|
||||
@mock_warden.expects(:authenticate?).with(:scope => :user)
|
||||
@controller.user_signed_in?
|
||||
@@ -90,6 +100,11 @@ class ControllerAuthenticableTest < ActionController::TestCase
|
||||
@controller.admin_signed_in?
|
||||
end
|
||||
|
||||
test 'proxy publisher_account_signed_in? to authenticate? with namespaced publisher account scope' do
|
||||
@mock_warden.expects(:authenticate?).with(:scope => :publisher_account)
|
||||
@controller.publisher_account_signed_in?
|
||||
end
|
||||
|
||||
test 'proxy user_session to session scope in warden' do
|
||||
@mock_warden.expects(:authenticate).with(:scope => :user).returns(true)
|
||||
@mock_warden.expects(:session).with(:user).returns({})
|
||||
@@ -102,6 +117,12 @@ class ControllerAuthenticableTest < ActionController::TestCase
|
||||
@controller.admin_session
|
||||
end
|
||||
|
||||
test 'proxy publisher_account_session from namespaced scope to session scope in warden' do
|
||||
@mock_warden.expects(:authenticate).with(:scope => :publisher_account).returns(true)
|
||||
@mock_warden.expects(:session).with(:publisher_account).returns({})
|
||||
@controller.publisher_account_session
|
||||
end
|
||||
|
||||
test 'sign in proxy to set_user on warden' do
|
||||
user = User.new
|
||||
@mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
|
||||
@@ -126,6 +147,15 @@ class ControllerAuthenticableTest < ActionController::TestCase
|
||||
@controller.sign_out(User.new)
|
||||
end
|
||||
|
||||
test 'sign out everybody proxy to logout on warden' do
|
||||
Devise.mappings.keys.each { |scope|
|
||||
@mock_warden.expects(:user).with(scope).returns(true)
|
||||
}
|
||||
|
||||
@mock_warden.expects(:logout).with(*Devise.mappings.keys).returns(true)
|
||||
@controller.sign_out_all_scopes
|
||||
end
|
||||
|
||||
test 'stored location for returns the location for a given scope' do
|
||||
assert_nil @controller.stored_location_for(:user)
|
||||
@controller.session[:"user_return_to"] = "/foo.bar"
|
||||
|
||||
@@ -10,37 +10,28 @@ class HelpersTest < ActionController::TestCase
|
||||
def setup
|
||||
@mock_warden = OpenStruct.new
|
||||
@controller.request.env['warden'] = @mock_warden
|
||||
@controller.request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
end
|
||||
|
||||
test 'get resource name from request path' do
|
||||
@request.path = '/users/session'
|
||||
test 'get resource name from env' do
|
||||
assert_equal :user, @controller.resource_name
|
||||
end
|
||||
|
||||
test 'get resource name from specific request path' do
|
||||
@request.path = '/admin_area/session'
|
||||
assert_equal :admin, @controller.resource_name
|
||||
end
|
||||
|
||||
test 'get resource class from request path' do
|
||||
@request.path = '/users/session'
|
||||
test 'get resource class from env' do
|
||||
assert_equal User, @controller.resource_class
|
||||
end
|
||||
|
||||
test 'get resource instance variable from request path' do
|
||||
@request.path = '/admin_area/session'
|
||||
@controller.instance_variable_set(:@admin, admin = Admin.new)
|
||||
test 'get resource instance variable from env' do
|
||||
@controller.instance_variable_set(:@user, admin = Admin.new)
|
||||
assert_equal admin, @controller.resource
|
||||
end
|
||||
|
||||
test 'set resource instance variable from request path' do
|
||||
@request.path = '/admin_area/session'
|
||||
|
||||
test 'set resource instance variable from env' do
|
||||
admin = @controller.send(:resource_class).new
|
||||
@controller.send(:resource=, admin)
|
||||
|
||||
assert_equal admin, @controller.send(:resource)
|
||||
assert_equal admin, @controller.instance_variable_get(:@admin)
|
||||
assert_equal admin, @controller.instance_variable_get(:@user)
|
||||
end
|
||||
|
||||
test 'resources methods are not controller actions' do
|
||||
|
||||
@@ -44,4 +44,15 @@ class RoutesTest < ActionController::TestCase
|
||||
assert_path_and_url :confirmation
|
||||
assert_path_and_url :confirmation, :new
|
||||
end
|
||||
|
||||
test 'should alias unlock to mapped user unlock' do
|
||||
assert_path_and_url :unlock
|
||||
assert_path_and_url :unlock, :new
|
||||
end
|
||||
|
||||
test 'should alias registration to mapped user registration' do
|
||||
assert_path_and_url :registration
|
||||
assert_path_and_url :registration, :new
|
||||
assert_path_and_url :registration, :edit
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,7 +23,7 @@ class Encryptors < ActiveSupport::TestCase
|
||||
test "should have length #{value} for #{key.inspect}" do
|
||||
swap Devise, :encryptor => key do
|
||||
encryptor = Devise::Encryptors.const_get(key.to_s.classify)
|
||||
assert_equal value, encryptor.digest('a', 4, encryptor.salt, nil).size
|
||||
assert_equal value, encryptor.digest('a', 4, encryptor.salt(4), nil).size
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ class FailureTest < ActiveSupport::TestCase
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'warden.options' => { :scope => :user },
|
||||
'rack.session' => {},
|
||||
'action_dispatch.request.formats' => Array(env_params.delete('formats') || :html),
|
||||
'action_dispatch.request.formats' => Array(env_params.delete('formats') || Mime::HTML),
|
||||
'rack.input' => "",
|
||||
'warden' => OpenStruct.new(:message => nil)
|
||||
}.merge!(env_params)
|
||||
@@ -77,6 +77,23 @@ class FailureTest < ActiveSupport::TestCase
|
||||
assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
|
||||
end
|
||||
|
||||
test 'dont return WWW-authenticate on ajax call if http_authenticatable_on_xhr false' do
|
||||
swap Devise, :http_authenticatable_on_xhr => false do
|
||||
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
|
||||
assert_equal 302, @response.first
|
||||
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
|
||||
assert_nil @response.second['WWW-Authenticate']
|
||||
end
|
||||
end
|
||||
|
||||
test 'return WWW-authenticate on ajax call if http_authenticatable_on_xhr true' do
|
||||
swap Devise, :http_authenticatable_on_xhr => true do
|
||||
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
|
||||
assert_equal 401, @response.first
|
||||
assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
|
||||
end
|
||||
end
|
||||
|
||||
test 'uses the proxy failure message as response body' do
|
||||
call_failure('formats' => :xml, 'warden' => OpenStruct.new(:message => :invalid))
|
||||
assert_match '<error>Invalid email or password.</error>', @response.third.body
|
||||
@@ -88,11 +105,6 @@ class FailureTest < ActiveSupport::TestCase
|
||||
assert_equal 401, @response.first
|
||||
end
|
||||
end
|
||||
|
||||
test 'works for xml http requests' do
|
||||
call_failure('formats' => :html, 'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
|
||||
assert_equal 401, @response.first
|
||||
end
|
||||
end
|
||||
|
||||
context 'With recall' do
|
||||
@@ -100,6 +112,7 @@ class FailureTest < ActiveSupport::TestCase
|
||||
env = {
|
||||
"action_dispatch.request.parameters" => { :controller => "devise/sessions" },
|
||||
"warden.options" => { :recall => "new", :attempted_path => "/users/sign_in" },
|
||||
"devise.mapping" => Devise.mappings[:user],
|
||||
"warden" => stub_everything
|
||||
}
|
||||
call_failure(env)
|
||||
|
||||
33
test/indifferent_hash.rb
Normal file
33
test/indifferent_hash.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
require 'test_helper'
|
||||
|
||||
class IndifferentHashTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@hash = Devise::IndifferentHash.new
|
||||
end
|
||||
|
||||
test "it overwrites getter and setter" do
|
||||
@hash[:foo] = "bar"
|
||||
assert_equal "bar", @hash["foo"]
|
||||
assert_equal "bar", @hash[:foo]
|
||||
|
||||
@hash["foo"] = "baz"
|
||||
assert_equal "baz", @hash["foo"]
|
||||
assert_equal "baz", @hash[:foo]
|
||||
end
|
||||
|
||||
test "it overwrites update" do
|
||||
@hash.update :foo => "bar"
|
||||
assert_equal "bar", @hash["foo"]
|
||||
assert_equal "bar", @hash[:foo]
|
||||
|
||||
@hash.update "foo" => "baz"
|
||||
assert_equal "baz", @hash["foo"]
|
||||
assert_equal "baz", @hash[:foo]
|
||||
end
|
||||
|
||||
test "it returns a Hash on to_hash" do
|
||||
@hash[:foo] = "bar"
|
||||
assert_equal Hash["foo", "bar"], @hash.to_hash
|
||||
assert_kind_of Hash, @hash.to_hash
|
||||
end
|
||||
end if defined?(Devise::IndifferentHash)
|
||||
@@ -1,6 +1,15 @@
|
||||
require 'test_helper'
|
||||
|
||||
class AuthenticationSanityTest < ActionController::IntegrationTest
|
||||
|
||||
def setup
|
||||
Devise.sign_out_all_scopes = false
|
||||
end
|
||||
|
||||
def teardown
|
||||
Devise.sign_out_all_scopes = false
|
||||
end
|
||||
|
||||
test 'home should be accessible without sign in' do
|
||||
visit '/'
|
||||
assert_response :success
|
||||
@@ -29,7 +38,7 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
|
||||
assert warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
test 'sign out as user should not touch admin authentication' do
|
||||
test 'sign out as user should not touch admin authentication if sign_out_all_scopes is false' do
|
||||
sign_in_as_user
|
||||
sign_in_as_admin
|
||||
|
||||
@@ -38,7 +47,7 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
|
||||
assert warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
test 'sign out as admin should not touch user authentication' do
|
||||
test 'sign out as admin should not touch user authentication if sign_out_all_scopes is false' do
|
||||
sign_in_as_user
|
||||
sign_in_as_admin
|
||||
|
||||
@@ -47,6 +56,26 @@ class AuthenticationSanityTest < ActionController::IntegrationTest
|
||||
assert warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'sign out as user should also sign out admin if sign_out_all_scopes is true' do
|
||||
Devise.sign_out_all_scopes = true
|
||||
sign_in_as_user
|
||||
sign_in_as_admin
|
||||
|
||||
get destroy_user_session_path
|
||||
assert_not warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
test 'sign out as admin should also sign out user if sign_out_all_scopes is true' do
|
||||
Devise.sign_out_all_scopes = true
|
||||
sign_in_as_user
|
||||
sign_in_as_admin
|
||||
|
||||
get destroy_admin_session_path
|
||||
assert_not warden.authenticated?(:admin)
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'not signed in as admin should not be able to access admins actions' do
|
||||
get admins_path
|
||||
|
||||
@@ -160,7 +189,7 @@ class AuthenticationRedirectTest < ActionController::IntegrationTest
|
||||
follow_redirect!
|
||||
sign_in_as_user :visit => false
|
||||
|
||||
assert_template 'users/index'
|
||||
assert_current_url '/users'
|
||||
assert_nil session[:"user_return_to"]
|
||||
end
|
||||
|
||||
@@ -176,7 +205,7 @@ class AuthenticationRedirectTest < ActionController::IntegrationTest
|
||||
follow_redirect!
|
||||
sign_in_as_user :visit => false
|
||||
|
||||
assert_template 'users/index'
|
||||
assert_current_url '/users'
|
||||
assert_nil session[:"user_return_to"]
|
||||
end
|
||||
|
||||
@@ -202,11 +231,22 @@ class AuthenticationSessionTest < ActionController::IntegrationTest
|
||||
assert_redirected_to new_user_session_path
|
||||
end
|
||||
|
||||
test 'allows session to be set by a given scope' do
|
||||
test 'allows session to be set for a given scope' do
|
||||
sign_in_as_user
|
||||
get '/users'
|
||||
assert_equal "Cart", @controller.user_session[:cart]
|
||||
end
|
||||
|
||||
test 'session id is changed on sign in' do
|
||||
get '/users'
|
||||
session_id = request.session["session_id"]
|
||||
|
||||
get '/users'
|
||||
assert_equal session_id, request.session["session_id"]
|
||||
|
||||
sign_in_as_user
|
||||
assert_not_equal session_id, request.session["session_id"]
|
||||
end
|
||||
end
|
||||
|
||||
class AuthenticationWithScopesTest < ActionController::IntegrationTest
|
||||
@@ -249,12 +289,16 @@ class AuthenticationWithScopesTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test 'uses the mapping from the default scope if specified' do
|
||||
swap Devise, :use_default_scope => true do
|
||||
get '/sign_in'
|
||||
assert_response :ok
|
||||
assert_contain 'Sign in'
|
||||
end
|
||||
test 'uses the mapping from router' do
|
||||
sign_in_as_user :visit => "/as/sign_in"
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
test 'uses the mapping from nested devise_for call' do
|
||||
sign_in_as_user :visit => "/devise_for/sign_in"
|
||||
assert warden.authenticated?(:user)
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -276,4 +320,36 @@ class AuthenticationOthersTest < ActionController::IntegrationTest
|
||||
get '/sign_in'
|
||||
end
|
||||
end
|
||||
|
||||
test 'sign in with script name' do
|
||||
assert_nothing_raised do
|
||||
get new_user_session_path, {}, "SCRIPT_NAME" => "/omg"
|
||||
fill_in "email", :with => "user@test.com"
|
||||
end
|
||||
end
|
||||
|
||||
test 'registration in xml format' do
|
||||
assert_nothing_raised do
|
||||
post user_registration_path(:format => 'xml', :user => {:email => "test@example.com", :password => "invalid"} )
|
||||
end
|
||||
end
|
||||
|
||||
test 'does not explode when invalid user class is stored in session' do
|
||||
klass = User
|
||||
paths = ActiveSupport::Dependencies.autoload_paths.dup
|
||||
|
||||
begin
|
||||
sign_in_as_user
|
||||
assert warden.authenticated?(:user)
|
||||
|
||||
Object.send :remove_const, :User
|
||||
ActiveSupport::Dependencies.autoload_paths.clear
|
||||
|
||||
visit "/users"
|
||||
assert_not warden.authenticated?(:user)
|
||||
ensure
|
||||
Object.const_set(:User, klass)
|
||||
ActiveSupport::Dependencies.autoload_paths.replace(paths)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,16 +16,13 @@ class ConfirmationTest < ActionController::IntegrationTest
|
||||
fill_in 'email', :with => user.email
|
||||
click_button 'Resend confirmation instructions'
|
||||
|
||||
assert_template 'sessions/new'
|
||||
assert_current_url '/users/sign_in'
|
||||
assert_contain 'You will receive an email with instructions about how to confirm your account in a few minutes'
|
||||
assert_equal 1, ActionMailer::Base.deliveries.size
|
||||
end
|
||||
|
||||
test 'user with invalid confirmation token should not be able to confirm an account' do
|
||||
visit_user_confirmation_with_token('invalid_confirmation')
|
||||
|
||||
assert_response :success
|
||||
assert_template 'confirmations/new'
|
||||
assert_have_selector '#error_explanation'
|
||||
assert_contain /Confirmation token(.*)invalid/
|
||||
end
|
||||
@@ -33,26 +30,36 @@ class ConfirmationTest < ActionController::IntegrationTest
|
||||
test 'user with valid confirmation token should be able to confirm an account' do
|
||||
user = create_user(:confirm => false)
|
||||
assert_not user.confirmed?
|
||||
|
||||
visit_user_confirmation_with_token(user.confirmation_token)
|
||||
|
||||
assert_template 'home/index'
|
||||
assert_contain 'Your account was successfully confirmed.'
|
||||
|
||||
assert_current_url '/'
|
||||
assert user.reload.confirmed?
|
||||
end
|
||||
|
||||
test 'user already confirmed user should not be able to confirm the account again' do
|
||||
test 'already confirmed user should not be able to confirm the account again' do
|
||||
user = create_user(:confirm => false)
|
||||
user.confirmed_at = Time.now
|
||||
user.save
|
||||
visit_user_confirmation_with_token(user.confirmation_token)
|
||||
|
||||
assert_template 'confirmations/new'
|
||||
assert_have_selector '#error_explanation'
|
||||
assert_contain 'already confirmed'
|
||||
end
|
||||
|
||||
test 'already confirmed user should not be able to confirm the account again neither request confirmation' do
|
||||
user = create_user(:confirm => false)
|
||||
user.confirmed_at = Time.now
|
||||
user.save
|
||||
|
||||
visit_user_confirmation_with_token(user.confirmation_token)
|
||||
assert_contain 'already confirmed'
|
||||
|
||||
fill_in 'email', :with => user.email
|
||||
click_button 'Resend confirmation instructions'
|
||||
assert_contain 'already confirmed'
|
||||
end
|
||||
|
||||
test 'sign in user automatically after confirming it\'s email' do
|
||||
user = create_user(:confirm => false)
|
||||
visit_user_confirmation_with_token(user.confirmation_token)
|
||||
|
||||
@@ -39,6 +39,14 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test 'test request with oauth2 header doesnt get mistaken for basic authentication' do
|
||||
swap Devise, :http_authenticatable => true do
|
||||
add_oauth2_header
|
||||
assert_equal 401, status
|
||||
assert_equal 'Basic realm="Application"', headers["WWW-Authenticate"]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sign_in_as_new_user_with_http(username="user@test.com", password="123456")
|
||||
@@ -46,4 +54,11 @@ class HttpAuthenticationTest < ActionController::IntegrationTest
|
||||
get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "Basic #{ActiveSupport::Base64.encode64("#{username}:#{password}")}"
|
||||
user
|
||||
end
|
||||
|
||||
# Sign in with oauth2 token. This is just to test that it isn't misinterpreted as basic authentication
|
||||
def add_oauth2_header
|
||||
user = create_user
|
||||
get users_path(:format => :xml), {}, "HTTP_AUTHORIZATION" => "OAuth #{ActiveSupport::Base64.encode64("#{user.email}:123456")}"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -37,27 +37,25 @@ class LockTest < ActionController::IntegrationTest
|
||||
end
|
||||
|
||||
test 'unlocked pages should not be available if email strategy is disabled' do
|
||||
visit "/users/sign_in"
|
||||
click_link "Didn't receive unlock instructions?"
|
||||
visit "/admins/sign_in"
|
||||
|
||||
swap Devise, :unlock_strategy => :time do
|
||||
visit "/users/sign_in"
|
||||
|
||||
assert_raise Webrat::NotFoundError do
|
||||
click_link "Didn't receive unlock instructions?"
|
||||
end
|
||||
|
||||
assert_raise AbstractController::ActionNotFound do
|
||||
visit new_user_unlock_path
|
||||
end
|
||||
assert_raise Webrat::NotFoundError do
|
||||
click_link "Didn't receive unlock instructions?"
|
||||
end
|
||||
|
||||
assert_raise NameError do
|
||||
visit new_admin_unlock_path
|
||||
end
|
||||
|
||||
visit "/admins/unlock/new"
|
||||
assert_response :not_found
|
||||
end
|
||||
|
||||
test 'user with invalid unlock token should not be able to unlock an account' do
|
||||
visit_user_unlock_with_token('invalid_token')
|
||||
|
||||
assert_response :success
|
||||
assert_template 'unlocks/new'
|
||||
assert_current_url '/users/unlock?unlock_token=invalid_token'
|
||||
assert_have_selector '#error_explanation'
|
||||
assert_contain /Unlock token(.*)invalid/
|
||||
end
|
||||
@@ -68,7 +66,7 @@ class LockTest < ActionController::IntegrationTest
|
||||
|
||||
visit_user_unlock_with_token(user.unlock_token)
|
||||
|
||||
assert_template 'home/index'
|
||||
assert_current_url '/'
|
||||
assert_contain 'Your account was successfully unlocked.'
|
||||
|
||||
assert_not user.reload.access_locked?
|
||||
|
||||
@@ -65,8 +65,8 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
fill_in 'password confirmation', :with => '123456'
|
||||
click_button 'Sign up'
|
||||
|
||||
assert_template 'registrations/new'
|
||||
assert_contain 'Email has already been taken'
|
||||
assert_current_url '/users'
|
||||
assert_contain(/Email .* already.*taken/)
|
||||
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
@@ -92,7 +92,7 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
fill_in 'current password', :with => '123456'
|
||||
click_button 'Update'
|
||||
|
||||
assert_template 'home/index'
|
||||
assert_current_url '/'
|
||||
assert_contain 'You updated your account successfully.'
|
||||
|
||||
assert_equal "user.new@email.com", User.first.email
|
||||
@@ -122,7 +122,7 @@ class RegistrationTest < ActionController::IntegrationTest
|
||||
fill_in 'current password', :with => '123456'
|
||||
click_button 'Update'
|
||||
|
||||
assert_template 'home/index'
|
||||
assert_current_url '/'
|
||||
assert_contain 'You updated your account successfully.'
|
||||
|
||||
assert User.first.valid_password?('pas123')
|
||||
|
||||
@@ -3,7 +3,6 @@ require 'test_helper'
|
||||
class RememberMeTest < ActionController::IntegrationTest
|
||||
|
||||
def create_user_and_remember(add_to_token='')
|
||||
Devise.remember_for = 1
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
raw_cookie = User.serialize_into_cookie(user).tap { |a| a.last << add_to_token }
|
||||
@@ -17,6 +16,16 @@ class RememberMeTest < ActionController::IntegrationTest
|
||||
request.cookie_jar['raw_cookie']
|
||||
end
|
||||
|
||||
def signed_cookie(key)
|
||||
controller.send(:cookies).signed[key]
|
||||
end
|
||||
|
||||
def cookie_expires(key)
|
||||
cookie = response.headers["Set-Cookie"].split("\n").grep(/^#{key}/).first
|
||||
cookie.split(";").map(&:strip).grep(/^expires=/)
|
||||
Time.parse($')
|
||||
end
|
||||
|
||||
test 'do not remember the user if he has not checked remember me option' do
|
||||
user = sign_in_as_user
|
||||
assert_nil request.cookies["remember_user_cookie"]
|
||||
@@ -39,6 +48,16 @@ class RememberMeTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test 'cookies are destroyed on unverified requests' do
|
||||
swap ApplicationController, :allow_forgery_protection => true do
|
||||
user = create_user_and_remember
|
||||
get users_path
|
||||
assert warden.authenticated?(:user)
|
||||
post root_path, :authenticity_token => 'INVALID'
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
||||
test 'remember the user before sign in' do
|
||||
user = create_user_and_remember
|
||||
get users_path
|
||||
@@ -47,6 +66,50 @@ class RememberMeTest < ActionController::IntegrationTest
|
||||
assert warden.user(:user) == user
|
||||
end
|
||||
|
||||
test 'does not extend remember period through sign in' do
|
||||
swap Devise, :extend_remember_period => true, :remember_for => 1.year do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
|
||||
user.remember_created_at = old = 10.days.ago
|
||||
user.save
|
||||
|
||||
sign_in_as_user :remember_me => true
|
||||
user.reload
|
||||
|
||||
assert warden.user(:user) == user
|
||||
assert_equal old.to_i, user.remember_created_at.to_i
|
||||
end
|
||||
end
|
||||
|
||||
test 'if both extend_remember_period and remember_across_browsers are true, sends the same token with a new expire date' do
|
||||
swap Devise, :remember_across_browsers => true, :extend_remember_period => true, :remember_for => 1.year do
|
||||
user = create_user_and_remember
|
||||
token = user.remember_token
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago
|
||||
user.save!
|
||||
|
||||
get users_path
|
||||
assert (cookie_expires("remember_user_token") - 1.year) > (old + 5.minutes)
|
||||
assert_equal token, signed_cookie("remember_user_token").last
|
||||
end
|
||||
end
|
||||
|
||||
test 'if both extend_remember_period and remember_across_browsers are false, sends a new token with old expire date' do
|
||||
swap Devise, :remember_across_browsers => false, :extend_remember_period => false, :remember_for => 1.year do
|
||||
user = create_user_and_remember
|
||||
token = user.remember_token
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago
|
||||
user.save!
|
||||
|
||||
get users_path
|
||||
assert (cookie_expires("remember_user_token") - 1.year) < (old + 5.minutes)
|
||||
assert_not_equal token, signed_cookie("remember_user_token").last
|
||||
end
|
||||
end
|
||||
|
||||
test 'do not remember other scopes' do
|
||||
user = create_user_and_remember
|
||||
get root_path
|
||||
@@ -78,6 +141,7 @@ class RememberMeTest < ActionController::IntegrationTest
|
||||
get destroy_user_session_path
|
||||
assert_not warden.authenticated?(:user)
|
||||
assert_nil user.reload.remember_token
|
||||
assert_nil warden.cookies['remember_user_token']
|
||||
end
|
||||
|
||||
test 'do not remember the user anymore after forget' do
|
||||
@@ -87,5 +151,6 @@ class RememberMeTest < ActionController::IntegrationTest
|
||||
get destroy_user_session_path
|
||||
get users_path
|
||||
assert_not warden.authenticated?(:user)
|
||||
assert_nil warden.cookies['remember_user_token']
|
||||
end
|
||||
end
|
||||
|
||||
@@ -65,6 +65,22 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
test 'should not be subject to injection' do
|
||||
swap Devise, :token_authentication_key => :secret_token do
|
||||
user1 = create_user()
|
||||
|
||||
# Clean up user cache
|
||||
@user = nil
|
||||
|
||||
user2 = create_user(:email => "another@test.com")
|
||||
user2.update_attribute(:authentication_token, "ANOTHERTOKEN")
|
||||
|
||||
assert_not_equal user1, user2
|
||||
visit users_path(Devise.token_authentication_key.to_s + '[$ne]' => user1.authentication_token)
|
||||
assert_nil warden.user(:user)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sign_in_as_new_user_with_token(options = {})
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
require 'test_helper'
|
||||
|
||||
class FakeRequest < Struct.new(:path_info, :params)
|
||||
end
|
||||
|
||||
class MappingTest < ActiveSupport::TestCase
|
||||
def fake_request(path, params={})
|
||||
FakeRequest.new(path, params)
|
||||
end
|
||||
|
||||
test 'store options' do
|
||||
mapping = Devise.mappings[:user]
|
||||
@@ -8,27 +14,15 @@ class MappingTest < ActiveSupport::TestCase
|
||||
assert_equal User.devise_modules, mapping.modules
|
||||
assert_equal :users, mapping.plural
|
||||
assert_equal :user, mapping.singular
|
||||
assert_equal :users, mapping.path
|
||||
assert_equal "users", mapping.path
|
||||
end
|
||||
|
||||
test 'allows path to be given' do
|
||||
assert_equal :admin_area, Devise.mappings[:admin].path
|
||||
assert_equal "admin_area", Devise.mappings[:admin].path
|
||||
end
|
||||
|
||||
test 'allows custom singular to be given' do
|
||||
assert_equal :accounts, Devise.mappings[:manager].path
|
||||
end
|
||||
|
||||
test 'allows a controller depending on the mapping' do
|
||||
allowed = Devise.mappings[:user].allowed_controllers
|
||||
assert allowed.include?("devise/sessions")
|
||||
assert allowed.include?("devise/confirmations")
|
||||
assert allowed.include?("devise/passwords")
|
||||
|
||||
allowed = Devise.mappings[:admin].allowed_controllers
|
||||
assert allowed.include?("sessions")
|
||||
assert_not allowed.include?("devise/confirmations")
|
||||
assert_not allowed.include?("devise/unlocks")
|
||||
assert_equal "accounts", Devise.mappings[:manager].path
|
||||
end
|
||||
|
||||
test 'has strategies depending on the model declaration' do
|
||||
@@ -36,15 +30,6 @@ class MappingTest < ActiveSupport::TestCase
|
||||
assert_equal [:database_authenticatable], Devise.mappings[:admin].strategies
|
||||
end
|
||||
|
||||
test 'find mapping by path' do
|
||||
assert_nil Devise::Mapping.find_by_path("/foo/bar")
|
||||
assert_equal Devise.mappings[:user], Devise::Mapping.find_by_path("/users/session")
|
||||
end
|
||||
|
||||
test 'find mapping by customized path' do
|
||||
assert_equal Devise.mappings[:admin], Devise::Mapping.find_by_path("/admin_area/session")
|
||||
end
|
||||
|
||||
test 'find scope for a given object' do
|
||||
assert_equal :user, Devise::Mapping.find_scope!(User)
|
||||
assert_equal :user, Devise::Mapping.find_scope!(:user)
|
||||
@@ -82,26 +67,6 @@ class MappingTest < ActiveSupport::TestCase
|
||||
assert_equal 'unblock', mapping.path_names[:unlock]
|
||||
end
|
||||
|
||||
test 'has an empty path as default path prefix' do
|
||||
mapping = Devise.mappings[:user]
|
||||
assert_equal '/', mapping.path_prefix
|
||||
end
|
||||
|
||||
test 'allow path prefix to be configured' do
|
||||
mapping = Devise.mappings[:manager]
|
||||
assert_equal '/:locale/', mapping.path_prefix
|
||||
end
|
||||
|
||||
test 'retrieve as from the proper position' do
|
||||
assert_equal 1, Devise.mappings[:user].segment_position
|
||||
assert_equal 2, Devise.mappings[:manager].segment_position
|
||||
end
|
||||
|
||||
test 'path is returned with path prefix and as' do
|
||||
assert_equal '/users', Devise.mappings[:user].full_path
|
||||
assert_equal '/:locale/accounts', Devise.mappings[:manager].full_path
|
||||
end
|
||||
|
||||
test 'magic predicates' do
|
||||
mapping = Devise.mappings[:user]
|
||||
assert mapping.authenticatable?
|
||||
@@ -113,8 +78,8 @@ class MappingTest < ActiveSupport::TestCase
|
||||
mapping = Devise.mappings[:admin]
|
||||
assert mapping.authenticatable?
|
||||
assert mapping.recoverable?
|
||||
assert mapping.lockable?
|
||||
assert_not mapping.confirmable?
|
||||
assert_not mapping.lockable?
|
||||
assert_not mapping.rememberable?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -133,7 +133,7 @@ class ConfirmableTest < ActiveSupport::TestCase
|
||||
user.instance_eval { def confirmation_required?; false end }
|
||||
user.save
|
||||
user.send_confirmation_instructions
|
||||
assert_not_nil user.confirmation_token
|
||||
assert_not_nil user.reload.confirmation_token
|
||||
end
|
||||
|
||||
test 'should not resend email instructions if the user change his email' do
|
||||
|
||||
@@ -98,6 +98,13 @@ class DatabaseAuthenticatableTest < ActiveSupport::TestCase
|
||||
assert_not user.valid_password?('654321')
|
||||
end
|
||||
|
||||
test 'should not validate password when salt is nil' do
|
||||
admin = create_admin
|
||||
admin.password_salt = nil
|
||||
admin.save
|
||||
assert_not admin.valid_password?('123456')
|
||||
end
|
||||
|
||||
test 'should respond to current password' do
|
||||
assert new_user.respond_to?(:current_password)
|
||||
end
|
||||
|
||||
@@ -107,4 +107,112 @@ class RememberableTest < ActiveSupport::TestCase
|
||||
assert_not user.remember_expired?
|
||||
end
|
||||
end
|
||||
|
||||
test 'if extend_remember_period is false, remember_me! should generate a new timestamp if expired' do
|
||||
swap Devise, :remember_for => 5.minutes do
|
||||
user = create_user
|
||||
user.remember_me!(false)
|
||||
assert user.remember_created_at
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago
|
||||
user.save
|
||||
|
||||
user.remember_me!(false)
|
||||
assert_not_equal old.to_i, user.remember_created_at.to_i
|
||||
end
|
||||
end
|
||||
|
||||
test 'if extend_remember_period is false, remember_me! should not generate a new timestamp' do
|
||||
swap Devise, :remember_for => 1.year do
|
||||
user = create_user
|
||||
user.remember_me!(false)
|
||||
assert user.remember_created_at
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago.utc
|
||||
user.save
|
||||
|
||||
user.remember_me!(false)
|
||||
assert_equal old.to_i, user.remember_created_at.to_i
|
||||
end
|
||||
end
|
||||
|
||||
test 'if extend_remember_period is true, remember_me! should always generate a new timestamp' do
|
||||
swap Devise, :remember_for => 1.year do
|
||||
user = create_user
|
||||
user.remember_me!(true)
|
||||
assert user.remember_created_at
|
||||
|
||||
user.remember_created_at = old = 10.minutes.ago
|
||||
user.save
|
||||
|
||||
user.remember_me!(true)
|
||||
assert_not_equal old, user.remember_created_at
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is true, remember_me! should create a new token if no token exists' do
|
||||
swap Devise, :remember_across_browsers => true, :remember_for => 1.year do
|
||||
user = create_user
|
||||
assert_equal nil, user.remember_token
|
||||
user.remember_me!
|
||||
assert_not_equal nil, user.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is true, remember_me! should create a new token if a token exists but has expired' do
|
||||
swap Devise, :remember_across_browsers => true, :remember_for => 1.day do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
user.remember_created_at = 2.days.ago
|
||||
user.save
|
||||
token = user.remember_token
|
||||
user.remember_me!
|
||||
assert_not_equal token, user.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is true, remember_me! should not create a new token if a token exists and has not expired' do
|
||||
swap Devise, :remember_across_browsers => true, :remember_for => 2.days do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
user.remember_created_at = 1.day.ago
|
||||
user.save
|
||||
token = user.remember_token
|
||||
user.remember_me!
|
||||
assert_equal token, user.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is false, remember_me! should create a new token if no token exists' do
|
||||
swap Devise, :remember_across_browsers => false do
|
||||
user = create_user
|
||||
assert_equal nil, user.remember_token
|
||||
user.remember_me!
|
||||
assert_not_equal nil, user.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is false, remember_me! should create a new token if a token exists but has expired' do
|
||||
swap Devise, :remember_across_browsers => false, :remember_for => 1.day do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
user.remember_created_at = 2.days.ago
|
||||
user.save
|
||||
token = user.remember_token
|
||||
user.remember_me!
|
||||
assert_not_equal token, user.remember_token
|
||||
end
|
||||
end
|
||||
|
||||
test 'if remember_across_browsers is false, remember_me! should create a new token if a token exists and has not expired' do
|
||||
swap Devise, :remember_across_browsers => false, :remember_for => 2.days do
|
||||
user = create_user
|
||||
user.remember_me!
|
||||
user.remember_created_at = 1.day.ago
|
||||
user.save
|
||||
token = user.remember_token
|
||||
user.remember_me!
|
||||
assert_not_equal token, user.remember_token
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -34,4 +34,16 @@ class TokenAuthenticatableTest < ActiveSupport::TestCase
|
||||
assert_nil authenticated_user
|
||||
end
|
||||
|
||||
end
|
||||
test 'should not be subject to injection' do
|
||||
user1 = create_user
|
||||
user1.ensure_authentication_token!
|
||||
user1.confirm!
|
||||
|
||||
user2 = create_user
|
||||
user2.ensure_authentication_token!
|
||||
user2.confirm!
|
||||
|
||||
user = User.find_for_token_authentication(:auth_token => {'$ne' => user1.authentication_token})
|
||||
assert_nil user
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
require 'test_helper'
|
||||
|
||||
class ValidatableTest < ActiveSupport::TestCase
|
||||
extend Devise::TestSilencer if [:mongoid, :data_mapper].include?(DEVISE_ORM)
|
||||
|
||||
test 'should require email to be set' do
|
||||
user = new_user(:email => nil)
|
||||
assert user.invalid?
|
||||
@@ -15,11 +13,11 @@ class ValidatableTest < ActiveSupport::TestCase
|
||||
|
||||
user = new_user(:email => '')
|
||||
assert user.invalid?
|
||||
assert_not_equal 'has already been taken', user.errors[:email].join
|
||||
assert_no_match(/taken/, user.errors[:email].join)
|
||||
|
||||
user.email = existing_user.email
|
||||
assert user.invalid?
|
||||
assert_equal 'has already been taken', user.errors[:email].join
|
||||
assert_match(/taken/, user.errors[:email].join)
|
||||
end
|
||||
|
||||
test 'should require correct email format, allowing blank' do
|
||||
|
||||
@@ -26,16 +26,16 @@ class ActiveRecordTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'can cherry pick modules' do
|
||||
assert_include_modules Admin, :database_authenticatable, :registerable, :timeoutable, :recoverable
|
||||
assert_include_modules Admin, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable
|
||||
end
|
||||
|
||||
test 'chosen modules are inheritable' do
|
||||
assert_include_modules Inheritable, :database_authenticatable, :registerable, :timeoutable, :recoverable
|
||||
assert_include_modules Inheritable, :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable
|
||||
end
|
||||
|
||||
test 'order of module inclusion' do
|
||||
correct_module_order = [:database_authenticatable, :recoverable, :registerable, :timeoutable]
|
||||
incorrect_module_order = [:database_authenticatable, :timeoutable, :registerable, :recoverable]
|
||||
correct_module_order = [:database_authenticatable, :recoverable, :registerable, :lockable, :timeoutable]
|
||||
incorrect_module_order = [:database_authenticatable, :timeoutable, :registerable, :recoverable, :lockable]
|
||||
|
||||
assert_include_modules Admin, *incorrect_module_order
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
require 'rails/test_help'
|
||||
|
||||
DataMapper.auto_migrate!
|
||||
|
||||
class ActiveSupport::TestCase
|
||||
setup do
|
||||
User.all.destroy!
|
||||
Admin.all.destroy!
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,6 @@
|
||||
Mongoid.configure do |config|
|
||||
config.master = Mongo::Connection.new('127.0.0.1', 27017).db("devise-test-suite")
|
||||
config.master = Mongo::Connection.new('127.0.0.1', 27017).db("devise-test-suite")
|
||||
config.use_utc = true
|
||||
end
|
||||
|
||||
class ActiveSupport::TestCase
|
||||
@@ -7,4 +8,4 @@ class ActiveSupport::TestCase
|
||||
User.delete_all
|
||||
Admin.delete_all
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,4 +7,4 @@ require 'rake'
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
|
||||
Rails::Application.load_tasks
|
||||
Rails.application.load_tasks
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
class Admin < ActiveRecord::Base
|
||||
devise :database_authenticatable, :registerable, :timeoutable, :recoverable
|
||||
devise :database_authenticatable, :registerable, :timeoutable, :recoverable, :lockable, :unlock_strategy => :time
|
||||
end
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
class Publisher::RegistrationsController < ApplicationController
|
||||
end
|
||||
@@ -0,0 +1,2 @@
|
||||
class Publisher::SessionsController < ApplicationController
|
||||
end
|
||||
@@ -1,5 +1,5 @@
|
||||
class UsersController < ApplicationController
|
||||
before_filter :authenticate_user!
|
||||
before_filter :authenticate_user!, :except => :accept
|
||||
respond_to :html, :xml
|
||||
|
||||
def index
|
||||
@@ -7,6 +7,10 @@ class UsersController < ApplicationController
|
||||
respond_with(current_user)
|
||||
end
|
||||
|
||||
def accept
|
||||
@current_user = current_user
|
||||
end
|
||||
|
||||
def expire
|
||||
user_session['last_request_at'] = 31.minutes.ago.utc
|
||||
render :text => 'User will be expired on next request'
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
class Admin
|
||||
include DataMapper::Resource
|
||||
|
||||
property :id, Serial
|
||||
property :username, String
|
||||
|
||||
devise :database_authenticatable, :registerable, :timeoutable, :recoverable
|
||||
|
||||
def self.create!(*args)
|
||||
create(*args)
|
||||
end
|
||||
end
|
||||
@@ -1,2 +0,0 @@
|
||||
module Shim
|
||||
end
|
||||
@@ -1,23 +0,0 @@
|
||||
class User
|
||||
include DataMapper::Resource
|
||||
|
||||
extend Devise::Orm::DataMapper::Schema
|
||||
include Devise::Orm::DataMapper::Compatibility
|
||||
|
||||
property :id, Serial
|
||||
property :username, String
|
||||
|
||||
devise :database_authenticatable, :confirmable, :lockable, :recoverable,
|
||||
:registerable, :rememberable, :timeoutable, :token_authenticatable,
|
||||
:trackable, :validatable
|
||||
|
||||
timestamps :at
|
||||
|
||||
def self.create!(*args)
|
||||
create(*args)
|
||||
end
|
||||
|
||||
def self.destroy_all
|
||||
all.destroy
|
||||
end
|
||||
end
|
||||
@@ -2,5 +2,5 @@ class Admin
|
||||
include Mongoid::Document
|
||||
include Shim
|
||||
|
||||
devise :database_authenticatable, :timeoutable, :registerable, :recoverable
|
||||
devise :database_authenticatable, :timeoutable, :registerable, :recoverable, :lockable, :unlock_strategy => :time
|
||||
end
|
||||
|
||||
@@ -17,8 +17,8 @@ require "devise"
|
||||
module RailsApp
|
||||
class Application < Rails::Application
|
||||
# Add additional load paths for your own custom dirs
|
||||
config.load_paths.reject!{ |p| p =~ /\/app\/(\w+)$/ && !%w(controllers helpers views).include?($1) }
|
||||
config.load_paths += [ "#{config.root}/app/#{DEVISE_ORM}" ]
|
||||
config.autoload_paths.reject!{ |p| p =~ /\/app\/(\w+)$/ && !%w(controllers helpers views).include?($1) }
|
||||
config.autoload_paths += [ "#{config.root}/app/#{DEVISE_ORM}" ]
|
||||
|
||||
# Configure generators values. Many other options are available, be sure to check the documentation.
|
||||
# config.generators do |g|
|
||||
|
||||
@@ -7,7 +7,7 @@ begin
|
||||
rescue LoadError
|
||||
require 'rubygems'
|
||||
require 'bundler'
|
||||
Bundler.setup :default, DEVISE_ORM
|
||||
Bundler.setup :default, :test, DEVISE_ORM
|
||||
end
|
||||
|
||||
$:.unshift File.expand_path('../../../../lib', __FILE__)
|
||||
$:.unshift File.expand_path('../../../../lib', __FILE__)
|
||||
|
||||
@@ -28,4 +28,6 @@ RailsApp::Application.configure do
|
||||
# config.active_record.schema_format = :sql
|
||||
|
||||
config.action_dispatch.show_exceptions = false
|
||||
|
||||
config.active_support.deprecation = :stderr
|
||||
end
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
# Use this hook to configure devise mailer, warden hooks and so forth. The first
|
||||
# four configuration values can also be set straight in your models.
|
||||
Devise.setup do |config|
|
||||
# Invoke `rake secret` and use the printed value to setup a pepper to generate
|
||||
# the encrypted password. By default no pepper is used.
|
||||
# config.pepper = "rake secret output"
|
||||
# ==> Mailer Configuration
|
||||
# Configure the e-mail address which will be shown in DeviseMailer.
|
||||
config.mailer_sender = "please-change-me@config-initializers-devise.com"
|
||||
|
||||
# Configure how many times you want the password re-encrypted. Default is 10.
|
||||
# config.stretches = 10
|
||||
# Configure the class responsible to send e-mails.
|
||||
# config.mailer = "Devise::Mailer"
|
||||
|
||||
# Define which will be the encryption algorithm. Supported algorithms are :sha1
|
||||
# (default) and :sha512. Devise also supports encryptors from others authentication
|
||||
# frameworks as :clearance_sha1, :authlogic_sha512 (then you should set stretches
|
||||
# above to 20 for default behavior) and :restful_authentication_sha1 (then you
|
||||
# should set stretches to 10, and copy REST_AUTH_SITE_KEY to pepper)
|
||||
# config.encryptor = :sha1
|
||||
# ==> ORM configuration
|
||||
# Load and configure the ORM. Supports :active_record (default) and
|
||||
# :mongoid (bson_ext recommended) by default. Other ORMs may be
|
||||
# available as additional gems.
|
||||
require "devise/orm/#{DEVISE_ORM}"
|
||||
|
||||
# ==> Configuration for any authentication mechanism
|
||||
# Configure which keys are used when authenticating an user. By default is
|
||||
# just :email. You can configure it to use [:username, :subdomain], so for
|
||||
# authenticating an user, both parameters are required. Remember that those
|
||||
@@ -22,40 +22,108 @@ Devise.setup do |config|
|
||||
# session. If you need permissions, you should implement that in a before filter.
|
||||
# config.authentication_keys = [ :email ]
|
||||
|
||||
# The time you want give to your user to confirm his account. During this time
|
||||
# Tell if authentication through request.params is enabled. True by default.
|
||||
# config.params_authenticatable = true
|
||||
|
||||
# Tell if authentication through HTTP Basic Auth is enabled. True by default.
|
||||
config.http_authenticatable = true
|
||||
|
||||
# The realm used in Http Basic Authentication
|
||||
# config.http_authentication_realm = "Application"
|
||||
|
||||
# ==> Configuration for :database_authenticatable
|
||||
# For bcrypt, this is the cost for hashing the password and defaults to 10. If
|
||||
# using other encryptors, it sets how many times you want the password re-encrypted.
|
||||
config.stretches = 10
|
||||
|
||||
# Define which will be the encryption algorithm. Devise also supports encryptors
|
||||
# from others authentication tools as :clearance_sha1, :authlogic_sha512 (then
|
||||
# you should set stretches above to 20 for default behavior) and :restful_authentication_sha1
|
||||
# (then you should set stretches to 10, and copy REST_AUTH_SITE_KEY to pepper)
|
||||
config.encryptor = :bcrypt
|
||||
|
||||
# Setup a pepper to generate the encrypted password.
|
||||
config.pepper = "d142367154e5beacca404b1a6a4f8bc52c6fdcfa3ccc3cf8eb49f3458a688ee6ac3b9fae488432a3bfca863b8a90008368a9f3a3dfbe5a962e64b6ab8f3a3a1a"
|
||||
|
||||
# ==> Configuration for :confirmable
|
||||
# The time you want to give your user to confirm his account. During this time
|
||||
# he will be able to access your application without confirming. Default is nil.
|
||||
# When confirm_within is zero, the user won't be able to sign in without confirming.
|
||||
# You can use this to let your user access some features of your application
|
||||
# without confirming the account, but blocking it after a certain period
|
||||
# (ie 2 days).
|
||||
# config.confirm_within = 2.days
|
||||
|
||||
# ==> Configuration for :rememberable
|
||||
# The time the user will be remembered without asking for credentials again.
|
||||
# config.remember_for = 2.weeks
|
||||
|
||||
# If true, a valid remember token can be re-used between multiple browsers.
|
||||
# config.remember_across_browsers = true
|
||||
|
||||
# If true, extends the user's remember period when remembered via cookie.
|
||||
# config.extend_remember_period = false
|
||||
|
||||
# ==> Configuration for :validatable
|
||||
# Range for password length
|
||||
# config.password_length = 6..20
|
||||
|
||||
# Regex to use to validate the email address
|
||||
# config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
|
||||
|
||||
# ==> Configuration for :timeoutable
|
||||
# The time you want to timeout the user session without activity. After this
|
||||
# time the user will be asked for credentials again.
|
||||
# config.timeout_in = 10.minutes
|
||||
|
||||
# Configure the e-mail address which will be shown in DeviseMailer.
|
||||
config.mailer_sender = "please-change-me-omg@yourapp.com"
|
||||
|
||||
# Load and configure the ORM. Supports :active_record, :data_mapper and :mongoid.
|
||||
require "devise/orm/#{DEVISE_ORM}"
|
||||
|
||||
# Turn scoped views on. Before rendering "sessions/new", it will first check for
|
||||
# "sessions/users/new". It's turned off by default because it's slower if you
|
||||
# are using only default views.
|
||||
# config.scoped_views = true
|
||||
|
||||
# Number of authentication tries before locking an account.
|
||||
# config.maximum_attempts = 20
|
||||
# ==> Configuration for :lockable
|
||||
# Defines which strategy will be used to lock an account.
|
||||
# :failed_attempts = Locks an account after a number of failed attempts to sign in.
|
||||
# :none = No lock strategy. You should handle locking by yourself.
|
||||
# config.lock_strategy = :failed_attempts
|
||||
|
||||
# Defines which strategy will be used to unlock an account.
|
||||
# :email = Sends an unlock link to the user email
|
||||
# :time = Re-enables login after a certain amount of time (see :unlock_in below)
|
||||
# :both = enables both strategies
|
||||
# :both = Enables both strategies
|
||||
# :none = No unlock strategy. You should handle unlocking by yourself.
|
||||
# config.unlock_strategy = :both
|
||||
|
||||
# Number of authentication tries before locking an account if lock_strategy
|
||||
# is failed attempts.
|
||||
# config.maximum_attempts = 20
|
||||
|
||||
# Time interval to unlock the account if :time is enabled as unlock_strategy.
|
||||
# config.unlock_in = 1.hour
|
||||
|
||||
# ==> Configuration for :token_authenticatable
|
||||
# Defines name of the authentication token params key
|
||||
# config.token_authentication_key = :auth_token
|
||||
|
||||
# ==> Scopes configuration
|
||||
# Turn scoped views on. Before rendering "sessions/new", it will first check for
|
||||
# "users/sessions/new". It's turned off by default because it's slower if you
|
||||
# are using only default views.
|
||||
# config.scoped_views = true
|
||||
|
||||
# Configure the default scope given to Warden. By default it's the first
|
||||
# devise role declared in your routes.
|
||||
# config.default_scope = :user
|
||||
|
||||
# Configure sign_out behavior.
|
||||
# By default sign_out is scoped (i.e. /users/sign_out affects only :user scope).
|
||||
# In case of sign_out_all_scopes set to true any logout action will sign out all active scopes.
|
||||
# config.sign_out_all_scopes = false
|
||||
|
||||
# ==> Navigation configuration
|
||||
# Lists the formats that should be treated as navigational. Formats like
|
||||
# :html, should redirect to the sign in page when the user does not have
|
||||
# access, but formats like :xml or :json, should return 401.
|
||||
# If you have any extra navigational formats, like :iphone or :mobile, you
|
||||
# should add them to the navigational formats lists. Default is [:html]
|
||||
# config.navigational_formats = [:html, :iphone]
|
||||
|
||||
# ==> Warden configuration
|
||||
# If you want to use other strategies, that are not (yet) supported by Devise,
|
||||
# you can configure them inside the config.warden block. The example below
|
||||
# allows you to setup OAuth, using http://github.com/roman/warden_oauth
|
||||
@@ -66,13 +134,6 @@ Devise.setup do |config|
|
||||
# twitter.consumer_key = <YOUR CONSUMER KEY>
|
||||
# twitter.options :site => 'http://twitter.com'
|
||||
# end
|
||||
# manager.default_strategies.unshift :twitter_oauth
|
||||
# end
|
||||
|
||||
# Configure default_url_options if you are using dynamic segments in :path_prefix
|
||||
# for devise_for.
|
||||
#
|
||||
# config.default_url_options do
|
||||
# { :locale => I18n.locale }
|
||||
# manager.default_strategies(:scope => :user).unshift :twitter_oauth
|
||||
# end
|
||||
end
|
||||
|
||||
@@ -1,29 +1,47 @@
|
||||
Rails::Application.routes.draw do
|
||||
Rails.application.routes.draw do
|
||||
# Resources for testing
|
||||
resources :users, :only => [:index] do
|
||||
get :expire, :on => :member
|
||||
get :accept, :on => :member
|
||||
end
|
||||
|
||||
resources :admins, :only => [:index]
|
||||
|
||||
devise_for :users
|
||||
devise_for :admin, :path => "admin_area", :controllers => { :sessions => "sessions" }, :skip => :passwords
|
||||
devise_for :accounts, :singular => "manager", :path_prefix => ":locale",
|
||||
:class_name => "User", :path_names => {
|
||||
:sign_in => "login", :sign_out => "logout",
|
||||
:password => "secret", :confirmation => "verification",
|
||||
:unlock => "unblock", :sign_up => "register",
|
||||
:registration => "management"
|
||||
}
|
||||
# Users scope
|
||||
devise_for :users do
|
||||
match "/devise_for/sign_in", :to => "devise/sessions#new"
|
||||
end
|
||||
|
||||
as :user do
|
||||
match "/as/sign_in", :to => "devise/sessions#new"
|
||||
end
|
||||
|
||||
match "/admin_area/home", :to => "admins#index", :as => :admin_root
|
||||
match "/sign_in", :to => "devise/sessions#new"
|
||||
|
||||
# Dummy route for new admin pasword
|
||||
match "/anywhere", :to => "foo#bar", :as => :new_admin_password
|
||||
# Admin scope
|
||||
devise_for :admin, :path => "admin_area", :controllers => { :sessions => "sessions" }, :skip => :passwords
|
||||
|
||||
root :to => "home#index"
|
||||
match "/admin_area/home", :to => "admins#index", :as => :admin_root
|
||||
match "/anywhere", :to => "foo#bar", :as => :new_admin_password
|
||||
|
||||
authenticate(:admin) do
|
||||
match "/private", :to => "home#private", :as => :private
|
||||
end
|
||||
|
||||
# Other routes for routing_test.rb
|
||||
namespace :publisher, :path_names => { :sign_in => "i_don_care", :sign_out => "get_out" } do
|
||||
devise_for :accounts, :class_name => "User", :path_names => { :sign_in => "get_in" }
|
||||
end
|
||||
|
||||
scope ":locale" do
|
||||
devise_for :accounts, :singular => "manager", :class_name => "User",
|
||||
:path_names => {
|
||||
:sign_in => "login", :sign_out => "logout",
|
||||
:password => "secret", :confirmation => "verification",
|
||||
:unlock => "unblock", :sign_up => "register",
|
||||
:registration => "management"
|
||||
}
|
||||
end
|
||||
|
||||
root :to => "home#index"
|
||||
end
|
||||
@@ -1,25 +1,29 @@
|
||||
require 'test_helper'
|
||||
|
||||
class MapRoutingTest < ActionController::TestCase
|
||||
|
||||
class DefaultRoutingTest < ActionController::TestCase
|
||||
test 'map new user session' do
|
||||
assert_recognizes({:controller => 'devise/sessions', :action => 'new'}, {:path => 'users/sign_in', :method => :get})
|
||||
assert_named_route "/users/sign_in", :new_user_session_path
|
||||
end
|
||||
|
||||
test 'map create user session' do
|
||||
assert_recognizes({:controller => 'devise/sessions', :action => 'create'}, {:path => 'users/sign_in', :method => :post})
|
||||
assert_named_route "/users/sign_in", :user_session_path
|
||||
end
|
||||
|
||||
test 'map destroy user session' do
|
||||
assert_recognizes({:controller => 'devise/sessions', :action => 'destroy'}, {:path => 'users/sign_out', :method => :get})
|
||||
assert_named_route "/users/sign_out", :destroy_user_session_path
|
||||
end
|
||||
|
||||
test 'map new user confirmation' do
|
||||
assert_recognizes({:controller => 'devise/confirmations', :action => 'new'}, 'users/confirmation/new')
|
||||
assert_named_route "/users/confirmation/new", :new_user_confirmation_path
|
||||
end
|
||||
|
||||
test 'map create user confirmation' do
|
||||
assert_recognizes({:controller => 'devise/confirmations', :action => 'create'}, {:path => 'users/confirmation', :method => :post})
|
||||
assert_named_route "/users/confirmation", :user_confirmation_path
|
||||
end
|
||||
|
||||
test 'map show user confirmation' do
|
||||
@@ -28,14 +32,17 @@ class MapRoutingTest < ActionController::TestCase
|
||||
|
||||
test 'map new user password' do
|
||||
assert_recognizes({:controller => 'devise/passwords', :action => 'new'}, 'users/password/new')
|
||||
assert_named_route "/users/password/new", :new_user_password_path
|
||||
end
|
||||
|
||||
test 'map create user password' do
|
||||
assert_recognizes({:controller => 'devise/passwords', :action => 'create'}, {:path => 'users/password', :method => :post})
|
||||
assert_named_route "/users/password", :user_password_path
|
||||
end
|
||||
|
||||
test 'map edit user password' do
|
||||
assert_recognizes({:controller => 'devise/passwords', :action => 'edit'}, 'users/password/edit')
|
||||
assert_named_route "/users/password/edit", :edit_user_password_path
|
||||
end
|
||||
|
||||
test 'map update user password' do
|
||||
@@ -44,10 +51,12 @@ class MapRoutingTest < ActionController::TestCase
|
||||
|
||||
test 'map new user unlock' do
|
||||
assert_recognizes({:controller => 'devise/unlocks', :action => 'new'}, 'users/unlock/new')
|
||||
assert_named_route "/users/unlock/new", :new_user_unlock_path
|
||||
end
|
||||
|
||||
test 'map create user unlock' do
|
||||
assert_recognizes({:controller => 'devise/unlocks', :action => 'create'}, {:path => 'users/unlock', :method => :post})
|
||||
assert_named_route "/users/unlock", :user_unlock_path
|
||||
end
|
||||
|
||||
test 'map show user unlock' do
|
||||
@@ -56,14 +65,17 @@ class MapRoutingTest < ActionController::TestCase
|
||||
|
||||
test 'map new user registration' do
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'new'}, 'users/sign_up')
|
||||
assert_named_route "/users/sign_up", :new_user_registration_path
|
||||
end
|
||||
|
||||
test 'map create user registration' do
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'create'}, {:path => 'users', :method => :post})
|
||||
assert_named_route "/users", :user_registration_path
|
||||
end
|
||||
|
||||
test 'map edit user registration' do
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'edit'}, {:path => 'users/edit', :method => :get})
|
||||
assert_named_route "/users/edit", :edit_user_registration_path
|
||||
end
|
||||
|
||||
test 'map update user registration' do
|
||||
@@ -74,6 +86,14 @@ class MapRoutingTest < ActionController::TestCase
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'destroy'}, {:path => 'users', :method => :delete})
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def assert_named_route(result, name)
|
||||
assert_equal result, @routes.url_helpers.send(name)
|
||||
end
|
||||
end
|
||||
|
||||
class CustomizedRoutingTest < ActionController::TestCase
|
||||
test 'map admin with :path option' do
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'new'}, {:path => 'admin_area/sign_up', :method => :get})
|
||||
end
|
||||
@@ -112,3 +132,15 @@ class MapRoutingTest < ActionController::TestCase
|
||||
assert_recognizes({:controller => 'devise/registrations', :action => 'new', :locale => 'en'}, '/en/accounts/management/register')
|
||||
end
|
||||
end
|
||||
|
||||
class ScopedRoutingTest < ActionController::TestCase
|
||||
test 'map publisher account' do
|
||||
assert_recognizes({:controller => 'publisher/registrations', :action => 'new'}, {:path => '/publisher/accounts/sign_up', :method => :get})
|
||||
assert_equal '/publisher/accounts/sign_up', @routes.url_helpers.new_publisher_account_registration_path
|
||||
end
|
||||
|
||||
test 'map publisher account merges path names' do
|
||||
assert_recognizes({:controller => 'publisher/sessions', :action => 'new'}, {:path => '/publisher/accounts/get_in', :method => :get})
|
||||
assert_equal '/publisher/accounts/get_in', @routes.url_helpers.new_publisher_account_session_path
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,6 +37,12 @@ class ActiveSupport::TestCase
|
||||
User.create!(valid_attributes(attributes))
|
||||
end
|
||||
|
||||
def create_admin(attributes={})
|
||||
valid_attributes = valid_attributes(attributes)
|
||||
valid_attributes.delete(:username)
|
||||
Admin.create!(valid_attributes)
|
||||
end
|
||||
|
||||
# Execute the block setting the given values and restoring old values after
|
||||
# the block is executed.
|
||||
def swap(object, new_values)
|
||||
|
||||
@@ -9,7 +9,7 @@ class ActionDispatch::IntegrationTest
|
||||
@user ||= begin
|
||||
user = User.create!(
|
||||
:username => 'usertest',
|
||||
:email => 'user@test.com',
|
||||
:email => options[:email] || 'user@test.com',
|
||||
:password => '123456',
|
||||
:password_confirmation => '123456',
|
||||
:created_at => Time.now.utc
|
||||
@@ -31,7 +31,7 @@ class ActionDispatch::IntegrationTest
|
||||
|
||||
def sign_in_as_user(options={}, &block)
|
||||
user = create_user(options)
|
||||
get new_user_session_path unless options[:visit] == false
|
||||
visit_with_option options[:visit], new_user_session_path
|
||||
fill_in 'email', :with => 'user@test.com'
|
||||
fill_in 'password', :with => options[:password] || '123456'
|
||||
check 'remember me' if options[:remember_me] == true
|
||||
@@ -42,7 +42,7 @@ class ActionDispatch::IntegrationTest
|
||||
|
||||
def sign_in_as_admin(options={}, &block)
|
||||
admin = create_admin(options)
|
||||
get new_admin_session_path unless options[:visit] == false
|
||||
visit_with_option options[:visit], new_admin_session_path
|
||||
fill_in 'email', :with => 'admin@test.com'
|
||||
fill_in 'password', :with => '123456'
|
||||
yield if block_given?
|
||||
@@ -57,16 +57,32 @@ class ActionDispatch::IntegrationTest
|
||||
assert [301, 302].include?(@integration_session.status),
|
||||
"Expected status to be 301 or 302, got #{@integration_session.status}"
|
||||
|
||||
url = prepend_host(url)
|
||||
location = prepend_host(@integration_session.headers["Location"])
|
||||
assert_equal url, location
|
||||
assert_url url, @integration_session.headers["Location"]
|
||||
end
|
||||
|
||||
def assert_current_url(expected)
|
||||
assert_url expected, current_url
|
||||
end
|
||||
|
||||
def assert_url(expected, actual)
|
||||
assert_equal prepend_host(expected), prepend_host(actual)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def visit_with_option(given, default)
|
||||
case given
|
||||
when String
|
||||
visit given
|
||||
when FalseClass
|
||||
# Do nothing
|
||||
else
|
||||
visit default
|
||||
end
|
||||
end
|
||||
|
||||
def prepend_host(url)
|
||||
url = "http://#{request.host}#{url}" if url[0] == ?/
|
||||
url
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
require 'webrat/core/elements/field'
|
||||
require 'webrat/core/elements/form'
|
||||
require 'action_dispatch/testing/integration'
|
||||
|
||||
module Webrat
|
||||
Field.class_eval do
|
||||
def parse_rails_request_params(params)
|
||||
Form.class_eval do
|
||||
def self.parse_rails_request_params(params)
|
||||
Rack::Utils.parse_nested_query(params)
|
||||
end
|
||||
end
|
||||
@@ -13,20 +13,5 @@ module ActionDispatch #:nodoc:
|
||||
IntegrationTest.class_eval do
|
||||
include Webrat::Methods
|
||||
include Webrat::Matchers
|
||||
|
||||
# The Rails version of within supports passing in a model and Webrat
|
||||
# will apply a scope based on Rails' dom_id for that model.
|
||||
#
|
||||
# Example:
|
||||
# within User.last do
|
||||
# click_link "Delete"
|
||||
# end
|
||||
def within(selector_or_object, &block)
|
||||
if selector_or_object.is_a?(String)
|
||||
super
|
||||
else
|
||||
super('#' + RecordIdentifier.dom_id(selector_or_object), &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,8 +9,9 @@ require "rails/test_help"
|
||||
require "orm/#{DEVISE_ORM}"
|
||||
|
||||
I18n.load_path << File.expand_path("../support/locale/en.yml", __FILE__)
|
||||
require 'mocha'
|
||||
|
||||
require 'mocha'
|
||||
require 'webrat'
|
||||
Webrat.configure do |config|
|
||||
config.mode = :rails
|
||||
config.open_error_files = false
|
||||
@@ -18,4 +19,4 @@ end
|
||||
|
||||
# Add support to load paths so we can overwrite broken webrat setup
|
||||
$:.unshift File.expand_path('../support', __FILE__)
|
||||
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
||||
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
||||
|
||||
@@ -10,14 +10,28 @@ class TestHelpersTest < ActionController::TestCase
|
||||
assert_equal "You need to sign in or sign up before continuing.", flash[:alert]
|
||||
end
|
||||
|
||||
test "redirects if attempting to access a page with a unconfirmed account" do
|
||||
test "redirects if attempting to access a page with an unconfirmed account" do
|
||||
swap Devise, :confirm_within => 0 do
|
||||
sign_in create_user
|
||||
user = create_user
|
||||
assert !user.active?
|
||||
|
||||
sign_in user
|
||||
get :index
|
||||
assert_redirected_to new_user_session_path
|
||||
end
|
||||
end
|
||||
|
||||
test "returns nil if accessing current_user with an unconfirmed account" do
|
||||
swap Devise, :confirm_within => 0 do
|
||||
user = create_user
|
||||
assert !user.active?
|
||||
|
||||
sign_in user
|
||||
get :accept, :id => user
|
||||
assert_nil assigns(:current_user)
|
||||
end
|
||||
end
|
||||
|
||||
test "does not redirect with valid user" do
|
||||
user = create_user
|
||||
user.confirm!
|
||||
|
||||
Reference in New Issue
Block a user