login_sugar_generator 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- data/USAGE +32 -0
- data/login_sugar_generator.rb +79 -0
- data/templates/README +194 -0
- data/templates/_view_edit.rhtml +30 -0
- data/templates/_view_password.rhtml +21 -0
- data/templates/clock.rb +14 -0
- data/templates/controller.rb +179 -0
- data/templates/controller_test.rb +254 -0
- data/templates/create_db +7 -0
- data/templates/default_setup.zip +0 -0
- data/templates/helper.rb +41 -0
- data/templates/integration_test.rb +95 -0
- data/templates/layout.rhtml +13 -0
- data/templates/login_environment.rb +21 -0
- data/templates/login_system.rb +54 -0
- data/templates/migration_login_sugar.rb +21 -0
- data/templates/mock_clock.rb +14 -0
- data/templates/mock_notify.rb +16 -0
- data/templates/notify.rb +50 -0
- data/templates/notify_change_password.rhtml +10 -0
- data/templates/notify_delete.rhtml +5 -0
- data/templates/notify_forgot_password.rhtml +11 -0
- data/templates/notify_pending_delete.rhtml +9 -0
- data/templates/notify_signup.rhtml +12 -0
- data/templates/stylesheet.css +74 -0
- data/templates/user.rb +101 -0
- data/templates/user_model.erbsql +18 -0
- data/templates/user_test.rb +133 -0
- data/templates/users.yml +48 -0
- data/templates/view_change_password.rhtml +15 -0
- data/templates/view_edit.rhtml +19 -0
- data/templates/view_forgot_password.rhtml +19 -0
- data/templates/view_login.rhtml +24 -0
- data/templates/view_logout.rhtml +8 -0
- data/templates/view_signup.rhtml +14 -0
- data/templates/view_welcome.rhtml +10 -0
- metadata +80 -0
data/USAGE
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
NAME
|
2
|
+
login_sugar - creates a functional login system with email validation and salted hash passwords
|
3
|
+
|
4
|
+
SYNOPSIS
|
5
|
+
login_sugar [Controller name]
|
6
|
+
|
7
|
+
Good names are User, Account, Person, etc
|
8
|
+
|
9
|
+
See README_LOGIN_SUGAR for configuration instructions.
|
10
|
+
|
11
|
+
DESCRIPTION
|
12
|
+
This generator creates a general purpose login system.
|
13
|
+
|
14
|
+
Included:
|
15
|
+
- a model which uses SHA1 encryption and salted hashes for passwords
|
16
|
+
- a controller with signup, login, welcome and logoff actions
|
17
|
+
- a mailer that integrates with the controller to prevent script based
|
18
|
+
account creation (i.e., requires account verification from the
|
19
|
+
registered email address) and supports forgotten and changed passwords
|
20
|
+
- a mixin which lets you easily add advanced authentication
|
21
|
+
features to your abstract base controller
|
22
|
+
- an example database migration script with the minimal sql required to
|
23
|
+
get the model to work.
|
24
|
+
- extensive unit and functional test cases to make sure nothing breaks.
|
25
|
+
- token based authentication
|
26
|
+
|
27
|
+
EXAMPLE
|
28
|
+
./script/generate login_sugar User
|
29
|
+
|
30
|
+
This will generate a User controller with login and logout methods.
|
31
|
+
The class names are UserController, User (model), and UserNotifier
|
32
|
+
(mailer). It will also generate a module named UserLoginSystem.
|
@@ -0,0 +1,79 @@
|
|
1
|
+
class LoginSugarGenerator < Rails::Generator::NamedBase
|
2
|
+
|
3
|
+
attr_accessor :controller_class_name
|
4
|
+
#
|
5
|
+
#TODO
|
6
|
+
# - rakify try_it.sh
|
7
|
+
# - store user.id in session
|
8
|
+
|
9
|
+
def manifest
|
10
|
+
record do |m|
|
11
|
+
# Check for class naming collisions.
|
12
|
+
#m.class_collisions class_path, "#{class_name}Controller", "#{class_name}ControllerTest", "#{class_name}Helper", "#{class_name}LoginSystem"
|
13
|
+
|
14
|
+
# Login module, controller class, functional test, and helper.
|
15
|
+
m.template "login_system.rb", "lib/#{file_name}_system.rb"
|
16
|
+
m.template "controller.rb", File.join("app/controllers", class_path, "#{file_name}_controller.rb")
|
17
|
+
m.template "controller_test.rb", "test/functional/#{file_name}_controller_test.rb"
|
18
|
+
m.template "integration_test.rb", "test/integration/#{file_name}_system_test.rb"
|
19
|
+
m.template "helper.rb", File.join("app/helpers", class_path, "#{file_name}_helper.rb")
|
20
|
+
|
21
|
+
# Model class, unit test, fixtures, and example schema.
|
22
|
+
m.template "user.rb", File.join("app/models", class_path, "#{file_name}.rb")
|
23
|
+
m.template "notify.rb", File.join("app/models", class_path, "#{file_name}_notify.rb")
|
24
|
+
m.template "mock_notify.rb", "test/mocks/test/#{file_name}_notify.rb"
|
25
|
+
m.file "mock_clock.rb", "test/mocks/test/clock.rb"
|
26
|
+
m.template "clock.rb", "lib/clock.rb"
|
27
|
+
|
28
|
+
m.template "user_test.rb", "test/unit/#{file_name}_test.rb"
|
29
|
+
m.template "users.yml", "test/fixtures/#{plural_name}.yml"
|
30
|
+
m.directory "db/migrate"
|
31
|
+
m.template "migration_login_sugar.rb", "db/migrate/migration_login_sugar__rename_this_to_fit_your_project.rb"
|
32
|
+
|
33
|
+
# Configuration and miscellaneous
|
34
|
+
m.template "login_environment.rb", "config/environments/#{file_name}_environment.rb"
|
35
|
+
#m.file "create_db", "script/create_db"
|
36
|
+
#m.template "en.yaml", "lang/en.yaml"
|
37
|
+
m.file "default_setup.zip", "default_login_sugar_setup.zip"
|
38
|
+
|
39
|
+
# Layout and stylesheet.
|
40
|
+
m.template "layout.rhtml", "app/views/layouts/#{file_name}.rhtml"
|
41
|
+
m.directory "public/stylesheets"
|
42
|
+
m.template "stylesheet.css", "public/stylesheets/#{file_name}.css"
|
43
|
+
|
44
|
+
# Views.
|
45
|
+
m.directory File.join("app/views", class_path, file_name)
|
46
|
+
login_views.each do |action|
|
47
|
+
m.template "view_#{action}.rhtml",
|
48
|
+
File.join("app/views", class_path, file_name, "#{action}.rhtml")
|
49
|
+
end
|
50
|
+
|
51
|
+
# Partials
|
52
|
+
m.directory File.join("app/views", class_path, file_name)
|
53
|
+
partial_views.each do |action|
|
54
|
+
m.template "_view_#{action}.rhtml",
|
55
|
+
File.join("app/views", class_path, file_name, "_#{action}.rhtml")
|
56
|
+
end
|
57
|
+
|
58
|
+
m.directory File.join("app/views", "#{singular_name}_notify")
|
59
|
+
notify_views.each do |action|
|
60
|
+
m.template "notify_#{action}.rhtml",
|
61
|
+
File.join("app/views", "#{singular_name}_notify", "#{action}.rhtml")
|
62
|
+
end
|
63
|
+
|
64
|
+
m.template "README", "README_LOGIN_SUGAR"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def login_views
|
69
|
+
%w(welcome login logout edit signup forgot_password change_password)
|
70
|
+
end
|
71
|
+
|
72
|
+
def partial_views
|
73
|
+
%w(edit password)
|
74
|
+
end
|
75
|
+
|
76
|
+
def notify_views
|
77
|
+
%w(signup forgot_password change_password)
|
78
|
+
end
|
79
|
+
end
|
data/templates/README
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
== About
|
2
|
+
|
3
|
+
login_sugar is a modification of salted_login generator 1.1.1 that works
|
4
|
+
out of the box on Rails 1.1.6
|
5
|
+
|
6
|
+
Changes:
|
7
|
+
- tests all pass out of the box on Rails >= 1.1.4
|
8
|
+
- using ActiveRecord::Migrations for db setup
|
9
|
+
- put underscores in first_name and last_name user attributes
|
10
|
+
- replaced Mock Time extension with a Mock Clock.
|
11
|
+
- README_USER_LOGIN is a one stop readme
|
12
|
+
- contains a default configuration zip
|
13
|
+
- session references se symbols
|
14
|
+
- localization removed
|
15
|
+
|
16
|
+
More about salted_login_generator at http://rubyforge.org/projects/salted-login
|
17
|
+
|
18
|
+
== Prerequisite
|
19
|
+
|
20
|
+
If you are on Windoze, see http://wiki.rubyonrails.com/rails/pages/iconv/
|
21
|
+
|
22
|
+
== Installation
|
23
|
+
|
24
|
+
If you are working with a fresh rails 1.1.6 project, you can unzip the included
|
25
|
+
default_login_sugar_setup.zip file in your RAILS_ROOT directory. It contains
|
26
|
+
preconfigured application controller, environment.rb, application_helper.rb and
|
27
|
+
test_helper.rb that should work if you used User as your controller names when
|
28
|
+
running the generator. If you do this, you can skip down to the PHASE II
|
29
|
+
section below. BUT DON'T DO THIS IF YOU HAVE ALREADY MODIFIED YOUR RAILS APP
|
30
|
+
as it will overwrite your existing files. Of course, you should have those
|
31
|
+
under source control anyhow...
|
32
|
+
|
33
|
+
- PHASE I -
|
34
|
+
|
35
|
+
After generating the login system, edit your app/controllers/application.rb
|
36
|
+
file. The beginning of your ApplicationController should look something like
|
37
|
+
this:
|
38
|
+
|
39
|
+
require '<%= file_name %>_system'
|
40
|
+
|
41
|
+
class ApplicationController < ActionController::Base
|
42
|
+
include <%= class_name %>System
|
43
|
+
helper :<%= singular_name %>
|
44
|
+
model :<%= singular_name %>
|
45
|
+
before_filter :authenticate_user
|
46
|
+
|
47
|
+
Add the following at the end of your config/environment.rb file:
|
48
|
+
|
49
|
+
require 'environments/<%= singular_name %>_environment'
|
50
|
+
|
51
|
+
Add the following line to the top of your test/test_helper.rb:
|
52
|
+
|
53
|
+
require 'user_notify'
|
54
|
+
|
55
|
+
- PHASE II -
|
56
|
+
|
57
|
+
Under the 'environments' subdirectory, you'll find <%= singular_name %>_environment.rb.
|
58
|
+
Edit this file as necessary.
|
59
|
+
|
60
|
+
Import the <%= singular_name %> model into the database.
|
61
|
+
|
62
|
+
You'll have to create your development and test databases first and configure your
|
63
|
+
config/database.yml appropriately. Note, if you are using mysql you will need to edit
|
64
|
+
test/fixtures/users.yml and make the indicated change on the last fixture.
|
65
|
+
|
66
|
+
You can use the provided migration script in
|
67
|
+
db/migrate/migration_login_sugar__rename_this_to_fit_your_project.rb.
|
68
|
+
|
69
|
+
This model is meant as an example and you
|
70
|
+
can extend it, however I suggest first completing the stock installation and running
|
71
|
+
the tests to confirm installation, then create a new migration to add your new columns.
|
72
|
+
|
73
|
+
Rename db/migrate/migration_login_sugar__rename_this_to_fit_your_project.rb to
|
74
|
+
db/migrate/###_login_sugar.rb where ### is the proper new migration level. For example,
|
75
|
+
if this is your first migration for this rails project, use 001. If you name it something
|
76
|
+
other than ###_login_sugar.rb then you'll need to edit the file and change the class name
|
77
|
+
of the migration in the class definition as well.
|
78
|
+
|
79
|
+
Then run:
|
80
|
+
|
81
|
+
rake migrate && rake db:test:clone
|
82
|
+
|
83
|
+
Go ahead and run the unit and functional tests now:
|
84
|
+
|
85
|
+
rake
|
86
|
+
|
87
|
+
These should all pass.
|
88
|
+
|
89
|
+
Finally, you must properly configure ActionMailer for your mail settings. For
|
90
|
+
example, I have the following in config/environments/development.rb (for a
|
91
|
+
.Mac account, and without my username and password, obviously):
|
92
|
+
|
93
|
+
ActionMailer::Base.server_settings = {
|
94
|
+
:address => "smtp.mac.com",
|
95
|
+
:port => 25,
|
96
|
+
:domain => "smtp.mac.com",
|
97
|
+
:user_name => "<your user name here>",
|
98
|
+
:password => "<your password here>",
|
99
|
+
:authentication => :login
|
100
|
+
}
|
101
|
+
|
102
|
+
You'll need to configure it properly so that email can be sent. One of the
|
103
|
+
easiest ways to test your configuration is to temporarily reraise exceptions
|
104
|
+
from the signup method (so that you get the actual mailer exception string).
|
105
|
+
In the rescue statement, put a single "raise" statement in. Once you've
|
106
|
+
debugged any setting problems, remove that statement to get the proper flash
|
107
|
+
error handling back.
|
108
|
+
|
109
|
+
== How to use it
|
110
|
+
|
111
|
+
Now you can go around and happily add "before_filter :authenticate_user" to the
|
112
|
+
controllers which you would like to protect.
|
113
|
+
|
114
|
+
After integrating the login system with your rails application navigate to your
|
115
|
+
new controller's signup method. There you can create a new account. After you
|
116
|
+
are done you should have a look at your DB. Your freshly created <%= singular_name %>
|
117
|
+
will be there but the password will be a sha1 hashed 40 digit mess. I find
|
118
|
+
this should be the minimum of security which every page offering login &
|
119
|
+
password should give its customers. Now you can move to one of those
|
120
|
+
controllers which you protected with the before_filter :authenticate_user snippet.
|
121
|
+
You will automatically be re-directed to your freshly created login controller
|
122
|
+
and you are asked for a password. After entering valid account data you will be
|
123
|
+
taken back to the controller which you requested earlier. Simple huh?
|
124
|
+
|
125
|
+
== Tips & Tricks
|
126
|
+
|
127
|
+
How do I...
|
128
|
+
|
129
|
+
... access the user who is currently logged in
|
130
|
+
|
131
|
+
A: You can get the <%= singular_name %> object from the session using @session[:<%= singular_name %>]
|
132
|
+
Example:
|
133
|
+
Welcome <%%= @session[:<%= singular_name %>].name %>
|
134
|
+
|
135
|
+
... restrict access to only a few methods?
|
136
|
+
|
137
|
+
A: Use before_filters build in scoping.
|
138
|
+
Example:
|
139
|
+
before_filter :authenticate_user, :only => [:myaccount, :changepassword]
|
140
|
+
before_filter :authenticate_user, :except => [:index]
|
141
|
+
|
142
|
+
... check if a user is logged-in in my views?
|
143
|
+
|
144
|
+
A: @session[:<%= singular_name %>] will tell you. Here is an example helper which you can use to make this more pretty:
|
145
|
+
Example:
|
146
|
+
def <%= singular_name %>?
|
147
|
+
!@session[:<%= singular_name %>].nil?
|
148
|
+
end
|
149
|
+
|
150
|
+
... return a user to the page they came from before logging in?
|
151
|
+
F
|
152
|
+
A: The user will be send back to the last url which called the method "store_location"
|
153
|
+
Example:
|
154
|
+
User was at /articles/show/1, wants to log in.
|
155
|
+
in articles_controller.rb, add store_location to the show function and
|
156
|
+
send the user to the login form.
|
157
|
+
After he logs in he will be send back to /articles/show/1
|
158
|
+
|
159
|
+
You can find more help at http://wiki.rubyonrails.com/rails/show/SaltedLoginGenerator
|
160
|
+
|
161
|
+
== Troubleshooting
|
162
|
+
|
163
|
+
One of the more common problems people have seen is that after verifying an
|
164
|
+
account by following the emailed URL, they are unable to login via the
|
165
|
+
normal login method since the verified field is not properly set in the
|
166
|
+
<%= singular_name %> model's row in the DB.
|
167
|
+
|
168
|
+
The most common cause of this problem is that the DB and session get out of
|
169
|
+
sync. In particular, it always happens for me after recreating the DB if I
|
170
|
+
have run the server previously. To fix the problem, remove the /tmp/ruby*
|
171
|
+
session files (from wherever they are for your installation) while the server
|
172
|
+
is stopped, and then restart. This usually is the cause of the problem.
|
173
|
+
|
174
|
+
A forthcoming release will probably fix this via a well placed reset_session
|
175
|
+
call (or requirement to add it after running the generator) so that it is done
|
176
|
+
automatically on startup.
|
177
|
+
|
178
|
+
== Changelog
|
179
|
+
|
180
|
+
login_sugar
|
181
|
+
0.9.4 removed scaffold references, removed localization, added generator rake task
|
182
|
+
0.9.3 fixed Clock.now, symbolized session references
|
183
|
+
0.9.2 fixed localization reference for sign in form (thanks Nym)
|
184
|
+
0.9.1 fixed double first_name replacing last_name (thanks BobF)
|
185
|
+
0.9.0 first release, modified salted_login 1.1.1
|
186
|
+
|
187
|
+
salted_login
|
188
|
+
|
189
|
+
1.0.9 Fixed hardcoded generator name (in controller test and schema) and README
|
190
|
+
1.0.8 Generator/schema fixes and some README fixes/improvements
|
191
|
+
1.0.7 Fixed bad bug with missing attr_accessor :new_password in user class
|
192
|
+
1.0.6 Proper delete support and bug fixes
|
193
|
+
1.0.5 Lots of fixes and changes (see rubyforge.org/salted-login)
|
194
|
+
1.0.0 First gem release
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<div class="<%= singular_name %>_edit">
|
2
|
+
<%%= hidden_field '<%= singular_name %>', 'form', :value => 'edit' %>
|
3
|
+
<table>
|
4
|
+
<tr class="two_columns">
|
5
|
+
<td class="prompt"><label>First Name:</label></td>
|
6
|
+
<td class="value"><%%= text_field '<%= singular_name %>', 'first_name' %></td>
|
7
|
+
</tr>
|
8
|
+
<tr class="two_columns">
|
9
|
+
<td class="prompt"><label>Last Name:</label></td>
|
10
|
+
<td class="value"><%%= text_field '<%= singular_name %>', 'last_name' %></td>
|
11
|
+
</tr>
|
12
|
+
<tr class="two_columns">
|
13
|
+
<td class="prompt"><label>Login:</label></td>
|
14
|
+
<td class="value">
|
15
|
+
<%%= @<%= singular_name %>.new_record? ? text_field( '<%= singular_name %>', 'login' ) : @<%= singular_name %>.login %>
|
16
|
+
</td>
|
17
|
+
</tr>
|
18
|
+
<tr class="two_columns">
|
19
|
+
<td class="prompt"><label>Email:</label></td>
|
20
|
+
<td class="value"><%%= text_field '<%= singular_name %>', 'email' %></td>
|
21
|
+
</tr>
|
22
|
+
<%% if submit %>
|
23
|
+
<tr>
|
24
|
+
<td>
|
25
|
+
<%%= submit_tag <%= singular_name %>.new_record? ? 'signup' : 'change_settings', :class => 'two_columns' %>
|
26
|
+
</td>
|
27
|
+
</tr>
|
28
|
+
<%% end %>
|
29
|
+
</table>
|
30
|
+
</div>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="<%= singular_name %>_password">
|
2
|
+
<%%= hidden_field '<%= singular_name %>', 'form', :value => 'change_password' %>
|
3
|
+
|
4
|
+
<table>
|
5
|
+
<tr class="two_columns">
|
6
|
+
<td class="prompt"><label>Password:</label></td>
|
7
|
+
<td class="value"><%%= password_field '<%= singular_name %>', 'password', :size => 30 %></td>
|
8
|
+
</tr>
|
9
|
+
<tr class="two_columns">
|
10
|
+
<td class="prompt"><label>Password confirmation:</label></td>
|
11
|
+
<td class="value"><%%= password_field '<%= singular_name %>', 'password_confirmation', :size => 30 %></td>
|
12
|
+
</tr>
|
13
|
+
<%% if submit %>
|
14
|
+
<tr>
|
15
|
+
<td>
|
16
|
+
<%%= submit_tag 'change_password' %>
|
17
|
+
</td>
|
18
|
+
</tr>
|
19
|
+
<%% end %>
|
20
|
+
</table>
|
21
|
+
</div>
|
data/templates/clock.rb
ADDED
@@ -0,0 +1,179 @@
|
|
1
|
+
class <%= class_name %>Controller < ApplicationController
|
2
|
+
layout '<%= singular_name %>'
|
3
|
+
|
4
|
+
skip_before_filter :authenticate_<%= singular_name %>, :only => [ :login, :signup, :forgot_password ]
|
5
|
+
|
6
|
+
def login
|
7
|
+
return if generate_blank_form
|
8
|
+
@<%= singular_name %> = <%= class_name %>.new(@params['<%= singular_name %>'])
|
9
|
+
<%= singular_name %> = <%= class_name %>.authenticate(@params['<%= singular_name %>']['login'], @params['<%= singular_name %>']['password'])
|
10
|
+
if <%= singular_name %>
|
11
|
+
@current_<%= singular_name %> = <%= singular_name %>
|
12
|
+
@session[:<%= singular_name %>_id] = <%= singular_name %>.id
|
13
|
+
flash['notice'] = 'Login succeeded'
|
14
|
+
redirect_back_or_default :action => 'welcome'
|
15
|
+
else
|
16
|
+
@login = @params['<%= singular_name %>']['login']
|
17
|
+
flash['message'] = 'Login failed'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def signup
|
22
|
+
return if generate_blank_form
|
23
|
+
@params['<%= singular_name %>'].delete('form')
|
24
|
+
@<%= singular_name %> = <%= class_name %>.new(@params['<%= singular_name %>'])
|
25
|
+
begin
|
26
|
+
<%= class_name %>.transaction(@<%= singular_name %>) do
|
27
|
+
@<%= singular_name %>.password_needs_confirmation = true
|
28
|
+
if @<%= singular_name %>.save
|
29
|
+
key = @<%= singular_name %>.generate_security_token
|
30
|
+
url = url_for(:action => 'welcome')
|
31
|
+
url += "?<%= singular_name %>[id]=#{@<%= singular_name %>.id}&key=#{key}"
|
32
|
+
<%= class_name %>Notify.deliver_signup(@<%= singular_name %>, @params['<%= singular_name %>']['password'], url)
|
33
|
+
flash['notice'] = 'Signup successful! Please check your registered email account to verify your account registration and continue with the login.'
|
34
|
+
redirect_to :action => 'login'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
rescue Exception => ex
|
38
|
+
report_exception ex
|
39
|
+
flash['message'] = 'Error creating account: confirmation email not sent'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def logout
|
44
|
+
@session[:<%= singular_name %>_id] = nil
|
45
|
+
@current_<%= singular_name %> = nil
|
46
|
+
redirect_to :action => 'login'
|
47
|
+
end
|
48
|
+
|
49
|
+
def change_password
|
50
|
+
return if generate_filled_in
|
51
|
+
@params['<%= singular_name %>'].delete('form')
|
52
|
+
begin
|
53
|
+
@<%= singular_name %>.change_password(@params['<%= singular_name %>']['password'], @params['<%= singular_name %>']['password_confirmation'])
|
54
|
+
@<%= singular_name %>.save!
|
55
|
+
rescue Exception => ex
|
56
|
+
report_exception ex
|
57
|
+
flash.now['message'] = 'Your password could not be changed at this time. Please retry.'
|
58
|
+
render and return
|
59
|
+
end
|
60
|
+
begin
|
61
|
+
<%= class_name %>Notify.deliver_change_password(@<%= singular_name %>, @params['<%= singular_name %>']['password'])
|
62
|
+
rescue Exception => ex
|
63
|
+
report_exception ex
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
def forgot_password
|
69
|
+
if authenticated_<%= singular_name %>?
|
70
|
+
flash['message'] = 'You are currently logged in. You may change your password now.'
|
71
|
+
redirect_to :action => 'change_password'
|
72
|
+
return
|
73
|
+
end
|
74
|
+
|
75
|
+
return if generate_blank_form
|
76
|
+
|
77
|
+
if @params['<%= singular_name %>']['email'].empty?
|
78
|
+
flash.now['message'] = 'Please enter a valid email address.'
|
79
|
+
elsif (<%= singular_name %> = <%= class_name %>.find_by_email(@params['<%= singular_name %>']['email'])).nil?
|
80
|
+
flash.now['message'] = "We could not find a <%= singular_name %> with the email address #{CGI.escapeHTML(@params['<%= singular_name %>']['email'])}"
|
81
|
+
else
|
82
|
+
begin
|
83
|
+
<%= class_name %>.transaction(<%= singular_name %>) do
|
84
|
+
key = <%= singular_name %>.generate_security_token
|
85
|
+
url = url_for(:action => 'change_password')
|
86
|
+
url += "?<%= singular_name %>[id]=#{<%= singular_name %>.id}&key=#{key}"
|
87
|
+
<%= class_name %>Notify.deliver_forgot_password(<%= singular_name %>, url)
|
88
|
+
flash['notice'] = "Instructions on resetting your password have been emailed to #{CGI.escapeHTML(@params['<%= singular_name %>']['email'])}."
|
89
|
+
unless authenticated_<%= singular_name %>?
|
90
|
+
redirect_to :action => 'login'
|
91
|
+
return
|
92
|
+
end
|
93
|
+
redirect_back_or_default :action => 'welcome'
|
94
|
+
end
|
95
|
+
rescue Exception => ex
|
96
|
+
report_exception ex
|
97
|
+
flash.now['message'] = "Your password could not be emailed to #{CGI.escapeHTML(@params['<%= singular_name %>']['email'])}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def edit
|
103
|
+
return if generate_filled_in
|
104
|
+
if @params['<%= singular_name %>']['form']
|
105
|
+
form = @params['<%= singular_name %>'].delete('form')
|
106
|
+
begin
|
107
|
+
case form
|
108
|
+
when "edit"
|
109
|
+
changeable_fields = ['first_name', 'last_name', 'email']
|
110
|
+
params = @params['<%= singular_name %>'].delete_if { |k,v| not changeable_fields.include?(k) }
|
111
|
+
@<%= singular_name %>.attributes = params
|
112
|
+
@<%= singular_name %>.save
|
113
|
+
flash.now['notice'] = "<%= class_name %> has been updated."
|
114
|
+
when "change_password"
|
115
|
+
change_password
|
116
|
+
when "delete"
|
117
|
+
delete
|
118
|
+
else
|
119
|
+
raise "unknown edit action"
|
120
|
+
end
|
121
|
+
rescue Exception => ex
|
122
|
+
logger.warn ex
|
123
|
+
logger.warn ex.backtrace
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def delete
|
129
|
+
@<%= singular_name %> = @current_<%= singular_name %> || <%= class_name %>.find_by_id( @session[:<%= singular_name %>_id] )
|
130
|
+
begin
|
131
|
+
@<%= singular_name %>.update_attribute( :deleted, true )
|
132
|
+
logout
|
133
|
+
rescue Exception => ex
|
134
|
+
flash.now['message'] = "Error: #{@ex}."
|
135
|
+
redirect_back_or_default :action => 'welcome'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def welcome
|
140
|
+
end
|
141
|
+
|
142
|
+
protected
|
143
|
+
|
144
|
+
def protect?(action)
|
145
|
+
if ['login', 'signup', 'forgot_password'].include?(action)
|
146
|
+
return false
|
147
|
+
else
|
148
|
+
return true
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Generate a template <%= singular_name %> for certain actions on get
|
153
|
+
def generate_blank_form
|
154
|
+
case @request.method
|
155
|
+
when :get
|
156
|
+
@<%= singular_name %> = <%= class_name %>.new
|
157
|
+
render
|
158
|
+
return true
|
159
|
+
end
|
160
|
+
return false
|
161
|
+
end
|
162
|
+
|
163
|
+
# Generate a template <%= singular_name %> for certain actions on get
|
164
|
+
def generate_filled_in
|
165
|
+
@<%= singular_name %> = @current_<%= singular_name %> || <%= class_name %>.find_by_id( @session[:<%= singular_name %>_id] )
|
166
|
+
case @request.method
|
167
|
+
when :get
|
168
|
+
render
|
169
|
+
return true
|
170
|
+
end
|
171
|
+
return false
|
172
|
+
end
|
173
|
+
|
174
|
+
def report_exception( ex )
|
175
|
+
logger.warn ex
|
176
|
+
logger.warn ex.backtrace.join("\n")
|
177
|
+
end
|
178
|
+
|
179
|
+
end
|