Skip to content
This repository
Browse code

Merge and fix conflicts.

  • Loading branch information...
commit 32991e13c43bc7f07a18cedbe75e85808368426c 2 parents d2fa737 + c4764c9
Marcelo Silveira authored January 09, 2010

Showing 37 changed files with 255 additions and 225 deletions. Show diff stats Hide diff stats

  1. 28  CHANGELOG.rdoc
  2. 56  README.rdoc
  3. 2  Rakefile
  4. 13  app/models/devise_mailer.rb
  5. 7  generators/devise/devise_generator.rb
  6. 22  generators/devise/templates/README
  7. 2  generators/devise_install/devise_install_generator.rb
  8. 18  generators/devise_install/templates/README
  9. 24  generators/devise_install/templates/devise.rb
  10. 41  lib/devise.rb
  11. 6  lib/devise/controllers/helpers.rb
  12. 9  lib/devise/encryptors/authlogic_sha512.rb
  13. 20  lib/devise/encryptors/base.rb
  14. 21  lib/devise/encryptors/bcrypt.rb
  15. 9  lib/devise/encryptors/clearance_sha1.rb
  16. 9  lib/devise/encryptors/restful_authentication_sha1.rb
  17. 9  lib/devise/encryptors/sha1.rb
  18. 9  lib/devise/encryptors/sha512.rb
  19. 2  lib/devise/hooks/trackable.rb
  20. 2  lib/devise/mapping.rb
  21. 2  lib/devise/models/authenticatable.rb
  22. 1  lib/devise/models/timeoutable.rb
  23. 40  lib/devise/orm/data_mapper.rb
  24. 4  lib/devise/rails.rb
  25. 2  lib/devise/rails/routes.rb
  26. 8  lib/devise/test_helpers.rb
  27. 2  lib/devise/version.rb
  28. 60  test/devise_test.rb
  29. 5  test/encryptors_test.rb
  30. 26  test/integration/authenticatable_test.rb
  31. 8  test/integration/confirmable_test.rb
  32. 2  test/integration/trackable_test.rb
  33. 2  test/mailers/confirmation_instructions_test.rb
  34. 2  test/mailers/reset_password_instructions_test.rb
  35. 1  test/rails_app/config/environment.rb
  36. 5  test/rails_app/config/initializers/new_rails_defaults.rb
  37. 1  test/rails_app/config/routes.rb
28  CHANGELOG.rdoc
Source Rendered
... ...
@@ -1,4 +1,32 @@
1 1
 * enhancements
  2
+  * Move salt to encryptors
  3
+
  4
+* bug fix
  5
+  * Bcrypt generator was not being loaded neither setting the proper salt
  6
+
  7
+== 0.8.0
  8
+
  9
+* enhancements
  10
+  * Warden 0.8.0 compatibility
  11
+  * Add an easy for map.connect "sign_in", :controller => "sessions", :action => "new" to work
  12
+  * Added :bcrypt encryptor (by github.com/capotej)
  13
+
  14
+* bug fix
  15
+  * sign_in_count is also increased when user signs in via password change, confirmation, etc..
  16
+  * More DataMapper compatibility (by github.com/lancecarlson)
  17
+
  18
+* deprecation
  19
+  * Removed DeviseMailer.sender
  20
+
  21
+== 0.7.5
  22
+
  23
+* enhancements
  24
+  * Set a default value for mailer to avoid find_template issues
  25
+  * Add models configuration to MongoMapper::EmbeddedDocument as well
  26
+
  27
+== 0.7.4
  28
+
  29
+* enhancements
2 30
   * Extract Activatable from Confirmable
3 31
   * Decouple Serializers from Devise modules
4 32
   * Devise::Lockable
56  README.rdoc
Source Rendered
@@ -7,23 +7,26 @@ Devise is a flexible authentication solution for Rails based on Warden. It:
7 7
 * Allows you to have multiple roles (or models/scopes) signed in at the same time;
8 8
 * Is based on a modularity concept: use just what you really need.
9 9
 
10  
-Right now it's composed of seven mainly modules:
  10
+Right now it's composed of six modules included by default when you invoke "devise :all" in your models:
11 11
 
12 12
 * Authenticatable: responsible for encrypting password and validating authenticity of a user while signing in.
13 13
 * Confirmable: responsible for verifying whether an account is already confirmed to sign in, and to send emails with confirmation instructions.
14 14
 * Recoverable: takes care of reseting the user password and send reset instructions.
15 15
 * Rememberable: manages generating and clearing token for remember the user from a saved cookie.
16  
-* Activatable: if you need to activate accounts by other means, which are not through confirmation, use this module.
17  
-* Timeoutable: expires sessions without activity in a certain period of time.
18 16
 * Trackable: tracks sign in count, timestamps and ip.
19 17
 * Validatable: creates all needed validations for email and password. It's totally optional, so you're able to to customize validations by yourself.
  18
+
  19
+And it also includes the optional modules:
  20
+
  21
+* Activatable: if you need to activate accounts by other means, which are not through confirmation, use this module.
  22
+* Timeoutable: expires sessions without activity in a certain period of time.
20 23
 * Lockable: takes care of locking an account based on the number of failed sign in attempts. Handles unlock via expire and email.
21 24
 
22 25
 There's an example application using Devise at http://github.com/plataformatec/devise_example .
23 26
 
