Skip to content

Commit

Permalink
Keep modules definition in a different file.
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Mar 3, 2010
1 parent af39afc commit 0386275
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 147 deletions.
3 changes: 2 additions & 1 deletion devise.gemspec
Expand Up @@ -9,7 +9,7 @@ Gem::Specification.new do |s|

s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
s.authors = ["Jos\303\251 Valim", "Carlos Ant\303\264nio"]
s.date = %q{2010-02-24}
s.date = %q{2010-03-03}
s.description = %q{Flexible authentication solution for Rails with Warden}
s.email = %q{contact@plataformatec.com.br}
s.extra_rdoc_files = [
Expand Down Expand Up @@ -74,6 +74,7 @@ Gem::Specification.new do |s|
"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/mongo_mapper.rb",
Expand Down
191 changes: 79 additions & 112 deletions lib/devise.rb
@@ -1,6 +1,5 @@
module Devise
autoload :FailureApp, 'devise/failure_app'
autoload :Models, 'devise/models'
autoload :Schema, 'devise/schema'
autoload :TestHelpers, 'devise/test_helpers'

Expand All @@ -21,40 +20,17 @@ module Encryptors
autoload :Sha1, 'devise/encryptors/sha1'
end

ALL = []

# Authentication ones first
ALL.push :authenticatable, :http_authenticatable, :token_authenticatable, :rememberable

# Misc after
ALL.push :recoverable, :registerable, :validatable

# The ones which can sign out after
ALL.push :activatable, :confirmable, :lockable, :timeoutable

# Stats for last, so we make sure the user is really signed in
ALL.push :trackable

# Maps controller names to devise modules.
CONTROLLERS = {
:authenticatable => :sessions,
:token_authenticatable => :sessions,
:recoverable => :passwords,
:confirmable => :confirmations,
:registerable => :registrations,
:lockable => :unlocks
}

# Routes for generating url helpers.
ROUTES = [:session, :password, :confirmation, :registration, :unlock]

STRATEGIES = [:rememberable, :http_authenticatable, :token_authenticatable, :authenticatable]
# Constants which holds devise configuration for extensions. Those should
# not be modified by the "end user".
ALL = []
CONTROLLERS = {}
ROUTES = []
STRATEGIES = []
FLASH_MESSAGES = [:unauthenticated]

# True values used to check params
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE']

# Maps the messages types that are used in flash message.
FLASH_MESSAGES = [:unauthenticated, :unconfirmed, :invalid, :invalid_token, :timeout, :inactive, :locked]

# Declare encryptors length which are used in migrations.
ENCRYPTORS_LENGTH = {
:sha1 => 40,
Expand Down Expand Up @@ -143,99 +119,90 @@ module Encryptors
mattr_accessor :http_authentication_realm
@@http_authentication_realm = "Application"

class << self
# Default way to setup Devise. Run script/generate devise_install to create
# a fresh initializer with all configuration values.
def setup
yield self
end
# Default way to setup Devise. Run rails generate devise_install to create
# a fresh initializer with all configuration values.
def self.setup
yield self
end

# TODO Remove me on 1.1.0 final
def orm=(value)
ActiveSupport::Deprecation.warn "Devise.orm= and config.orm= are deprecated. " <<
"Just load \"devise/orm/\#{ORM_NAME}\" if Devise supports your ORM"
# Make Devise aware of an 3rd party Devise-module. For convenience.
#
# == Options:
#
# +strategy+ - Boolean value representing if this module got a custom *strategy*.
# Default is +false+. Note: Devise will auto-detect this in such case if this is true.
# +model+ - String representing the load path to a custom *model* for this module (to autoload.)
# Default is +nil+ (i.e. +false+).
# +controller+ - Symbol representing the name of an exisiting or custom *controller* for this module.
# Default is +nil+ (i.e. +false+).
# +route+ - Symbol representing the named *router* helper for this module.
# Default is +nil+ (i.e. +false+).
# +flash+ - Symbol representing the *flash messages* used by this helper.
# Default is +nil+ (i.e. +false+).
#
# == Examples:
#
# Devise.add_module(:party_module)
# Devise.add_module(:party_module, :strategy => true, :controller => :sessions)
# Devise.add_module(:party_module, :autoload => 'party_module/model')
#
def self.add_module(module_name, options = {})
ALL << module_name
options.assert_valid_keys(:strategy, :model, :controller, :route, :flash)

{ :strategy => STRATEGIES, :flash => FLASH_MESSAGES, :route => ROUTES }.each do |key, value|
next unless options[key]
name = (options[key] == true ? module_name : options[key])
value.unshift(name) unless value.include?(name)
end

# TODO Remove me on 1.1.0 final
def default_url_options
ActiveSupport::Deprecation.warn "Devise.default_url_options and config.default_url_options are deprecated. " <<
"Just modify ApplicationController.default_url_options and Devise will automatically pick it up"
if options[:controller]
Devise::CONTROLLERS[module_name] = options[:controller].to_sym
end

# Sets warden configuration using a block that will be invoked on warden
# initialization.
#
# Devise.initialize do |config|
# config.confirm_within = 2.days
#
# config.warden do |manager|
# # Configure warden to use other strategies, like oauth.
# manager.oauth(:twitter)
# end
# end
def warden(&block)
@warden_config = block
if options[:model]
model_path = (options[:model] == true ? "devise/models/#{module_name}" : options[:model])
Devise::Models.send(:autoload, module_name.to_s.camelize.to_sym, model_path)
end

# A method used internally to setup warden manager from the Rails initialize
# block.
def configure_warden(config) #:nodoc:
config.default_strategies *Devise::STRATEGIES
config.failure_app = Devise::FailureApp
config.silence_missing_strategies!
config.default_scope = Devise.default_scope
Devise::Mapping.register module_name
end

# If the user provided a warden hook, call it now.
@warden_config.try :call, config
end
# Sets warden configuration using a block that will be invoked on warden
# initialization.
#
# Devise.initialize do |config|
# config.confirm_within = 2.days
#
# config.warden do |manager|
# # Configure warden to use other strategies, like oauth.
# manager.oauth(:twitter)
# end
# end
def self.warden(&block)
@warden_config = block
end

# Generate a friendly string randomically to be used as token.
def friendly_token
ActiveSupport::SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
end
# A method used internally to setup warden manager from the Rails initialize
# block.
def self.configure_warden(config) #:nodoc:
config.default_strategies *Devise::STRATEGIES
config.failure_app = Devise::FailureApp
config.silence_missing_strategies!
config.default_scope = Devise.default_scope

# Make Devise aware of an 3rd party Devise-module. For convenience.
#
# == Options:
#
# +strategy+ - Boolean value representing if this module got a custom *strategy*.
# Default is +false+. Note: Devise will auto-detect this in such case if this is true.
# +model+ - String representing a load path to a custom *model* for this module (to autoload).
# Default is +nil+ (i.e. +false+).
# +controller+ - Symbol representing a name of an exisiting or custom *controller* for this module.
# Default is +nil+ (i.e. +false+).
#
# == Examples:
#
# Devise.add_module(:party_module)
# Devise.add_module(:party_module, :strategy => true, :controller => :sessions)
# Devise.add_module(:party_module, :model => 'party_module/model')
#
def add_module(module_name, options = {})
Devise::ALL.unshift module_name unless Devise::ALL.include?(module_name)
Devise::STRATEGIES.unshift module_name if options[:strategy] && !Devise::STRATEGIES.include?(module_name)

if options[:controller]
Devise::CONTROLLERS[module_name] = options[:controller].to_sym
end

if options[:model]
Devise::Models.module_eval do
autoload :"#{module_name.to_s.classify}", options[:model]
end
end

Devise::Mapping.register module_name
end
# If the user provided a warden hook, call it now.
@warden_config.try :call, config
end
end

begin
require 'warden'
rescue
gem 'warden'
require 'warden'
# Generate a friendly string randomically to be used as token.
def self.friendly_token
ActiveSupport::SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n")
end
end

require 'warden'
require 'devise/mapping'
require 'devise/models'
require 'devise/modules'
require 'devise/rails'
15 changes: 6 additions & 9 deletions lib/devise/mapping.rb
Expand Up @@ -111,15 +111,12 @@ def path
# self.modules.include?(:confirmable)
# end
#
def self.register(*modules)
modules.each do |m|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{m}?
self.modules.include?(:#{m})
end
METHOD
end
def self.register(m)
class_eval <<-METHOD, __FILE__, __LINE__ + 1
def #{m}?
self.modules.include?(:#{m})
end
METHOD
end
Devise::Mapping.register *ALL
end
end
11 changes: 0 additions & 11 deletions lib/devise/models.rb
@@ -1,16 +1,5 @@
module Devise
module Models
autoload :Activatable, 'devise/models/activatable'
autoload :Authenticatable, 'devise/models/authenticatable'
autoload :Confirmable, 'devise/models/confirmable'
autoload :Lockable, 'devise/models/lockable'
autoload :Recoverable, 'devise/models/recoverable'
autoload :Rememberable, 'devise/models/rememberable'
autoload :Registerable, 'devise/models/registerable'
autoload :Timeoutable, 'devise/models/timeoutable'
autoload :Trackable, 'devise/models/trackable'
autoload :Validatable, 'devise/models/validatable'

# Creates configuration values for Devise and for the given module.
#
# Devise::Models.config(Devise::Authenticable, :stretches, 10)
Expand Down
25 changes: 25 additions & 0 deletions lib/devise/modules.rb
@@ -0,0 +1,25 @@
require 'active_support/core_ext/object/with_options'

Devise.with_options :model => true do |d|
# Strategies first
d.with_options :strategy => true do |s|
s.add_module :authenticatable, :controller => :sessions, :flash => :invalid, :route => :session
s.add_module :http_authenticatable
s.add_module :token_authenticatable, :controller => :sessions, :flash => :invalid_token, :route => :session
s.add_module :rememberable
end

# Misc after
d.add_module :recoverable, :controller => :passwords, :route => :password
d.add_module :registerable, :controller => :registrations, :route => :registration
d.add_module :validatable

# The ones which can sign out after
d.add_module :activatable, :flash => :inactive
d.add_module :confirmable, :controller => :confirmations, :flash => :unconfirmed, :route => :confirmation
d.add_module :lockable, :controller => :unlocks, :flash => :locked, :route => :unlock
d.add_module :timeoutable, :flash => :timeout

# Stats for last, so we make sure the user is really signed in
d.add_module :trackable
end
7 changes: 3 additions & 4 deletions test/devise_test.rb
Expand Up @@ -25,7 +25,7 @@ class DeviseTest < ActiveSupport::TestCase
Devise.configure_warden(config)

assert_equal Devise::FailureApp, config.failure_app
assert_equal [:rememberable, :http_authenticatable, :token_authenticatable, :authenticatable], config.default_strategies
assert_equal [:rememberable, :token_authenticatable, :http_authenticatable, :authenticatable], config.default_strategies
assert_equal :user, config.default_scope
assert config.silence_missing_strategies?
end
Expand Down Expand Up @@ -58,10 +58,9 @@ class DeviseTest < ActiveSupport::TestCase
Devise::STRATEGIES.delete(:banana)

assert_nothing_raised(Exception) { Devise.add_module(:kivi, :controller => :fruits) }
assert_not_nil Devise::CONTROLLERS[:fruits]
assert_equal 1, Devise::CONTROLLERS[:fruits].select { |v| v == :kivi }.size
assert_equal :fruits, Devise::CONTROLLERS[:kivi]
Devise::ALL.delete(:kivi)
Devise::CONTROLLERS.delete(:fruits)
Devise::CONTROLLERS.delete(:kivi)

assert_nothing_raised(Exception) { Devise.add_module(:authenticatable_again, :model => 'devise/model/authenticatable') }
assert defined?(Devise::Models::AuthenticatableAgain)
Expand Down
20 changes: 10 additions & 10 deletions test/mapping_test.rb
Expand Up @@ -5,7 +5,7 @@ class MappingTest < ActiveSupport::TestCase
test 'store options' do
mapping = Devise.mappings[:user]
assert_equal User, mapping.to
assert_equal User.devise_modules, mapping.for
assert_equal User.devise_modules, mapping.modules
assert_equal :users, mapping.as
end

Expand All @@ -18,15 +18,15 @@ class MappingTest < ActiveSupport::TestCase
end

test 'allows a controller depending on the mapping' do
mapping = Devise.mappings[:user]
assert mapping.allows?(:sessions)
assert mapping.allows?(:confirmations)
assert mapping.allows?(:passwords)

mapping = Devise.mappings[:admin]
assert mapping.allows?(:sessions)
assert_not mapping.allows?(:confirmations)
assert_not mapping.allows?(:passwords)
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/passwords")
end

test 'find mapping by path' do
Expand Down

0 comments on commit 0386275

Please sign in to comment.