mischa-clearance 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +21 -0
- data/README.textile +136 -0
- data/Rakefile +83 -0
- data/TODO.textile +24 -0
- data/generators/clearance/USAGE +1 -0
- data/generators/clearance/clearance_generator.rb +69 -0
- data/generators/clearance/templates/app/controllers/application.rb +5 -0
- data/generators/clearance/templates/app/controllers/confirmations_controller.rb +3 -0
- data/generators/clearance/templates/app/controllers/passwords_controller.rb +3 -0
- data/generators/clearance/templates/app/controllers/sessions_controller.rb +3 -0
- data/generators/clearance/templates/app/controllers/users_controller.rb +3 -0
- data/generators/clearance/templates/app/models/clearance_mailer.rb +5 -0
- data/generators/clearance/templates/app/models/user.rb +3 -0
- data/generators/clearance/templates/app/views/clearance_mailer/change_password.html.erb +6 -0
- data/generators/clearance/templates/app/views/clearance_mailer/confirmation.html.erb +1 -0
- data/generators/clearance/templates/app/views/confirmations/new.html.erb +6 -0
- data/generators/clearance/templates/app/views/passwords/edit.html.erb +23 -0
- data/generators/clearance/templates/app/views/passwords/new.html.erb +15 -0
- data/generators/clearance/templates/app/views/sessions/new.html.erb +26 -0
- data/generators/clearance/templates/app/views/users/_form.html.erb +13 -0
- data/generators/clearance/templates/app/views/users/edit.html.erb +4 -0
- data/generators/clearance/templates/app/views/users/new.html.erb +4 -0
- data/generators/clearance/templates/test/factories.rb +9 -0
- data/generators/clearance/templates/test/functional/confirmations_controller_test.rb +5 -0
- data/generators/clearance/templates/test/functional/passwords_controller_test.rb +5 -0
- data/generators/clearance/templates/test/functional/sessions_controller_test.rb +5 -0
- data/generators/clearance/templates/test/functional/users_controller_test.rb +5 -0
- data/generators/clearance/templates/test/unit/clearance_mailer_test.rb +6 -0
- data/generators/clearance/templates/test/unit/user_test.rb +5 -0
- data/lib/clearance.rb +15 -0
- data/lib/clearance/app/controllers/application_controller.rb +84 -0
- data/lib/clearance/app/controllers/confirmations_controller.rb +46 -0
- data/lib/clearance/app/controllers/passwords_controller.rb +67 -0
- data/lib/clearance/app/controllers/sessions_controller.rb +79 -0
- data/lib/clearance/app/controllers/users_controller.rb +47 -0
- data/lib/clearance/app/models/clearance_mailer.rb +33 -0
- data/lib/clearance/app/models/user.rb +86 -0
- data/lib/clearance/test/functional/confirmations_controller_test.rb +85 -0
- data/lib/clearance/test/functional/passwords_controller_test.rb +188 -0
- data/lib/clearance/test/functional/sessions_controller_test.rb +148 -0
- data/lib/clearance/test/functional/users_controller_test.rb +69 -0
- data/lib/clearance/test/test_helper.rb +94 -0
- data/lib/clearance/test/unit/clearance_mailer_test.rb +63 -0
- data/lib/clearance/test/unit/user_test.rb +208 -0
- data/lib/clearance/version.rb +7 -0
- metadata +127 -0
data/LICENSE
ADDED
@@ -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.
|
data/README.textile
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
h1. Clearance
|
2
|
+
|
3
|
+
Simple, complete Ruby web app authentication.
|
4
|
+
|
5
|
+
"We have clearance, Clarence.":http://www.youtube.com/v/mNRXJEE3Nz8
|
6
|
+
|
7
|
+
h2. Gem installation (Rails 2.1+)
|
8
|
+
|
9
|
+
In config/environments/test.rb:
|
10
|
+
|
11
|
+
config.gem 'mocha'
|
12
|
+
config.gem 'thoughtbot-shoulda', :lib => 'shoulda', :source => "http://gems.github.com"
|
13
|
+
config.gem 'thoughtbot-factory_girl', :lib => 'factory_girl', :source => "http://gems.github.com"
|
14
|
+
|
15
|
+
In config/environment.rb:
|
16
|
+
|
17
|
+
config.gem "thoughtbot-clearance", :lib => 'clearance', :source => 'http://gems.github.com/'
|
18
|
+
|
19
|
+
Then:
|
20
|
+
|
21
|
+
rake gems:install
|
22
|
+
rake gems:unpack
|
23
|
+
|
24
|
+
h2. Generator
|
25
|
+
|
26
|
+
In a greenfield application, just run the generator:
|
27
|
+
|
28
|
+
script/generate clearance
|
29
|
+
|
30
|
+
This will create:
|
31
|
+
|
32
|
+
app/controllers/confirmations_controller.rb
|
33
|
+
app/controllers/passwords_controller.rb
|
34
|
+
app/controllers/sessions_controller.rb
|
35
|
+
app/controllers/users_controller.rb
|
36
|
+
app/models/user.rb
|
37
|
+
app/models/user_mailer.rb
|
38
|
+
app/views/confirmations/new.html.erb
|
39
|
+
app/views/passwords/edit.html.erb
|
40
|
+
app/views/passwords/new.html.erb
|
41
|
+
app/views/sessions/new.html.erb
|
42
|
+
app/views/user_mailer/change_password.html.erb
|
43
|
+
app/views/user_mailer/confirmation.html.erb
|
44
|
+
app/views/users/_form.html.erb
|
45
|
+
app/views/users/edit.html.erb
|
46
|
+
app/views/users/new.html.erb
|
47
|
+
test/functional/confirmations_controller_test.rb
|
48
|
+
test/functional/passwords_controller_test.rb
|
49
|
+
test/functional/sessions_controller_test.rb
|
50
|
+
test/functional/users_controller_test.rb
|
51
|
+
test/unit/user_mailer_test.rb
|
52
|
+
test/unit/user_test.rb
|
53
|
+
|
54
|
+
Add the corresponding Clearance module for any file(s) you don't want to override. They are namespaced exactly like the directory structure of a Rails app:
|
55
|
+
|
56
|
+
app/models/user.rb already exists.
|
57
|
+
include Clearance::App::Models::User
|
58
|
+
|
59
|
+
h2. Tests
|
60
|
+
|
61
|
+
The tests use "Shoulda":http://thoughtbot.com/projects/shoulda >= 2.0.4 and "Factory Girl":http://thoughtbot.com/projects/factory_girl. You should create a User Factory:
|
62
|
+
|
63
|
+
Factory.sequence :email do |n|
|
64
|
+
"user#{n}@example.com"
|
65
|
+
end
|
66
|
+
|
67
|
+
Factory.define :user do |user|
|
68
|
+
user.email { Factory.next :email }
|
69
|
+
user.password "password"
|
70
|
+
user.password_confirmation "password"
|
71
|
+
end
|
72
|
+
|
73
|
+
In test/test_helper.rb:
|
74
|
+
|
75
|
+
class Test::Unit::TestCase
|
76
|
+
self.use_transactional_fixtures = true
|
77
|
+
self.use_instantiated_fixtures = false
|
78
|
+
include Clearance::Test::TestHelper
|
79
|
+
end
|
80
|
+
|
81
|
+
h2. Controllers
|
82
|
+
|
83
|
+
In app/controllers/application_controller.rb:
|
84
|
+
|
85
|
+
class ApplicationController < ActionController::Base
|
86
|
+
helper :all
|
87
|
+
protect_from_forgery
|
88
|
+
include Clearance::App::Controllers::ApplicationController
|
89
|
+
end
|
90
|
+
|
91
|
+
h2. Migration
|
92
|
+
|
93
|
+
Your users table needs a few columns.
|
94
|
+
|
95
|
+
create_table(:users) do |t|
|
96
|
+
t.string :email
|
97
|
+
t.string :crypted_password, :limit => 40
|
98
|
+
t.string :salt, :limit => 40
|
99
|
+
t.string :remember_token
|
100
|
+
t.datetime :remember_token_expires_at
|
101
|
+
t.boolean :confirmed, :default => false, :null => false
|
102
|
+
end
|
103
|
+
|
104
|
+
add_index :users, [:email, :crypted_password]
|
105
|
+
add_index :users, [:id, :salt]
|
106
|
+
add_index :users, :email
|
107
|
+
add_index :users, :remember_token
|
108
|
+
|
109
|
+
h2. Routes
|
110
|
+
|
111
|
+
map.resources :users
|
112
|
+
map.resource :session
|
113
|
+
map.resources :users, :has_one => :password
|
114
|
+
map.resources :users, :has_one => :confirmation
|
115
|
+
map.resources :passwords
|
116
|
+
map.root :controller => 'sessions', :action => 'new'
|
117
|
+
|
118
|
+
h2. Environments
|
119
|
+
|
120
|
+
In config/environments/test.rb and config/environments/development.rb:
|
121
|
+
|
122
|
+
HOST = "localhost"
|
123
|
+
|
124
|
+
In config/environment.rb:
|
125
|
+
|
126
|
+
DO_NOT_REPLY = "donotreply@example.com"
|
127
|
+
PROJECT_NAME = "my_app_name"
|
128
|
+
|
129
|
+
h2. Authors
|
130
|
+
|
131
|
+
* thoughtbot, inc.
|
132
|
+
* Dan Croak
|
133
|
+
* Jason Morrison
|
134
|
+
* Mike Burns
|
135
|
+
* Josh Nichols
|
136
|
+
* Mike Breen
|
data/Rakefile
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'date'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
|
7
|
+
def gem_files
|
8
|
+
FileList["[A-Z]*", "{generators,lib}/**/*"]
|
9
|
+
end
|
10
|
+
|
11
|
+
test_files_pattern = 'test/rails_root/test/{unit,functional,other}/**/*_test.rb'
|
12
|
+
namespace :test do
|
13
|
+
Rake::TestTask.new(:all => 'generator:tests') do |t|
|
14
|
+
t.libs << 'lib'
|
15
|
+
t.pattern = test_files_pattern
|
16
|
+
t.verbose = false
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
20
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
21
|
+
t.spec_opts = ['--options', "\"test/rails_root/spec/spec.opts\""]
|
22
|
+
t.spec_files = FileList['test/rails_root/spec/**/*_spec.rb']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Run the test suite"
|
27
|
+
task :default => ['test:all', 'test:spec']
|
28
|
+
|
29
|
+
load 'lib/clearance/version.rb'
|
30
|
+
|
31
|
+
gemspec_doc = <<-GEMSPEC_DOC
|
32
|
+
s.date = "#{Date.today.strftime('%Y-%m-%d')}"
|
33
|
+
s.name = "clearance"
|
34
|
+
s.summary = "Fork of clearance"
|
35
|
+
s.email = "info@hashrocket.com"
|
36
|
+
s.version = "#{Clearance::Version::MAJOR}.#{Clearance::Version::MINOR}.#{Clearance::Version::PATCH}"
|
37
|
+
s.homepage = "http://github.com/hashrocket/clearance"
|
38
|
+
s.description = "Fork of clearance, not-purely-restful, but with Facebook goodness"
|
39
|
+
s.authors = [
|
40
|
+
"thoughtbot, inc.",
|
41
|
+
"Dan Croak",
|
42
|
+
"Josh Nichols",
|
43
|
+
"Jason Morrison",
|
44
|
+
"Mike Burns",
|
45
|
+
"Mike Breen",
|
46
|
+
"Hashrocket, Inc.",
|
47
|
+
"Les Hill",
|
48
|
+
"Jon Larkowski",
|
49
|
+
"Wes Gibbs"
|
50
|
+
]
|
51
|
+
GEMSPEC_DOC
|
52
|
+
|
53
|
+
spec = Gem::Specification.new do |s|
|
54
|
+
eval(gemspec_doc)
|
55
|
+
s.files = gem_files
|
56
|
+
end
|
57
|
+
|
58
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
59
|
+
pkg.need_zip = true
|
60
|
+
pkg.need_tar = true
|
61
|
+
end
|
62
|
+
|
63
|
+
namespace :generator do
|
64
|
+
desc "Run the generator on the tests"
|
65
|
+
task :tests do
|
66
|
+
system "mkdir -p test/rails_root/vendor/plugins/clearance"
|
67
|
+
system "cp -R generators test/rails_root/vendor/plugins/clearance"
|
68
|
+
system "cd test/rails_root; ./script/generate clearance"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "Generate the Clearance gemspec"
|
73
|
+
task :gemspec do
|
74
|
+
|
75
|
+
File.open("clearance.gemspec", "w") do |file|
|
76
|
+
file.write "Gem::Specification.new do |s|\n"
|
77
|
+
file.write(gemspec_doc)
|
78
|
+
file.write " s.files = [\n"
|
79
|
+
file.write gem_files.map {|f| %Q{ "#{f}"}}.join(",\n")
|
80
|
+
file.write " ]\n"
|
81
|
+
file.write "end\n"
|
82
|
+
end
|
83
|
+
end
|
data/TODO.textile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
(highest priority first)
|
2
|
+
|
3
|
+
# activation code (like restful-auth) instead of salt?
|
4
|
+
# remove dependency on root_url?
|
5
|
+
# should_have_form should be pulled into shoulda
|
6
|
+
# generator should print out instructions to include modules existing files
|
7
|
+
# check to make sure attr_accessible doesn't override and w/ attr_protected
|
8
|
+
# move shoulda macros in test_helper to shoulda_macros folder
|
9
|
+
# add shoulda and factory girl dependencies to gemspec
|
10
|
+
# refactor Mailer default_url_options[:host] to something cleaner
|
11
|
+
# application controller uses protected, all other controllers use private
|
12
|
+
# add information about url_after_create to README or github wikis
|
13
|
+
|
14
|
+
ideas to steal from merb-auth:
|
15
|
+
|
16
|
+
# store current_user on the session, not controller
|
17
|
+
# respond with 401 Unauthorized when request requires authentication
|
18
|
+
# respond with 405 Method Not Allowed when action requested isn’t allowed
|
19
|
+
# 401 and 405 need to be in Exceptions controller or use safety_valve
|
20
|
+
# email confirmation is a strategy
|
21
|
+
# forgot password is a strategy
|
22
|
+
# salted password is a strategy
|
23
|
+
|
24
|
+
http://adam.speaksoutofturn.com/articles/entication_vs_orization.html
|
@@ -0,0 +1 @@
|
|
1
|
+
script/generate clearance
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class ClearanceGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
def manifest
|
4
|
+
record do |m|
|
5
|
+
m.directory File.join("app", "controllers")
|
6
|
+
["app/controllers/confirmations_controller.rb",
|
7
|
+
"app/controllers/passwords_controller.rb",
|
8
|
+
"app/controllers/sessions_controller.rb",
|
9
|
+
"app/controllers/users_controller.rb"].each do |file|
|
10
|
+
m.file file, file
|
11
|
+
end
|
12
|
+
|
13
|
+
m.directory File.join("app", "models")
|
14
|
+
["app/models/user.rb",
|
15
|
+
"app/models/clearance_mailer.rb"].each do |file|
|
16
|
+
m.file file, file
|
17
|
+
end
|
18
|
+
|
19
|
+
m.directory File.join("app", "views")
|
20
|
+
m.directory File.join("app", "views", "confirmations")
|
21
|
+
["app/views/confirmations/new.html.erb"].each do |file|
|
22
|
+
m.file file, file
|
23
|
+
end
|
24
|
+
|
25
|
+
m.directory File.join("app", "views", "passwords")
|
26
|
+
["app/views/passwords/new.html.erb",
|
27
|
+
"app/views/passwords/edit.html.erb"].each do |file|
|
28
|
+
m.file file, file
|
29
|
+
end
|
30
|
+
|
31
|
+
m.directory File.join("app", "views", "sessions")
|
32
|
+
["app/views/sessions/new.html.erb"].each do |file|
|
33
|
+
m.file file, file
|
34
|
+
end
|
35
|
+
|
36
|
+
m.directory File.join("app", "views", "clearance_mailer")
|
37
|
+
["app/views/clearance_mailer/change_password.html.erb",
|
38
|
+
"app/views/clearance_mailer/confirmation.html.erb"].each do |file|
|
39
|
+
m.file file, file
|
40
|
+
end
|
41
|
+
|
42
|
+
m.directory File.join("app", "views", "users")
|
43
|
+
["app/views/users/_form.html.erb",
|
44
|
+
"app/views/users/edit.html.erb",
|
45
|
+
"app/views/users/new.html.erb"].each do |file|
|
46
|
+
m.file file, file
|
47
|
+
end
|
48
|
+
|
49
|
+
m.directory File.join("test", "functional")
|
50
|
+
["test/functional/confirmations_controller_test.rb",
|
51
|
+
"test/functional/passwords_controller_test.rb",
|
52
|
+
"test/functional/sessions_controller_test.rb",
|
53
|
+
"test/functional/users_controller_test.rb"].each do |file|
|
54
|
+
m.file file, file
|
55
|
+
end
|
56
|
+
|
57
|
+
m.directory File.join("test", "unit")
|
58
|
+
["test/unit/clearance_mailer_test.rb",
|
59
|
+
"test/unit/user_test.rb"].each do |file|
|
60
|
+
m.file file, file
|
61
|
+
end
|
62
|
+
|
63
|
+
["test/factories.rb"].each do |file|
|
64
|
+
m.file file, file
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
Someone, hopefully you, has requested that we send you a link to change your password.
|
2
|
+
|
3
|
+
Here's the link:
|
4
|
+
<%= edit_user_password_url @user, :email => @user.email, :password => @user.crypted_password %>
|
5
|
+
|
6
|
+
If you didn't request this, no need to freak out, your password hasn't been changed. You can just ignore this email.
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= new_user_confirmation_url :user_id => @user, :salt => @user.salt %>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<p>
|
2
|
+
Your password has been reset. Choose a new password below.
|
3
|
+
</p>
|
4
|
+
|
5
|
+
<%= error_messages_for :user %>
|
6
|
+
<% form_for(:user,
|
7
|
+
:url => user_password_path(
|
8
|
+
@user,
|
9
|
+
:email => @user.email,
|
10
|
+
:password => @user.crypted_password),
|
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, 'Verify password' %>
|
18
|
+
<%= form.password_field :password_confirmation %>
|
19
|
+
</div>
|
20
|
+
<div class="submit_field">
|
21
|
+
<%= form.submit 'Save this password' %>
|
22
|
+
</div>
|
23
|
+
<% end %>
|
@@ -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' %>
|
14
|
+
</div>
|
15
|
+
<% end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<% form_for :session, :url => session_path do |form| %>
|
2
|
+
<div class="text_field">
|
3
|
+
<%= form.label :email %>
|
4
|
+
<%= form.text_field :email %>
|
5
|
+
</div>
|
6
|
+
<div class="text_field">
|
7
|
+
<%= form.label :password %>
|
8
|
+
<%= form.password_field :password %>
|
9
|
+
</div>
|
10
|
+
<div class="text_field">
|
11
|
+
<%= form.check_box :remember_me %>
|
12
|
+
<%= form.label :remember_me %>
|
13
|
+
</div>
|
14
|
+
<div class="submit_field">
|
15
|
+
<%= form.submit 'Login', :disable_with => 'Please wait...' %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<ul>
|
20
|
+
<li>
|
21
|
+
<%= link_to "Sign up", new_user_path %>
|
22
|
+
</li>
|
23
|
+
<li>
|
24
|
+
<%= link_to "Forgot My Password", new_password_path %>
|
25
|
+
</li>
|
26
|
+
</ul>
|