rails3-restful-authentication 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. data/CHANGELOG +70 -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 +40 -0
  7. data/lib/authentication/by_cookie_token.rb +73 -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/restful_authentication.rb +3 -0
  51. data/lib/tasks/auth.rake +33 -0
  52. data/lib/trustification.rb +14 -0
  53. data/lib/trustification/email_validation.rb +20 -0
  54. metadata +130 -0
@@ -0,0 +1,70 @@
1
+ h1. provide restful_authentication.rb to require the gem
2
+
3
+ h1. Internal Changes to code
4
+
5
+ As always, this is just a copy-and-pasted version of the CHANGELOG file in the source code tree.
6
+
7
+ h2. Changes for the May, 2008 version of restful-authentication
8
+
9
+ h3. Changes to user model
10
+
11
+ * recently_activated? belongs only if stateful
12
+ * Gave migration a 40-char limit on remember_token & an index on users by login
13
+ * **Much** stricter login and email validation
14
+ * put length constraints in migration too
15
+ * password in 6, 40
16
+ * salt and remember_token now much less predictability
17
+
18
+ h3. Changes to session_controller
19
+
20
+ * use uniform logout function
21
+ * use uniform remember_cookie functions
22
+ * avoid calling logged_in? which will auto-log-you-in (safe in the face of
23
+ logout! call, but idiot-proof)
24
+ * Moved reset_session into only the "now logged in" branch
25
+ ** wherever it goes, it has to be in front of the current_user= call
26
+ ** See more in README-Tradeoffs.txt
27
+ * made a place to take action on failed login attempt
28
+ * recycle login and remember_me setting on failed login
29
+ * nil'ed out the password field in 'new' view
30
+
31
+ h3. Changes to users_controller
32
+
33
+ * use uniform logout function
34
+ * use uniform remember_cookie functions
35
+ * Moved reset_session into only the "now logged in" branch
36
+ ** wherever it goes, it has to be in front of the current_user= call
37
+ ** See more in README-Tradeoffs.txt
38
+ * made the implicit login only happen for non-activationed sites
39
+ * On a failed signup, kick you back to the signin screen (but strip out the password & confirmation)
40
+ * more descriptive error messages in activate()
41
+
42
+ h3. users_helper
43
+
44
+ * link_to_user, link_to_current_user, link_to_signin_with_IP
45
+ * if_authorized(action, resource, &block) view function (with appropriate
46
+ warning)
47
+
48
+ h3. authenticated_system
49
+
50
+ * Made authorized? take optional arguments action=nil, resource=nil, *args
51
+ This makes its signature better match traditional approaches to access control
52
+ eg Reference Monitor in "Security Patterns":http://www.securitypatterns.org/patterns.html)
53
+ * authorized? should be a helper too
54
+ * added uniform logout! methods
55
+ * format.any (as found in access_denied) doesn't work until
56
+ http://dev.rubyonrails.org/changeset/8987 lands.
57
+ * cookies are now refreshed each time we cross the logged out/in barrier, as
58
+ "best":http://palisade.plynt.com/issues/2004Jul/safe-auth-practices/
59
+ "practice":http://www.owasp.org/index.php/Session_Management#Regeneration_of_Session_Tokens
60
+
61
+ h3. Other
62
+
63
+ * Used escapes <%= %> in email templates (among other reasons, so courtenay's
64
+ "'dumbass' test":http://tinyurl.com/684g9t doesn't complain)
65
+ * Added site key to generator, users.yml.
66
+ * Made site key generation idempotent in the most crude and hackish way
67
+ * 100% coverage apart from the stateful code. (needed some access_control
68
+ checks, and the http_auth stuff)
69
+ * Stories!
70
+
@@ -0,0 +1,176 @@
1
+ h1. "Restful Authentication Generator":https://github.com/vatrai/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
+ * "https://github.com/vatrai/restful_authentication/issues":https://github.com/vatrai/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,40 @@
1
+ module Authentication
2
+ mattr_accessor :login_regex, :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[[:alnum:]][[:alnum:]\.\-_@]+\z/ # Unicode, strict
8
+ # self.login_regex = /\A[^[:cntrl:]\\<>\/&]*\z/ # Unicode, permissive
9
+
10
+ self.bad_login_message = "use only letters, numbers, and .-_@ please.".freeze
11
+
12
+ self.name_regex = /\A[^[:cntrl:]\\<>\/&]*\z/ # Unicode, permissive
13
+ self.bad_name_message = "avoid non-printing characters and \\&gt;&lt;&amp;/ please.".freeze
14
+
15
+ self.email_name_regex = '[\w\.%\+\-]+'.freeze
16
+ self.domain_head_regex = '(?:[A-Z0-9\-]+\.)+'.freeze
17
+ self.domain_tld_regex = '(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|jobs|museum)'.freeze
18
+ self.email_regex = /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i
19
+ self.bad_email_message = "should look like an email address.".freeze
20
+
21
+ def self.included(recipient)
22
+ recipient.extend(ModelClassMethods)
23
+ recipient.class_eval do
24
+ include ModelInstanceMethods
25
+ end
26
+ end
27
+
28
+ module ModelClassMethods
29
+ def secure_digest(*args)
30
+ Digest::SHA1.hexdigest(args.flatten.join('--'))
31
+ end
32
+
33
+ def make_token
34
+ secure_digest(Time.now, (1..10).map{ rand.to_s })
35
+ end
36
+ end # class methods
37
+
38
+ module ModelInstanceMethods
39
+ end # instance methods
40
+ end
@@ -0,0 +1,73 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Authentication
3
+ module ByCookieToken
4
+ def self.included(recipient)
5
+ recipient.extend(ModelClassMethods)
6
+ recipient.class_eval do
7
+ include ModelInstanceMethods
8
+ end
9
+ end
10
+
11
+ module ModelClassMethods
12
+ end
13
+
14
+ module ModelInstanceMethods
15
+ def remember_token?
16
+ (!remember_token.blank?) &&
17
+ remember_token_expires_at && (Time.now.utc < remember_token_expires_at.utc)
18
+ end
19
+
20
+ def remember_me
21
+ remember_me_for 2.weeks
22
+ end
23
+
24
+ def remember_me_for(time)
25
+ remember_me_until time.from_now.utc
26
+ end
27
+
28
+ def remember_me_until(time)
29
+ self.remember_token_expires_at = time
30
+ self.remember_token = self.class.make_token
31
+ save(:validate => false)
32
+ end
33
+
34
+ # refresh token (keeping same expires_at) if it exists
35
+ def refresh_token
36
+ if remember_token?
37
+ self.remember_token = self.class.make_token
38
+ save(:validate => false)
39
+ end
40
+ end
41
+
42
+ #
43
+ # Deletes the server-side record of the authentication token. The
44
+ # client-side (browser cookie) and server-side (this remember_token) must
45
+ # always be deleted together.
46
+ #
47
+ def forget_me
48
+ self.remember_token_expires_at = nil
49
+ self.remember_token = nil
50
+ save(:validate => false)
51
+ end
52
+ end # instance methods
53
+ end
54
+
55
+ module ByCookieTokenController
56
+ # Stuff directives into including module
57
+ def self.included( recipient )
58
+ recipient.extend( ControllerClassMethods )
59
+ recipient.class_eval do
60
+ include ControllerInstanceMethods
61
+ end
62
+ end
63
+
64
+ #
65
+ # Class Methods
66
+ #
67
+ module ControllerClassMethods
68
+ end # class methods
69
+
70
+ module ControllerInstanceMethods
71
+ end # instance methods
72
+ end
73
+ end
@@ -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