jashmenn-restful-authentication 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/CHANGELOG +68 -0
  2. data/README.textile +176 -0
  3. data/Rakefile +32 -0
  4. data/TODO +15 -0
  5. data/init.rb +3 -0
  6. data/lib/authentication.rb +44 -0
  7. data/lib/authentication/by_cookie_token.rb +82 -0
  8. data/lib/authentication/by_password.rb +64 -0
  9. data/lib/authorization.rb +14 -0
  10. data/lib/authorization/aasm_roles.rb +63 -0
  11. data/lib/authorization/stateful_roles.rb +62 -0
  12. data/lib/generators/authenticated/USAGE +1 -0
  13. data/lib/generators/authenticated/authenticated_generator.rb +524 -0
  14. data/lib/generators/authenticated/templates/_model_partial.html.erb +8 -0
  15. data/lib/generators/authenticated/templates/activation.erb +3 -0
  16. data/lib/generators/authenticated/templates/authenticated_system.rb +189 -0
  17. data/lib/generators/authenticated/templates/authenticated_test_helper.rb +22 -0
  18. data/lib/generators/authenticated/templates/controller.rb +41 -0
  19. data/lib/generators/authenticated/templates/features/accounts.feature +109 -0
  20. data/lib/generators/authenticated/templates/features/sessions.feature +134 -0
  21. data/lib/generators/authenticated/templates/features/step_definitions/ra_env.rb +9 -0
  22. data/lib/generators/authenticated/templates/features/step_definitions/ra_navigation_steps.rb +48 -0
  23. data/lib/generators/authenticated/templates/features/step_definitions/ra_resource_steps.rb +178 -0
  24. data/lib/generators/authenticated/templates/features/step_definitions/ra_response_steps.rb +169 -0
  25. data/lib/generators/authenticated/templates/features/step_definitions/rest_auth_features_helper.rb +81 -0
  26. data/lib/generators/authenticated/templates/features/step_definitions/user_steps.rb +131 -0
  27. data/lib/generators/authenticated/templates/helper.rb +2 -0
  28. data/lib/generators/authenticated/templates/login.html.erb +16 -0
  29. data/lib/generators/authenticated/templates/mailer.rb +26 -0
  30. data/lib/generators/authenticated/templates/migration.rb +26 -0
  31. data/lib/generators/authenticated/templates/model.rb +87 -0
  32. data/lib/generators/authenticated/templates/model_controller.rb +83 -0
  33. data/lib/generators/authenticated/templates/model_helper.rb +93 -0
  34. data/lib/generators/authenticated/templates/model_helper_spec.rb +158 -0
  35. data/lib/generators/authenticated/templates/observer.rb +11 -0
  36. data/lib/generators/authenticated/templates/signup.html.erb +19 -0
  37. data/lib/generators/authenticated/templates/signup_notification.erb +8 -0
  38. data/lib/generators/authenticated/templates/site_keys.rb +38 -0
  39. data/lib/generators/authenticated/templates/spec/controllers/access_control_spec.rb +101 -0
  40. data/lib/generators/authenticated/templates/spec/controllers/authenticated_system_spec.rb +102 -0
  41. data/lib/generators/authenticated/templates/spec/controllers/sessions_controller_spec.rb +127 -0
  42. data/lib/generators/authenticated/templates/spec/controllers/users_controller_spec.rb +131 -0
  43. data/lib/generators/authenticated/templates/spec/fixtures/users.yml +60 -0
  44. data/lib/generators/authenticated/templates/spec/helpers/users_helper_spec.rb +141 -0
  45. data/lib/generators/authenticated/templates/spec/models/user_spec.rb +227 -0
  46. data/lib/generators/authenticated/templates/test/functional_test.rb +82 -0
  47. data/lib/generators/authenticated/templates/test/mailer_test.rb +32 -0
  48. data/lib/generators/authenticated/templates/test/model_functional_test.rb +93 -0
  49. data/lib/generators/authenticated/templates/test/unit_test.rb +164 -0
  50. data/lib/tasks/auth.rake +33 -0
  51. data/lib/trustification.rb +14 -0
  52. data/lib/trustification/email_validation.rb +20 -0
  53. metadata +103 -0
