diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index 046419b3..f438312a 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,6 +1,10 @@ +* bug fix + * Fixed a bug where remember me module was not working properly + * enhancements * Moved encryption strategy into the Encryptors module to allow several algorithms (by github.com/mhfs) * Implemented encryptors for Clearance, Authlogic and Restful-Authentication (by github.com/mhfs) + * Added support for MongoMapper == 0.4.3 diff --git a/README.rdoc b/README.rdoc index a68345fc..a6df52d8 100644 --- a/README.rdoc +++ b/README.rdoc @@ -232,6 +232,11 @@ Take a look at our locale file to check all available messages. Devise implements encryption strategies for Clearance, Authlogic and Restful-Authentication. To make use of it set the desired encryptor in the encryptor initializer config option. You might also need to rename your encrypted password and salt columns to match Devises's one (encrypted_password and password_salt). +== Other ORMs + +Devise was made to work from scratch with ActiveRecord. However it currently supports MongoMapper as well. +To use it, just set Devise.orm or configure it in the initialization file (which is created with devise_install). + == TODO Please refer to TODO file. @@ -241,6 +246,7 @@ Please refer to TODO file. * José Valim (http://github.com/josevalim) * Carlos Antônio da Silva (http://github.com/carlosantoniodasilva) * Marcelo Silveira (http://github.com/mhfs) +* Cyril Mougel (http://github.com/shingara) == Bugs and Feedback diff --git a/generators/devise_install/templates/devise.rb b/generators/devise_install/templates/devise.rb index 8b36e0e8..99669710 100644 --- a/generators/devise_install/templates/devise.rb +++ b/generators/devise_install/templates/devise.rb @@ -25,6 +25,9 @@ Devise.setup do |config| # Configure the e-mail address which will be shown in DeviseMailer. # config.mailer_sender = "foo.bar@yourapp.com" + # Configure the ORM. Supports :active_record and :mongo_mapper + # config.orm = :active_record + # 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 diff --git a/lib/devise.rb b/lib/devise.rb index de98ddf7..14157bc5 100644 --- a/lib/devise.rb +++ b/lib/devise.rb @@ -58,8 +58,9 @@ module Devise mattr_accessor :mappings @@mappings = {} + # Stores the chosen ORM. mattr_accessor :orm - @@orm = 'active_record' + @@orm = :active_record class << self # Default way to setup Devise. Run script/generate devise_install to create @@ -110,13 +111,12 @@ module Devise @warden_config.try :call, manager end - ## - # The class to call with orm define - def model_orm - @@model_orm ||= "Devise::Orm::#{@@orm.camelize}".constantize + # The class of the configured ORM + def orm_class + Devise::Orm.const_get(@@orm.to_s.camelize.to_sym) end end end require 'devise/warden' -require 'devise/rails' +require 'devise/rails' \ No newline at end of file diff --git a/lib/devise/migrations.rb b/lib/devise/migrations.rb deleted file mode 100644 index 65dc3db5..00000000 --- a/lib/devise/migrations.rb +++ /dev/null @@ -1,57 +0,0 @@ -module Devise - # Helpers to migration: - # - # create_table :accounts do |t| - # t.authenticatable - # t.confirmable - # t.recoverable - # t.rememberable - # t.timestamps - # end - # - # However this method does not add indexes. If you need them, here is the declaration: - # - # add_index "accounts", ["email"], :name => "email", :unique => true - # add_index "accounts", ["confirmation_token"], :name => "confirmation_token", :unique => true - # add_index "accounts", ["reset_password_token"], :name => "reset_password_token", :unique => true - # - module Migrations - - # Creates email, encrypted_password and password_salt. - # - # == Options - # * :null when true, allow columns to be null - # * :encryptor The encryptor going to be used, necessary for setting the proper encrypter password length - # - def authenticatable(options={}) - null = options[:null] || false - encryptor = options[:encryptor] || :sha1 - - string :email, :null => null, :limit => 100 - string :encrypted_password, :null => null, :limit => Devise::ENCRYPTORS_LENGTH[encryptor] - string :password_salt, :null => null, :limit => 20 - end - - # Creates confirmation_token, confirmed_at and confirmation_sent_at. - # - def confirmable - string :confirmation_token, :limit => 20 - datetime :confirmed_at - datetime :confirmation_sent_at - end - - # Creates reset_password_token. - # - def recoverable - string :reset_password_token, :limit => 20 - end - - # Creates remember_token and remember_created_at. - # - def rememberable - string :remember_token, :limit => 20 - datetime :remember_created_at - end - - end -end diff --git a/lib/devise/models.rb b/lib/devise/models.rb index 445cf94a..97a1b9a8 100644 --- a/lib/devise/models.rb +++ b/lib/devise/models.rb @@ -92,8 +92,9 @@ module Devise # Convert new keys to methods which overwrites Devise defaults options.each { |key, value| send(:"#{key}=", value) } - send :include, Devise.model_orm - add_fields(modules) + + # Call specific hooks for each ORM + Devise.orm_class.included_modules_hook(self, devise_modules) end # Stores all modules included inside the model, so we are able to verify diff --git a/lib/devise/orm/active_record.rb b/lib/devise/orm/active_record.rb index 6efe3ec8..74de94da 100644 --- a/lib/devise/orm/active_record.rb +++ b/lib/devise/orm/active_record.rb @@ -1,17 +1,37 @@ module Devise module Orm + # This module contains some helpers and handle schema (migrations): + # + # create_table :accounts do |t| + # t.authenticatable + # t.confirmable + # t.recoverable + # t.rememberable + # t.timestamps + # end + # + # However this method does not add indexes. If you need them, here is the declaration: + # + # add_index "accounts", ["email"], :name => "email", :unique => true + # add_index "accounts", ["confirmation_token"], :name => "confirmation_token", :unique => true + # add_index "accounts", ["reset_password_token"], :name => "reset_password_token", :unique => true + # module ActiveRecord - include Devise::Orm::Base + # Required ORM hook. By default, do nothing on ActiveRecord. + def self.included_modules_hook(klass, modules) + end + + include Devise::Schema + + # Tell how to apply schema methods. + def apply_schema(name, type, options={}) + column name, type.to_s.downcase.to_sym, options + end end end end - -# Include alld devise definition about ActiveRecord -Rails.configuration.after_initialize do - if defined?(ActiveRecord) - ActiveRecord::Base.extend Devise::Models - ActiveRecord::Base.extend Devise::Orm::ActiveRecord - ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Devise::Migrations - end -end +if defined?(ActiveRecord) + ActiveRecord::Base.extend Devise::Models + ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Devise::Orm::ActiveRecord +end \ No newline at end of file diff --git a/lib/devise/orm/base.rb b/lib/devise/orm/base.rb deleted file mode 100644 index faea86b8..00000000 --- a/lib/devise/orm/base.rb +++ /dev/null @@ -1,9 +0,0 @@ -module Devise - module Orm - module Base - def add_fields(modules) - # Nothing happen because no modules - end - end - end -end diff --git a/lib/devise/orm/mongo_mapper.rb b/lib/devise/orm/mongo_mapper.rb index d64eee30..f6aba195 100644 --- a/lib/devise/orm/mongo_mapper.rb +++ b/lib/devise/orm/mongo_mapper.rb @@ -1,40 +1,23 @@ module Devise module Orm module MongoMapper + # Include attributes modules and set the proper ones. + def self.included_modules_hook(klass, modules) + klass.send :extend, self - include Devise::Orm::Base - - def authenticatable - key :email, String - key :encrypted_password, String - key :password_salt, String - end - - def confirmable - key :confirmation_token, String - key :confirmed_at, DateTime - key :confirmation_sent_at, DateTime - end - - def recoverable - key :reset_password_token, String - end - - def rememberable - key :remember_token, String - key :remember_created_at, DateTime - end - - ## - # Add all keys - def add_fields(modules) modules.each do |mod| - send(mod) + klass.send(mod) end end + + include Devise::Schema + + # Tell how to apply schema methods. + def apply_schema(name, type, options={}) + key name, type, options + end end end end -MongoMapper::Document::ClassMethods.send(:include, Devise::Models) -MongoMapper::Document::ClassMethods.send(:include, Devise::Orm::MongoMapper) +MongoMapper::Document::ClassMethods.send(:include, Devise::Models) \ No newline at end of file diff --git a/lib/devise/rails.rb b/lib/devise/rails.rb index 08ddeeec..f7817ef7 100644 --- a/lib/devise/rails.rb +++ b/lib/devise/rails.rb @@ -2,6 +2,8 @@ require 'devise/rails/routes' require 'devise/rails/warden_compat' Rails.configuration.after_initialize do + require "devise/orm/#{Devise.orm}" + # Adds Warden Manager to Rails middleware stack, configuring default devise # strategy and also the failure app. Rails.configuration.middleware.use Warden::Manager do |manager| @@ -12,6 +14,4 @@ Rails.configuration.after_initialize do Rails.configuration.middleware.use Devise::Middlewares::Rememberable I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), 'locales', 'en.yml')) - - require "devise/orm/#{Devise.orm}" end diff --git a/lib/devise/schema.rb b/lib/devise/schema.rb new file mode 100644 index 00000000..dc8ab6a9 --- /dev/null +++ b/lib/devise/schema.rb @@ -0,0 +1,43 @@ +module Devise + # Holds devise schema information. To use it, just include its methods + # and overwrite the apply_schema method. + module Schema + + # Creates email, encrypted_password and password_salt. + # + # == Options + # * :null when true, allow columns to be null + # * :encryptor The encryptor going to be used, necessary for setting the proper encrypter password length + def authenticatable(options={}) + null = options[:null] || false + encryptor = options[:encryptor] || :sha1 + + apply_schema :email, String, :null => null, :limit => 100 + apply_schema :encrypted_password, String, :null => null, :limit => Devise::ENCRYPTORS_LENGTH[encryptor] + apply_schema :password_salt, String, :null => null, :limit => 20 + end + + # Creates confirmation_token, confirmed_at and confirmation_sent_at. + def confirmable + apply_schema :confirmation_token, String, :limit => 20 + apply_schema :confirmed_at, DateTime + apply_schema :confirmation_sent_at, DateTime + end + + # Creates reset_password_token. + def recoverable + apply_schema :reset_password_token, String, :limit => 20 + end + + # Creates remember_token and remember_created_at. + def rememberable + apply_schema :remember_token, String, :limit => 20 + apply_schema :remember_created_at, DateTime + end + + # Overwrite with specific modification to create your own schema. + def apply_schema(name, tupe, options={}) + raise NotImplementedError + end + end +end