24 27
 == Dependencies
25 28
 
26  
-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).
  29
+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).
27 30
 
28 31
 == Installation
29 32
 
@@ -48,13 +51,13 @@ Run the generator:
48 51
 
49 52
 	ruby script/generate devise_install
50 53
 
51  
-And you're ready to go.
  54
+And you're ready to go. The generator will install an initializer which describes Devise's configuration options. Be sure to take a look.
52 55
 
53 56
 == Basic Usage
54 57
 
55 58
 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.
56 59
 
57  
-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.
  60
+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.
58 61
 
59 62
 We're assuming here you want a User model. First of all you have to setup a migration with the following fields:
60 63
 
@@ -63,6 +66,7 @@ We're assuming here you want a User model. First of all you have to setup a migr
63 66
     t.confirmable
64 67
     t.recoverable
65 68
     t.rememberable
  69
+    t.trackable
66 70
     t.lockable
67 71
     t.timestamps
68 72
   end
@@ -74,35 +78,21 @@ You may also want to add some indexes to improve performance:
74 78
   add_index :your_table, :reset_password_token  # for recoverable
75 79
   add_index :your_table, :unlock_token          # for lockable
76 80
 
77  
-Now let's setup a User model adding the devise line to have your authentication working:
  81
+Now let's setup a User model adding the devise line:
78 82
 
79 83
   class User < ActiveRecord::Base
80  
-    devise :authenticatable
  84
+    devise :all
81 85
   end
82 86
 
83  
-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.
84  
-
85  
-You could also include the other devise modules as below:
86  
-
87  
-  # Include only authenticatable stuff
88  
-  devise :authenticatable
89  
-
90  
-  # Include authenticatable + confirmable
91  
-  devise :authenticatable, :confirmable
92  
-
93  
-  # Include authenticatable + recoverable + rememberable
94  
-  devise :authenticatable, :recoverable, :rememberable
95  
-
96  
-  # Include authenticatable + timeoutable
97  
-  devise :authenticatable, :timeoutable
  87
+This will include the six default modules outlined at the beginning. You can exclude and remove any module at will:
98 88
 
99  
-  # Include all of them
100  
-  devise :all
  89
+  # Include timeout configuration
  90
+  devise :all, :timeoutable
101 91
 
102  
-  # Include all except recoverable
103  
-  devise :all, :except => :recoverable
  92
+  # Remove validations
  93
+  devise :all, :except => :validatable
104 94
 
105  
-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.
  95
+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.
106 96
 
107 97
 == Model configuration
108 98
 
@@ -148,26 +138,26 @@ After signing in a user, confirming it's account or updating it's password, devi
148 138
 
149 139
 You can also overwrite after_sign_in_path_for and after_sign_out_path_for to customize better your redirect hooks.
150 140
 
151  
-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:
  141
+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:
152 142
 
153  
-  DeviseMailer.sender = "no-reply@yourapp.com"
154 143
   config.action_mailer.default_url_options = { :host => 'localhost:3000' }
155 144
 
156 145
 == Views
157 146
 
158  
-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.
  147
+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.
159 148
 
160 149
 == Tidying up
161 150
 
162  
-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:
  151
+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:
163 152
 
164 153
   # Create a migration with the required fields
165 154
   create_table :admins do |t|
166 155
     t.authenticatable
  156
+    t.trackable
167 157
   end
168 158
 
169 159
   # Inside your Admin model
170  
-  devise :authenticatable, :validatable
  160
+  devise :authenticatable, :trackable, :timeoutable
171 161
 
172 162
   # Inside your routes
173 163
   map.devise_for :admin
2  Rakefile
@@ -44,7 +44,7 @@ begin
44 44
     s.description = "Flexible authentication solution for Rails with Warden"
45 45
     s.authors = ['José Valim', 'Carlos Antônio']
46 46
     s.files =  FileList["[A-Z]*", "{app,config,generators,lib}/**/*", "init.rb"]
47  
-    s.add_dependency("warden", "~> 0.6.4")
  47
+    s.add_dependency("warden", "~> 0.8.1")
48 48
   end
49 49
 
50 50
   Jeweler::GemcutterTasks.new
13  app/models/devise_mailer.rb
... ...
@@ -1,16 +1,5 @@
1 1
 class DeviseMailer < ::ActionMailer::Base
2 2
 
3  
-  # Sets who is sending the e-mail
4  
-  def self.sender=(value)
5  
-    @@sender = value
6  
-  end
7  
-
8  
-  # Reads who is sending the e-mail
9  
-  def self.sender
10  
-    @@sender
11  
-  end
12  
-  self.sender = nil
13  
-
14 3
   # Deliver confirmation instructions when the user is created or its email is
15 4
   # updated, and also when confirmation is manually requested
16 5
   def confirmation_instructions(record)
@@ -34,7 +23,7 @@ def setup_mail(record, key)
34 23
       raise "Invalid devise resource #{record}" unless mapping
35 24
 
36 25
       subject      translate(mapping, key)
37  
-      from         self.class.sender
  26
+      from         Devise.mailer_sender
38 27
       recipients   record.email
39 28
       sent_on      Time.now
40 29
       content_type 'text/html'
7  generators/devise/devise_generator.rb
@@ -4,18 +4,11 @@ class DeviseGenerator < Rails::Generator::NamedBase
4 4
 
5 5
   def manifest
