mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
Merge and fix conflicts.
This commit is contained in:
commit
32991e13c4
37 changed files with 255 additions and 225 deletions
|
@ -1,3 +1,31 @@
|
|||
* enhancements
|
||||
* Move salt to encryptors
|
||||
|
||||
* bug fix
|
||||
* Bcrypt generator was not being loaded neither setting the proper salt
|
||||
|
||||
== 0.8.0
|
||||
|
||||
* enhancements
|
||||
* Warden 0.8.0 compatibility
|
||||
* Add an easy for map.connect "sign_in", :controller => "sessions", :action => "new" to work
|
||||
* Added :bcrypt encryptor (by github.com/capotej)
|
||||
|
||||
* bug fix
|
||||
* sign_in_count is also increased when user signs in via password change, confirmation, etc..
|
||||
* More DataMapper compatibility (by github.com/lancecarlson)
|
||||
|
||||
* deprecation
|
||||
* Removed DeviseMailer.sender
|
||||
|
||||
== 0.7.5
|
||||
|
||||
* enhancements
|
||||
* Set a default value for mailer to avoid find_template issues
|
||||
* Add models configuration to MongoMapper::EmbeddedDocument as well
|
||||
|
||||
== 0.7.4
|
||||
|
||||
* enhancements
|
||||
* Extract Activatable from Confirmable
|
||||
* Decouple Serializers from Devise modules
|
||||
|
|
56
README.rdoc
56
README.rdoc
|
@ -7,23 +7,26 @@ Devise is a flexible authentication solution for Rails based on Warden. It:
|
|||
* Allows you to have multiple roles (or models/scopes) signed in at the same time;
|
||||
* Is based on a modularity concept: use just what you really need.
|
||||
|
||||
Right now it's composed of seven mainly modules:
|
||||
Right now it's composed of six modules included by default when you invoke "devise :all" in your models:
|
||||
|
||||
* Authenticatable: responsible for encrypting password and validating authenticity of a user while signing in.
|
||||
* Confirmable: responsible for verifying whether an account is already confirmed to sign in, and to send emails with confirmation instructions.
|
||||
* Recoverable: takes care of reseting the user password and send reset instructions.
|
||||
* Rememberable: manages generating and clearing token for remember the user from a saved cookie.
|
||||
* Activatable: if you need to activate accounts by other means, which are not through confirmation, use this module.
|
||||
* Timeoutable: expires sessions without activity in a certain period of time.
|
||||
* Trackable: tracks sign in count, timestamps and ip.
|
||||
* Validatable: creates all needed validations for email and password. It's totally optional, so you're able to to customize validations by yourself.
|
||||
|
||||
And it also includes the optional modules:
|
||||
|
||||
* Activatable: if you need to activate accounts by other means, which are not through confirmation, use this module.
|
||||
* Timeoutable: expires sessions without activity in a certain period of time.
|
||||
* Lockable: takes care of locking an account based on the number of failed sign in attempts. Handles unlock via expire and email.
|
||||
|
||||
There's an example application using Devise at http://github.com/plataformatec/devise_example .
|
||||
|
||||
== Dependencies
|
||||
|
||||
Devise is based on Warden (http://github.com/hassox/warden), a Rack Authentication Framework so you need to install it as a gem. Please ensure you have it installed in order to use devise (see instalation below).
|
||||
Devise is based on Warden (http://github.com/hassox/warden), a Rack Authentication Framework so you need to install it as a gem. Please ensure you have it installed in order to use devise (see installation below).
|
||||
|
||||
== Installation
|
||||
|
||||
|
@ -48,13 +51,13 @@ Run the generator:
|
|||
|
||||
ruby script/generate devise_install
|
||||
|
||||
And you're ready to go.
|
||||
And you're ready to go. The generator will install an initializer which describes Devise's configuration options. Be sure to take a look.
|
||||
|
||||
== Basic Usage
|
||||
|
||||
This is a walkthrough with all steps you need to setup a devise resource, including model, migration, route files, and optional configuration. You can also check out the *Generators* section below to help you start.
|
||||
|
||||
Devise must be set up within the model (or models) you want to use, and devise routes must be created inside your routes.rb file.
|
||||
Devise must be set up within the model (or models) you want to use, and devise routes must be created inside your config/routes.rb file.
|
||||
|
||||
We're assuming here you want a User model. First of all you have to setup a migration with the following fields:
|
||||
|
||||
|
@ -63,6 +66,7 @@ We're assuming here you want a User model. First of all you have to setup a migr
|
|||
t.confirmable
|
||||
t.recoverable
|
||||
t.rememberable
|
||||
t.trackable
|
||||
t.lockable
|
||||
t.timestamps
|
||||
end
|
||||
|
@ -74,35 +78,21 @@ You may also want to add some indexes to improve performance:
|
|||
add_index :your_table, :reset_password_token # for recoverable
|
||||
add_index :your_table, :unlock_token # for lockable
|
||||
|
||||
Now let's setup a User model adding the devise line to have your authentication working:
|
||||
Now let's setup a User model adding the devise line:
|
||||
|
||||
class User < ActiveRecord::Base
|
||||
devise :authenticatable
|
||||
devise :all
|
||||
end
|
||||
|
||||
This line adds devise authenticatable inside your User class. Devise don't rely on _attr_accessible_ or _attr_protected_ inside its modules, so be sure to setup what attributes are accessible or protected in your model.
|
||||
This will include the six default modules outlined at the beginning. You can exclude and remove any module at will:
|
||||
|
||||
You could also include the other devise modules as below:
|
||||
# Include timeout configuration
|
||||
devise :all, :timeoutable
|
||||
|
||||
# Include only authenticatable stuff
|
||||
devise :authenticatable
|
||||
# Remove validations
|
||||
devise :all, :except => :validatable
|
||||
|
||||
# Include authenticatable + confirmable
|
||||
devise :authenticatable, :confirmable
|
||||
|
||||
# Include authenticatable + recoverable + rememberable
|
||||
devise :authenticatable, :recoverable, :rememberable
|
||||
|
||||
# Include authenticatable + timeoutable
|
||||
devise :authenticatable, :timeoutable
|
||||
|
||||
# Include all of them
|
||||
devise :all
|
||||
|
||||
# Include all except recoverable
|
||||
devise :all, :except => :recoverable
|
||||
|
||||
Note that validations aren't added by default, so you're able to customize it. In order to have automatic validations working just include :validatable.
|
||||
Remember that Devise don't rely on _attr_accessible_ or _attr_protected_ inside its modules, so be sure to setup what attributes are accessible or protected in your model.
|
||||
|
||||
== Model configuration
|
||||
|
||||
|
@ -148,26 +138,26 @@ After signing in a user, confirming it's account or updating it's password, devi
|
|||
|
||||
You can also overwrite after_sign_in_path_for and after_sign_out_path_for to customize better your redirect hooks.
|
||||
|
||||
Finally, if you are using confirmable or recoverable, you also need to setup default url options for the mailer. Here's is the configuration for development:
|
||||
Finally, if you are using confirmable or recoverable, you also need to setup default url options for the mailer in each environment. Here's is the configuration for config/environments/development.rb:
|
||||
|
||||
DeviseMailer.sender = "no-reply@yourapp.com"
|
||||
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
||||
|
||||
== Views
|
||||
|
||||
By default devise will use the same views for all scopes/roles you have. But what if you need so different views to each of them? Devise also has an easy way to accomplish it: just setup :scoped_views to true inside your devise config file, and you will be able to have views based on scope like 'sessions/users/new' and 'sessions/admin/new'. If no view is found within the scope, Devise will fallback to the default view.
|
||||
By default devise will use the same views for all scopes/roles you have. But what if you need so different views to each of them? Devise also has an easy way to accomplish it: just setup config,scoped_views to true inside your devise config file, and you will be able to have views based on scope like 'sessions/users/new' and 'sessions/admin/new'. If no view is found within the scope, Devise will fallback to the default view.
|
||||
|
||||
== Tidying up
|
||||
|
||||
Devise let's you setup as many roles as you want, so let's say you already have this User model and also want an Admin model with the same authentication stuff, but not confirmation or password recovery. Just follow the same steps:
|
||||
Devise let's you setup as many roles as you want, so let's say you already have this User model and also want an Admin model with just authentication, trackable and timeoutable stuff and none of confirmation or password recovery. Just follow the same steps:
|
||||
|
||||
# Create a migration with the required fields
|
||||
create_table :admins do |t|
|
||||
t.authenticatable
|
||||
t.trackable
|
||||
end
|
||||
|
||||
# Inside your Admin model
|
||||
devise :authenticatable, :validatable
|
||||
devise :authenticatable, :trackable, :timeoutable
|
||||
|
||||
# Inside your routes
|
||||
map.devise_for :admin
|
||||
|
|
2
Rakefile
2
Rakefile
|
@ -44,7 +44,7 @@ begin
|
|||
s.description = "Flexible authentication solution for Rails with Warden"
|
||||
s.authors = ['José Valim', 'Carlos Antônio']
|
||||
s.files = FileList["[A-Z]*", "{app,config,generators,lib}/**/*", "init.rb"]
|
||||
s.add_dependency("warden", "~> 0.6.4")
|
||||
s.add_dependency("warden", "~> 0.8.1")
|
||||
end
|
||||
|
||||
Jeweler::GemcutterTasks.new
|
||||
|
|
|
@ -1,16 +1,5 @@
|
|||
class DeviseMailer < ::ActionMailer::Base
|
||||
|
||||
# Sets who is sending the e-mail
|
||||
def self.sender=(value)
|
||||
@@sender = value
|
||||
end
|
||||
|
||||
# Reads who is sending the e-mail
|
||||
def self.sender
|
||||
@@sender
|
||||
end
|
||||
self.sender = nil
|
||||
|
||||
# Deliver confirmation instructions when the user is created or its email is
|
||||
# updated, and also when confirmation is manually requested
|
||||
def confirmation_instructions(record)
|
||||
|
@ -34,7 +23,7 @@ class DeviseMailer < ::ActionMailer::Base
|
|||
raise "Invalid devise resource #{record}" unless mapping
|
||||
|
||||
subject translate(mapping, key)
|
||||
from self.class.sender
|
||||
from Devise.mailer_sender
|
||||
recipients record.email
|
||||
sent_on Time.now
|
||||
content_type 'text/html'
|
||||
|
|
|
@ -4,18 +4,11 @@ class DeviseGenerator < Rails::Generator::NamedBase
|
|||
|
||||
def manifest
|
||||
record do |m|
|
||||
# Model
|
||||
m.directory(File.join('app', 'models', class_path))
|
||||
m.template 'model.rb', File.join('app', 'models', "#{file_path}.rb")
|
||||
|
||||
# Migration
|
||||
m.migration_template 'migration.rb', 'db/migrate', :migration_file_name => "devise_create_#{table_name}"
|
||||
|
||||
# Routing
|
||||
m.route_devise table_name
|
||||
|
||||
# Readme
|
||||
m.readme "README"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
|
||||
================================================================================
|
||||
|
||||
Some setup you must do manually if you haven't yet:
|
||||
|
||||
1. Setup defaut url options for your specific environment. Here is an example of development environment:
|
||||
|
||||
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
||||
|
||||
It's a Rails required configuration. In production it must be the actual host your application is deployed to.
|
||||
|
||||
2. Setup default sender for mails. In config/environment.rb:
|
||||
|
||||
DeviseMailer.sender = "test@example.com"
|
||||
|
||||
You can also configure this value by running script/generate devise_install and setting config.mailer_sender,
|
||||
|
||||
3. Ensure you have defined root_url to *something* in your config/routes.rb:
|
||||
|
||||
map.root :controller => 'home'
|
||||
|
||||
================================================================================
|
|
@ -7,6 +7,8 @@ class DeviseInstallGenerator < Rails::Generator::Base
|
|||
|
||||
m.directory "config/locales"
|
||||
m.file "../../../lib/devise/locales/en.yml", "config/locales/devise.en.yml"
|
||||
|
||||
m.readme "README"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
18
generators/devise_install/templates/README
Normal file
18
generators/devise_install/templates/README
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
===============================================================================
|
||||
|
||||
Some setup you must do manually if you haven't yet:
|
||||
|
||||
1. Setup default url options for your specific environment. Here is an
|
||||
example of development environment:
|
||||
|
||||
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
||||
|
||||
This is a required Rails configuration. In production is must be the
|
||||
actual host of your application
|
||||
|
||||
2. Ensure you have defined root_url to *something* in your config/routes.rb:
|
||||
|
||||
map.root :controller => 'home'
|
||||
|
||||
===============================================================================
|
|
@ -10,6 +10,9 @@ Devise.setup do |config|
|
|||
# to check the docs for a complete set.
|
||||
config.all = [:authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable, :lockable]
|
||||
|
||||
# Configure the e-mail address which will be shown in DeviseMailer.
|
||||
config.mailer_sender = "please-change-me@config-initializers-devise.com"
|
||||
|
||||
# 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"
|
||||
|
@ -18,10 +21,10 @@ Devise.setup do |config|
|
|||
# config.stretches = 10
|
||||
|
||||
# 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)
|
||||
# (default), :sha512 and :bcrypt. 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 = :sha1
|
||||
|
||||
# Configure which keys are used when authenticating an user. By default is
|
||||
|
@ -42,9 +45,6 @@ Devise.setup do |config|
|
|||
# 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 = "foo.bar@yourapp.com"
|
||||
|
||||
# Load and configure the ORM. Supports :active_record, :data_mapper and :mongo_mapper.
|
||||
# require 'devise/orm/mongo_mapper'
|
||||
# config.orm = :mongo_mapper
|
||||
|
@ -66,6 +66,16 @@ Devise.setup do |config|
|
|||
# Time interval to unlock the account if :time is enabled as unlock_strategy.
|
||||
# config.unlock_in = 1.hour
|
||||
|
||||
# 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.
|
||||
# config.use_default_scope = true
|
||||
|
||||
# Configure the default scope used by Devise. By default it's the first devise
|
||||
# role declared in your routes.
|
||||
# config.default_scope = :user
|
||||
|
||||
# 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
|
||||
|
|
|
@ -11,6 +11,8 @@ module Devise
|
|||
end
|
||||
|
||||
module Encryptors
|
||||
autoload :Base, 'devise/encryptors/base'
|
||||
autoload :Bcrypt, 'devise/encryptors/bcrypt'
|
||||
autoload :AuthlogicSha512, 'devise/encryptors/authlogic_sha512'
|
||||
autoload :AuthlogicSha1, 'devise/encryptors/authlogic_sha1'
|
||||
autoload :RestfulAuthenticationSha1, 'devise/encryptors/restful_authentication_sha1'
|
||||
|
@ -48,7 +50,8 @@ module Devise
|
|||
:sha512 => 128,
|
||||
:clearance_sha1 => 40,
|
||||
:restful_authentication_sha1 => 40,
|
||||
:authlogic_sha512 => 128
|
||||
:authlogic_sha512 => 128,
|
||||
:bcrypt => 60
|
||||
}
|
||||
|
||||
# Email regex used to validate email formats. Retrieved from authlogic.
|
||||
|
@ -117,6 +120,18 @@ 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
|
||||
|
||||
# The default scope which is used by warden.
|
||||
mattr_accessor :default_scope
|
||||
@@default_scope = nil
|
||||
|
||||
# Address which sends Devise e-mails.
|
||||
mattr_accessor :mailer_sender
|
||||
@@mailer_sender
|
||||
|
||||
class << self
|
||||
# Default way to setup Devise. Run script/generate devise_install to create
|
||||
# a fresh initializer with all configuration values.
|
||||
|
@ -124,12 +139,6 @@ module Devise
|
|||
yield self
|
||||
end
|
||||
|
||||
# Sets the sender in DeviseMailer.
|
||||
def mailer_sender=(value)
|
||||
DeviseMailer.sender = value
|
||||
end
|
||||
alias :sender= :mailer_sender=
|
||||
|
||||
# Sets warden configuration using a block that will be invoked on warden
|
||||
# initialization.
|
||||
#
|
||||
|
@ -152,15 +161,16 @@ module Devise
|
|||
|
||||
# A method used internally to setup warden manager from the Rails initialize
|
||||
# block.
|
||||
def configure_warden_manager(manager) #:nodoc:
|
||||
manager.default_strategies *Devise::STRATEGIES
|
||||
manager.default_serializers *Devise::SERIALIZERS
|
||||
manager.failure_app = Devise::FailureApp
|
||||
manager.silence_missing_strategies!
|
||||
manager.silence_missing_serializers!
|
||||
def configure_warden(config) #:nodoc:
|
||||
config.default_strategies *Devise::STRATEGIES
|
||||
config.default_serializers *Devise::SERIALIZERS
|
||||
config.failure_app = Devise::FailureApp
|
||||
config.silence_missing_strategies!
|
||||
config.silence_missing_serializers!
|
||||
config.default_scope = Devise.default_scope
|
||||
|
||||
# If the user provided a warden hook, call it now.
|
||||
@warden_config.try :call, manager
|
||||
@warden_config.try :call, config
|
||||
end
|
||||
|
||||
# The class of the configured ORM
|
||||
|
@ -185,6 +195,5 @@ end
|
|||
# Clear some Warden default configuration which will be overwritten
|
||||
Warden::Strategies.clear!
|
||||
Warden::Serializers.clear!
|
||||
Warden::Manager.default_scope = nil
|
||||
|
||||
require 'devise/rails'
|
||||
require 'devise/rails'
|
||||
|
|
|
@ -35,7 +35,11 @@ module Devise
|
|||
|
||||
# Attempt to find the mapped route for devise based on request path
|
||||
def devise_mapping
|
||||
@devise_mapping ||= Devise::Mapping.find_by_path(request.path)
|
||||
@devise_mapping ||= begin
|
||||
mapping = Devise::Mapping.find_by_path(request.path)
|
||||
mapping ||= Devise.mappings[Devise.default_scope] if Devise.use_default_scope
|
||||
mapping
|
||||
end
|
||||
end
|
||||
|
||||
# Overwrites devise_controller? to return true
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
require "digest/sha2"
|
||||
|
||||
module Devise
|
||||
# Implements a way of adding different encryptions.
|
||||
# The class should implement a self.digest method that taks the following params:
|
||||
# - password
|
||||
# - stretches: the number of times the encryption will be applied
|
||||
# - salt: the password salt as defined by devise
|
||||
# - pepper: Devise config option
|
||||
#
|
||||
module Encryptors
|
||||
# = AuthlogicSha512
|
||||
# Simulates Authlogic's default encryption mechanism.
|
||||
# Warning: it uses Devise's stretches configuration to port Authlogic's one. Should be set to 20 in the initializer to silumate
|
||||
# the default behavior.
|
||||
class AuthlogicSha512
|
||||
class AuthlogicSha512 < Base
|
||||
|
||||
# Gererates a default password digest based on salt, pepper and the
|
||||
# incoming password.
|
||||
|
|
20
lib/devise/encryptors/base.rb
Normal file
20
lib/devise/encryptors/base.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module Devise
|
||||
# Implements a way of adding different encryptions.
|
||||
# The class should implement a self.digest method that taks the following params:
|
||||
# - password
|
||||
# - stretches: the number of times the encryption will be applied
|
||||
# - salt: the password salt as defined by devise
|
||||
# - pepper: Devise config option
|
||||
#
|
||||
module Encryptors
|
||||
class Base
|
||||
def self.digest
|
||||
raise NotImplemented
|
||||
end
|
||||
|
||||
def self.salt
|
||||
Devise.friendly_token
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
lib/devise/encryptors/bcrypt.rb
Normal file
21
lib/devise/encryptors/bcrypt.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
require "bcrypt"
|
||||
|
||||
module Devise
|
||||
module Encryptors
|
||||
# = BCrypt
|
||||
# Uses the BCrypt hash algorithm to encrypt passwords.
|
||||
class Bcrypt < Base
|
||||
|
||||
# Gererates a default password digest based on stretches, salt, pepper and the
|
||||
# incoming password. We don't strech it ourselves since BCrypt does so internally.
|
||||
def self.digest(password, stretches, salt, pepper)
|
||||
::BCrypt::Engine.hash_secret([password, pepper].join, salt, stretches)
|
||||
end
|
||||
|
||||
def self.salt
|
||||
::BCrypt::Engine.generate_salt
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,19 +1,12 @@
|
|||
require "digest/sha1"
|
||||
|
||||
module Devise
|
||||
# Implements a way of adding different encryptions.
|
||||
# The class should implement a self.digest method that taks the following params:
|
||||
# - password
|
||||
# - stretches: the number of times the encryption will be applied
|
||||
# - salt: the password salt as defined by devise
|
||||
# - pepper: Devise config option
|
||||
#
|
||||
module Encryptors
|
||||
# = ClearanceSha1
|
||||
# Simulates Clearance's default encryption mechanism.
|
||||
# Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
|
||||
# Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES
|
||||
class ClearanceSha1
|
||||
class ClearanceSha1 < Base
|
||||
|
||||
# Gererates a default password digest based on salt, pepper and the
|
||||
# incoming password.
|
||||
|
|
|
@ -1,20 +1,13 @@
|
|||
require "digest/sha1"
|
||||
|
||||
module Devise
|
||||
# Implements a way of adding different encryptions.
|
||||
# The class should implement a self.digest method that taks the following params:
|
||||
# - password
|
||||
# - stretches: the number of times the encryption will be applied
|
||||
# - salt: the password salt as defined by devise
|
||||
# - pepper: Devise config option
|
||||
#
|
||||
module Encryptors
|
||||
# = RestfulAuthenticationSha1
|
||||
# Simulates Restful Authentication's default encryption mechanism.
|
||||
# Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
|
||||
# Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES. Should be set to 10 in
|
||||
# the initializer to silumate the default behavior.
|
||||
class RestfulAuthenticationSha1
|
||||
class RestfulAuthenticationSha1 < Base
|
||||
|
||||
# Gererates a default password digest based on salt, pepper and the
|
||||
# incoming password.
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
require "digest/sha1"
|
||||
|
||||
module Devise
|
||||
# Implements a way of adding different encryptions.
|
||||
# The class should implement a self.digest method that taks the following params:
|
||||
# - password
|
||||
# - stretches: the number of times the encryption will be applied
|
||||
# - salt: the password salt as defined by devise
|
||||
# - pepper: Devise config option
|
||||
#
|
||||
module Encryptors
|
||||
# = Sha1
|
||||
# Uses the Sha1 hash algorithm to encrypt passwords.
|
||||
class Sha1
|
||||
class Sha1 < Base
|
||||
|
||||
# Gererates a default password digest based on stretches, salt, pepper and the
|
||||
# incoming password.
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
require "digest/sha2"
|
||||
|
||||
module Devise
|
||||
# Implements a way of adding different encryptions.
|
||||
# The class should implement a self.digest method that taks the following params:
|
||||
# - password
|
||||
# - stretches: the number of times the encryption will be applied
|
||||
# - salt: the password salt as defined by devise
|
||||
# - pepper: Devise config option
|
||||
#
|
||||
module Encryptors
|
||||
# = Sha512
|
||||
# Uses the Sha512 hash algorithm to encrypt passwords.
|
||||
class Sha512
|
||||
class Sha512 < Base
|
||||
|
||||
# Gererates a default password digest based on salt, pepper and the
|
||||
# incoming password.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# After each sign in, update sign in time, sign in count and sign in IP.
|
||||
Warden::Manager.after_authentication do |record, warden, options|
|
||||
Warden::Manager.after_set_user :event => [:authentication, :set_user] do |record, warden, options|
|
||||
scope = options[:scope]
|
||||
if Devise.mappings[scope].try(:trackable?) && warden.authenticated?(scope)
|
||||
old_current, new_current = record.current_sign_in_at, Time.now
|
||||
|
|
|
@ -29,7 +29,7 @@ module Devise
|
|||
def self.find_by_path(path)
|
||||
Devise.mappings.each_value do |mapping|
|
||||
route = path.split("/")[mapping.as_position]
|
||||
return mapping if mapping.as == route.to_sym
|
||||
return mapping if route && mapping.as == route.to_sym
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ module Devise
|
|||
@password = new_password
|
||||
|
||||
if @password.present?
|
||||
self.password_salt = Devise.friendly_token
|
||||
self.password_salt = self.class.encryptor_class.salt
|
||||
self.encrypted_password = password_digest(@password)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,6 @@ module Devise
|
|||
#
|
||||
# timeout: the time you want to timeout the user session without activity.
|
||||
module Timeoutable
|
||||
|
||||
def self.included(base)
|
||||
base.extend ClassMethods
|
||||
end
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
module Devise
|
||||
module Orm
|
||||
module DataMapper
|
||||
module InstanceMethods
|
||||
def save(flag=nil)
|
||||
if flag == false
|
||||
save!
|
||||
else
|
||||
super()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.included_modules_hook(klass, modules)
|
||||
klass.send :extend, self
|
||||
klass.send :include, InstanceMethods
|
||||
|
||||
yield
|
||||
|
||||
modules.each do |mod|
|
||||
|
@ -19,11 +31,24 @@ module Devise
|
|||
|
||||
# Hooks for confirmable
|
||||
def before_create(*args)
|
||||
before :create, *args
|
||||
wrap_hook(:before, *args)
|
||||
end
|
||||
|
||||
def after_create(*args)
|
||||
after :create, *args
|
||||
wrap_hook(:after, *args)
|
||||
end
|
||||
|
||||
def wrap_hook(action, *args)
|
||||
options = args.extract_options!
|
||||
|
||||
args.each do |callback|
|
||||
send action, :create, callback
|
||||
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
||||
def #{callback}
|
||||
super if #{options[:if] || true}
|
||||
end
|
||||
METHOD
|
||||
end
|
||||
end
|
||||
|
||||
# Add ActiveRecord like finder
|
||||
|
@ -39,15 +64,6 @@ module Devise
|
|||
end
|
||||
end
|
||||
|
||||
# In Datamapper, we need to call save! if we don't want to execute callbacks.
|
||||
def save(flag=nil)
|
||||
if flag == false
|
||||
save!
|
||||
else
|
||||
super()
|
||||
end
|
||||
end
|
||||
|
||||
# Tell how to apply schema methods. This automatically maps :limit to
|
||||
# :length and :null to :nullable.
|
||||
def apply_schema(name, type, options={})
|
||||
|
@ -64,4 +80,4 @@ module Devise
|
|||
end
|
||||
end
|
||||
|
||||
DataMapper::Model.send(:include, Devise::Models)
|
||||
DataMapper::Model.send(:include, Devise::Models)
|
|
@ -6,8 +6,8 @@ Rails.configuration.after_initialize do
|
|||
|
||||
# Adds Warden Manager to Rails middleware stack, configuring default devise
|
||||
# strategy and also the failure app.
|
||||
Rails.configuration.middleware.use Warden::Manager do |manager|
|
||||
Devise.configure_warden_manager(manager)
|
||||
Rails.configuration.middleware.use Warden::Manager do |config|
|
||||
Devise.configure_warden(config)
|
||||
end
|
||||
|
||||
I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), 'locales', 'en.yml'))
|
||||
|
|
|
@ -82,7 +82,7 @@ module ActionController::Routing
|
|||
resources.map!(&:to_sym)
|
||||
resources.each do |resource|
|
||||
mapping = Devise::Mapping.new(resource, options.dup)
|
||||
Warden::Manager.default_scope ||= mapping.name
|
||||
Devise.default_scope ||= mapping.name
|
||||
Devise.mappings[mapping.name] = mapping
|
||||
|
||||
route_options = mapping.route_options.merge(:path_prefix => mapping.raw_path, :name_prefix => "#{mapping.name}_")
|
||||
|
|
|
@ -7,17 +7,17 @@ module Devise
|
|||
end
|
||||
|
||||
# This is a Warden::Proxy customized for functional tests. It's meant to
|
||||
# some of Warden::Manager resposnabilities, as retrieving configuration
|
||||
# some of Warden::Manager responsibilities, as retrieving configuration
|
||||
# options and calling the FailureApp.
|
||||
class TestWarden < Warden::Proxy #:nodoc:
|
||||
attr_reader :controller
|
||||
|
||||
def initialize(controller)
|
||||
@controller = controller
|
||||
manager = Warden::Manager.new(nil) do |manager|
|
||||
Devise.configure_warden_manager(manager)
|
||||
manager = Warden::Manager.new(nil) do |config|
|
||||
Devise.configure_warden(config)
|
||||
end
|
||||
super(controller.request.env, manager.config)
|
||||
super(controller.request.env, manager)
|
||||
end
|
||||
|
||||
def authenticate!(*args)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module Devise
|
||||
VERSION = "0.7.4".freeze
|
||||
VERSION = "0.8.1".freeze
|
||||
end
|
||||
|
|
|
@ -7,43 +7,6 @@ module Devise
|
|||
end
|
||||
|
||||
class DeviseTest < ActiveSupport::TestCase
|
||||
class MockManager
|
||||
attr_accessor :failure_app
|
||||
attr_reader :default_strategies, :silence_missing_strategies
|
||||
|
||||
def silence_missing_strategies!
|
||||
@silence_missing_strategies = true
|
||||
end
|
||||
|
||||
def silence_missing_serializers!
|
||||
@silence_missing_serializers = true
|
||||
end
|
||||
|
||||
def default_strategies(*args)
|
||||
if args.empty?
|
||||
@default_strategies
|
||||
else
|
||||
@default_strategies = args
|
||||
end
|
||||
end
|
||||
|
||||
def default_serializers(*args)
|
||||
if args.empty?
|
||||
@default_serializers
|
||||
else
|
||||
@default_serializers = args
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'DeviseMailer.sender can be configured through Devise' do
|
||||
swap DeviseMailer, :sender => "foo@bar" do
|
||||
assert_equal "foo@bar", DeviseMailer.sender
|
||||
Devise.mailer_sender = "bar@foo"
|
||||
assert_equal "bar@foo", DeviseMailer.sender
|
||||
end
|
||||
end
|
||||
|
||||
test 'model options can be configured through Devise' do
|
||||
swap Devise, :confirm_within => 113, :pepper => "foo" do
|
||||
assert_equal 113, Devise.confirm_within
|
||||
|
@ -58,28 +21,25 @@ class DeviseTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test 'warden manager configuration' do
|
||||
manager = MockManager.new
|
||||
Devise.configure_warden_manager(manager)
|
||||
config = Warden::Config.new
|
||||
Devise.configure_warden(config)
|
||||
|
||||
assert_equal Devise::FailureApp, manager.failure_app
|
||||
assert_equal [:authenticatable], manager.default_strategies
|
||||
assert manager.silence_missing_strategies
|
||||
end
|
||||
|
||||
test 'warden default scope is set' do
|
||||
assert_equal :user, Warden::Manager.default_scope
|
||||
assert_equal Devise::FailureApp, config.failure_app
|
||||
assert_equal [:authenticatable], config.default_strategies
|
||||
assert_equal :user, config.default_scope
|
||||
assert config.silence_missing_strategies?
|
||||
assert config.silence_missing_serializers?
|
||||
end
|
||||
|
||||
test 'warden manager user configuration through a block' do
|
||||
begin
|
||||
@executed = false
|
||||
Devise.warden do |manager|
|
||||
Devise.warden do |config|
|
||||
@executed = true
|
||||
assert_kind_of MockManager, manager
|
||||
assert_kind_of Warden::Config, config
|
||||
end
|
||||
|
||||
manager = MockManager.new
|
||||
Devise.configure_warden_manager(manager)
|
||||
Devise.configure_warden(Warden::Config.new)
|
||||
assert @executed
|
||||
ensure
|
||||
Devise.clean_warden_config!
|
||||
|
|
|
@ -17,11 +17,12 @@ class Encryptors < ActiveSupport::TestCase
|
|||
encryptor = Devise::Encryptors::ClearanceSha1.digest('123mudar', nil, '65c58472c207c829f28c68619d3e3aefed18ab3f', nil)
|
||||
assert_equal clearance, encryptor
|
||||
end
|
||||
|
||||
|
||||
Devise::ENCRYPTORS_LENGTH.each do |key, value|
|
||||
test "should have length #{value} for #{key.inspect}" do
|
||||
swap Devise, :encryptor => key do
|
||||
assert_equal value, Devise::Encryptors.const_get(key.to_s.classify).digest('a', 2, 'b', 'c').size
|
||||
encryptor = Devise::Encryptors.const_get(key.to_s.classify)
|
||||
assert_equal value, encryptor.digest('a', 4, encryptor.salt, nil).size
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -154,12 +154,6 @@ class AuthenticationTest < ActionController::IntegrationTest
|
|||
assert_contain 'You need to sign in or sign up before continuing.'
|
||||
end
|
||||
|
||||
test 'render 404 on roles without permission' do
|
||||
get 'admin_area/password/new'
|
||||
assert_response :not_found
|
||||
assert_not_contain 'Send me reset password instructions'
|
||||
end
|
||||
|
||||
test 'return to default url if no other was requested' do
|
||||
sign_in_as_user
|
||||
|
||||
|
@ -221,4 +215,24 @@ class AuthenticationTest < ActionController::IntegrationTest
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'render 404 on roles without permission' do
|
||||
get 'admin_area/password/new'
|
||||
assert_response :not_found
|
||||
assert_not_contain 'Send me reset password instructions'
|
||||
end
|
||||
|
||||
test 'render 404 on roles without mapping' do
|
||||
get 'sign_in'
|
||||
assert_response :not_found
|
||||
assert_not_contain 'Sign in'
|
||||
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
|
||||
end
|
||||
end
|
||||
|
|
|
@ -60,6 +60,14 @@ class ConfirmationTest < ActionController::IntegrationTest
|
|||
assert warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
test 'increases sign count when signed in through confirmation' do
|
||||
user = create_user(:confirm => false)
|
||||
visit_user_confirmation_with_token(user.confirmation_token)
|
||||
|
||||
user.reload
|
||||
assert_equal 1, user.sign_in_count
|
||||
end
|
||||
|
||||
test 'not confirmed user with setup to block without confirmation should not be able to sign in' do
|
||||
swap Devise, :confirm_within => 0.days do
|
||||
sign_in_as_user(:confirm => false)
|
||||
|
|
|
@ -51,7 +51,7 @@ class TrackableHooksTest < ActionController::IntegrationTest
|
|||
assert_equal 2, user.sign_in_count
|
||||
end
|
||||
|
||||
test "does not update anything if user is signed out along the way" do
|
||||
test "does not update anything if user has signed out along the way" do
|
||||
swap Devise, :confirm_within => 0 do
|
||||
user = create_user(:confirm => false)
|
||||
sign_in_as_user
|
||||
|
|
|
@ -4,7 +4,7 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
|
|||
|
||||
def setup
|
||||
setup_mailer
|
||||
DeviseMailer.sender = 'test@example.com'
|
||||
Devise.mailer_sender = 'test@example.com'
|
||||
end
|
||||
|
||||
def user
|
||||
|
|
|
@ -4,7 +4,7 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
|
|||
|
||||
def setup
|
||||
setup_mailer
|
||||
DeviseMailer.sender = 'test@example.com'
|
||||
Devise.mailer_sender = 'test@example.com'
|
||||
end
|
||||
|
||||
def user
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
# Specifies gem version of Rails to use when vendor/rails is not present
|
||||
RAILS_GEM_VERSION = '2.3.5' unless defined? RAILS_GEM_VERSION
|
||||
DEVISE_ORM = :active_record unless defined? DEVISE_ORM
|
||||
|
||||
# Bootstrap the Rails environment, frameworks, and default configuration
|
||||
require File.join(File.dirname(__FILE__), 'boot')
|
||||
|
|
|
@ -18,4 +18,7 @@ ActiveSupport.use_standard_json_time_format = true
|
|||
|
||||
# Don't escape HTML entities in JSON, leave that for the #json_escape helper.
|
||||
# if you're including raw json in an HTML page.
|
||||
ActiveSupport.escape_html_entities_in_json = false
|
||||
ActiveSupport.escape_html_entities_in_json = false
|
||||
|
||||
# Clean up silencers
|
||||
Rails.backtrace_cleaner.remove_silencers!
|
|
@ -12,6 +12,7 @@ ActionController::Routing::Routes.draw do |map|
|
|||
map.connect '/admin_area/password/new', :controller => "passwords", :action => "new"
|
||||
map.admin_root '/admin_area/home', :controller => "admins", :action => "index"
|
||||
|
||||
map.connect '/sign_in', :controller => "sessions", :action => "new"
|
||||
map.connect ':controller/:action/:id'
|
||||
map.connect ':controller/:action/:id.:format'
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue