Commit 588faac9c8f84b6b874cd4b004dbe5712563eff6
1 parent
384ed39e
Exists in
master
and in
1 other branch
adding a cucumber db to database.yml. unpacking clearance as a plugin. convertin…
…g webrat steps to use test::unit assertions instead of rspec matchers.
Showing
48 changed files
with
1817 additions
and
25 deletions
Show diff stats
config/database.yml
1 | 1 | # SQLite version 3.x |
2 | 2 | # gem install sqlite3-ruby (not necessary on OS X Leopard) |
3 | -development: | |
3 | +development: &default | |
4 | 4 | adapter: sqlite3 |
5 | 5 | database: db/development.sqlite3 |
6 | 6 | pool: 5 |
7 | 7 | timeout: 5000 |
8 | 8 | |
9 | -# Warning: The database defined as "test" will be erased and | |
10 | -# re-generated from your development database when you run "rake". | |
11 | -# Do not set this db to the same as development or production. | |
12 | 9 | test: |
13 | - adapter: sqlite3 | |
10 | + <<: *default | |
14 | 11 | database: db/test.sqlite3 |
15 | - pool: 5 | |
16 | - timeout: 5000 | |
17 | 12 | |
18 | -production: | |
19 | - adapter: sqlite3 | |
20 | - database: db/production.sqlite3 | |
21 | - pool: 5 | |
22 | - timeout: 5000 | |
13 | +cucumber: | |
14 | + <<: *default | |
15 | + database: db/cucumber.sqlite3 | |
23 | 16 | ... | ... |
config/environments/cucumber.rb
... | ... | @@ -15,7 +15,13 @@ config.action_controller.allow_forgery_protection = false |
15 | 15 | # ActionMailer::Base.deliveries array. |
16 | 16 | config.action_mailer.delivery_method = :test |
17 | 17 | |
18 | -config.gem "cucumber", :lib => false, :version => ">=0.3.11" unless File.directory?(File.join(Rails.root, 'vendor/plugins/cucumber')) | |
19 | -config.gem "webrat", :lib => false, :version => ">=0.4.4" unless File.directory?(File.join(Rails.root, 'vendor/plugins/webrat')) | |
20 | -config.gem "rspec", :lib => false, :version => ">=1.2.6" unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec')) | |
21 | -config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.2.6" unless File.directory?(File.join(Rails.root, 'vendor/plugins/rspec-rails')) | |
18 | +config.gem "cucumber", :lib => false, :version => ">=0.3.11" | |
19 | +config.gem "webrat", :lib => false, :version => ">=0.4.4" | |
20 | + | |
21 | +# config.gem "rspec", :lib => false, :version => ">=1.2.6" | |
22 | +# config.gem "rspec-rails", :lib => 'spec/rails', :version => ">=1.2.6" | |
23 | + | |
24 | +require 'rubygems' | |
25 | +require 'factory_girl' | |
26 | +require 'shoulda' | |
27 | + | ... | ... |
features/step_definitions/webrat_steps.rb
... | ... | @@ -91,29 +91,37 @@ When /^I attach the file at "([^\"]*)" to "([^\"]*)"$/ do |path, field| |
91 | 91 | end |
92 | 92 | |
93 | 93 | Then /^I should see "([^\"]*)"$/ do |text| |
94 | - response.should contain(text) | |
94 | + # response.should contain(text) | |
95 | + assert_match /#{text}/m, @response.body | |
95 | 96 | end |
96 | 97 | |
97 | 98 | Then /^I should not see "([^\"]*)"$/ do |text| |
98 | - response.should_not contain(text) | |
99 | + # response.should_not contain(text) | |
100 | + assert_no_match /#{text}/m, @response.body | |
99 | 101 | end |
100 | 102 | |
101 | 103 | Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value| |
102 | - field_labeled(field).value.should =~ /#{value}/ | |
104 | + # field_labeled(field).value.should =~ /#{value}/ | |
105 | + assert_match /#{value}/, field_labeled(field).value | |
103 | 106 | end |
104 | 107 | |
105 | 108 | Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value| |
106 | - field_labeled(field).value.should_not =~ /#{value}/ | |
109 | + # field_labeled(field).value.should_not =~ /#{value}/ | |
110 | + assert_no_match /#{value}/, field_labeled(field).value | |
107 | 111 | end |
108 | - | |
112 | + | |
109 | 113 | Then /^the "([^\"]*)" checkbox should be checked$/ do |label| |
110 | - field_labeled(label).should be_checked | |
114 | + # field_labeled(label).should be_checked | |
115 | + assert field_labeled(label).checked? | |
111 | 116 | end |
112 | 117 | |
113 | 118 | Then /^the "([^\"]*)" checkbox should not be checked$/ do |label| |
114 | - field_labeled(label).should_not be_checked | |
119 | + # field_labeled(label).should_not be_checked | |
120 | + assert !field_labeled(label).checked? | |
115 | 121 | end |
116 | 122 | |
117 | 123 | Then /^I should be on (.+)$/ do |page_name| |
118 | - URI.parse(current_url).path.should == path_to(page_name) | |
124 | + # URI.parse(current_url).path.should == path_to(page_name) | |
125 | + assert_equal path_to(page_name), URI.parse(current_url).path | |
119 | 126 | end |
127 | + | ... | ... |
features/support/env.rb
vendor/plugins/thoughtbot-clearance-0.6.8/CHANGELOG.textile
0 → 100644
... | ... | @@ -0,0 +1,162 @@ |
1 | +h2. 0.6.8 (06/24/2009) | |
2 | + | |
3 | +* Added defined? checks for various Rails constants such as ActionController | |
4 | +for easier unit testing of Clearance extensions... particularly ActiveRecord | |
5 | +extensions... particularly strong_password. (Dan Croak) | |
6 | + | |
7 | +h2. 0.6.7 (06/13/2009) | |
8 | + | |
9 | +* [#30] Added sign_up, sign_in, sign_out named routes. (Dan Croak) | |
10 | +* [#22] Minimizing Reek smell: Duplication in redirect_back_or. (Dan Croak) | |
11 | +* Deprecated sign_user_in. Told developers to use sign_in instead. (Dan | |
12 | +Croak) | |
13 | +* [#16] flash_success_after_create, flash_notice_after_create, flash_failure_after_create, flash_sucess_after_update, flash_success_after_destroy, etc. (Dan Croak) | |
14 | +* [#17] bug. added #create to forbidden before_filters on confirmations controller. (Dan Croak) | |
15 | +* [#24] should_be_signed_in_as shouldn't look in the session. (Dan Croak) | |
16 | +* README improvements. (Dan Croak) | |
17 | +* Move routes loading to separate file. (Joshua Clayton) | |
18 | + | |
19 | +h2. 0.6.6 (05/18/2009) | |
20 | + | |
21 | +* [#14] replaced class_eval in Clearance::User with modules. This was needed | |
22 | +in a thoughtbot client app so we could write our own validations. (Dan Croak) | |
23 | + | |
24 | +h2. 0.6.5 (05/17/2009) | |
25 | + | |
26 | +* [#6] Make Clearance i18n aware. (Timur Vafin, Marcel Goerner, Eugene Bolshakov, Dan Croak) | |
27 | + | |
28 | +h2. 0.6.4 (05/12/2009) | |
29 | + | |
30 | +* Moved issue tracking to Github from Lighthouse. (Dan Croak) | |
31 | +* [#7] asking higher-level questions of controllers in webrat steps, such as signed_in? instead of what's in the session. same for accessors. (Dan Croak) | |
32 | +* [#11] replacing sign_in_as & sign_out shoulda macros with a stubbing (requires no dependency) approach. this will avoid dealing with the internals of current_user, such as session & cookies. added sign_in macro which signs in an email confirmed user from clearance's factories. (Dan Croak) | |
33 | +* [#13] move private methods on sessions controller into Clearance::Authentication module (Dan Croak) | |
34 | +* [#9] audited flash keys. (Dan Croak) | |
35 | + | |
36 | +h2. 0.6.3 (04/23/2009) | |
37 | + | |
38 | +* Scoping ClearanceMailer properly within controllers so it works in production environments. (Nick Quaranto) | |
39 | + | |
40 | +h2. 0.6.2 (04/22/2009) | |
41 | + | |
42 | +* Insert Clearance::User into User model if it exists. (Nick Quaranto) | |
43 | +* World(NavigationHelpers) Cucumber 3.0 style. (Shay Arnett & Mark Cornick) | |
44 | + | |
45 | +h2. 0.6.1 (04/21/2009) | |
46 | +* Scope operators are necessary to keep Rails happy. Reverting the original | |
47 | +revert so they're back in the library now for constants referenced inside of | |
48 | +the gem. (Nick Quaranto) | |
49 | + | |
50 | +h2. 0.6.0 (04/21/2009) | |
51 | + | |
52 | +* Converted Clearance to a Rails engine. (Dan Croak & Joe Ferris) | |
53 | +* Include Clearance::User in User model in app. (Dan Croak & Joe Ferris) | |
54 | +* Include Clearance::Authentication in ApplicationController. (Dan Croak & Joe Ferris) | |
55 | +* Namespace controllers under Clearance. (Dan Croak & Joe Ferris) | |
56 | +* Routes move to engine, use namespaced controllers but publicly the same. (Dan Croak & Joe Ferris) | |
57 | +* If you want to override a controller, subclass it like SessionsController < | |
58 | +Clearance::SessionsController. This gives you access to usual hooks such as | |
59 | +url_after_create. (Dan Croak & Joe Ferris) | |
60 | +* Controllers, mailer, model, routes all unit tested inside engine. Use | |
61 | +script/generate clearance_features to test integration of Clearance with your | |
62 | +Rails app. No longer including modules in your app's test files. (Dan Croak & Joe Ferris) | |
63 | +* Moved views to engine. (Joe Ferris) | |
64 | +* Converted generated test/factories/clearance.rb to use inheritence for | |
65 | +email_confirmed_user. (Dan Croak) | |
66 | +* Corrected some spelling errors with methods (Nick Quaranto) | |
67 | +* Converted "I should see error messages" to use a regex in the features (Nick | |
68 | +Quaranto) | |
69 | +* Loading clearance routes after rails routes via some monkeypatching (Nick | |
70 | +Quaranto) | |
71 | +* Made the clearance controllers unloadable to stop constant loading errors in | |
72 | +development mode (Nick Quaranto) | |
73 | + | |
74 | +h2. 0.5.6 (4/11/2009) | |
75 | + | |
76 | +* [#57] Step definition changed for "User should see error messages" so | |
77 | +features won't fail for certain validations. (Nick Quaranto) | |
78 | + | |
79 | +h2. 0.5.5 (3/23/2009) | |
80 | + | |
81 | +* Removing duplicate test to get rid of warning. (Nick Quaranto) | |
82 | + | |
83 | +h2. 0.5.4 (3/21/2009) | |
84 | + | |
85 | +* When users fail logging in, redirect them instead of rendering. (Matt | |
86 | +Jankowski) | |
87 | + | |
88 | +h2. 0.5.3 (3/5/2009) | |
89 | + | |
90 | +* Clearance now works with (and requires) Shoulda 2.10.0. (Mark Cornick, Joe | |
91 | +Ferris, Dan Croak) | |
92 | +* Prefer flat over nested contexts in sessions_controller_test. (Joe Ferris, | |
93 | +Dan Croak) | |
94 | + | |
95 | +h2. 0.5.2 (3/2/2009) | |
96 | + | |
97 | +* Fixed last remaining errors in Rails 2.3 tests. Now fully compatible. (Joe | |
98 | +Ferris, Dan Croak) | |
99 | + | |
100 | +h2. 0.5.1 (2/27/2009) | |
101 | + | |
102 | +* [#46] A user with unconfirmed email who resets password now confirms email. | |
103 | +(Marcel Görner) | |
104 | +* Refactored user_from_cookie, user_from_session, User#authenticate to use | |
105 | +more direct return code instead of ugly, harder to read ternary. (Dan Croak) | |
106 | +* Switch order of cookies and sessions to take advantage of Rails 2.3's "Rack-based lazy-loaded sessions":http://is.gd/i23E. (Dan Croak) | |
107 | +* Altered generator to interact with application_controller.rb instead of | |
108 | +application.rb in Rails 2.3 apps. (Dan Croak) | |
109 | +* [#42] Bug fix. Rack-based session change altered how to test remember me | |
110 | +cookie. (Mihai Anca) | |
111 | + | |
112 | +h2. 0.5.0 (2/27/2009) | |
113 | + | |
114 | +* Fixed problem with Cucumber features. (Dan Croak) | |
115 | +* Fixed mising HTTP fluency use case. (Dan Croak) | |
116 | +* Refactored User#update_password to take just parameters it needs. (Dan | |
117 | +Croak) | |
118 | +* Refactored User unit tests to be more readable. (Dan Croak) | |
119 | + | |
120 | +h2. 0.4.9 (2/20/2009) | |
121 | + | |
122 | +* Protect passwords & confirmations actions with forbidden filters. (Dan Croak) | |
123 | +* Return 403 Forbidden status code in those cases. (Tim Pope) | |
124 | +* Test 403 Forbidden status code in Cucumber feature. (Dan Croak, Joe Ferris) | |
125 | +* Raise custom ActionController::Forbidden error internally. (Joe Ferris, Mike Burns, Jason Morrison) | |
126 | +* Test ActionController::Forbidden error is raised in functional test. (Joe Ferris, Mike Burns, Dan Croak) | |
127 | +* [#45] Fixed bug that allowed anyone to edit another user's password (Marcel Görner) | |
128 | +* Required Factory Girl >= 1.2.0. (Dan Croak) | |
129 | + | |
130 | +h2. 0.4.8 (2/16/2009) | |
131 | + | |
132 | +* Added support paths for Cucumber. (Ben Mabey) | |
133 | +* Added documentation for the flash. (Ben Mabey) | |
134 | +* Generators require "test_helper" instead of File.join. for rr compatibility. (Joe Ferris) | |
135 | +* Removed interpolated email address from flash message to make i18n easier. (Bence Nagy) | |
136 | +* Standardized flash messages that refer to email delivery. (Dan Croak) | |
137 | + | |
138 | +h2. 0.4.7 (2/12/2009) | |
139 | + | |
140 | +* Removed Clearance::Test::TestHelper so there is one less setup step. (Dan Croak) | |
141 | +* All test helpers now in shoulda_macros. (Dan Croak) | |
142 | + | |
143 | +h2. 0.4.6 (2/11/2009) | |
144 | + | |
145 | +* Made the modules behave like mixins again. (hat-tip Eloy Duran) | |
146 | +* Created Actions and PrivateMethods modules on controllers for future RDoc reasons. (Dan Croak, Joe Ferris) | |
147 | + | |
148 | +h2. 0.4.5 (2/9/2009) | |
149 | + | |
150 | +* [#43] Removed email downcasing because local-part is case sensitive per RFC5321. (Dan Croak) | |
151 | +* [#42] Removed dependency on Mocha. (Dan Croak) | |
152 | +* Required Shoulda >= 2.9.1. (Dan Croak) | |
153 | +* Added password reset feature to clearance_features generator. (Eugene Bolshakov, Dan Croak) | |
154 | +* Removed unnecessary session[:salt]. (Dan Croak) | |
155 | +* [#41] Only store location for session[:return_to] for GET requests. (Dan Croak) | |
156 | +* Audited "sign up" naming convention. "Register" had slipped in a few places. (Dan Croak) | |
157 | +* Switched to SHA1 encryption. Cypher doesn't matter much for email confirmation, password reset. Better to have shorter hashes in the emails for clients who line break on 72 chars. (Dan Croak) | |
158 | + | |
159 | +h2. 0.4.4 (2/2/2009) | |
160 | + | |
161 | +* Added a generator for Cucumber features. (Joe Ferris, Dan Croak) | |
162 | +* Standarized naming for "Sign up," "Sign in," and "Sign out". (Dan Croak) | ... | ... |
... | ... | @@ -0,0 +1,21 @@ |
1 | +The MIT License | |
2 | + | |
3 | +Copyright (c) 2008 thoughtbot, inc. | |
4 | + | |
5 | +Permission is hereby granted, free of charge, to any person obtaining a copy | |
6 | +of this software and associated documentation files (the "Software"), to deal | |
7 | +in the Software without restriction, including without limitation the rights | |
8 | +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
9 | +copies of the Software, and to permit persons to whom the Software is | |
10 | +furnished to do so, subject to the following conditions: | |
11 | + | |
12 | +The above copyright notice and this permission notice shall be included in | |
13 | +all copies or substantial portions of the Software. | |
14 | + | |
15 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 | +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 | +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
18 | +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 | +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 | +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
21 | +THE SOFTWARE. | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/README.textile
0 → 100644
... | ... | @@ -0,0 +1,123 @@ |
1 | +h1. Clearance | |
2 | + | |
3 | +Rails authentication with email & password. | |
4 | + | |
5 | +"We have clearance, Clarence.":http://www.youtube.com/v/mNRXJEE3Nz8 | |
6 | + | |
7 | +h2. Wiki | |
8 | + | |
9 | +Most information regarding Clearance is on the "Github Wiki":http://wiki.github.com/thoughtbot/clearance. | |
10 | + | |
11 | +h2. Installation | |
12 | + | |
13 | +Clearance is a Rails engine. It works with versions of Rails greater than 2.3. | |
14 | + | |
15 | +In config/environment.rb: | |
16 | + | |
17 | +<pre> | |
18 | +config.gem "thoughtbot-clearance", | |
19 | + :lib => 'clearance', | |
20 | + :source => 'http://gems.github.com', | |
21 | + :version => '0.6.6' | |
22 | +</pre> | |
23 | + | |
24 | +Vendor the gem: | |
25 | + | |
26 | +<pre> | |
27 | +rake gems:install | |
28 | +rake gems:unpack | |
29 | +</pre> | |
30 | + | |
31 | +Make sure the development database exists and run the generator: | |
32 | + | |
33 | +@script/generate clearance@ | |
34 | + | |
35 | +A number of files will be created and instructions will be printed. | |
36 | + | |
37 | +You may already have some of these files. Don't worry. You'll be asked if you want to overwrite them. | |
38 | + | |
39 | +Run the migration: | |
40 | + | |
41 | +@rake db:migrate@ | |
42 | + | |
43 | +Define a HOST constant in your environment files. | |
44 | +In config/environments/test.rb and config/environments/development.rb it can be: | |
45 | + | |
46 | +@HOST = "localhost"@ | |
47 | + | |
48 | +In production.rb it must be the actual host your application is deployed to. | |
49 | +The constant is used by mailers to generate URLs in emails. | |
50 | + | |
51 | +In config/environment.rb: | |
52 | + | |
53 | +@DO_NOT_REPLY = "donotreply@example.com"@ | |
54 | + | |
55 | +Define root_url to *something* in your config/routes.rb: | |
56 | + | |
57 | +@map.root :controller => 'home'@ | |
58 | + | |
59 | +h2. Cucumber Features | |
60 | + | |
61 | +As your app evolves, you want to know that authentication still works. Clearance's opinion is that you should test its integration with your app using "Cucumber":http://cukes.info/. | |
62 | + | |
63 | +In config/environments/test.rb: | |
64 | + | |
65 | +<pre> | |
66 | +config.gem 'webrat', | |
67 | + :version => '= 0.4.4' | |
68 | +config.gem 'cucumber', | |
69 | + :version => '= 0.3.0' | |
70 | +config.gem 'thoughtbot-factory_girl', | |
71 | + :lib => 'factory_girl', | |
72 | + :source => "http://gems.github.com", | |
73 | + :version => '1.2.1' | |
74 | +</pre> | |
75 | + | |
76 | +Vendor the gems: | |
77 | + | |
78 | +<pre> | |
79 | +rake gems:install RAILS_ENV=test | |
80 | +rake gems:unpack RAILS_ENV=test | |
81 | +</pre> | |
82 | + | |
83 | +We don't vendor nokogiri due to its native extensions, so install it normally on your machine: | |
84 | + | |
85 | +@sudo gem install nokogiri@ | |
86 | + | |
87 | +Run the Cucumber generator (if you haven't already) and Clearance's feature generator: | |
88 | + | |
89 | +<pre> | |
90 | +script/generate cucumber | |
91 | +script/generate clearance_features | |
92 | +</pre> | |
93 | + | |
94 | +All of the files generated should be new with the exception of the features/support/paths.rb file. If you have not modified your paths.rb then you will be okay to replace it with this one. If you need to keep your paths.rb file then add these locations in your paths.rb manually: | |
95 | + | |
96 | +<pre> | |
97 | +def path_to(page_name) | |
98 | + case page_name | |
99 | + ... | |
100 | + when /the sign up page/i | |
101 | + new_user_path | |
102 | + when /the sign in page/i | |
103 | + new_session_path | |
104 | + when /the password reset request page/i | |
105 | + new_password_path | |
106 | + ... | |
107 | +end | |
108 | +</pre> | |
109 | + | |
110 | +h2. Authors | |
111 | + | |
112 | +Clearance was extracted out of "Hoptoad":http://hoptoadapp.com. We merged the authentication code from two of thoughtbot's clients' Rails apps and have since used it each time we need authentication. The following people have improved the library. Thank you! | |
113 | + | |
114 | +Dan Croak, Mike Burns, Jason Morrison, Joe Ferris, Eugene Bolshakov, Nick Quaranto, Josh Nichols, Mike Breen, Marcel Görner, Bence Nagy, Ben Mabey, Eloy Duran, Tim Pope, Mihai Anca, Mark Cornick, Shay Arnett, Joshua Clayton & Mustafa Ekim. | |
115 | + | |
116 | +h2. Questions? | |
117 | + | |
118 | +Ask the "mailing list":http://groups.google.com/group/thoughtbot-clearance | |
119 | + | |
120 | +h2. Suggestions, Bugs, Refactoring? | |
121 | + | |
122 | +Fork away and create a "Github Issue":http://github.com/thoughtbot/clearance/issues. Please don't send pull requests. | |
123 | + | ... | ... |
... | ... | @@ -0,0 +1,76 @@ |
1 | +# encoding: utf-8 | |
2 | + | |
3 | +require 'rake' | |
4 | +require 'rake/testtask' | |
5 | +require 'cucumber/rake/task' | |
6 | + | |
7 | +namespace :test do | |
8 | + Rake::TestTask.new(:all => ["generator:cleanup", | |
9 | + "generator:generate"]) do |task| | |
10 | + task.libs << "lib" | |
11 | + task.libs << "test" | |
12 | + task.pattern = "test/**/*_test.rb" | |
13 | + task.verbose = false | |
14 | + end | |
15 | + | |
16 | + Cucumber::Rake::Task.new(:features) do |t| | |
17 | + t.cucumber_opts = "--format progress" | |
18 | + t.feature_pattern = "test/rails_root/features/*.feature" | |
19 | + end | |
20 | +end | |
21 | + | |
22 | +generators = %w(clearance clearance_features) | |
23 | + | |
24 | +namespace :generator do | |
25 | + desc "Cleans up the test app before running the generator" | |
26 | + task :cleanup do | |
27 | + generators.each do |generator| | |
28 | + FileList["generators/#{generator}/templates/**/*.*"].each do |each| | |
29 | + file = "test/rails_root/#{each.gsub("generators/#{generator}/templates/",'')}" | |
30 | + File.delete(file) if File.exists?(file) | |
31 | + end | |
32 | + end | |
33 | + | |
34 | + FileList["test/rails_root/db/**/*"].each do |each| | |
35 | + FileUtils.rm_rf(each) | |
36 | + end | |
37 | + FileUtils.rm_rf("test/rails_root/vendor/plugins/clearance") | |
38 | + FileUtils.mkdir_p("test/rails_root/vendor/plugins") | |
39 | + clearance_root = File.expand_path(File.dirname(__FILE__)) | |
40 | + system("ln -s #{clearance_root} test/rails_root/vendor/plugins/clearance") | |
41 | + end | |
42 | + | |
43 | + desc "Run the generator on the tests" | |
44 | + task :generate do | |
45 | + generators.each do |generator| | |
46 | + system "cd test/rails_root && ./script/generate #{generator} && rake db:migrate db:test:prepare" | |
47 | + end | |
48 | + end | |
49 | +end | |
50 | + | |
51 | +desc "Run the test suite" | |
52 | +task :default => ['test:all', 'test:features'] | |
53 | + | |
54 | +gem_spec = Gem::Specification.new do |gem_spec| | |
55 | + gem_spec.name = "clearance" | |
56 | + gem_spec.version = "0.6.8" | |
57 | + gem_spec.summary = "Rails authentication with email & password." | |
58 | + gem_spec.email = "support@thoughtbot.com" | |
59 | + gem_spec.homepage = "http://github.com/thoughtbot/clearance" | |
60 | + gem_spec.description = "Rails authentication with email & password." | |
61 | + gem_spec.authors = ["Dan Croak", "Mike Burns", "Jason Morrison", | |
62 | + "Joe Ferris", "Eugene Bolshakov", "Nick Quaranto", | |
63 | + "Josh Nichols", "Mike Breen", "Marcel Görner", | |
64 | + "Bence Nagy", "Ben Mabey", "Eloy Duran", | |
65 | + "Tim Pope", "Mihai Anca", "Mark Cornick", | |
66 | + "Shay Arnett"] | |
67 | + gem_spec.files = FileList["[A-Z]*", "{app,config,generators,lib,shoulda_macros,rails}/**/*"] | |
68 | +end | |
69 | + | |
70 | +desc "Generate a gemspec file" | |
71 | +task :gemspec do | |
72 | + File.open("#{gem_spec.name}.gemspec", 'w') do |f| | |
73 | + f.write gem_spec.to_yaml | |
74 | + end | |
75 | +end | |
76 | + | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/controllers/clearance/confirmations_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,52 @@ |
1 | +class Clearance::ConfirmationsController < ApplicationController | |
2 | + unloadable | |
3 | + | |
4 | + before_filter :forbid_confirmed_user, :only => [:new, :create] | |
5 | + before_filter :forbid_missing_token, :only => [:new, :create] | |
6 | + before_filter :forbid_non_existent_user, :only => [:new, :create] | |
7 | + filter_parameter_logging :token | |
8 | + | |
9 | + def new | |
10 | + create | |
11 | + end | |
12 | + | |
13 | + def create | |
14 | + @user = ::User.find_by_id_and_token(params[:user_id], params[:token]) | |
15 | + @user.confirm_email! | |
16 | + | |
17 | + sign_in(@user) | |
18 | + flash_success_after_create | |
19 | + redirect_to(url_after_create) | |
20 | + end | |
21 | + | |
22 | + private | |
23 | + | |
24 | + def forbid_confirmed_user | |
25 | + user = ::User.find_by_id(params[:user_id]) | |
26 | + if user && user.email_confirmed? | |
27 | + raise ActionController::Forbidden, "confirmed user" | |
28 | + end | |
29 | + end | |
30 | + | |
31 | + def forbid_missing_token | |
32 | + if params[:token].blank? | |
33 | + raise ActionController::Forbidden, "missing token" | |
34 | + end | |
35 | + end | |
36 | + | |
37 | + def forbid_non_existent_user | |
38 | + unless ::User.find_by_id_and_token(params[:user_id], params[:token]) | |
39 | + raise ActionController::Forbidden, "non-existent user" | |
40 | + end | |
41 | + end | |
42 | + | |
43 | + def flash_success_after_create | |
44 | + flash[:success] = translate(:confirmed_email, | |
45 | + :scope => [:clearance, :controllers, :confirmations], | |
46 | + :default => "Confirmed email and signed in.") | |
47 | + end | |
48 | + | |
49 | + def url_after_create | |
50 | + root_url | |
51 | + end | |
52 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/controllers/clearance/passwords_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,81 @@ |
1 | +class Clearance::PasswordsController < ApplicationController | |
2 | + unloadable | |
3 | + | |
4 | + before_filter :forbid_missing_token, :only => [:edit, :update] | |
5 | + before_filter :forbid_non_existent_user, :only => [:edit, :update] | |
6 | + filter_parameter_logging :password, :password_confirmation | |
7 | + | |
8 | + def new | |
9 | + render :template => 'passwords/new' | |
10 | + end | |
11 | + | |
12 | + def create | |
13 | + if user = ::User.find_by_email(params[:password][:email]) | |
14 | + user.forgot_password! | |
15 | + ::ClearanceMailer.deliver_change_password user | |
16 | + flash_notice_after_create | |
17 | + redirect_to(url_after_create) | |
18 | + else | |
19 | + flash_failure_after_create | |
20 | + render :template => 'passwords/new' | |
21 | + end | |
22 | + end | |
23 | + | |
24 | + def edit | |
25 | + @user = ::User.find_by_id_and_token(params[:user_id], params[:token]) | |
26 | + render :template => 'passwords/edit' | |
27 | + end | |
28 | + | |
29 | + def update | |
30 | + @user = ::User.find_by_id_and_token(params[:user_id], params[:token]) | |
31 | + | |
32 | + if @user.update_password(params[:user][:password], | |
33 | + params[:user][:password_confirmation]) | |
34 | + @user.confirm_email! | |
35 | + sign_in(@user) | |
36 | + flash_success_after_update | |
37 | + redirect_to(url_after_update) | |
38 | + else | |
39 | + render :template => 'passwords/edit' | |
40 | + end | |
41 | + end | |
42 | + | |
43 | + private | |
44 | + | |
45 | + def forbid_missing_token | |
46 | + if params[:token].blank? | |
47 | + raise ActionController::Forbidden, "missing token" | |
48 | + end | |
49 | + end | |
50 | + | |
51 | + def forbid_non_existent_user | |
52 | + unless ::User.find_by_id_and_token(params[:user_id], params[:token]) | |
53 | + raise ActionController::Forbidden, "non-existent user" | |
54 | + end | |
55 | + end | |
56 | + | |
57 | + def flash_notice_after_create | |
58 | + flash[:notice] = translate(:deliver_change_password, | |
59 | + :scope => [:clearance, :controllers, :passwords], | |
60 | + :default => "You will receive an email within the next few minutes. " << | |
61 | + "It contains instructions for changing your password.") | |
62 | + end | |
63 | + | |
64 | + def flash_failure_after_create | |
65 | + flash.now[:failure] = translate(:unknown_email, | |
66 | + :scope => [:clearance, :controllers, :passwords], | |
67 | + :default => "Unknown email.") | |
68 | + end | |
69 | + | |
70 | + def url_after_create | |
71 | + new_session_url | |
72 | + end | |
73 | + | |
74 | + def flash_success_after_update | |
75 | + flash[:success] = translate(:signed_in, :default => "Signed in.") | |
76 | + end | |
77 | + | |
78 | + def url_after_update | |
79 | + root_url | |
80 | + end | |
81 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/controllers/clearance/sessions_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,67 @@ |
1 | +class Clearance::SessionsController < ApplicationController | |
2 | + unloadable | |
3 | + | |
4 | + protect_from_forgery :except => :create | |
5 | + filter_parameter_logging :password | |
6 | + | |
7 | + def new | |
8 | + render :template => 'sessions/new' | |
9 | + end | |
10 | + | |
11 | + def create | |
12 | + @user = ::User.authenticate(params[:session][:email], | |
13 | + params[:session][:password]) | |
14 | + if @user.nil? | |
15 | + flash_failure_after_create | |
16 | + render :template => 'sessions/new', :status => :unauthorized | |
17 | + else | |
18 | + if @user.email_confirmed? | |
19 | + sign_in(@user) | |
20 | + remember(@user) if remember? | |
21 | + flash_success_after_create | |
22 | + redirect_back_or(url_after_create) | |
23 | + else | |
24 | + ::ClearanceMailer.deliver_confirmation(@user) | |
25 | + flash_notice_after_create | |
26 | + redirect_to(new_session_url) | |
27 | + end | |
28 | + end | |
29 | + end | |
30 | + | |
31 | + def destroy | |
32 | + forget(current_user) | |
33 | + flash_success_after_destroy | |
34 | + redirect_to(url_after_destroy) | |
35 | + end | |
36 | + | |
37 | + private | |
38 | + | |
39 | + def flash_failure_after_create | |
40 | + flash.now[:failure] = translate(:bad_email_or_password, | |
41 | + :scope => [:clearance, :controllers, :sessions], | |
42 | + :default => "Bad email or password.") | |
43 | + end | |
44 | + | |
45 | + def flash_success_after_create | |
46 | + flash[:success] = translate(:signed_in, :default => "Signed in.") | |
47 | + end | |
48 | + | |
49 | + def flash_notice_after_create | |
50 | + flash[:notice] = translate(:unconfirmed_email, | |
51 | + :scope => [:clearance, :controllers, :sessions], | |
52 | + :default => "User has not confirmed email. " << | |
53 | + "Confirmation email will be resent.") | |
54 | + end | |
55 | + | |
56 | + def url_after_create | |
57 | + root_url | |
58 | + end | |
59 | + | |
60 | + def flash_success_after_destroy | |
61 | + flash[:success] = translate(:signed_out, :default => "Signed out.") | |
62 | + end | |
63 | + | |
64 | + def url_after_destroy | |
65 | + new_session_url | |
66 | + end | |
67 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/controllers/clearance/users_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,35 @@ |
1 | +class Clearance::UsersController < ApplicationController | |
2 | + unloadable | |
3 | + | |
4 | + before_filter :redirect_to_root, :only => [:new, :create], :if => :signed_in? | |
5 | + filter_parameter_logging :password | |
6 | + | |
7 | + def new | |
8 | + @user = ::User.new(params[:user]) | |
9 | + render :template => 'users/new' | |
10 | + end | |
11 | + | |
12 | + def create | |
13 | + @user = ::User.new params[:user] | |
14 | + if @user.save | |
15 | + ::ClearanceMailer.deliver_confirmation @user | |
16 | + flash_notice_after_create | |
17 | + redirect_to(url_after_create) | |
18 | + else | |
19 | + render :template => 'users/new' | |
20 | + end | |
21 | + end | |
22 | + | |
23 | + private | |
24 | + | |
25 | + def flash_notice_after_create | |
26 | + flash[:notice] = translate(:deliver_confirmation, | |
27 | + :scope => [:clearance, :controllers, :users], | |
28 | + :default => "You will receive an email within the next few minutes. " << | |
29 | + "It contains instructions for confirming your account.") | |
30 | + end | |
31 | + | |
32 | + def url_after_create | |
33 | + new_session_url | |
34 | + end | |
35 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/models/clearance_mailer.rb
0 → 100644
... | ... | @@ -0,0 +1,23 @@ |
1 | +class ClearanceMailer < ActionMailer::Base | |
2 | + | |
3 | + default_url_options[:host] = HOST | |
4 | + | |
5 | + def change_password(user) | |
6 | + from DO_NOT_REPLY | |
7 | + recipients user.email | |
8 | + subject I18n.t(:change_password, | |
9 | + :scope => [:clearance, :models, :clearance_mailer], | |
10 | + :default => "Change your password") | |
11 | + body :user => user | |
12 | + end | |
13 | + | |
14 | + def confirmation(user) | |
15 | + from DO_NOT_REPLY | |
16 | + recipients user.email | |
17 | + subject I18n.t(:confirmation, | |
18 | + :scope => [:clearance, :models, :clearance_mailer], | |
19 | + :default => "Account confirmation") | |
20 | + body :user => user | |
21 | + end | |
22 | + | |
23 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/clearance_mailer/change_password.html.erb
0 → 100644
... | ... | @@ -0,0 +1,7 @@ |
1 | +Someone, hopefully you, has requested that we send you a link to change your password. | |
2 | + | |
3 | +Here's the link: | |
4 | + | |
5 | +<%= edit_user_password_url(@user, :token => @user.token, :escape => false) %> | |
6 | + | |
7 | +If you didn't request this, ignore this email. Don't worry. Your password hasn't been changed. | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/clearance_mailer/confirmation.html.erb
0 → 100644
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/passwords/edit.html.erb
0 → 100644
... | ... | @@ -0,0 +1,23 @@ |
1 | +<h2>Change your password</h2> | |
2 | + | |
3 | +<p> | |
4 | + Your password has been reset. Choose a new password below. | |
5 | +</p> | |
6 | + | |
7 | +<%= error_messages_for :user %> | |
8 | + | |
9 | +<% form_for(:user, | |
10 | + :url => user_password_path(@user, :token => @user.token), | |
11 | + :html => { :method => :put }) do |form| %> | |
12 | + <div class="password_field"> | |
13 | + <%= form.label :password, "Choose password" %> | |
14 | + <%= form.password_field :password %> | |
15 | + </div> | |
16 | + <div class="password_field"> | |
17 | + <%= form.label :password_confirmation, "Confirm password" %> | |
18 | + <%= form.password_field :password_confirmation %> | |
19 | + </div> | |
20 | + <div class="submit_field"> | |
21 | + <%= form.submit "Save this password", :disable_with => "Please wait..." %> | |
22 | + </div> | |
23 | +<% end %> | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/passwords/new.html.erb
0 → 100644
... | ... | @@ -0,0 +1,15 @@ |
1 | +<h2>Change your password</h2> | |
2 | + | |
3 | +<p> | |
4 | + We will email you a link to change your password. | |
5 | +</p> | |
6 | + | |
7 | +<% form_for :password, :url => passwords_path do |form| %> | |
8 | + <div class="text_field"> | |
9 | + <%= form.label :email, "Email address" %> | |
10 | + <%= form.text_field :email %> | |
11 | + </div> | |
12 | + <div class="submit_field"> | |
13 | + <%= form.submit "Reset password", :disable_with => "Please wait..." %> | |
14 | + </div> | |
15 | +<% end %> | |
0 | 16 | \ No newline at end of file | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/sessions/new.html.erb
0 → 100644
... | ... | @@ -0,0 +1,28 @@ |
1 | +<h2>Sign in</h2> | |
2 | + | |
3 | +<% form_for :session, :url => session_path do |form| %> | |
4 | + <div class="text_field"> | |
5 | + <%= form.label :email %> | |
6 | + <%= form.text_field :email %> | |
7 | + </div> | |
8 | + <div class="text_field"> | |
9 | + <%= form.label :password %> | |
10 | + <%= form.password_field :password %> | |
11 | + </div> | |
12 | + <div class="text_field"> | |
13 | + <%= form.check_box :remember_me %> | |
14 | + <%= form.label :remember_me %> | |
15 | + </div> | |
16 | + <div class="submit_field"> | |
17 | + <%= form.submit "Sign in", :disable_with => "Please wait..." %> | |
18 | + </div> | |
19 | +<% end %> | |
20 | + | |
21 | +<ul> | |
22 | + <li> | |
23 | + <%= link_to "Sign up", new_user_path %> | |
24 | + </li> | |
25 | + <li> | |
26 | + <%= link_to "Forgot password?", new_password_path %> | |
27 | + </li> | |
28 | +</ul> | |
0 | 29 | \ No newline at end of file | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/users/_form.html.erb
0 → 100644
... | ... | @@ -0,0 +1,13 @@ |
1 | +<%= form.error_messages %> | |
2 | +<div class="text_field"> | |
3 | + <%= form.label :email %> | |
4 | + <%= form.text_field :email %> | |
5 | +</div> | |
6 | +<div class="password_field"> | |
7 | + <%= form.label :password %> | |
8 | + <%= form.password_field :password %> | |
9 | +</div> | |
10 | +<div class="password_field"> | |
11 | + <%= form.label :password_confirmation, "Confirm password" %> | |
12 | + <%= form.password_field :password_confirmation %> | |
13 | +</div> | |
0 | 14 | \ No newline at end of file | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/app/views/users/new.html.erb
0 → 100644
vendor/plugins/thoughtbot-clearance-0.6.8/config/clearance_routes.rb
0 → 100644
... | ... | @@ -0,0 +1,30 @@ |
1 | +ActionController::Routing::Routes.draw do |map| | |
2 | + map.resources :passwords, | |
3 | + :controller => 'clearance/passwords', | |
4 | + :only => [:new, :create] | |
5 | + | |
6 | + map.resource :session, | |
7 | + :controller => 'clearance/sessions', | |
8 | + :only => [:new, :create, :destroy] | |
9 | + | |
10 | + map.resources :users, :controller => 'clearance/users' do |users| | |
11 | + users.resource :password, | |
12 | + :controller => 'clearance/passwords', | |
13 | + :only => [:create, :edit, :update] | |
14 | + | |
15 | + users.resource :confirmation, | |
16 | + :controller => 'clearance/confirmations', | |
17 | + :only => [:new, :create] | |
18 | + end | |
19 | + | |
20 | + map.sign_up 'sign_up', | |
21 | + :controller => 'clearance/users', | |
22 | + :action => 'new' | |
23 | + map.sign_in 'sign_in', | |
24 | + :controller => 'clearance/sessions', | |
25 | + :action => 'new' | |
26 | + map.sign_out 'sign_out', | |
27 | + :controller => 'clearance/sessions', | |
28 | + :action => 'destroy', | |
29 | + :method => :delete | |
30 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/USAGE
0 → 100644
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/clearance_generator.rb
0 → 100644
... | ... | @@ -0,0 +1,41 @@ |
1 | +require File.expand_path(File.dirname(__FILE__) + "/lib/insert_commands.rb") | |
2 | +require File.expand_path(File.dirname(__FILE__) + "/lib/rake_commands.rb") | |
3 | +require 'factory_girl' | |
4 | + | |
5 | +class ClearanceGenerator < Rails::Generator::Base | |
6 | + | |
7 | + def manifest | |
8 | + record do |m| | |
9 | + m.insert_into "app/controllers/application_controller.rb", | |
10 | + "include Clearance::Authentication" | |
11 | + | |
12 | + user_model = "app/models/user.rb" | |
13 | + if File.exists?(user_model) | |
14 | + m.insert_into user_model, "include Clearance::User" | |
15 | + else | |
16 | + m.directory File.join("app", "models") | |
17 | + m.file "user.rb", user_model | |
18 | + end | |
19 | + | |
20 | + m.directory File.join("test", "factories") | |
21 | + m.file "factories.rb", "test/factories/clearance.rb" | |
22 | + | |
23 | + m.migration_template "migrations/#{migration_name}.rb", | |
24 | + 'db/migrate', | |
25 | + :migration_file_name => "clearance_#{migration_name}" | |
26 | + | |
27 | + m.readme "README" | |
28 | + end | |
29 | + end | |
30 | + | |
31 | + private | |
32 | + | |
33 | + def migration_name | |
34 | + if ActiveRecord::Base.connection.table_exists?(:users) | |
35 | + 'update_users' | |
36 | + else | |
37 | + 'create_users' | |
38 | + end | |
39 | + end | |
40 | + | |
41 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/lib/insert_commands.rb
0 → 100644
... | ... | @@ -0,0 +1,33 @@ |
1 | +# Mostly pinched from http://github.com/ryanb/nifty-generators/tree/master | |
2 | + | |
3 | +Rails::Generator::Commands::Base.class_eval do | |
4 | + def file_contains?(relative_destination, line) | |
5 | + File.read(destination_path(relative_destination)).include?(line) | |
6 | + end | |
7 | +end | |
8 | + | |
9 | +Rails::Generator::Commands::Create.class_eval do | |
10 | + def insert_into(file, line) | |
11 | + logger.insert "#{line} into #{file}" | |
12 | + unless options[:pretend] || file_contains?(file, line) | |
13 | + gsub_file file, /^(class|module) .+$/ do |match| | |
14 | + "#{match}\n #{line}" | |
15 | + end | |
16 | + end | |
17 | + end | |
18 | +end | |
19 | + | |
20 | +Rails::Generator::Commands::Destroy.class_eval do | |
21 | + def insert_into(file, line) | |
22 | + logger.remove "#{line} from #{file}" | |
23 | + unless options[:pretend] | |
24 | + gsub_file file, "\n #{line}", '' | |
25 | + end | |
26 | + end | |
27 | +end | |
28 | + | |
29 | +Rails::Generator::Commands::List.class_eval do | |
30 | + def insert_into(file, line) | |
31 | + logger.insert "#{line} into #{file}" | |
32 | + end | |
33 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/lib/rake_commands.rb
0 → 100644
... | ... | @@ -0,0 +1,22 @@ |
1 | +Rails::Generator::Commands::Create.class_eval do | |
2 | + def rake_db_migrate | |
3 | + logger.rake "db:migrate" | |
4 | + unless system("rake db:migrate") | |
5 | + logger.rake "db:migrate failed. Rolling back" | |
6 | + command(:destroy).invoke! | |
7 | + end | |
8 | + end | |
9 | +end | |
10 | + | |
11 | +Rails::Generator::Commands::Destroy.class_eval do | |
12 | + def rake_db_migrate | |
13 | + logger.rake "db:rollback" | |
14 | + system "rake db:rollback" | |
15 | + end | |
16 | +end | |
17 | + | |
18 | +Rails::Generator::Commands::List.class_eval do | |
19 | + def rake_db_migrate | |
20 | + logger.rake "db:migrate" | |
21 | + end | |
22 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/README
0 → 100644
... | ... | @@ -0,0 +1,22 @@ |
1 | + | |
2 | +******************************************************************************* | |
3 | + | |
4 | +Ok, enough fancy automatic stuff. Time for some old school monkey copy-pasting. | |
5 | + | |
6 | +1. Define a HOST constant in your environments files. | |
7 | +In config/environments/test.rb and config/environments/development.rb it can be: | |
8 | + | |
9 | + HOST = "localhost" | |
10 | + | |
11 | +In production.rb it must be the actual host your application is deployed to. | |
12 | +The constant is used by mailers to generate URLs in emails. | |
13 | + | |
14 | +2. In config/environment.rb: | |
15 | + | |
16 | + DO_NOT_REPLY = "donotreply@example.com" | |
17 | + | |
18 | +3. Define root_url to *something* in your config/routes.rb: | |
19 | + | |
20 | + map.root :controller => 'home' | |
21 | + | |
22 | +******************************************************************************* | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/factories.rb
0 → 100644
... | ... | @@ -0,0 +1,13 @@ |
1 | +Factory.sequence :email do |n| | |
2 | + "user#{n}@example.com" | |
3 | +end | |
4 | + | |
5 | +Factory.define :user do |user| | |
6 | + user.email { Factory.next :email } | |
7 | + user.password { "password" } | |
8 | + user.password_confirmation { "password" } | |
9 | +end | |
10 | + | |
11 | +Factory.define :email_confirmed_user, :parent => :user do |user| | |
12 | + user.email_confirmed { true } | |
13 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/migrations/create_users.rb
0 → 100644
... | ... | @@ -0,0 +1,20 @@ |
1 | +class ClearanceCreateUsers < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + create_table(:users) do |t| | |
4 | + t.string :email | |
5 | + t.string :encrypted_password, :limit => 128 | |
6 | + t.string :salt, :limit => 128 | |
7 | + t.string :token, :limit => 128 | |
8 | + t.datetime :token_expires_at | |
9 | + t.boolean :email_confirmed, :default => false, :null => false | |
10 | + end | |
11 | + | |
12 | + add_index :users, [:id, :token] | |
13 | + add_index :users, :email | |
14 | + add_index :users, :token | |
15 | + end | |
16 | + | |
17 | + def self.down | |
18 | + drop_table :users | |
19 | + end | |
20 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/migrations/update_users.rb
0 → 100644
... | ... | @@ -0,0 +1,41 @@ |
1 | +class ClearanceUpdateUsers < ActiveRecord::Migration | |
2 | + def self.up | |
3 | +<% | |
4 | + existing_columns = ActiveRecord::Base.connection.columns(:users).collect { |each| each.name } | |
5 | + columns = [ | |
6 | + [:email, 't.string :email'], | |
7 | + [:encrypted_password, 't.string :encrypted_password, :limit => 128'], | |
8 | + [:salt, 't.string :salt, :limit => 128'], | |
9 | + [:token, 't.string :token, :limit => 128'], | |
10 | + [:token_expires_at, 't.datetime :token_expires_at'], | |
11 | + [:email_confirmed, 't.boolean :email_confirmed, :default => false, :null => false'] | |
12 | + ].delete_if {|c| existing_columns.include?(c.first.to_s)} | |
13 | +-%> | |
14 | + change_table(:users) do |t| | |
15 | +<% columns.each do |c| -%> | |
16 | + <%= c.last %> | |
17 | +<% end -%> | |
18 | + end | |
19 | + | |
20 | +<% | |
21 | + existing_indexes = ActiveRecord::Base.connection.indexes(:users) | |
22 | + index_names = existing_indexes.collect { |each| each.name } | |
23 | + new_indexes = [ | |
24 | + [:index_users_on_id_and_token, 'add_index :users, [:id, :token]'], | |
25 | + [:index_users_on_email, 'add_index :users, :email'], | |
26 | + [:index_users_on_token, 'add_index :users, :token'] | |
27 | + ].delete_if { |each| index_names.include?(each.first.to_s) } | |
28 | +-%> | |
29 | +<% new_indexes.each do |each| -%> | |
30 | + <%= each.last %> | |
31 | +<% end -%> | |
32 | + end | |
33 | + | |
34 | + def self.down | |
35 | + change_table(:users) do |t| | |
36 | +<% unless columns.empty? -%> | |
37 | + t.remove <%= columns.collect { |each| ":#{each.first}" }.join(',') %> | |
38 | +<% end -%> | |
39 | + end | |
40 | + end | |
41 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance/templates/user.rb
0 → 100644
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/USAGE
0 → 100644
... | ... | @@ -0,0 +1 @@ |
1 | +script/generate clearance_features | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/clearance_features_generator.rb
0 → 100644
... | ... | @@ -0,0 +1,20 @@ |
1 | +class ClearanceFeaturesGenerator < Rails::Generator::Base | |
2 | + | |
3 | + def manifest | |
4 | + record do |m| | |
5 | + m.directory File.join("features", "step_definitions") | |
6 | + m.directory File.join("features", "support") | |
7 | + | |
8 | + ["features/step_definitions/clearance_steps.rb", | |
9 | + "features/step_definitions/factory_girl_steps.rb", | |
10 | + "features/support/paths.rb", | |
11 | + "features/sign_in.feature", | |
12 | + "features/sign_out.feature", | |
13 | + "features/sign_up.feature", | |
14 | + "features/password_reset.feature"].each do |file| | |
15 | + m.file file, file | |
16 | + end | |
17 | + end | |
18 | + end | |
19 | + | |
20 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/features/password_reset.feature
0 → 100644
... | ... | @@ -0,0 +1,33 @@ |
1 | +Feature: Password reset | |
2 | + In order to sign in even if user forgot their password | |
3 | + A user | |
4 | + Should be able to reset it | |
5 | + | |
6 | + Scenario: User is not signed up | |
7 | + Given no user exists with an email of "email@person.com" | |
8 | + When I request password reset link to be sent to "email@person.com" | |
9 | + Then I should see "Unknown email" | |
10 | + | |
11 | + Scenario: User is signed up and requests password reset | |
12 | + Given I signed up with "email@person.com/password" | |
13 | + When I request password reset link to be sent to "email@person.com" | |
14 | + Then I should see "instructions for changing your password" | |
15 | + And a password reset message should be sent to "email@person.com" | |
16 | + | |
17 | + Scenario: User is signed up updated his password and types wrong confirmation | |
18 | + Given I signed up with "email@person.com/password" | |
19 | + When I follow the password reset link sent to "email@person.com" | |
20 | + And I update my password with "newpassword/wrongconfirmation" | |
21 | + Then I should see error messages | |
22 | + And I should be signed out | |
23 | + | |
24 | + Scenario: User is signed up and updates his password | |
25 | + Given I signed up with "email@person.com/password" | |
26 | + When I follow the password reset link sent to "email@person.com" | |
27 | + And I update my password with "newpassword/newpassword" | |
28 | + Then I should be signed in | |
29 | + When I sign out | |
30 | + Then I should be signed out | |
31 | + And I sign in as "email@person.com/newpassword" | |
32 | + Then I should be signed in | |
33 | + | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/features/sign_in.feature
0 → 100644
... | ... | @@ -0,0 +1,42 @@ |
1 | +Feature: Sign in | |
2 | + In order to get access to protected sections of the site | |
3 | + A user | |
4 | + Should be able to sign in | |
5 | + | |
6 | + Scenario: User is not signed up | |
7 | + Given no user exists with an email of "email@person.com" | |
8 | + When I go to the sign in page | |
9 | + And I sign in as "email@person.com/password" | |
10 | + Then I should see "Bad email or password" | |
11 | + And I should be signed out | |
12 | + | |
13 | + Scenario: User is not confirmed | |
14 | + Given I signed up with "email@person.com/password" | |
15 | + When I go to the sign in page | |
16 | + And I sign in as "email@person.com/password" | |
17 | + Then I should see "User has not confirmed email" | |
18 | + And I should be signed out | |
19 | + | |
20 | + Scenario: User enters wrong password | |
21 | + Given I am signed up and confirmed as "email@person.com/password" | |
22 | + When I go to the sign in page | |
23 | + And I sign in as "email@person.com/wrongpassword" | |
24 | + Then I should see "Bad email or password" | |
25 | + And I should be signed out | |
26 | + | |
27 | + Scenario: User signs in successfully | |
28 | + Given I am signed up and confirmed as "email@person.com/password" | |
29 | + When I go to the sign in page | |
30 | + And I sign in as "email@person.com/password" | |
31 | + Then I should see "Signed in" | |
32 | + And I should be signed in | |
33 | + | |
34 | + Scenario: User signs in and checks "remember me" | |
35 | + Given I am signed up and confirmed as "email@person.com/password" | |
36 | + When I go to the sign in page | |
37 | + And I sign in with "remember me" as "email@person.com/password" | |
38 | + Then I should see "Signed in" | |
39 | + And I should be signed in | |
40 | + When I return next time | |
41 | + Then I should be signed in | |
42 | + | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/features/sign_out.feature
0 → 100644
... | ... | @@ -0,0 +1,23 @@ |
1 | +Feature: Sign out | |
2 | + To protect my account from unauthorized access | |
3 | + A signed in user | |
4 | + Should be able to sign out | |
5 | + | |
6 | + Scenario: User signs out | |
7 | + Given I am signed up and confirmed as "email@person.com/password" | |
8 | + When I sign in as "email@person.com/password" | |
9 | + Then I should be signed in | |
10 | + And I sign out | |
11 | + Then I should see "Signed out" | |
12 | + And I should be signed out | |
13 | + | |
14 | + Scenario: User who was remembered signs out | |
15 | + Given I am signed up and confirmed as "email@person.com/password" | |
16 | + When I sign in with "remember me" as "email@person.com/password" | |
17 | + Then I should be signed in | |
18 | + And I sign out | |
19 | + Then I should see "Signed out" | |
20 | + And I should be signed out | |
21 | + When I return next time | |
22 | + Then I should be signed out | |
23 | + | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/features/sign_up.feature
0 → 100644
... | ... | @@ -0,0 +1,28 @@ |
1 | +Feature: Sign up | |
2 | + In order to get access to protected sections of the site | |
3 | + A user | |
4 | + Should be able to sign up | |
5 | + | |
6 | + Scenario: User signs up with invalid data | |
7 | + When I go to the sign up page | |
8 | + And I fill in "Email" with "invalidemail" | |
9 | + And I fill in "Password" with "password" | |
10 | + And I fill in "Confirm password" with "" | |
11 | + And I press "Sign Up" | |
12 | + Then I should see error messages | |
13 | + | |
14 | + Scenario: User signs up with valid data | |
15 | + When I go to the sign up page | |
16 | + And I fill in "Email" with "email@person.com" | |
17 | + And I fill in "Password" with "password" | |
18 | + And I fill in "Confirm password" with "password" | |
19 | + And I press "Sign Up" | |
20 | + Then I should see "instructions for confirming" | |
21 | + And a confirmation message should be sent to "email@person.com" | |
22 | + | |
23 | + Scenario: User confirms his account | |
24 | + Given I signed up with "email@person.com/password" | |
25 | + When I follow the confirmation link sent to "email@person.com" | |
26 | + Then I should see "Confirmed email and signed in" | |
27 | + And I should be signed in | |
28 | + | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/features/step_definitions/clearance_steps.rb
0 → 100644
... | ... | @@ -0,0 +1,110 @@ |
1 | +# General | |
2 | + | |
3 | +Then /^I should see error messages$/ do | |
4 | + assert_match /error(s)? prohibited/m, response.body | |
5 | +end | |
6 | + | |
7 | +# Database | |
8 | + | |
9 | +Given /^no user exists with an email of "(.*)"$/ do |email| | |
10 | + assert_nil User.find_by_email(email) | |
11 | +end | |
12 | + | |
13 | +Given /^I signed up with "(.*)\/(.*)"$/ do |email, password| | |
14 | + user = Factory :user, | |
15 | + :email => email, | |
16 | + :password => password, | |
17 | + :password_confirmation => password | |
18 | +end | |
19 | + | |
20 | +Given /^I am signed up and confirmed as "(.*)\/(.*)"$/ do |email, password| | |
21 | + user = Factory :email_confirmed_user, | |
22 | + :email => email, | |
23 | + :password => password, | |
24 | + :password_confirmation => password | |
25 | +end | |
26 | + | |
27 | +# Session | |
28 | + | |
29 | +Then /^I should be signed in$/ do | |
30 | + assert controller.signed_in? | |
31 | +end | |
32 | + | |
33 | +Then /^I should be signed out$/ do | |
34 | + assert ! controller.signed_in? | |
35 | +end | |
36 | + | |
37 | +When /^session is cleared$/ do | |
38 | + request.reset_session | |
39 | + controller.instance_variable_set(:@_current_user, nil) | |
40 | +end | |
41 | + | |
42 | +# Emails | |
43 | + | |
44 | +Then /^a confirmation message should be sent to "(.*)"$/ do |email| | |
45 | + user = User.find_by_email(email) | |
46 | + sent = ActionMailer::Base.deliveries.first | |
47 | + assert_equal [user.email], sent.to | |
48 | + assert_match /confirm/i, sent.subject | |
49 | + assert !user.token.blank? | |
50 | + assert_match /#{user.token}/, sent.body | |
51 | +end | |
52 | + | |
53 | +When /^I follow the confirmation link sent to "(.*)"$/ do |email| | |
54 | + user = User.find_by_email(email) | |
55 | + visit new_user_confirmation_path(:user_id => user, :token => user.token) | |
56 | +end | |
57 | + | |
58 | +Then /^a password reset message should be sent to "(.*)"$/ do |email| | |
59 | + user = User.find_by_email(email) | |
60 | + sent = ActionMailer::Base.deliveries.first | |
61 | + assert_equal [user.email], sent.to | |
62 | + assert_match /password/i, sent.subject | |
63 | + assert !user.token.blank? | |
64 | + assert_match /#{user.token}/, sent.body | |
65 | +end | |
66 | + | |
67 | +When /^I follow the password reset link sent to "(.*)"$/ do |email| | |
68 | + user = User.find_by_email(email) | |
69 | + visit edit_user_password_path(:user_id => user, :token => user.token) | |
70 | +end | |
71 | + | |
72 | +When /^I try to change the password of "(.*)" without token$/ do |email| | |
73 | + user = User.find_by_email(email) | |
74 | + visit edit_user_password_path(:user_id => user) | |
75 | +end | |
76 | + | |
77 | +Then /^I should be forbidden$/ do | |
78 | + assert_response :forbidden | |
79 | +end | |
80 | + | |
81 | +# Actions | |
82 | + | |
83 | +When /^I sign in( with "remember me")? as "(.*)\/(.*)"$/ do |remember, email, password| | |
84 | + When %{I go to the sign in page} | |
85 | + And %{I fill in "Email" with "#{email}"} | |
86 | + And %{I fill in "Password" with "#{password}"} | |
87 | + And %{I check "Remember me"} if remember | |
88 | + And %{I press "Sign In"} | |
89 | +end | |
90 | + | |
91 | +When /^I sign out$/ do | |
92 | + visit '/session', :delete | |
93 | +end | |
94 | + | |
95 | +When /^I request password reset link to be sent to "(.*)"$/ do |email| | |
96 | + When %{I go to the password reset request page} | |
97 | + And %{I fill in "Email address" with "#{email}"} | |
98 | + And %{I press "Reset password"} | |
99 | +end | |
100 | + | |
101 | +When /^I update my password with "(.*)\/(.*)"$/ do |password, confirmation| | |
102 | + And %{I fill in "Choose password" with "#{password}"} | |
103 | + And %{I fill in "Confirm password" with "#{confirmation}"} | |
104 | + And %{I press "Save this password"} | |
105 | +end | |
106 | + | |
107 | +When /^I return next time$/ do | |
108 | + When %{session is cleared} | |
109 | + And %{I go to the homepage} | |
110 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/features/step_definitions/factory_girl_steps.rb
0 → 100644
vendor/plugins/thoughtbot-clearance-0.6.8/generators/clearance_features/templates/features/support/paths.rb
0 → 100644
... | ... | @@ -0,0 +1,22 @@ |
1 | +module NavigationHelpers | |
2 | + def path_to(page_name) | |
3 | + case page_name | |
4 | + | |
5 | + when /the homepage/i | |
6 | + root_path | |
7 | + when /the sign up page/i | |
8 | + new_user_path | |
9 | + when /the sign in page/i | |
10 | + new_session_path | |
11 | + when /the password reset request page/i | |
12 | + new_password_path | |
13 | + | |
14 | + # Add more page name => path mappings here | |
15 | + | |
16 | + else | |
17 | + raise "Can't find mapping from \"#{page_name}\" to a path." | |
18 | + end | |
19 | + end | |
20 | +end | |
21 | + | |
22 | +World(NavigationHelpers) | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance.rb
0 → 100644
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/authentication.rb
0 → 100644
... | ... | @@ -0,0 +1,100 @@ |
1 | +module Clearance | |
2 | + module Authentication | |
3 | + | |
4 | + def self.included(controller) | |
5 | + controller.send(:include, InstanceMethods) | |
6 | + | |
7 | + controller.class_eval do | |
8 | + helper_method :current_user | |
9 | + helper_method :signed_in? | |
10 | + | |
11 | + hide_action :current_user, :signed_in? | |
12 | + end | |
13 | + end | |
14 | + | |
15 | + module InstanceMethods | |
16 | + def current_user | |
17 | + @_current_user ||= (user_from_cookie || user_from_session) | |
18 | + end | |
19 | + | |
20 | + def signed_in? | |
21 | + ! current_user.nil? | |
22 | + end | |
23 | + | |
24 | + protected | |
25 | + | |
26 | + def authenticate | |
27 | + deny_access unless signed_in? | |
28 | + end | |
29 | + | |
30 | + def user_from_session | |
31 | + if session[:user_id] | |
32 | + return nil unless user = ::User.find_by_id(session[:user_id]) | |
33 | + return user if user.email_confirmed? | |
34 | + end | |
35 | + end | |
36 | + | |
37 | + def user_from_cookie | |
38 | + if token = cookies[:remember_token] | |
39 | + return nil unless user = ::User.find_by_token(token) | |
40 | + return user if user.remember? | |
41 | + end | |
42 | + end | |
43 | + | |
44 | + def sign_user_in(user) | |
45 | + warn "[DEPRECATION] sign_user_in: unnecessary. use sign_in(user) instead." | |
46 | + sign_in(user) | |
47 | + end | |
48 | + | |
49 | + def sign_in(user) | |
50 | + if user | |
51 | + session[:user_id] = user.id | |
52 | + end | |
53 | + end | |
54 | + | |
55 | + def remember? | |
56 | + params[:session] && params[:session][:remember_me] == "1" | |
57 | + end | |
58 | + | |
59 | + def remember(user) | |
60 | + user.remember_me! | |
61 | + cookies[:remember_token] = { :value => user.token, | |
62 | + :expires => user.token_expires_at } | |
63 | + end | |
64 | + | |
65 | + def forget(user) | |
66 | + user.forget_me! if user | |
67 | + cookies.delete(:remember_token) | |
68 | + reset_session | |
69 | + end | |
70 | + | |
71 | + def redirect_back_or(default) | |
72 | + redirect_to(return_to || default) | |
73 | + clear_return_to | |
74 | + end | |
75 | + | |
76 | + def return_to | |
77 | + session[:return_to] || params[:return_to] | |
78 | + end | |
79 | + | |
80 | + def clear_return_to | |
81 | + session[:return_to] = nil | |
82 | + end | |
83 | + | |
84 | + def redirect_to_root | |
85 | + redirect_to(root_url) | |
86 | + end | |
87 | + | |
88 | + def store_location | |
89 | + session[:return_to] = request.request_uri if request.get? | |
90 | + end | |
91 | + | |
92 | + def deny_access(flash_message = nil, opts = {}) | |
93 | + store_location | |
94 | + flash[:failure] = flash_message if flash_message | |
95 | + redirect_to(new_session_url) | |
96 | + end | |
97 | + end | |
98 | + | |
99 | + end | |
100 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/extensions/errors.rb
0 → 100644
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/extensions/rescue.rb
0 → 100644
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/extensions/routes.rb
0 → 100644
... | ... | @@ -0,0 +1,14 @@ |
1 | +if defined?(ActionController::Routing::RouteSet) | |
2 | + class ActionController::Routing::RouteSet | |
3 | + def load_routes_with_clearance! | |
4 | + lib_path = File.dirname(__FILE__) | |
5 | + clearance_routes = File.join(lib_path, *%w[.. .. .. config clearance_routes.rb]) | |
6 | + unless configuration_files.include?(clearance_routes) | |
7 | + add_configuration_file(clearance_routes) | |
8 | + end | |
9 | + load_routes_without_clearance! | |
10 | + end | |
11 | + | |
12 | + alias_method_chain :load_routes!, :clearance | |
13 | + end | |
14 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/lib/clearance/user.rb
0 → 100644
... | ... | @@ -0,0 +1,143 @@ |
1 | +require 'digest/sha1' | |
2 | + | |
3 | +module Clearance | |
4 | + module User | |
5 | + | |
6 | + def self.included(model) | |
7 | + model.extend(ClassMethods) | |
8 | + | |
9 | + model.send(:include, InstanceMethods) | |
10 | + model.send(:include, AttrAccessible) | |
11 | + model.send(:include, AttrAccessor) | |
12 | + model.send(:include, Validations) | |
13 | + model.send(:include, Callbacks) | |
14 | + end | |
15 | + | |
16 | + module AttrAccessible | |
17 | + def self.included(model) | |
18 | + model.class_eval do | |
19 | + attr_accessible :email, :password, :password_confirmation | |
20 | + end | |
21 | + end | |
22 | + end | |
23 | + | |
24 | + module AttrAccessor | |
25 | + def self.included(model) | |
26 | + model.class_eval do | |
27 | + attr_accessor :password, :password_confirmation | |
28 | + end | |
29 | + end | |
30 | + end | |
31 | + | |
32 | + module Validations | |
33 | + def self.included(model) | |
34 | + model.class_eval do | |
35 | + validates_presence_of :email | |
36 | + validates_uniqueness_of :email, :case_sensitive => false | |
37 | + validates_format_of :email, :with => %r{.+@.+\..+} | |
38 | + | |
39 | + validates_presence_of :password, :if => :password_required? | |
40 | + validates_confirmation_of :password, :if => :password_required? | |
41 | + end | |
42 | + end | |
43 | + end | |
44 | + | |
45 | + module Callbacks | |
46 | + def self.included(model) | |
47 | + model.class_eval do | |
48 | + before_save :initialize_salt, :encrypt_password, :initialize_token | |
49 | + end | |
50 | + end | |
51 | + end | |
52 | + | |
53 | + module InstanceMethods | |
54 | + def authenticated?(password) | |
55 | + encrypted_password == encrypt(password) | |
56 | + end | |
57 | + | |
58 | + def encrypt(string) | |
59 | + generate_hash("--#{salt}--#{string}--") | |
60 | + end | |
61 | + | |
62 | + def remember? | |
63 | + token_expires_at && Time.now.utc < token_expires_at | |
64 | + end | |
65 | + | |
66 | + def remember_me! | |
67 | + remember_me_until! 2.weeks.from_now.utc | |
68 | + end | |
69 | + | |
70 | + def forget_me! | |
71 | + clear_token | |
72 | + save(false) | |
73 | + end | |
74 | + | |
75 | + def confirm_email! | |
76 | + self.email_confirmed = true | |
77 | + self.token = nil | |
78 | + save(false) | |
79 | + end | |
80 | + | |
81 | + def forgot_password! | |
82 | + generate_token | |
83 | + save(false) | |
84 | + end | |
85 | + | |
86 | + def update_password(new_password, new_password_confirmation) | |
87 | + self.password = new_password | |
88 | + self.password_confirmation = new_password_confirmation | |
89 | + clear_token if valid? | |
90 | + save | |
91 | + end | |
92 | + | |
93 | + protected | |
94 | + | |
95 | + def generate_hash(string) | |
96 | + Digest::SHA1.hexdigest(string) | |
97 | + end | |
98 | + | |
99 | + def initialize_salt | |
100 | + if new_record? | |
101 | + self.salt = generate_hash("--#{Time.now.utc.to_s}--#{password}--") | |
102 | + end | |
103 | + end | |
104 | + | |
105 | + def encrypt_password | |
106 | + return if password.blank? | |
107 | + self.encrypted_password = encrypt(password) | |
108 | + end | |
109 | + | |
110 | + def generate_token | |
111 | + self.token = encrypt("--#{Time.now.utc.to_s}--#{password}--") | |
112 | + self.token_expires_at = nil | |
113 | + end | |
114 | + | |
115 | + def clear_token | |
116 | + self.token = nil | |
117 | + self.token_expires_at = nil | |
118 | + end | |
119 | + | |
120 | + def initialize_token | |
121 | + generate_token if new_record? | |
122 | + end | |
123 | + | |
124 | + def password_required? | |
125 | + encrypted_password.blank? || !password.blank? | |
126 | + end | |
127 | + | |
128 | + def remember_me_until!(time) | |
129 | + self.token_expires_at = time | |
130 | + self.token = encrypt("--#{token_expires_at}--#{password}--") | |
131 | + save(false) | |
132 | + end | |
133 | + end | |
134 | + | |
135 | + module ClassMethods | |
136 | + def authenticate(email, password) | |
137 | + return nil unless user = find_by_email(email) | |
138 | + return user if user.authenticated?(password) | |
139 | + end | |
140 | + end | |
141 | + | |
142 | + end | |
143 | +end | ... | ... |
vendor/plugins/thoughtbot-clearance-0.6.8/shoulda_macros/clearance.rb
0 → 100644
... | ... | @@ -0,0 +1,262 @@ |
1 | +module Clearance | |
2 | + module Shoulda | |
3 | + | |
4 | + # STATE OF AUTHENTICATION | |
5 | + | |
6 | + def should_be_signed_in_as(&block) | |
7 | + should "be signed in as #{block.bind(self).call}" do | |
8 | + user = block.bind(self).call | |
9 | + assert_not_nil user, | |
10 | + "please pass a User. try: should_be_signed_in_as { @user }" | |
11 | + assert_equal user, @controller.send(:current_user), | |
12 | + "#{user.inspect} is not the current_user, " << | |
13 | + "which is #{@controller.send(:current_user).inspect}" | |
14 | + end | |
15 | + end | |
16 | + | |
17 | + def should_be_signed_in_and_email_confirmed_as(&block) | |
18 | + warn "[DEPRECATION] should_be_signed_in_and_email_confirmed_as: questionable usefulness" | |
19 | + should_be_signed_in_as &block | |
20 | + | |
21 | + should "have confirmed email" do | |
22 | + user = block.bind(self).call | |
23 | + | |
24 | + assert_not_nil user | |
25 | + assert_equal user, assigns(:user) | |
26 | + assert assigns(:user).email_confirmed? | |
27 | + end | |
28 | + end | |
29 | + | |
30 | + def should_not_be_signed_in | |
31 | + should "not be signed in" do | |
32 | + assert_nil session[:user_id] | |
33 | + end | |
34 | + end | |
35 | + | |
36 | + def should_deny_access_on(http_method, action, opts = {}) | |
37 | + warn "[DEPRECATION] should_deny_access_on: use a setup & should_deny_access(:flash => ?)" | |
38 | + flash_message = opts.delete(:flash) | |
39 | + context "on #{http_method} to #{action}" do | |
40 | + setup do | |
41 | + send(http_method, action, opts) | |
42 | + end | |
43 | + | |
44 | + should_deny_access(:flash => flash_message) | |
45 | + end | |
46 | + end | |
47 | + | |
48 | + def should_deny_access(opts = {}) | |
49 | + if opts[:flash] | |
50 | + should_set_the_flash_to opts[:flash] | |
51 | + else | |
52 | + should_not_set_the_flash | |
53 | + end | |
54 | + | |
55 | + should_redirect_to('new_session_url') { new_session_url } | |
56 | + end | |
57 | + | |
58 | + # HTTP FLUENCY | |
59 | + | |
60 | + def should_forbid(description, &block) | |
61 | + should "forbid #{description}" do | |
62 | + assert_raises ActionController::Forbidden do | |
63 | + instance_eval(&block) | |
64 | + end | |
65 | + end | |
66 | + end | |
67 | + | |
68 | + # CONTEXTS | |
69 | + | |
70 | + def signed_in_user_context(&blk) | |
71 | + warn "[DEPRECATION] signed_in_user_context: creates a Mystery Guest, causes Obscure Test" | |
72 | + context "A signed in user" do | |
73 | + setup do | |
74 | + @user = Factory(:user) | |
75 | + @user.confirm_email! | |
76 | + sign_in_as @user | |
77 | + end | |
78 | + merge_block(&blk) | |
79 | + end | |
80 | + end | |
81 | + | |
82 | + def public_context(&blk) | |
83 | + warn "[DEPRECATION] public_context: common case is no-op. call sign_out otherwise" | |
84 | + context "The public" do | |
85 | + setup { sign_out } | |
86 | + merge_block(&blk) | |
87 | + end | |
88 | + end | |
89 | + | |
90 | + # CREATING USERS | |
91 | + | |
92 | + def should_create_user_successfully | |
93 | + warn "[DEPRECATION] should_create_user_successfully: not meant to be public, no longer used internally" | |
94 | + should_assign_to :user | |
95 | + should_change 'User.count', :by => 1 | |
96 | + | |
97 | + should "send the confirmation email" do | |
98 | + assert_sent_email do |email| | |
99 | + email.subject =~ /account confirmation/i | |
100 | + end | |
101 | + end | |
102 | + | |
103 | + should_set_the_flash_to /confirm/i | |
104 | + should_redirect_to_url_after_create | |
105 | + end | |
106 | + | |
107 | + # RENDERING | |
108 | + | |
109 | + def should_render_nothing | |
110 | + should "render nothing" do | |
111 | + assert @response.body.blank? | |
112 | + end | |
113 | + end | |
114 | + | |
115 | + # REDIRECTS | |
116 | + | |
117 | + def should_redirect_to_url_after_create | |
118 | + should_redirect_to("the post-create url") do | |
119 | + @controller.send(:url_after_create) | |
120 | + end | |
121 | + end | |
122 | + | |
123 | + def should_redirect_to_url_after_update | |
124 | + should_redirect_to("the post-update url") do | |
125 | + @controller.send(:url_after_update) | |
126 | + end | |
127 | + end | |
128 | + | |
129 | + def should_redirect_to_url_after_destroy | |
130 | + should_redirect_to("the post-destroy url") do | |
131 | + @controller.send(:url_after_destroy) | |
132 | + end | |
133 | + end | |
134 | + | |
135 | + # VALIDATIONS | |
136 | + | |
137 | + def should_validate_confirmation_of(attribute, opts = {}) | |
138 | + warn "[DEPRECATION] should_validate_confirmation_of: not meant to be public, no longer used internally" | |
139 | + raise ArgumentError if opts[:factory].nil? | |
140 | + | |
141 | + context "on save" do | |
142 | + should_validate_confirmation_is_not_blank opts[:factory], attribute | |
143 | + should_validate_confirmation_is_not_bad opts[:factory], attribute | |
144 | + end | |
145 | + end | |
146 | + | |
147 | + def should_validate_confirmation_is_not_blank(factory, attribute, opts = {}) | |
148 | + warn "[DEPRECATION] should_validate_confirmation_is_not_blank: not meant to be public, no longer used internally" | |
149 | + should "validate #{attribute}_confirmation is not blank" do | |
150 | + model = Factory.build(factory, blank_confirmation_options(attribute)) | |
151 | + model.save | |
152 | + assert_confirmation_error(model, attribute, | |
153 | + "#{attribute}_confirmation cannot be blank") | |
154 | + end | |
155 | + end | |
156 | + | |
157 | + def should_validate_confirmation_is_not_bad(factory, attribute, opts = {}) | |
158 | + warn "[DEPRECATION] should_validate_confirmation_is_not_bad: not meant to be public, no longer used internally" | |
159 | + should "validate #{attribute}_confirmation is different than #{attribute}" do | |
160 | + model = Factory.build(factory, bad_confirmation_options(attribute)) | |
161 | + model.save | |
162 | + assert_confirmation_error(model, attribute, | |
163 | + "#{attribute}_confirmation cannot be different than #{attribute}") | |
164 | + end | |
165 | + end | |
166 | + | |
167 | + # FORMS | |
168 | + | |
169 | + def should_display_a_password_update_form | |
170 | + warn "[DEPRECATION] should_display_a_password_update_form: not meant to be public, no longer used internally" | |
171 | + should "have a form for the user's token, password, and password confirm" do | |
172 | + update_path = ERB::Util.h( | |
173 | + user_password_path(@user, :token => @user.token) | |
174 | + ) | |
175 | + | |
176 | + assert_select 'form[action=?]', update_path do | |
177 | + assert_select 'input[name=_method][value=?]', 'put' | |
178 | + assert_select 'input[name=?]', 'user[password]' | |
179 | + assert_select 'input[name=?]', 'user[password_confirmation]' | |
180 | + end | |
181 | + end | |
182 | + end | |
183 | + | |
184 | + def should_display_a_sign_up_form | |
185 | + warn "[DEPRECATION] should_display_a_sign_up_form: not meant to be public, no longer used internally" | |
186 | + should "display a form to sign up" do | |
187 | + assert_select "form[action=#{users_path}][method=post]", | |
188 | + true, "There must be a form to sign up" do | |
189 | + assert_select "input[type=text][name=?]", | |
190 | + "user[email]", true, "There must be an email field" | |
191 | + assert_select "input[type=password][name=?]", | |
192 | + "user[password]", true, "There must be a password field" | |
193 | + assert_select "input[type=password][name=?]", | |
194 | + "user[password_confirmation]", true, "There must be a password confirmation field" | |
195 | + assert_select "input[type=submit]", true, | |
196 | + "There must be a submit button" | |
197 | + end | |
198 | + end | |
199 | + end | |
200 | + | |
201 | + def should_display_a_sign_in_form | |
202 | + warn "[DEPRECATION] should_display_a_sign_in_form: not meant to be public, no longer used internally" | |
203 | + should 'display a "sign in" form' do | |
204 | + assert_select "form[action=#{session_path}][method=post]", | |
205 | + true, "There must be a form to sign in" do | |
206 | + assert_select "input[type=text][name=?]", | |
207 | + "session[email]", true, "There must be an email field" | |
208 | + assert_select "input[type=password][name=?]", | |
209 | + "session[password]", true, "There must be a password field" | |
210 | + assert_select "input[type=checkbox][name=?]", | |
211 | + "session[remember_me]", true, "There must be a 'remember me' check box" | |
212 | + assert_select "input[type=submit]", true, | |
213 | + "There must be a submit button" | |
214 | + end | |
215 | + end | |
216 | + end | |
217 | + end | |
218 | +end | |
219 | + | |
220 | +module Clearance | |
221 | + module Shoulda | |
222 | + module Helpers | |
223 | + def sign_in_as(user) | |
224 | + @controller.class_eval { attr_accessor :current_user } | |
225 | + @controller.current_user = user | |
226 | + return user | |
227 | + end | |
228 | + | |
229 | + def sign_in | |
230 | + sign_in_as Factory(:email_confirmed_user) | |
231 | + end | |
232 | + | |
233 | + def sign_out | |
234 | + @controller.class_eval { attr_accessor :current_user } | |
235 | + @controller.current_user = nil | |
236 | + end | |
237 | + | |
238 | + def blank_confirmation_options(attribute) | |
239 | + warn "[DEPRECATION] blank_confirmation_options: not meant to be public, no longer used internally" | |
240 | + opts = { attribute => attribute.to_s } | |
241 | + opts.merge("#{attribute}_confirmation".to_sym => "") | |
242 | + end | |
243 | + | |
244 | + def bad_confirmation_options(attribute) | |
245 | + warn "[DEPRECATION] bad_confirmation_options: not meant to be public, no longer used internally" | |
246 | + opts = { attribute => attribute.to_s } | |
247 | + opts.merge("#{attribute}_confirmation".to_sym => "not_#{attribute}") | |
248 | + end | |
249 | + | |
250 | + def assert_confirmation_error(model, attribute, message = "confirmation error") | |
251 | + warn "[DEPRECATION] assert_confirmation_error: not meant to be public, no longer used internally" | |
252 | + assert model.errors.on(attribute).include?("doesn't match confirmation"), | |
253 | + message | |
254 | + end | |
255 | + end | |
256 | + end | |
257 | +end | |
258 | + | |
259 | +class Test::Unit::TestCase | |
260 | + include Clearance::Shoulda::Helpers | |
261 | +end | |
262 | +Test::Unit::TestCase.extend(Clearance::Shoulda) | ... | ... |