6 6
     record do |m|
7  
-      # Model
8 7
       m.directory(File.join('app', 'models', class_path))
9 8
       m.template 'model.rb', File.join('app', 'models', "#{file_path}.rb")
10 9
 
11  
-      # Migration
12 10
       m.migration_template 'migration.rb', 'db/migrate', :migration_file_name => "devise_create_#{table_name}"
13  
-
14  
-      # Routing
15 11
       m.route_devise table_name
16  
-
17  
-      # Readme
18  
-      m.readme "README"
19 12
     end
20 13
   end
21 14
 
22  generators/devise/templates/README
... ...
@@ -1,22 +0,0 @@
1  
-
2  
-================================================================================
3  
-
4  
-Some setup you must do manually if you haven't yet:
5  
-
6  
-1. Setup defaut url options for your specific environment. Here is an example of development environment:
7  
-
8  
-    config.action_mailer.default_url_options = { :host => 'localhost:3000' }
9  
-
10  
-It's a Rails required configuration. In production it must be the actual host your application is deployed to.
11  
-
12  
-2. Setup default sender for mails. In config/environment.rb:
13  
-
14  
-    DeviseMailer.sender = "test@example.com"
15  
-
16  
-You can also configure this value by running script/generate devise_install and setting config.mailer_sender,
17  
-
18  
-3. Ensure you have defined root_url to *something* in your config/routes.rb:
19  
-
20  
-    map.root :controller => 'home'
21  
-
22  
-================================================================================
2  generators/devise_install/devise_install_generator.rb
@@ -7,6 +7,8 @@ def manifest
7 7
 
8 8
       m.directory "config/locales"
9 9
       m.file      "../../../lib/devise/locales/en.yml", "config/locales/devise.en.yml"
  10
+
  11
+      m.readme "README"
10 12
     end
11 13
   end
12 14
 
18  generators/devise_install/templates/README
... ...
@@ -0,0 +1,18 @@
  1
+
  2
+===============================================================================
  3
+
  4
+Some setup you must do manually if you haven't yet:
  5
+
  6
+  1. Setup default url options for your specific environment. Here is an
  7
+     example of development environment:
  8
+
  9
+       config.action_mailer.default_url_options = { :host => 'localhost:3000' }
  10
+
  11
+     This is a required Rails configuration. In production is must be the
  12
+     actual host of your application
  13
+
  14
+  2. Ensure you have defined root_url to *something* in your config/routes.rb:
  15
+
  16
+       map.root :controller => 'home'
  17
+
  18
+===============================================================================
24  generators/devise_install/templates/devise.rb
@@ -10,6 +10,9 @@
10 10
   # to check the docs for a complete set.
11 11
   config.all = [:authenticatable, :confirmable, :recoverable, :rememberable, :trackable, :validatable, :lockable]
12 12
 
  13
+  # Configure the e-mail address which will be shown in DeviseMailer.
  14
+  config.mailer_sender = "please-change-me@config-initializers-devise.com"
  15
+
13 16
   # Invoke `rake secret` and use the printed value to setup a pepper to generate
14 17
   # the encrypted password. By default no pepper is used.
15 18
   # config.pepper = "rake secret output"
@@ -18,10 +21,10 @@
18 21
   # config.stretches = 10
19 22
 
20 23
   # Define which will be the encryption algorithm. Supported algorithms are :sha1
21  
-  # (default) and :sha512. Devise also supports encryptors from others authentication
22  
-  # frameworks as :clearance_sha1, :authlogic_sha512 (then you should set stretches
23  
-  # above to 20 for default behavior) and :restful_authentication_sha1 (then you
24  
-  # should set stretches to 10, and copy REST_AUTH_SITE_KEY to pepper)
  24
+  # (default), :sha512 and :bcrypt. Devise also supports encryptors from others
  25
+  # authentication tools as :clearance_sha1, :authlogic_sha512 (then you should set
  26
+  # stretches above to 20 for default behavior) and :restful_authentication_sha1
  27
+  # (then you should set stretches to 10, and copy REST_AUTH_SITE_KEY to pepper)
25 28
   # config.encryptor = :sha1
26 29
 
27 30
   # Configure which keys are used when authenticating an user. By default is
@@ -42,9 +45,6 @@
42 45
   # time the user will be asked for credentials again.
43 46
   # config.timeout_in = 10.minutes
44 47
 
45  
-  # Configure the e-mail address which will be shown in DeviseMailer.
46  
-  # config.mailer_sender = "foo.bar@yourapp.com"
47  
-
48 48
   # Load and configure the ORM. Supports :active_record, :data_mapper and :mongo_mapper.
49 49
   # require 'devise/orm/mongo_mapper'
50 50
   # config.orm = :mongo_mapper
@@ -66,6 +66,16 @@
66 66
   # Time interval to unlock the account if :time is enabled as unlock_strategy.
67 67
   # config.unlock_in = 1.hour
68 68
 
  69
+  # By default, devise detects the role accessed based on the url. So whenever
  70
+  # accessing "/users/sign_in", it knows you are accessing an User. This makes
  71
+  # routes as "/sign_in" not possible, unless you tell Devise to use the default
  72
+  # scope, setting true below.
  73
+  # config.use_default_scope = true
  74
+
  75
+  # Configure the default scope used by Devise. By default it's the first devise
  76
+  # role declared in your routes.
  77
