salted_login_generator 1.1.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/salted_login_generator.rb +16 -1
- data/templates/README +41 -23
- data/templates/_view_edit.rhtml +0 -1
- data/templates/controller.rb +43 -36
- data/templates/controller_test.new.rb +328 -0
- data/templates/controller_test.old.rb +303 -0
- data/templates/controller_test.rb +97 -78
- data/templates/done +28 -0
- data/templates/helper.rb +12 -6
- data/templates/login_system.rb +11 -11
- data/templates/migration.rb +27 -0
- data/templates/notify.rb +6 -1
- data/templates/notify_change_password.rhtml +0 -5
- data/templates/notify_signup.rhtml +0 -1
- data/templates/user.rb +7 -5
- data/templates/user_model.erbsql +0 -1
- data/templates/user_test.rb +7 -7
- data/templates/users.yml +5 -10
- data/templates/view_change_password.rhtml +3 -3
- data/templates/view_edit.rhtml +8 -8
- data/templates/view_forgot_password.rhtml +3 -3
- data/templates/view_login.rhtml +2 -2
- data/templates/view_signup.rhtml +4 -4
- metadata +79 -70
data/salted_login_generator.rb
CHANGED
@@ -1,5 +1,16 @@
|
|
1
|
+
class Sandbox
|
2
|
+
def sandbox_binding
|
3
|
+
binding
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
1
7
|
class SaltedLoginGenerator < LocalizationGenerator #Rails::Generator::NamedBase
|
8
|
+
def create_sandbox
|
9
|
+
sandbox = Sandbox.new
|
10
|
+
sandbox
|
11
|
+
end
|
2
12
|
def manifest
|
13
|
+
|
3
14
|
record do |m|
|
4
15
|
m.dependency 'localization', [ARGV[1]]
|
5
16
|
|
@@ -15,6 +26,7 @@ class SaltedLoginGenerator < LocalizationGenerator #Rails::Generator::NamedBase
|
|
15
26
|
# Model class, unit test, fixtures, and example schema.
|
16
27
|
m.template "user.rb", File.join("app/models", class_path, "#{file_name}.rb")
|
17
28
|
m.template "notify.rb", File.join("app/models", class_path, "#{file_name}_notify.rb")
|
29
|
+
m.directory "db/migrate"
|
18
30
|
m.template "mock_notify.rb", "test/mocks/test/#{file_name}_notify.rb"
|
19
31
|
m.file "mock_time.rb", "test/mocks/test/time.rb"
|
20
32
|
|
@@ -22,13 +34,16 @@ class SaltedLoginGenerator < LocalizationGenerator #Rails::Generator::NamedBase
|
|
22
34
|
m.template "users.yml", "test/fixtures/#{plural_name}.yml"
|
23
35
|
m.template "user_model.erbsql", "db/user_model.erbsql"
|
24
36
|
|
37
|
+
|
38
|
+
m.migration_template("migration.rb", "db/migrate", {:migration_file_name => "create_#{plural_name}"})
|
39
|
+
|
25
40
|
# Configuration and miscellaneous
|
26
41
|
m.template "login_environment.rb", "config/environments/#{file_name}_environment.rb"
|
27
42
|
m.file "create_db", "script/create_db"
|
28
43
|
m.template "en.yaml", "lang/en.yaml"
|
29
44
|
|
30
45
|
# Layout and stylesheet.
|
31
|
-
m.template "scaffold:layout.
|
46
|
+
m.template "scaffold:layout.html.erb", "app/views/layouts/scaffold.rhtml"
|
32
47
|
m.template "scaffold:style.css", "public/stylesheets/scaffold.css"
|
33
48
|
|
34
49
|
# Views.
|
data/templates/README
CHANGED
@@ -4,30 +4,48 @@ After generating the login system, edit your app/controllers/application.rb
|
|
4
4
|
file. The beginning of your ApplicationController should look something like
|
5
5
|
this:
|
6
6
|
|
7
|
-
|
7
|
+
require 'localization'
|
8
|
+
require '<%= file_name %>_system'
|
9
|
+
require 'environment.rb'
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
before_filter :login_required
|
11
|
+
class ApplicationController < ActionController::Base
|
12
|
+
include Localization
|
13
|
+
include <%= class_name %>System
|
14
|
+
require_dependency <%= singular_name %>
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
db/user_model.sql.
|
16
|
+
And optionally, if you want to protect all actions of all controllers with login :
|
17
|
+
before_filter :login_required
|
18
|
+
|
19
|
+
And the ApplicationHelper (app/helpers/application_helper.rb) should contain :
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
module ApplicationHelper
|
22
|
+
include Localization
|
23
|
+
end
|
23
24
|
|
25
|
+
In the config/environment.rb, add the following lines after the final end :
|
26
|
+
|
27
|
+
require 'environments/localization_environment'
|
28
|
+
require 'localization'
|
29
|
+
Localization::load_localized_strings
|
24
30
|
require 'environments/<%= singular_name %>_environment'
|
25
31
|
|
26
|
-
|
32
|
+
You can import the <%= singular_name %> model into the database. This
|
33
|
+
model is meant as an example and you should extend it. If you just want to get
|
34
|
+
things up and running you can run the generated migration or create the table using the syntax in db/user_model.sql.
|
35
|
+
|
36
|
+
Under the 'environments' subdirectory, you'll find <%= singular_name %>_environment.rb.
|
27
37
|
Edit this file as necessary.
|
28
38
|
|
29
|
-
|
30
|
-
|
39
|
+
To make sure the test pass, check that these lines are present in test/test_helper.rb :
|
40
|
+
|
41
|
+
self.use_transactional_fixtures = false
|
42
|
+
self.use_instantiated_fixtures = true
|
43
|
+
|
44
|
+
Also, you must properly configure ActionMailer for your mail settings in config/environments/development.rb :
|
45
|
+
It may be simply (Unix or Mac OS X):
|
46
|
+
ActionMailer::Base.delivery_method=:sendmail
|
47
|
+
|
48
|
+
Or for example, I have the following in config/environments/development.rb (for a
|
31
49
|
.Mac account, and without my username and password, obviously):
|
32
50
|
|
33
51
|
ActionMailer::Base.server_settings = {
|
@@ -52,13 +70,14 @@ You need a database table corresponding to the <%= class_name %> model. Note
|
|
52
70
|
the table type for MySQL. Whatever DB you use, it must support transactions.
|
53
71
|
If it does not, the functional tests will not work properly, nor will the
|
54
72
|
application in the face of failures during certain DB creates and updates.
|
73
|
+
A migration file (mysql specific) will be created by the generate command.
|
74
|
+
You can change it to your specific database adapter :
|
55
75
|
|
56
76
|
mysql syntax:
|
57
77
|
CREATE TABLE <%= plural_name %> (
|
58
78
|
id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
59
79
|
login VARCHAR(80) NOT NULL,
|
60
80
|
salted_password VARCHAR(40) NOT NULL,
|
61
|
-
email VARCHAR(60) NOT NULL,
|
62
81
|
firstname VARCHAR(40),
|
63
82
|
lastname VARCHAR(40),
|
64
83
|
salt CHAR(40) NOT NULL,
|
@@ -75,7 +94,6 @@ application in the face of failures during certain DB creates and updates.
|
|
75
94
|
id SERIAL PRIMARY KEY
|
76
95
|
login VARCHAR(80) NOT NULL,
|
77
96
|
salted_password VARCHAR(40) NOT NULL,
|
78
|
-
email VARCHAR(60) NOT NULL,
|
79
97
|
firstname VARCHAR(40),
|
80
98
|
lastname VARCHAR(40),
|
81
99
|
salt CHAR(40) NOT NULL,
|
@@ -92,7 +110,6 @@ application in the face of failures during certain DB creates and updates.
|
|
92
110
|
id INTEGER PRIMARY KEY,
|
93
111
|
login VARCHAR(80) NOT NULL,
|
94
112
|
salted_password VARCHAR(40) NOT NULL,
|
95
|
-
email VARCHAR(60) NOT NULL,
|
96
113
|
firstname VARCHAR(40),
|
97
114
|
lastname VARCHAR(40),
|
98
115
|
salt CHAR(40) NOT NULL,
|
@@ -136,9 +153,9 @@ How do I...
|
|
136
153
|
|
137
154
|
... access the user who is currently logged in
|
138
155
|
|
139
|
-
A: You can get the <%= singular_name %> object from the session using
|
156
|
+
A: You can get the <%= singular_name %> object from the session using session['<%= singular_name %>']
|
140
157
|
Example:
|
141
|
-
Welcome <%%=
|
158
|
+
Welcome <%%= session['<%= singular_name %>'].name %>
|
142
159
|
|
143
160
|
... restrict access to only a few methods?
|
144
161
|
|
@@ -149,10 +166,10 @@ How do I...
|
|
149
166
|
|
150
167
|
... check if a user is logged-in in my views?
|
151
168
|
|
152
|
-
A:
|
169
|
+
A: session['<%= singular_name %>'] will tell you. Here is an example helper which you can use to make this more pretty:
|
153
170
|
Example:
|
154
171
|
def <%= singular_name %>?
|
155
|
-
|
172
|
+
!session['<%= singular_name %>'].nil?
|
156
173
|
end
|
157
174
|
|
158
175
|
... return a user to the page they came from before logging in?
|
@@ -185,6 +202,7 @@ automatically on startup.
|
|
185
202
|
|
186
203
|
== Changelog
|
187
204
|
|
205
|
+
2.0.0 Removed email field (the login IS now the email). Now runs with rails 2.0
|
188
206
|
1.0.9 Fixed hardcoded generator name (in controller test and schema) and README
|
189
207
|
1.0.8 Generator/schema fixes and some README fixes/improvements
|
190
208
|
1.0.7 Fixed bad bug with missing attr_accessor :new_password in user class
|
data/templates/_view_edit.rhtml
CHANGED
@@ -5,7 +5,6 @@
|
|
5
5
|
<%%= form_input changeable(<%= singular_name %>, "firstname"), "firstname" %>
|
6
6
|
<%%= form_input changeable(<%= singular_name %>, "lastname"), "lastname" %>
|
7
7
|
<%%= form_input changeable(<%= singular_name %>, "login"), "login", :size => 30 %><br/>
|
8
|
-
<%%= form_input changeable(<%= singular_name %>, "email"), "email" %>
|
9
8
|
<%% if submit %>
|
10
9
|
<%%= form_input :submit_button, <%= singular_name %>.new_record? ? 'signup' : 'change_settings', :class => 'two_columns' %>
|
11
10
|
<%% end %>
|
data/templates/controller.rb
CHANGED
@@ -1,31 +1,31 @@
|
|
1
1
|
class <%= class_name %>Controller < ApplicationController
|
2
|
-
|
2
|
+
before_filter :login_required, :only => [:welcome,:change_password]
|
3
3
|
layout 'scaffold'
|
4
4
|
|
5
5
|
def login
|
6
6
|
return if generate_blank
|
7
|
-
@<%= singular_name %> = <%= class_name %>.new(
|
8
|
-
if
|
7
|
+
@<%= singular_name %> = <%= class_name %>.new(params['<%= singular_name %>'])
|
8
|
+
if session['<%= singular_name %>'] = <%= class_name %>.authenticate(params['<%= singular_name %>']['login'], params['<%= singular_name %>']['password'])
|
9
9
|
flash['notice'] = l(:<%= singular_name %>_login_succeeded)
|
10
10
|
redirect_back_or_default :action => 'welcome'
|
11
11
|
else
|
12
|
-
@login =
|
12
|
+
@login = params['<%= singular_name %>']['login']
|
13
13
|
flash.now['message'] = l(:<%= singular_name %>_login_failed)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def signup
|
18
18
|
return if generate_blank
|
19
|
-
|
20
|
-
@<%= singular_name %> = <%= class_name %>.new(
|
19
|
+
params['<%= singular_name %>'].delete('form')
|
20
|
+
@<%= singular_name %> = <%= class_name %>.new(params['<%= singular_name %>'])
|
21
21
|
begin
|
22
|
-
<%= class_name %>.transaction
|
22
|
+
<%= class_name %>.transaction do
|
23
23
|
@<%= singular_name %>.new_password = true
|
24
24
|
if @<%= singular_name %>.save
|
25
25
|
key = @<%= singular_name %>.generate_security_token
|
26
26
|
url = url_for(:action => 'welcome')
|
27
27
|
url += "?<%= singular_name %>[id]=#{@<%= singular_name %>.id}&key=#{key}"
|
28
|
-
<%= class_name %>Notify.deliver_signup(@<%= singular_name %>,
|
28
|
+
<%= class_name %>Notify.deliver_signup(@<%= singular_name %>, params['<%= singular_name %>']['password'], url)
|
29
29
|
flash['notice'] = l(:<%= singular_name %>_signup_succeeded)
|
30
30
|
redirect_to :action => 'login'
|
31
31
|
end
|
@@ -36,19 +36,19 @@ class <%= class_name %>Controller < ApplicationController
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def logout
|
39
|
-
|
39
|
+
session['<%= singular_name %>'] = nil
|
40
40
|
redirect_to :action => 'login'
|
41
41
|
end
|
42
42
|
|
43
43
|
def change_password
|
44
44
|
return if generate_filled_in
|
45
|
-
|
45
|
+
params['<%= singular_name %>'].delete('form')
|
46
46
|
begin
|
47
|
-
<%= class_name %>.transaction
|
48
|
-
@<%= singular_name %>.change_password(
|
47
|
+
<%= class_name %>.transaction do
|
48
|
+
@<%= singular_name %>.change_password(params['<%= singular_name %>']['password'], params['<%= singular_name %>']['password_confirmation'])
|
49
49
|
if @<%= singular_name %>.save
|
50
|
-
<%= class_name %>Notify.deliver_change_password(@<%= singular_name %>,
|
51
|
-
flash.now['notice'] = l(:<%= singular_name %>_updated_password, "#{@<%= singular_name %>.
|
50
|
+
<%= class_name %>Notify.deliver_change_password(@<%= singular_name %>, params['<%= singular_name %>']['password'])
|
51
|
+
flash.now['notice'] = l(:<%= singular_name %>_updated_password, "#{@<%= singular_name %>.login}")
|
52
52
|
end
|
53
53
|
end
|
54
54
|
rescue
|
@@ -68,18 +68,18 @@ class <%= class_name %>Controller < ApplicationController
|
|
68
68
|
return if generate_blank
|
69
69
|
|
70
70
|
# Handle the :post
|
71
|
-
if
|
71
|
+
if params['<%= singular_name %>']['login'].nil?
|
72
72
|
flash.now['message'] = l(:<%= singular_name %>_enter_valid_email_address)
|
73
|
-
elsif (<%= singular_name %> = <%= class_name %>.
|
74
|
-
flash.now['message'] = l(:<%= singular_name %>_email_address_not_found, "#{
|
73
|
+
elsif (<%= singular_name %> = <%= class_name %>.find_by_login(params['<%= singular_name %>']['login'])).nil?
|
74
|
+
flash.now['message'] = l(:<%= singular_name %>_email_address_not_found, "#{params['<%= singular_name %>']['login']}")
|
75
75
|
else
|
76
76
|
begin
|
77
|
-
<%= class_name %>.transaction
|
77
|
+
<%= class_name %>.transaction do
|
78
78
|
key = <%= singular_name %>.generate_security_token
|
79
79
|
url = url_for(:action => 'change_password')
|
80
80
|
url += "?<%= singular_name %>[id]=#{<%= singular_name %>.id}&key=#{key}"
|
81
81
|
<%= class_name %>Notify.deliver_forgot_password(<%= singular_name %>, url)
|
82
|
-
flash['notice'] = l(:<%= singular_name %>_forgotten_password_emailed, "#{
|
82
|
+
flash['notice'] = l(:<%= singular_name %>_forgotten_password_emailed, "#{params['<%= singular_name %>']['login']}")
|
83
83
|
unless <%= singular_name %>?
|
84
84
|
redirect_to :action => 'login'
|
85
85
|
return
|
@@ -87,21 +87,21 @@ class <%= class_name %>Controller < ApplicationController
|
|
87
87
|
redirect_back_or_default :action => 'welcome'
|
88
88
|
end
|
89
89
|
rescue
|
90
|
-
flash.now['message'] = l(:<%= singular_name %>_forgotten_password_email_error, "#{
|
90
|
+
flash.now['message'] = l(:<%= singular_name %>_forgotten_password_email_error, "#{params['<%= singular_name %>']['login']}")
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
95
|
def edit
|
96
96
|
return if generate_filled_in
|
97
|
-
if
|
98
|
-
form =
|
97
|
+
if params['<%= singular_name %>']['form']
|
98
|
+
form = params['<%= singular_name %>'].delete('form')
|
99
99
|
begin
|
100
100
|
case form
|
101
101
|
when "edit"
|
102
102
|
changeable_fields = ['firstname', 'lastname']
|
103
|
-
|
104
|
-
@<%= singular_name %>.attributes =
|
103
|
+
p = params['<%= singular_name %>'].delete_if { |k,v| not changeable_fields.include?(k) }
|
104
|
+
@<%= singular_name %>.attributes = p
|
105
105
|
@<%= singular_name %>.save
|
106
106
|
when "change_password"
|
107
107
|
change_password
|
@@ -115,33 +115,40 @@ class <%= class_name %>Controller < ApplicationController
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def delete
|
118
|
-
@<%= singular_name %> =
|
118
|
+
@<%= singular_name %> = session['<%= singular_name %>']
|
119
119
|
begin
|
120
120
|
if <%= class_name %>System::CONFIG[:delayed_delete]
|
121
|
-
<%= class_name %>.transaction
|
121
|
+
<%= class_name %>.transaction do
|
122
122
|
key = @<%= singular_name %>.set_delete_after
|
123
123
|
url = url_for(:action => 'restore_deleted')
|
124
124
|
url += "?<%= singular_name %>[id]=#{@<%= singular_name %>.id}&key=#{key}"
|
125
125
|
<%= class_name %>Notify.deliver_pending_delete(@<%= singular_name %>, url)
|
126
126
|
end
|
127
127
|
else
|
128
|
+
session['<%= singular_name %>'] = nil;
|
128
129
|
destroy(@<%= singular_name %>)
|
129
130
|
end
|
130
131
|
logout
|
131
132
|
rescue
|
132
|
-
flash.now['message'] = l(:<%= singular_name %>_delete_email_error, "#{@<%= singular_name %>['
|
133
|
+
flash.now['message'] = l(:<%= singular_name %>_delete_email_error, "#{@<%= singular_name %>['login']}")
|
133
134
|
redirect_back_or_default :action => 'welcome'
|
134
135
|
end
|
135
136
|
end
|
136
137
|
|
137
138
|
def restore_deleted
|
138
|
-
@<%= singular_name %> =
|
139
|
-
@<%= singular_name
|
140
|
-
|
141
|
-
|
142
|
-
|
139
|
+
@<%= singular_name %> = <%= class_name %>.find_by_id(params['<%= singular_name %>']['id'])
|
140
|
+
if(@<%= singular_name %>)
|
141
|
+
@<%= singular_name %>.deleted = 0
|
142
|
+
if @<%= singular_name %>.token_expired? or params['key'] != @<%= singular_name %>.security_token or not @<%= singular_name %>.save
|
143
|
+
flash.now['notice'] = l(:<%= singular_name %>_restore_deleted_error, "#{@<%= singular_name %>['login']}")
|
144
|
+
redirect_to :action => 'login'
|
145
|
+
else
|
146
|
+
session['<%= singular_name %>'] = @<%= singular_name %>
|
147
|
+
redirect_to :action => 'welcome'
|
148
|
+
end
|
143
149
|
else
|
144
|
-
|
150
|
+
flash.now['notice'] = l(:<%= singular_name %>_restore_deleted_error, "")
|
151
|
+
redirect_to :action => 'login'
|
145
152
|
end
|
146
153
|
end
|
147
154
|
|
@@ -166,7 +173,7 @@ class <%= class_name %>Controller < ApplicationController
|
|
166
173
|
|
167
174
|
# Generate a template <%= singular_name %> for certain actions on get
|
168
175
|
def generate_blank
|
169
|
-
case
|
176
|
+
case request.method
|
170
177
|
when :get
|
171
178
|
@<%= singular_name %> = <%= class_name %>.new
|
172
179
|
render
|
@@ -177,8 +184,8 @@ class <%= class_name %>Controller < ApplicationController
|
|
177
184
|
|
178
185
|
# Generate a template <%= singular_name %> for certain actions on get
|
179
186
|
def generate_filled_in
|
180
|
-
@<%= singular_name %> =
|
181
|
-
case
|
187
|
+
@<%= singular_name %> = session['<%= singular_name %>']
|
188
|
+
case request.method
|
182
189
|
when :get
|
183
190
|
render
|
184
191
|
return true
|