salted_login_generator 1.1.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|