+  # config.default_scope = :user
  78
+
69 79
   # If you want to use other strategies, that are not (yet) supported by Devise,
70 80
   # you can configure them inside the config.warden block. The example below
71 81
   # allows you to setup OAuth, using http://github.com/roman/warden_oauth
41  lib/devise.rb
@@ -11,6 +11,8 @@ module Controllers
11 11
   end
12 12
 
13 13
   module Encryptors
  14
+    autoload :Base, 'devise/encryptors/base'
  15
+    autoload :Bcrypt, 'devise/encryptors/bcrypt'
14 16
     autoload :AuthlogicSha512, 'devise/encryptors/authlogic_sha512'
15 17
     autoload :AuthlogicSha1, 'devise/encryptors/authlogic_sha1'
16 18
     autoload :RestfulAuthenticationSha1, 'devise/encryptors/restful_authentication_sha1'
@@ -48,7 +50,8 @@ module Orm
48 50
     :sha512 => 128,
49 51
     :clearance_sha1 => 40,
50 52
     :restful_authentication_sha1 => 40,
51  
-    :authlogic_sha512 => 128
  53
+    :authlogic_sha512 => 128,
  54
+    :bcrypt => 60
52 55
   }
53 56
 
54 57
   # Email regex used to validate email formats. Retrieved from authlogic.
@@ -117,6 +120,18 @@ module Orm
117 120
   mattr_accessor :unlock_in
118 121
   @@unlock_in = 1.hour
119 122
 
  123
+  # Tell when to use the default scope, if one cannot be found from routes.
  124
+  mattr_accessor :use_default_scope
  125
+  @@use_default_scope
  126
+
  127
+  # The default scope which is used by warden.
  128
+  mattr_accessor :default_scope
  129
+  @@default_scope = nil
  130
+
  131
+  # Address which sends Devise e-mails.
  132
+  mattr_accessor :mailer_sender
  133
+  @@mailer_sender
  134
+
120 135
   class << self
121 136
     # Default way to setup Devise. Run script/generate devise_install to create
122 137
     # a fresh initializer with all configuration values.
@@ -124,12 +139,6 @@ def setup
124 139
       yield self
125 140
     end
126 141
 
127  
-    # Sets the sender in DeviseMailer.
128  
-    def mailer_sender=(value)
129  
-      DeviseMailer.sender = value
130  
-    end
131  
-    alias :sender= :mailer_sender=
132  
-
133 142
     # Sets warden configuration using a block that will be invoked on warden
134 143
     # initialization.
135 144
     #
@@ -152,15 +161,16 @@ def default_url_options(&block)
152 161
 
153 162
     # A method used internally to setup warden manager from the Rails initialize
154 163
     # block.
155  
-    def configure_warden_manager(manager) #:nodoc:
156  
-      manager.default_strategies *Devise::STRATEGIES
157  
-      manager.default_serializers *Devise::SERIALIZERS
158  
-      manager.failure_app = Devise::FailureApp
159  
-      manager.silence_missing_strategies!
160  
-      manager.silence_missing_serializers!
  164
+    def configure_warden(config) #:nodoc:
  165
+      config.default_strategies *Devise::STRATEGIES
  166
+      config.default_serializers *Devise::SERIALIZERS
  167
+      config.failure_app = Devise::FailureApp
  168
+      config.silence_missing_strategies!
  169
+      config.silence_missing_serializers!
  170
+      config.default_scope = Devise.default_scope
161 171
 
162 172
       # If the user provided a warden hook, call it now.
163  
-      @warden_config.try :call, manager
  173
+      @warden_config.try :call, config
164 174
     end
165 175
 
166 176
     # The class of the configured ORM
@@ -185,6 +195,5 @@ def friendly_token
185 195
 # Clear some Warden default configuration which will be overwritten
186 196
 Warden::Strategies.clear!
187 197
 Warden::Serializers.clear!
188  
-Warden::Manager.default_scope = nil
189 198
 
190  
-require 'devise/rails'
  199
+require 'devise/rails'
6  lib/devise/controllers/helpers.rb
@@ -35,7 +35,11 @@ def resource_class
35 35
 
36 36
       # Attempt to find the mapped route for devise based on request path
37 37
       def devise_mapping
38  
-        @devise_mapping ||= Devise::Mapping.find_by_path(request.path)
  38
+        @devise_mapping ||= begin
  39
+          mapping   = Devise::Mapping.find_by_path(request.path)
  40
+          mapping ||= Devise.mappings[Devise.default_scope] if Devise.use_default_scope
  41
+          mapping
  42
+        end
39 43
       end
40 44
 
41 45
       # Overwrites devise_controller? to return true
9  lib/devise/encryptors/authlogic_sha512.rb
... ...
@@ -1,19 +1,12 @@
1 1
 require "digest/sha2"
2 2
 
3 3
 module Devise
4  
-  # Implements a way of adding different encryptions.
5  
-  # The class should implement a self.digest method that taks the following params:
6  
-  #   - password
7  
-  #   - stretches: the number of times the encryption will be applied
8  
-  #   - salt: the password salt as defined by devise
9  
-  #   - pepper: Devise config option
10  
-  #
11 4
   module Encryptors
12 5
     # = AuthlogicSha512
13 6
     # Simulates Authlogic's default encryption mechanism.