@@ -0,0 +1,68 @@
1
+ h1. Internal Changes to code
2
+
3
+ As always, this is just a copy-and-pasted version of the CHANGELOG file in the source code tree.
4
+
5
+ h2. Changes for the May, 2008 version of restful-authentication
6
+
7
+ h3. Changes to user model
8
+
9
+ * recently_activated? belongs only if stateful
10
+ * Gave migration a 40-char limit on remember_token & an index on users by login
11
+ * **Much** stricter login and email validation
12
+ * put length constraints in migration too
13
+ * password in 6, 40
14
+ * salt and remember_token now much less predictability
15
+
16
+ h3. Changes to session_controller
17
+
18
+ * use uniform logout function
19
+ * use uniform remember_cookie functions
20
+ * avoid calling logged_in? which will auto-log-you-in (safe in the face of
21
+ logout! call, but idiot-proof)
22
+ * Moved reset_session into only the "now logged in" branch
23
+ ** wherever it goes, it has to be in front of the current_user= call
24
+ ** See more in README-Tradeoffs.txt
25
+ * made a place to take action on failed login attempt
26
+ * recycle login and remember_me setting on failed login
27
+ * nil'ed out the password field in 'new' view
28
+
29
+ h3. Changes to users_controller
30
+
31
+ * use uniform logout function
32
+ * use uniform remember_cookie functions
33
+ * Moved reset_session into only the "now logged in" branch
34
+ ** wherever it goes, it has to be in front of the current_user= call
35
+ ** See more in README-Tradeoffs.txt
36
+ * made the implicit login only happen for non-activationed sites
37
+ * On a failed signup, kick you back to the signin screen (but strip out the password & confirmation)
38
+ * more descriptive error messages in activate()
39
+
40
+ h3. users_helper
41
+
42
+ * link_to_user, link_to_current_user, link_to_signin_with_IP
43
+ * if_authorized(action, resource, &block) view function (with appropriate
44
+ warning)
45
+
46
+ h3. authenticated_system
47
+
48
+ * Made authorized? take optional arguments action=nil, resource=nil, *args
49
+ This makes its signature better match traditional approaches to access control
50
+ eg Reference Monitor in "Security Patterns":http://www.securitypatterns.org/patterns.html)
51
+ * authorized? should be a helper too
52
+ * added uniform logout! methods
53
+ * format.any (as found in access_denied) doesn't work until
54
+ http://dev.rubyonrails.org/changeset/8987 lands.
55
+ * cookies are now refreshed each time we cross the logged out/in barrier, as
56
+ "best":http://palisade.plynt.com/issues/2004Jul/safe-auth-practices/
57
+ "practice":http://www.owasp.org/index.php/Session_Management#Regeneration_of_Session_Tokens
58
+
59
+ h3. Other
60
+
61
+ * Used escapes <%= %> in email templates (among other reasons, so courtenay's
62
+ "'dumbass' test":http://tinyurl.com/684g9t doesn't complain)
63
+ * Added site key to generator, users.yml.
64
+ * Made site key generation idempotent in the most crude and hackish way
65
+ * 100% coverage apart from the stateful code. (needed some access_control
66
+ checks, and the http_auth stuff)
67
+ * Stories!
68
+
@@ -0,0 +1,176 @@
1
+ h1. "Restful Authentication Generator":http://github.com/Satish/restful-authentication
2
+
3
+ This widely-used plugin provides a foundation for securely managing user authentication:
4
+ * Login / logout
5
+ * Secure password handling
6
+ * Account activation by validating email
7
+ * Account approval / disabling by admin
8
+ * Rudimentary hooks for authorization and access control.
9
+
10
+ Several features were updated in May, 2008.
11
+ * "Stable newer version":http://github.com/technoweenie/restful-authentication/tree/master
12
+ * "'Classic' (backward-compatible) version":http://github.com/technoweenie/restful-authentication/tree/classic
13
+ * "Experimental version":http://github.com/technoweenie/restful-authentication/tree/modular (Much more modular, needs testing & review)
14
+
15
+ !! important: if you upgrade your site, existing user account !!
16
+ !! passwords will stop working unless you use @--old-passwords@ !!
17
+
18
+ h2. Issue Tracker
19
+
20
+ Please submit any bugs or annoyances at
21
+ * "http://github.com/Satish/restful-authentication/issues":http://github.com/Satish/restful-authentication/issues
22
+
23
+ h2. Documentation
24
+
25
+ This page has notes on
26
+ * "Installation":#INSTALL
27
+ * "New Features":#AWESOME
28
+ * "After installing":#POST-INSTALL
29
+
30
+ See the "wiki":http://github.com/technoweenie/restful-authentication/wikis/home (or the notes/ directory) if you want to learn more about:
31
+
32
+ * "Extensions, Addons and Alternatives":http://wiki.github.com/technoweenie/restful-authentication/addons such as HAML templates
33
+ * "Security Design Patterns":http://wiki.github.com/technoweenie/restful-authentication/security-patterns with "snazzy diagram":http://github.com/technoweenie/restful-authentication/tree/master/notes/SecurityFramework.png
34
+ * "Authentication":http://wiki.github.com/technoweenie/restful-authentication/authentication -- Lets a visitor identify herself (and lay claim to her corresponding Roles and measure of Trust)
35
+ * "Trust Metrics":http://wiki.github.com/technoweenie/restful-authentication/trustification -- Confidence we can rely on the outcomes of this visitor's actions.
36
+ * "Authorization":http://wiki.github.com/technoweenie/restful-authentication/authorization and Policy -- Based on trust and identity, what actions may this visitor perform?
37
+ * "Access Control":http://wiki.github.com/technoweenie/restful-authentication/access-control -- How the Authorization policy is actually enforced in your code (A: hopefully without turning it into a spaghetti of if thens)
38
+ * "Rails Plugins":http://wiki.github.com/technoweenie/restful-authentication/rails-plugins for Authentication, Trust, Authorization and Access Control
39
+ * "Tradeoffs":http://wiki.github.com/technoweenie/restful-authentication/tradeoffs -- for the paranoid or the curious, a rundown of tradeoffs made in the code
40
+ * "CHANGELOG":http://wiki.github.com/technoweenie/restful-authentication/CHANGELOG -- Summary of changes to internals
41
+ * "TODO":http://wiki.github.com/technoweenie/restful-authentication/todo -- Ideas for how you can help
42
+
43
+
44
+ These best version of the release notes are in the notes/ directory in the "source code":http://github.com/technoweenie/restful-authentication/tree/master -- look there for the latest version. The wiki versions are taken (manually) from there.
45
+
46
+ h2(#AWESOME). Exciting new features
47
+
48
+ h3. Stories
49
+
50
+ There are now "Cucumber":http://wiki.github.com/aslakhellesoy/cucumber/home features that allow expressive, enjoyable tests for the authentication code. The flexible code for resource testing in stories was extended from "Ben Mabey's.":http://www.benmabey.com/2008/02/04/rspec-plain-text-stories-webrat-chunky-bacon/
51
+
52
+ h3. Modularize to match security design patterns:
53
+
54
+ * Authentication (currently: password, browser cookie token, HTTP basic)
55
+ * Trust metric (email validation)
56
+ * Authorization (stateful roles)
57
+ * Leave a flexible framework that will play nicely with other access control / policy definition / trust metric plugins
58
+
59
+ h3. Other
60
+
61
+ * Added a few helper methods for linking to user pages
62
+ * Uniform handling of logout, remember_token
63
+ * Stricter email, login field validation
64
+ * Minor security fixes -- see CHANGELOG
65
+
66
+
67
+ h2. Non-backwards compatible Changes
68
+
69
+ Here are a few changes in the May 2008 release that increase "Defense in Depth"
70
+ but may require changes to existing accounts
71
+
72
+ * If you have an existing site, none of these changes are compelling enough to warrant migrating your userbase.
73
+ * If you are generating for a new site, all of these changes are low-impact. You should apply them.
74
+
75
+ h3. Passwords
76
+
77
+ The new password encryption (using a site key salt and stretching) will break existing user accounts' passwords. We recommend you use the @--old-passwords@
78
+ option or write a migration tool and submit it as a patch. See the "Tradeoffs":http://wiki.github.com/technoweenie/restful-authentication/tradeoffs note for more information.
79
+
80
+ h3. Validations
81
+
82
+ By default, email and usernames are validated against a somewhat strict pattern; your users' values may be now illegal. Adjust to suit.
83
+
84
+
85
+ h2(#INSTALL). Installation
86
+
87
+ This is a basic restful authentication generator for rails, taken from acts as authenticated. Currently it requires Rails3 beta.
88
+
89
+ **IMPORTANT FOR RAILS > 2.1 USERS** To avoid a @NameError@ exception ("lighthouse tracker ticket":http://rails_security.lighthouseapp.com/projects/15332-restful_authentication/tickets/2-not-a-valid-constant-name-errors#ticket-2-2), check out the code to have an _underscore_ and not _dash_ in its name:
90
+
91
+ If you're using git as your source control, you have three options.
92
+
93
+ * Install as a plugin <pre><code>rails plugin install git://github.com/Satish/restful-authentication.git restful_authentication</code></pre>
94
+
95
+ * Checkout into @vendor/plugins@ using
96
+ <pre><code>git clone git://github.com/Satish/restful-authentication.git restful_authentication</code></pre>and delete the .git folder inside the directory. (This will break the connection with the github repository, and allow you to include the code into your project with git add)
97
+
98
+ * Use git submodule. From the top level of your project, add the plugin
99
+ <pre><code>git submodule add git://github.com/Satish/restful-authentication.git vendor/plugins/restful_authentication</code></pre>This will create a reference link to the repository, which can be save into your project. You will need to let capistrano know that you want to update submodules on deploy via @set :git_enable_submodules, 1@.
100
+
101
+ "git-submodule docs":http://www.kernel.org/pub/software/scm/git/docs/git-submodule.html
102
+
103
+ To use the generator:
104
+ <pre><code>
105
+ rails g authenticated user sessions \
106
+ --include-activation \
107
+ --stateful \
108
+ --rspec \
109
+ --skip-migration \
110
+ --skip-routes \
111
+ --old-passwords
112
+ </code></pre>
113
+
114
+ * The first parameter specifies the model that gets created in signup (typically a user or account model). A model with migration is created, as well as a basic controller with the create method. You probably want to say "User" here.
115
+
116
+ * The second parameter specifies the session controller name(options default to @sessionsController@). This is the controller that handles the actual login/logout function on the site. (probably: "Session").
117
+
118
+ * @--include-activation@: Generates the code for a ActionMailer and its respective Activation Code through email.
119
+
120
+ * @--stateful@: Builds in support for acts_as_state_machine and generates activation code. (@--stateful@ implies @--include-activation@). Based on the idea at "http://www.vaporbase.com/postings/stateful_authentication":http://www.vaporbase.com/postings/stateful_authentication. Passing @--skip-migration@ will skip the user migration, and @--skip-routes@ will skip resource generation both useful if you've already run this generator. (Needs the "acts_as_state_machine plugin":http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/, but new installs should probably run with @--aasm@ instead.)
121
+
122
+ * @--aasm@: Works the same as stateful but uses the "updated aasm gem":http://github.com/rubyist/aasm/tree/master<br /> Add <code>gem 'rubyist-aasm', :require => 'aasm'</code> to @Gemfile@ for use in projects that use rails3-beta
123
+
124
+ * @--rspec@: Generate RSpec tests and Stories in place of standard rails tests. This requires the "RSpec-2 for Rails-3":http://github.com/rspec/rspec-rails, run @gem install rspec-rails --pre@ to install RSpec-2 for Rails-3(make sure you @rails g rspec:install@ after installing RSpec.) The rspec and story suite are much more thorough than the rails tests, and changes are unlikely to be backported.
125
+
126
+ * @--old-passwords@: Use the older password scheme (see [[#COMPATIBILITY]], above)
127
+
128
+ * @--skip-migration@: Don't generate a migration file for this model
129
+
130
+ * @--skip-routes@: Don't generate a resource line in @config/routes.rb@
131
+
132
+
133
+ h2(#POST-INSTALL). After installing
134
+
135
+ The below assumes a Model named 'User' and a Controller named 'Session'; please alter to suit. There are additional security minutae in @notes/README-Tradeoffs@ -- only the paranoid or the curious need bother, though.
136
+
137
+ * Add these familiar login URLs to your @config/routes.rb@ if you like:
138
+ <pre><code>
139
+ match 'login' => 'sessions#new', :as => :login
140
+ match 'logout' => 'sessions#destroy', :as => :logout
141
+ match 'signup' => 'users#new', :as => :signup
142
+ </code></pre>
143
+
144
+ * With @--include-activation@, also add to your @config/routes.rb@:
145
+ <pre><code>match 'activate/:activation_code' => 'users#activate', :as => :activate, :activation_code => nil</code></pre>
146
+ and add an observer to @config/application.rb@:
147
+ <pre><code>config.active_record.observers = :user_observer</code></pre>
148
+ Pay attention, may be this is not an issue for everybody, but if you should have problems, that the sent activation_code does match with that in the database stored, reload your user object before sending its data through email something like:
149
+ <pre><code>
150
+ class UserObserver < ActiveRecord::Observer
151
+ def after_create(user)
152
+ user.reload
153
+ UserMailer.deliver_signup_notification(user)
154
+ end
155
+ def after_save(user)
156
+ user.reload
157
+ UserMailer.deliver_activation(user) if user.recently_activated?
158
+ end
159
+ end
160
+ </code></pre>
161
+
162
+
163
+ * With @--stateful@, add an observer to config/environment.rb:
164
+ <pre><code>config.active_record.observers = :user_observer</code></pre>
165
+ and modify the users resource line in @config/routes.rb@ to read
166
+ <pre><code>
167
+ resources :users do
168
+ member do
169
+ put :suspend
170
+ put :unsuspend
171
+ delete :purge
172
+ end
173
+ end
174
+ </code></pre>
175
+
176
+ * If you use a public repository for your code (such as github, rubyforge, gitorious, etc.) make sure to NOT post your site_keys.rb (add a line like '/config/initializers/site_keys.rb' to your .gitignore or do the svn ignore dance), but make sure you DO keep it backed up somewhere safe.
@@ -0,0 +1,32 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
+
6
+ desc 'Default: run unit tests.'
7
+ task :default => :test
8
+
9
+ desc 'Test the restful_authentication plugin.'
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.libs << 'lib'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the restful_authentication plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'RestfulAuthentication'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ gemspec = eval(File.read("#{File.dirname(__FILE__)}/restful-authentication.gemspec"))
26
+ PKG_NAME = gemspec.name
27
+ PKG_VERSION = gemspec.version
28
+
29
+ Rake::GemPackageTask.new(gemspec) do |pkg|
30
+ pkg.need_zip = true
31
+ pkg.need_tar = true
32
+ end
data/TODO ADDED
@@ -0,0 +1,15 @@
1
+
2
+ h3. Authentication security projects for a later date
3
+
4
+
5
+ * Track 'failed logins this hour' and demand a captcha after say 5 failed logins
6
+ ("RECAPTCHA plugin.":http://agilewebdevelopment.com/plugins/recaptcha)
7
+ "De-proxy-ficate IP address": http://wiki.codemongers.com/NginxHttpRealIpModule
8
+
9
+ * Make cookie spoofing a little harder: we set the user's cookie to
10
+ (remember_token), but store digest(remember_token, request_IP). A CSRF cookie
11
+ spoofer has to then at least also spoof the user's originating IP
12
+ (see "Secure Programs HOWTO":http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/web-authentication.html)
13
+
14
+ * Log HTTP request on authentication / authorization failures
15
+ http://palisade.plynt.com/issues/2004Jul/safe-auth-practices
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ require File.join(File.dirname(__FILE__), "lib", "authentication")
2
+ require File.join(File.dirname(__FILE__), "lib", "authentication", "by_password")
3
+ require File.join(File.dirname(__FILE__), "lib", "authentication", "by_cookie_token")
@@ -0,0 +1,44 @@
1
+ module Authentication
2
+ mattr_accessor :login_regex, :login_regex_strict, :bad_login_message,
3
+ :name_regex, :bad_name_message,
4
+ :email_name_regex, :domain_head_regex, :domain_tld_regex, :email_regex, :bad_email_message
5
+
6
+ #self.login_regex = /\A\w[\w\.\-_@]+\z/ # ASCII, strict
7
+ self.login_regex = /\A\w[\w]*\z/ # ASCII, strict
8
+ # self.login_regex = /\A[[:alnum:]][[:alnum:]\.\-_@]+\z/ # Unicode, strict
9
+ # self.login_regex = /\A[^[:cntrl:]\\<>\/&]*\z/ # Unicode, permissive
10
+
11
+ self.login_regex_strict = /\A[[:alnum:]][[:alnum:]\_]+\z/ # Unicode, strict
12
+
13
+ #self.bad_login_message = "use only letters, numbers, and .-_@ please.".freeze
14
+ self.bad_login_message = "use only letters and numbers please".freeze
15
+
16
+ self.name_regex = /\A[^[:cntrl:]\\<>\/&]*\z/ # Unicode, permissive
17
+ self.bad_name_message = "avoid non-printing characters and \\&gt;&lt;&amp;/ please.".freeze
18
+
19
+ self.email_name_regex = '[\w\.%\+\-]+'.freeze
20
+ self.domain_head_regex = '(?:[A-Z0-9\-]+\.)+'.freeze
21
+ self.domain_tld_regex = '(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|jobs|museum|cat|tel|pro)'.freeze
22
+ self.email_regex = /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i
23
+ self.bad_email_message = "should look like an email address".freeze
24
+
25
+ def self.included(recipient)
26
+ recipient.extend(ModelClassMethods)
27
+ recipient.class_eval do
28
+ include ModelInstanceMethods
29
+ end
30
+ end
31
+
32
+ module ModelClassMethods
33
+ def secure_digest(*args)
34
+ Digest::SHA1.hexdigest(args.flatten.join('--'))
35
+ end
36
+
37
+ def make_token
38
+ secure_digest(Time.now, (1..10).map{ rand.to_s })
39
+ end
40
+ end # class methods
41
+
42
+ module ModelInstanceMethods
43
+ end # instance methods
44
+ end
@@ -0,0 +1,82 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Authentication
3
+ module ByCookieToken
4
+ # Stuff directives into including module
5
+ def self.included(recipient)
6
+ recipient.extend(ModelClassMethods)
7
+ recipient.class_eval do
8
+ include ModelInstanceMethods
9
+ end
10
+ end
11
+
12
+ #
13
+ # Class Methods
14
+ #
15
+ module ModelClassMethods
16
+ end # class methods
17
+
18
+ #
19
+ # Instance Methods
20
+ #
21
+ module ModelInstanceMethods
22
+ def remember_token?
23
+ (!remember_token.blank?) &&
24
+ remember_token_expires_at && (Time.now.utc < remember_token_expires_at.utc)
25
+ end
26
+
27
+ # These create and unset the fields required for remembering users between browser closes
28
+ def remember_me
29
+ remember_me_for 2.weeks
30
+ end
31
+
32
+ def remember_me_for(time)
33
+ remember_me_until time.from_now.utc
34
+ end
35
+
36
+ def remember_me_until(time)
37
+ self.remember_token_expires_at = time
38
+ self.remember_token = self.class.make_token
39
+ save(:validate => false)
40
+ end
41
+
42
+ # refresh token (keeping same expires_at) if it exists
43
+ def refresh_token
44
+ if remember_token?
45
+ self.remember_token = self.class.make_token
46
+ save(:validate => false)
47
+ end
48
+ end
49
+
50
+ #
51
+ # Deletes the server-side record of the authentication token. The
52
+ # client-side (browser cookie) and server-side (this remember_token) must
53
+ # always be deleted together.
54
+ #
55
+ def forget_me
56
+ self.remember_token_expires_at = nil
57
+ self.remember_token = nil
58
+ save(:validate => false)
59
+ end
60
+ end # instance methods
61
+ end
62
+
63
+ module ByCookieTokenController
64
+ # Stuff directives into including module
65
+ def self.included( recipient )
66
+ recipient.extend( ControllerClassMethods )
67
+ recipient.class_eval do
68
+ include ControllerInstanceMethods
69
+ end
70
+ end
71
+
72
+ #
73
+ # Class Methods
74
+ #
75
+ module ControllerClassMethods
76
+ end # class methods
77
+
78
+ module ControllerInstanceMethods
79
+ end # instance methods
80
+ end
81
+ end
82
+
@@ -0,0 +1,64 @@
1
+ module Authentication
2
+ module ByPassword
3
+ # Stuff directives into including module
4
+ def self.included(recipient)
5
+ recipient.extend(ModelClassMethods)
6
+ recipient.class_eval do
7
+ include ModelInstanceMethods
8
+
9
+ # Virtual attribute for the unencrypted password
10
+ attr_accessor :password
11
+ validates_presence_of :password, :if => :password_required?
12
+ validates_presence_of :password_confirmation, :if => :password_required?
13
+ validates_confirmation_of :password, :if => :password_required?
14
+ validates_length_of :password, :within => 6..40, :if => :password_required?
15
+ before_save :encrypt_password
16
+ end
17
+ end # #included directives
18
+
19
+ #
20
+ # Class Methods
21
+ #
22
+ module ModelClassMethods
23
+ # This provides a modest increased defense against a dictionary attack if
24
+ # your db were ever compromised, but will invalidate existing passwords.
25
+ # See the README and the file config/initializers/site_keys.rb
26
+ #
27
+ # It may not be obvious, but if you set REST_AUTH_SITE_KEY to nil and
28
+ # REST_AUTH_DIGEST_STRETCHES to 1 you'll have backwards compatibility with
29
+ # older versions of restful-authentication.
30
+ def password_digest(password, salt)
31
+ digest = REST_AUTH_SITE_KEY
32
+ REST_AUTH_DIGEST_STRETCHES.times do
33
+ digest = secure_digest(digest, salt, password, REST_AUTH_SITE_KEY)
34
+ end
35
+ digest
36
+ end
37
+ end # class methods
38
+
39
+ #
40
+ # Instance Methods
41
+ #
42
+ module ModelInstanceMethods
43
+
44
+ # Encrypts the password with the user salt
45
+ def encrypt(password)
46
+ self.class.password_digest(password, salt)
47
+ end
48
+
49
+ def authenticated?(password)
50
+ crypted_password == encrypt(password)
51
+ end
52
+
53
+ # before filter
54
+ def encrypt_password
55
+ return if password.blank?
56
+ self.salt = self.class.make_token if new_record?
57
+ self.crypted_password = encrypt(password)
58
+ end
59
+ def password_required?
60
+ crypted_password.blank? || !password.blank?
61
+ end
62
+ end # instance methods
63
+ end
64
+ end