14 7
     # Warning: it uses Devise's stretches configuration to port Authlogic's one. Should be set to 20 in the initializer to silumate
15 8
     #  the default behavior.
16  
-    class AuthlogicSha512
  9
+    class AuthlogicSha512 < Base
17 10
       
18 11
       # Gererates a default password digest based on salt, pepper and the
19 12
       # incoming password.
20  lib/devise/encryptors/base.rb
... ...
@@ -0,0 +1,20 @@
  1
+module Devise
  2
+  # Implements a way of adding different encryptions.
  3
+  # The class should implement a self.digest method that taks the following params:
  4
+  #   - password
  5
+  #   - stretches: the number of times the encryption will be applied
  6
+  #   - salt: the password salt as defined by devise
  7
+  #   - pepper: Devise config option
  8
+  #
  9
+  module Encryptors
  10
+    class Base
  11
+      def self.digest
  12
+        raise NotImplemented
  13
+      end
  14
+
  15
+      def self.salt
  16
+        Devise.friendly_token
  17
+      end
  18
+    end
  19
+  end
  20
+end
21  lib/devise/encryptors/bcrypt.rb
... ...
@@ -0,0 +1,21 @@
  1
+require "bcrypt"
  2
+
  3
+module Devise
  4
+  module Encryptors
  5
+    # = BCrypt 
  6
+    # Uses the BCrypt hash algorithm to encrypt passwords.
  7
+    class Bcrypt < Base
  8
+      
  9
+      # Gererates a default password digest based on stretches, salt, pepper and the
  10
+      # incoming password. We don't strech it ourselves since BCrypt does so internally.
  11
+      def self.digest(password, stretches, salt, pepper)
  12
+        ::BCrypt::Engine.hash_secret([password, pepper].join, salt, stretches)
  13
+      end
  14
+
  15
+      def self.salt
  16
+        ::BCrypt::Engine.generate_salt
  17
+      end
  18
+
  19
+    end
  20
+  end
  21
+end
9  lib/devise/encryptors/clearance_sha1.rb
... ...
@@ -1,19 +1,12 @@
1 1
 require "digest/sha1"
2 2
 
3 3
 module Devise
4  
-  # Implements a way of adding different encryptions.
5  
-  # The class should implement a self.digest method that taks the following params:
6  
-  #   - password
7  
-  #   - stretches: the number of times the encryption will be applied
8  
-  #   - salt: the password salt as defined by devise
9  
-  #   - pepper: Devise config option
10  
-  #
11 4
   module Encryptors
12 5
     # = ClearanceSha1
13 6
     # Simulates Clearance's default encryption mechanism.
14 7
     # Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
15 8
     # Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES
16  
-    class ClearanceSha1
  9
+    class ClearanceSha1 < Base
17 10
       
18 11
       # Gererates a default password digest based on salt, pepper and the
19 12
       # incoming password.
9  lib/devise/encryptors/restful_authentication_sha1.rb
... ...
@@ -1,20 +1,13 @@
1 1
 require "digest/sha1"
2 2
 
3 3
 module Devise
4  
-  # Implements a way of adding different encryptions.
5  
-  # The class should implement a self.digest method that taks the following params:
6  
-  #   - password
7  
-  #   - stretches: the number of times the encryption will be applied
8  
-  #   - salt: the password salt as defined by devise
9  
-  #   - pepper: Devise config option
10  
-  #
11 4
   module Encryptors
12 5
     # = RestfulAuthenticationSha1
13 6
     # Simulates Restful Authentication's default encryption mechanism.
14 7
     # Warning: it uses Devise's pepper to port the concept of REST_AUTH_SITE_KEY
15 8
     # Warning: it uses Devise's stretches configuration to port the concept of REST_AUTH_DIGEST_STRETCHES. Should be set to 10 in 
16 9
     # the initializer to silumate the default behavior.
17  
-    class RestfulAuthenticationSha1
  10
+    class RestfulAuthenticationSha1 < Base
18 11
       
19 12
       # Gererates a default password digest based on salt, pepper and the
20 13
       # incoming password.
9  lib/devise/encryptors/sha1.rb
... ...
@@ -1,17 +1,10 @@
1 1
 require "digest/sha1"
2 2
 
3 3
 module Devise
4  
-  # Implements a way of adding different encryptions.
5  
-  # The class should implement a self.digest method that taks the following params:
6  
-  #   - password
7  
-  #   - stretches: the number of times the encryption will be applied
8  
-  #   - salt: the password salt as defined by devise
9  
-  #   - pepper: Devise config option
10  
-  #
11 4
   module Encryptors
12 5
     # = Sha1
13 6
     # Uses the Sha1 hash algorithm to encrypt passwords.
14  
-    class Sha1
  7
+    class Sha1 < Base
15 8
       
16 9
       # Gererates a default password digest based on stretches, salt, pepper and the
17 10
       # incoming password.
9  lib/devise/encryptors/sha512.rb
... ...
@@ -1,17 +1,10 @@
1 1
 require "digest/sha2"
2 2
 
3 3
 module Devise
4  
-  # Implements a way of adding different encryptions.
5  
-  # The class should implement a self.digest method that taks the following params:
6  
-  #   - password
7  
-  #   - stretches: the number of times the encryption will be applied
8  
-  #   - salt: the password salt as defined by devise
9  
-  #   - pepper: Devise config option
10  
-  #
11 4
   module Encryptors
12 5
     # = Sha512
13 6
     # Uses the Sha512 hash algorithm to encrypt passwords.
14  
-    class Sha512
  7
+    class Sha512 < Base
15 8
       
16 9
       # Gererates a default password digest based on salt, pepper and the
17 10
       # incoming password.
2  lib/devise/hooks/trackable.rb
... ...
@@ -1,5 +1,5 @@
1 1
 # After each sign in, update sign in time, sign in count and sign in IP.
2  
-Warden::Manager.after_authentication do |record, warden, options|
  2
+Warden::Manager.after_set_user :event => [:authentication, :set_user] do |record, warden, options|
3 3
   scope = options[:scope]
4 4
   if Devise.mappings[scope].try(:trackable?) && warden.authenticated?(scope)
5 5
     old_current, new_current  = record.current_sign_in_at, Time.now
2  lib/devise/mapping.rb
@@ -29,7 +29,7 @@ class Mapping #:nodoc:
29 29
     def self.find_by_path(path)
30 30
       Devise.mappings.each_value do |mapping|
31 31
         route = path.split("/")[mapping.as_position]
32  
-        return mapping if mapping.as == route.to_sym
  32
+        return mapping if route && mapping.as == route.to_sym
33 33
       end
34 34
       nil
35 35
     end
2  lib/devise/models/authenticatable.rb
@@ -43,7 +43,7 @@ def password=(new_password)
43 43
         @password = new_password
44 44
 
45 45
         if @password.present?
46  
-          self.password_salt = Devise.friendly_token
  46
+          self.password_salt = self.class.encryptor_class.salt
47 47
           self.encrypted_password = password_digest(@password)
48 48
         end
49 49
       end
1  lib/devise/models/timeoutable.rb
@@ -12,7 +12,6 @@ module Models
12 12
     #
13 13
     #   timeout: the time you want to timeout the user session without activity.
14 14
     module Timeoutable
15  
-
16 15
       def self.included(base)
17 16
         base.extend ClassMethods
18 17
       end
40  lib/devise/orm/data_mapper.rb
... ...
@@ -1,8 +1,20 @@
1 1
 module Devise
2 2
   module Orm
3 3
     module DataMapper
  4
+      module InstanceMethods
  5
+        def save(flag=nil)
  6
+          if flag == false
  7
+            save!
  8
+          else
  9
+            super()
  10
+          end
  11
+        end
  12
+      end
  13
+
4 14
       def self.included_modules_hook(klass, modules)
5 15
         klass.send :extend, self
  16
+        klass.send :include, InstanceMethods
  17
+
6 18
         yield
7 19
 
8 20
         modules.each do |mod|
@@ -19,11 +31,24 @@ def self.included_modules_hook(klass, modules)
19 31
 
20 32
       # Hooks for confirmable
21 33
       def before_create(*args)
22  
-        before :create, *args
  34
+        wrap_hook(:before, *args)
23 35
       end
24 36
 
25 37
       def after_create(*args)
26  
-        after :create, *args
  38
+        wrap_hook(:after, *args)
  39
+      end
  40
+
  41
+      def wrap_hook(action, *args)
  42
+        options = args.extract_options!
  43
+
  44
+        args.each do |callback|
  45
+          send action, :create, callback
  46
+          class_eval <<-METHOD, __FILE__, __LINE__ + 1
  47
+            def #{callback}
  48
+              super if #{options[:if] || true}
  49
+            end
  50
+          METHOD
  51
+        end
27 52
       end
28 53
 
29 54
       # Add ActiveRecord like finder
@@ -39,15 +64,6 @@ def find(*args)
39 64
         end
40 65
       end
41 66
 
42  
-      # In Datamapper, we need to call save! if we don't want to execute callbacks.
43  
-      def save(flag=nil)
44  
-        if flag == false
45  
-          save!
46  
-        else
47  
-          super()
48  
-        end
49  
-      end
50  
-
51 67
       # Tell how to apply schema methods. This automatically maps :limit to
52 68
       # :length and :null to :nullable.
53 69
       def apply_schema(name, type, options={})
@@ -64,4 +80,4 @@ def apply_schema(name, type, options={})
64 80
   end
65 81
 end
66 82
 
67  
-DataMapper::Model.send(:include, Devise::Models)
  83
+DataMapper::Model.send(:include, Devise::Models)
4  lib/devise/rails.rb
@@ -6,8 +6,8 @@
6 6
 
7 7
   # Adds Warden Manager to Rails middleware stack, configuring default devise
8 8
   # strategy and also the failure app.
9  
-  Rails.configuration.middleware.use Warden::Manager do |manager|
10  
-    Devise.configure_warden_manager(manager)
  9
+  Rails.configuration.middleware.use Warden::Manager do |config|
  10
+    Devise.configure_warden(config)
11 11
   end
12 12
 
13 13
   I18n.load_path.unshift File.expand_path(File.join(File.dirname(__FILE__), 'locales', 'en.yml'))
2  lib/devise/rails/routes.rb
@@ -82,7 +82,7 @@ def devise_for(*resources)
82 82
         resources.map!(&:to_sym)
83 83
         resources.each do |resource|
84 84
           mapping = Devise::Mapping.new(resource, options.dup)
85  
-          Warden::Manager.default_scope ||= mapping.name
  85
+          Devise.default_scope ||= mapping.name
86 86
           Devise.mappings[mapping.name] = mapping
87 87
 
88 88
           route_options = mapping.route_options.merge(:path_prefix => mapping.raw_path, :name_prefix => "#{mapping.name}_")
8  lib/devise/test_helpers.rb
@@ -7,17 +7,17 @@ def self.included(base)
7 7
     end
8 8
 
9 9
     # This is a Warden::Proxy customized for functional tests. It's meant to
10  
-    # some of Warden::Manager resposnabilities, as retrieving configuration
  10
+    # some of Warden::Manager responsibilities, as retrieving configuration
11 11
     # options and calling the FailureApp.
12 12
     class TestWarden < Warden::Proxy #:nodoc:
13 13
       attr_reader :controller
14 14
 
15 15
       def initialize(controller)
16 16
         @controller = controller
17  
-        manager = Warden::Manager.new(nil) do |manager|
18  
-          Devise.configure_warden_manager(manager)
  17
+        manager = Warden::Manager.new(nil) do |config|
  18
+          Devise.configure_warden(config)
19 19
         end
20  
-        super(controller.request.env, manager.config)
  20
+        super(controller.request.env, manager)
21 21
       end
22 22
 
23 23
       def authenticate!(*args)
2  lib/devise/version.rb
... ...
@@ -1,3 +1,3 @@
1 1
 module Devise
2  
-  VERSION = "0.7.4".freeze
  2
+  VERSION = "0.8.1".freeze
3 3
 end
60  test/devise_test.rb
@@ -7,43 +7,6 @@ def self.clean_warden_config!
7 7
 end
8 8
 
9 9
 class DeviseTest < ActiveSupport::TestCase
10  
-  class MockManager
11  
-    attr_accessor :failure_app
12  
-    attr_reader :default_strategies, :silence_missing_strategies
13  
-
14  
-    def silence_missing_strategies!
15  
-      @silence_missing_strategies = true
16  
-    end
17  
-
18  
-    def silence_missing_serializers!
19  
-      @silence_missing_serializers = true
20  
-    end
21  
-
22  
-    def default_strategies(*args)
23  
-      if args.empty?
24  
-        @default_strategies
25  
-      else
26  
-        @default_strategies = args
27  
-      end
28  
-    end
29  
-
30  
-    def default_serializers(*args)
31  
-      if args.empty?
32  
-        @default_serializers
33  
-      else
34  
-        @default_serializers = args
35  
-      end
36  
-    end
37  
-  end
38  
-
39  
-  test 'DeviseMailer.sender can be configured through Devise' do
40  
-    swap DeviseMailer, :sender => "foo@bar" do
41  
-      assert_equal "foo@bar", DeviseMailer.sender
42  
-      Devise.mailer_sender = "bar@foo"
43  
-      assert_equal "bar@foo", DeviseMailer.sender
44  
-    end
45  
-  end
46  
-
47 10
   test 'model options can be configured through Devise' do
48 11
     swap Devise, :confirm_within => 113, :pepper => "foo" do
49 12
       assert_equal 113, Devise.confirm_within
@@ -58,28 +21,25 @@ def default_serializers(*args)
58 21
   end
59 22
 
60 23
   test 'warden manager configuration' do
61  
-    manager = MockManager.new
62  
-    Devise.configure_warden_manager(manager)
63  
-
64  
-    assert_equal Devise::FailureApp, manager.failure_app
65  
-    assert_equal [:authenticatable], manager.default_strategies
66  
-    assert manager.silence_missing_strategies
67  
-  end
  24
+    config = Warden::Config.new
  25
+    Devise.configure_warden(config)
68 26
 
69  
-  test 'warden default scope is set' do
70  
-    assert_equal :user, Warden::Manager.default_scope
  27
+    assert_equal Devise::FailureApp, config.failure_app
  28
+    assert_equal [:authenticatable], config.default_strategies
  29
+    assert_equal :user, config.default_scope
  30
+    assert config.silence_missing_strategies?
  31
+    assert config.silence_missing_serializers?
71 32
   end
72 33
 
73 34
   test 'warden manager user configuration through a block' do
74 35
     begin
75 36
       @executed = false
76  
-      Devise.warden do |manager|
  37
+      Devise.warden do |config|
77 38
         @executed = true
78  
-        assert_kind_of MockManager, manager
  39
+        assert_kind_of Warden::Config, config
79 40
       end
80 41
 
81  
-      manager = MockManager.new
82  
-      Devise.configure_warden_manager(manager)
  42
+      Devise.configure_warden(Warden::Config.new)
83 43
       assert @executed
84 44
     ensure
85 45
       Devise.clean_warden_config!
5  test/encryptors_test.rb
@@ -17,11 +17,12 @@ class Encryptors < ActiveSupport::TestCase
17 17
     encryptor = Devise::Encryptors::ClearanceSha1.digest('123mudar', nil, '65c58472c207c829f28c68619d3e3aefed18ab3f', nil)
18 18
     assert_equal clearance, encryptor
19 19
   end
20  
-
  20
+  
21 21
   Devise::ENCRYPTORS_LENGTH.each do |key, value|
22 22
     test "should have length #{value} for #{key.inspect}" do
23 23
       swap Devise, :encryptor => key do
24  
-        assert_equal value, Devise::Encryptors.const_get(key.to_s.classify).digest('a', 2, 'b', 'c').size
  24
+        encryptor = Devise::Encryptors.const_get(key.to_s.classify)
  25
+        assert_equal value, encryptor.digest('a', 4, encryptor.salt, nil).size
25 26
       end
26 27
     end
27 28
   end
26  test/integration/authenticatable_test.rb
@@ -154,12 +154,6 @@ class AuthenticationTest < ActionController::IntegrationTest
154 154
     assert_contain 'You need to sign in or sign up before continuing.'
155 155
   end
156 156
 
157  
-  test 'render 404 on roles without permission' do
158  
-    get 'admin_area/password/new'
159  
-    assert_response :not_found
160  
-    assert_not_contain 'Send me reset password instructions'
161  
-  end
162  
-
163 157
   test 'return to default url if no other was requested' do
164 158
     sign_in_as_user
165 159
 
@@ -221,4 +215,24 @@ class AuthenticationTest < ActionController::IntegrationTest
221 215
       end
222 216
     end
223 217
   end
  218
+
  219
+  test 'render 404 on roles without permission' do
  220
+    get 'admin_area/password/new'
  221
+    assert_response :not_found
  222
+    assert_not_contain 'Send me reset password instructions'
  223
+  end
  224
+
  225
+  test 'render 404 on roles without mapping' do
  226
+    get 'sign_in'
  227
+    assert_response :not_found
  228
+    assert_not_contain 'Sign in'
  229
+  end
  230
+
  231
+  test 'uses the mapping from the default scope if specified' do
  232
+    swap Devise, :use_default_scope => true do
  233
+      get 'sign_in'
  234
+      assert_response :ok
  235
+      assert_contain 'Sign in'
  236
+    end
  237
+  end
224 238
 end
8  test/integration/confirmable_test.rb
@@ -60,6 +60,14 @@ def visit_user_confirmation_with_token(confirmation_token)
60 60
     assert warden.authenticated?(:user)
61 61
   end
62 62
 
  63
+  test 'increases sign count when signed in through confirmation' do
  64
+    user = create_user(:confirm => false)
  65
+    visit_user_confirmation_with_token(user.confirmation_token)
  66
+
  67
+    user.reload
  68
+    assert_equal 1, user.sign_in_count
  69
+  end
  70
+
63 71
   test 'not confirmed user with setup to block without confirmation should not be able to sign in' do
64 72
     swap Devise, :confirm_within => 0.days do
65 73
       sign_in_as_user(:confirm => false)
2  test/integration/trackable_test.rb
@@ -51,7 +51,7 @@ class TrackableHooksTest < ActionController::IntegrationTest
51 51
     assert_equal 2, user.sign_in_count
52 52
   end
53 53
 
54  
-  test "does not update anything if user is signed out along the way" do
  54
+  test "does not update anything if user has signed out along the way" do
55 55
     swap Devise, :confirm_within => 0 do
56 56
       user = create_user(:confirm => false)
57 57
       sign_in_as_user
2  test/mailers/confirmation_instructions_test.rb
@@ -4,7 +4,7 @@ class ConfirmationInstructionsTest < ActionMailer::TestCase
4 4
 
5 5
   def setup
6 6
     setup_mailer
7  
-    DeviseMailer.sender = 'test@example.com'
  7
+    Devise.mailer_sender = 'test@example.com'
8 8
   end
9 9
 
10 10
   def user
2  test/mailers/reset_password_instructions_test.rb
@@ -4,7 +4,7 @@ class ResetPasswordInstructionsTest < ActionMailer::TestCase
4 4
 
5 5
   def setup
6 6
     setup_mailer
7  
-    DeviseMailer.sender = 'test@example.com'
  7
+    Devise.mailer_sender = 'test@example.com'
8 8
   end
9 9
 
10 10
   def user
1  test/rails_app/config/environment.rb
@@ -2,6 +2,7 @@
2 2
 
3 3
 # Specifies gem version of Rails to use when vendor/rails is not present
4 4
 RAILS_GEM_VERSION = '2.3.5' unless defined? RAILS_GEM_VERSION
  5
+DEVISE_ORM = :active_record unless defined? DEVISE_ORM
5 6
 
6 7
 # Bootstrap the Rails environment, frameworks, and default configuration
7 8
 require File.join(File.dirname(__FILE__), 'boot')
5  test/rails_app/config/initializers/new_rails_defaults.rb
@@ -18,4 +18,7 @@
18 18
 
19 19
 # Don't escape HTML entities in JSON, leave that for the #json_escape helper.
20 20
 # if you're including raw json in an HTML page.
21  
-ActiveSupport.escape_html_entities_in_json = false
  21
+ActiveSupport.escape_html_entities_in_json = false
  22
+
  23
+# Clean up silencers
  24
+Rails.backtrace_cleaner.remove_silencers!
1  test/rails_app/config/routes.rb
@@ -12,6 +12,7 @@
12 12
   map.connect '/admin_area/password/new', :controller => "passwords", :action => "new"
13 13
   map.admin_root '/admin_area/home', :controller => "admins", :action => "index"
14 14
 
  15
+  map.connect '/sign_in', :controller => "sessions", :action => "new"
15 16
   map.connect ':controller/:action/:id'
16 17
   map.connect ':controller/:action/:id.:format'
17 18
 end

0 notes on commit 32991e1

Please sign in to comment.
Something went wrong with that request. Please try again.