somatics3-generators 0.0.2
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/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/bin/somatics +21 -0
- data/bin/somatify +21 -0
- data/lib/generators/somatics/authenticated/authenticated_generator.rb +220 -0
- data/lib/generators/somatics/authenticated/templates/mailer.rb +25 -0
- data/lib/generators/somatics/authenticated/templates/migration.rb +26 -0
- data/lib/generators/somatics/authenticated/templates/model.rb +83 -0
- data/lib/generators/somatics/authenticated/templates/observer.rb +11 -0
- data/lib/generators/somatics/authenticated/templates/test/mailer_test.rb +31 -0
- data/lib/generators/somatics/authenticated/templates/test/model_functional_test.rb +93 -0
- data/lib/generators/somatics/authenticated/templates/test/sessions_functional_test.rb +82 -0
- data/lib/generators/somatics/authenticated/templates/test/unit_test.rb +164 -0
- data/lib/generators/somatics/authenticated/templates/test/users.yml +60 -0
- data/lib/generators/somatics/authenticated_controller/authenticated_controller_generator.rb +323 -0
- data/lib/generators/somatics/authenticated_controller/templates/_model_partial.html.erb +8 -0
- data/lib/generators/somatics/authenticated_controller/templates/activation.erb +3 -0
- data/lib/generators/somatics/authenticated_controller/templates/authenticated_system.rb +189 -0
- data/lib/generators/somatics/authenticated_controller/templates/authenticated_test_helper.rb +10 -0
- data/lib/generators/somatics/authenticated_controller/templates/config/initializers/site_keys.rb +38 -0
- data/lib/generators/somatics/authenticated_controller/templates/controller.rb +55 -0
- data/lib/generators/somatics/authenticated_controller/templates/helper.rb +91 -0
- data/lib/generators/somatics/authenticated_controller/templates/login.html.erb +29 -0
- data/lib/generators/somatics/authenticated_controller/templates/mailer.rb +25 -0
- data/lib/generators/somatics/authenticated_controller/templates/migration.rb +26 -0
- data/lib/generators/somatics/authenticated_controller/templates/model.rb +83 -0
- data/lib/generators/somatics/authenticated_controller/templates/observer.rb +11 -0
- data/lib/generators/somatics/authenticated_controller/templates/session_helper.rb +2 -0
- data/lib/generators/somatics/authenticated_controller/templates/sessions_controller.rb +43 -0
- data/lib/generators/somatics/authenticated_controller/templates/signup.html.erb +19 -0
- data/lib/generators/somatics/authenticated_controller/templates/signup_notification.erb +8 -0
- data/lib/generators/somatics/authenticated_controller/templates/test/mailer_test.rb +31 -0
- data/lib/generators/somatics/authenticated_controller/templates/test/model_functional_test.rb +93 -0
- data/lib/generators/somatics/authenticated_controller/templates/test/sessions_functional_test.rb +82 -0
- data/lib/generators/somatics/authenticated_controller/templates/test/unit_test.rb +164 -0
- data/lib/generators/somatics/authenticated_controller/templates/test/users.yml +60 -0
- data/lib/generators/somatics/helper/helper_generator.rb +16 -0
- data/lib/generators/somatics/install/install_generator.rb +65 -0
- data/lib/generators/somatics/install/templates/config/locales/somatics_en.yml +33 -0
- data/lib/generators/somatics/install/templates/config/locales/somatics_zh-TW.yml +33 -0
- data/lib/generators/somatics/install/templates/controller_admin.rb +16 -0
- data/lib/generators/somatics/install/templates/controller_home.rb +4 -0
- data/lib/generators/somatics/install/templates/helper_admin.rb +68 -0
- data/lib/generators/somatics/install/templates/layout_admin.html.erb +88 -0
- data/lib/generators/somatics/install/templates/lib/somatic_link_renderer.rb +42 -0
- data/lib/generators/somatics/install/templates/partial_menu.html.erb +1 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/add.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/arrow_collapsed.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/arrow_expanded.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/attachment.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/bullet_arrow_left.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/bullet_arrow_right.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/bullet_diamond.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/bullet_end.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/bullet_go.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/bullet_toggle_minus.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/bullet_toggle_plus.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/c.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/cancel.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/changeset.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/comment.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/comments.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/content-left.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/content-right.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/copy.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/csharp.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/database_key.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/default.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/delete.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/document.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/draft.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/duplicate.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/edit.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/exclamation.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/external.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/fav.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/fav_off.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/feed.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/folder.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/folder_open.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/footer-bg.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/footer-left.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/footer-right.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/group.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/help.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/history.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/image.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/lightning.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/link.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/loading.gif +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/locked.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/message.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/milestone.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/move.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/news.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/openid-bg.gif +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/package.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/pdf.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/php.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/plugin.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/projects.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/rails.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/reload.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/report.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/ruby.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/save.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/sort_asc.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/sort_desc.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/stats.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/table_multiple.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/task_done.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/task_late.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/task_parent_end.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/task_todo.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/text.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/text_list_bullets.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/textfield.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/ticket.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/ticket_checked.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/ticket_edit.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/ticket_go.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/ticket_note.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/time.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/time_add.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/toggle_check.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/true.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/unlock.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/user.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/warning.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/wiki_edit.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/xml.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/zip.png +0 -0
- data/lib/generators/somatics/install/templates/public/images/somatics/zoom_in.png +0 -0
- data/lib/generators/somatics/install/templates/public/javascripts/somatics/base.js +231 -0
- data/lib/generators/somatics/install/templates/public/javascripts/somatics/context_menu.js +237 -0
- data/lib/generators/somatics/install/templates/public/javascripts/somatics/controls.js +965 -0
- data/lib/generators/somatics/install/templates/public/javascripts/somatics/dragdrop.js +974 -0
- data/lib/generators/somatics/install/templates/public/javascripts/somatics/effects.js +1123 -0
- data/lib/generators/somatics/install/templates/public/javascripts/somatics/prototype.js +6001 -0
- data/lib/generators/somatics/install/templates/public/javascripts/somatics/rails.js +175 -0
- data/lib/generators/somatics/install/templates/public/javascripts/somatics/select_list_move.js +82 -0
- data/lib/generators/somatics/install/templates/public/stylesheets/somatics/base.css +948 -0
- data/lib/generators/somatics/install/templates/public/stylesheets/somatics/context_menu.css +52 -0
- data/lib/generators/somatics/install/templates/public/stylesheets/somatics/csshover.htc +122 -0
- data/lib/generators/somatics/install/templates/public/stylesheets/somatics/jstoolbar.css +95 -0
- data/lib/generators/somatics/install/templates/view_index.html.erb +1 -0
- data/lib/generators/somatics/scaffold/scaffold_generator.rb +25 -0
- data/lib/generators/somatics/scaffold/templates/_form.html.erb +23 -0
- data/lib/generators/somatics/scaffold/templates/edit.html.erb +6 -0
- data/lib/generators/somatics/scaffold/templates/index.html.erb +27 -0
- data/lib/generators/somatics/scaffold/templates/new.html.erb +5 -0
- data/lib/generators/somatics/scaffold/templates/show.html.erb +12 -0
- data/lib/generators/somatics/scaffold_controller/USAGE +20 -0
- data/lib/generators/somatics/scaffold_controller/scaffold_controller_generator.rb +137 -0
- data/lib/generators/somatics/scaffold_controller/templates/builder_index.pdf.prawn +25 -0
- data/lib/generators/somatics/scaffold_controller/templates/builder_index.xls.builder +24 -0
- data/lib/generators/somatics/scaffold_controller/templates/builder_index.xml.builder +10 -0
- data/lib/generators/somatics/scaffold_controller/templates/controller.rb +140 -0
- data/lib/generators/somatics/scaffold_controller/templates/locales_en.yml +17 -0
- data/lib/generators/somatics/scaffold_controller/templates/locales_zh-TW.yml +20 -0
- data/lib/generators/somatics/scaffold_controller/templates/partial_bulk.html.erb +12 -0
- data/lib/generators/somatics/scaffold_controller/templates/partial_edit.html.erb +7 -0
- data/lib/generators/somatics/scaffold_controller/templates/partial_form.html.erb +13 -0
- data/lib/generators/somatics/scaffold_controller/templates/partial_list.html.erb +42 -0
- data/lib/generators/somatics/scaffold_controller/templates/partial_menu.html.erb +1 -0
- data/lib/generators/somatics/scaffold_controller/templates/partial_show.html.erb +31 -0
- data/lib/generators/somatics/scaffold_controller/templates/view_edit.html.erb +24 -0
- data/lib/generators/somatics/scaffold_controller/templates/view_index.html.erb +28 -0
- data/lib/generators/somatics/scaffold_controller/templates/view_new.html.erb +14 -0
- data/lib/generators/somatics/scaffold_controller/templates/view_show.html.erb +24 -0
- data/lib/generators/somatics.rb +95 -0
- data/lib/somatics3-generators.rb +19 -0
- data/somatics3-generators.gemspec +223 -0
- data/templates/somatics.rb +128 -0
- data/test/helper.rb +10 -0
- data/test/test_somatics3-generators.rb +7 -0
- metadata +301 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
module <%= model_class_name %>AuthenticatedSystem
|
|
2
|
+
protected
|
|
3
|
+
# Returns true or false if the <%= file_name %> is logged in.
|
|
4
|
+
# Preloads @current_<%= file_name %> with the <%= file_name %> model if they're logged in.
|
|
5
|
+
def <%= file_name %>_logged_in?
|
|
6
|
+
!!current_<%= file_name %>
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Accesses the current <%= file_name %> from the session.
|
|
10
|
+
# Future calls avoid the database because nil is not equal to false.
|
|
11
|
+
def current_<%= file_name %>
|
|
12
|
+
@current_<%= file_name %> ||= (<%= file_name %>_login_from_session || <%= file_name %>_login_from_basic_auth || <%= file_name %>_login_from_cookie) unless @current_<%= file_name %> == false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Store the given <%= file_name %> id in the session.
|
|
16
|
+
def current_<%= file_name %>=(new_<%= file_name %>)
|
|
17
|
+
session[:<%= file_name %>_id] = new_<%= file_name %> ? new_<%= file_name %>.id : nil
|
|
18
|
+
@current_<%= file_name %> = new_<%= file_name %> || false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Check if the <%= file_name %> is authorized
|
|
22
|
+
#
|
|
23
|
+
# Override this method in your controllers if you want to restrict access
|
|
24
|
+
# to only a few actions or if you want to check if the <%= file_name %>
|
|
25
|
+
# has the correct rights.
|
|
26
|
+
#
|
|
27
|
+
# Example:
|
|
28
|
+
#
|
|
29
|
+
# # only allow nonbobs
|
|
30
|
+
# def authorized?
|
|
31
|
+
# current_<%= file_name %>.login != "bob"
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
def <%= file_name %>_authorized?(action = action_name, resource = nil)
|
|
35
|
+
<%= file_name %>_logged_in?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Filter method to enforce a login requirement.
|
|
39
|
+
#
|
|
40
|
+
# To require logins for all actions, use this in your controllers:
|
|
41
|
+
#
|
|
42
|
+
# before_filter :login_required
|
|
43
|
+
#
|
|
44
|
+
# To require logins for specific actions, use this in your controllers:
|
|
45
|
+
#
|
|
46
|
+
# before_filter :login_required, :only => [ :edit, :update ]
|
|
47
|
+
#
|
|
48
|
+
# To skip this in a subclassed controller:
|
|
49
|
+
#
|
|
50
|
+
# skip_before_filter :login_required
|
|
51
|
+
#
|
|
52
|
+
def <%= file_name %>_login_required
|
|
53
|
+
<%= file_name %>_authorized? || <%= file_name %>_access_denied
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Redirect as appropriate when an access request fails.
|
|
57
|
+
#
|
|
58
|
+
# The default action is to redirect to the login screen.
|
|
59
|
+
#
|
|
60
|
+
# Override this method in your controllers if you want to have special
|
|
61
|
+
# behavior in case the <%= file_name %> is not authorized
|
|
62
|
+
# to access the requested action. For example, a popup window might
|
|
63
|
+
# simply close itself.
|
|
64
|
+
def <%= file_name %>_access_denied
|
|
65
|
+
respond_to do |format|
|
|
66
|
+
format.html do
|
|
67
|
+
store_location
|
|
68
|
+
redirect_to <%= controller_routing_name %>_login_path
|
|
69
|
+
end
|
|
70
|
+
# format.any doesn't work in rails version < http://dev.rubyonrails.org/changeset/8987
|
|
71
|
+
# Add any other API formats here. (Some browsers, notably IE6, send Accept: */* and trigger
|
|
72
|
+
# the 'format.any' block incorrectly. See http://bit.ly/ie6_borken or http://bit.ly/ie6_borken2
|
|
73
|
+
# for a workaround.)
|
|
74
|
+
format.any(:json, :xml) do
|
|
75
|
+
request_http_basic_authentication 'Web Password'
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Store the URI of the current request in the session.
|
|
81
|
+
#
|
|
82
|
+
# We can return to this location by calling #redirect_back_or_default.
|
|
83
|
+
def store_location
|
|
84
|
+
session[:return_to] = request.request_uri
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Redirect to the URI stored by the most recent store_location call or
|
|
88
|
+
# to the passed default. Set an appropriately modified
|
|
89
|
+
# after_filter :store_location, :only => [:index, :new, :show, :edit]
|
|
90
|
+
# for any controller you want to be bounce-backable.
|
|
91
|
+
def redirect_back_or_default(default)
|
|
92
|
+
redirect_to(session[:return_to] || default)
|
|
93
|
+
session[:return_to] = nil
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Inclusion hook to make #current_<%= file_name %> and #logged_in?
|
|
97
|
+
# available as ActionView helper methods.
|
|
98
|
+
def self.included(base)
|
|
99
|
+
base.send :helper_method, :current_<%= file_name %>, :<%= file_name %>_logged_in?, :<%= file_name %>_authorized? if base.respond_to? :helper_method
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
#
|
|
103
|
+
# Login
|
|
104
|
+
#
|
|
105
|
+
|
|
106
|
+
# Called from #current_<%= file_name %>. First attempt to login by the <%= file_name %> id stored in the session.
|
|
107
|
+
def <%= file_name %>_login_from_session
|
|
108
|
+
self.current_<%= file_name %> = <%= model_class_name %>.find_by_id(session[:<%= file_name %>_id]) if session[:<%= file_name %>_id]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Called from #current_<%= file_name %>. Now, attempt to login by basic authentication information.
|
|
112
|
+
def <%= file_name %>_login_from_basic_auth
|
|
113
|
+
authenticate_with_http_basic do |login, password|
|
|
114
|
+
self.current_<%= file_name %> = <%= model_class_name %>.authenticate(login, password)
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
#
|
|
119
|
+
# Logout
|
|
120
|
+
#
|
|
121
|
+
|
|
122
|
+
# Called from #current_<%= file_name %>. Finaly, attempt to login by an expiring token in the cookie.
|
|
123
|
+
# for the paranoid: we _should_ be storing <%= file_name %>_token = hash(cookie_token, request IP)
|
|
124
|
+
def <%= file_name %>_login_from_cookie
|
|
125
|
+
<%= file_name %> = cookies[:auth_token] && <%= model_class_name %>.find_by_remember_token(cookies[:auth_token])
|
|
126
|
+
if <%= file_name %> && <%= file_name %>.remember_token?
|
|
127
|
+
self.current_<%= file_name %> = <%= file_name %>
|
|
128
|
+
<%= file_name %>_handle_remember_cookie! false # freshen cookie token (keeping date)
|
|
129
|
+
self.current_<%= file_name %>
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# This is ususally what you want; resetting the session willy-nilly wreaks
|
|
134
|
+
# havoc with forgery protection, and is only strictly necessary on login.
|
|
135
|
+
# However, **all session state variables should be unset here**.
|
|
136
|
+
def <%= file_name %>_logout_keeping_session!
|
|
137
|
+
# Kill server-side auth cookie
|
|
138
|
+
@current_<%= file_name %>.forget_me if @current_<%= file_name %>.is_a? <%= model_class_name %>
|
|
139
|
+
@current_<%= file_name %> = false # not logged in, and don't do it for me
|
|
140
|
+
<%= file_name %>_kill_remember_cookie! # Kill client-side auth cookie
|
|
141
|
+
session[:<%= file_name %>_id] = nil # keeps the session but kill our variable
|
|
142
|
+
# explicitly kill any other session variables you set
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# The session should only be reset at the tail end of a form POST --
|
|
146
|
+
# otherwise the request forgery protection fails. It's only really necessary
|
|
147
|
+
# when you cross quarantine (logged-out to logged-in).
|
|
148
|
+
def <%= file_name %>_logout_killing_session!
|
|
149
|
+
<%= file_name %>_logout_keeping_session!
|
|
150
|
+
reset_session
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
#
|
|
154
|
+
# Remember_me Tokens
|
|
155
|
+
#
|
|
156
|
+
# Cookies shouldn't be allowed to persist past their freshness date,
|
|
157
|
+
# and they should be changed at each login
|
|
158
|
+
|
|
159
|
+
# Cookies shouldn't be allowed to persist past their freshness date,
|
|
160
|
+
# and they should be changed at each login
|
|
161
|
+
|
|
162
|
+
def <%= file_name %>_valid_remember_cookie?
|
|
163
|
+
return nil unless @current_<%= file_name %>
|
|
164
|
+
(@current_<%= file_name %>.remember_token?) &&
|
|
165
|
+
(cookies[:auth_token] == @current_<%= file_name %>.remember_token)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Refresh the cookie auth token if it exists, create it otherwise
|
|
169
|
+
def <%= file_name %>_handle_remember_cookie!(new_cookie_flag)
|
|
170
|
+
return unless @current_<%= file_name %>
|
|
171
|
+
case
|
|
172
|
+
when <%= file_name %>_valid_remember_cookie? then @current_<%= file_name %>.refresh_token # keeping same expiry date
|
|
173
|
+
when new_cookie_flag then @current_<%= file_name %>.remember_me
|
|
174
|
+
else @current_<%= file_name %>.forget_me
|
|
175
|
+
end
|
|
176
|
+
<%= file_name %>_send_remember_cookie!
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def <%= file_name %>_kill_remember_cookie!
|
|
180
|
+
cookies.delete :auth_token
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def <%= file_name %>_send_remember_cookie!
|
|
184
|
+
cookies[:auth_token] = {
|
|
185
|
+
:value => @current_<%= file_name %>.remember_token,
|
|
186
|
+
:expires => @current_<%= file_name %>.remember_token_expires_at }
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module <%= model_class_name %>AuthenticatedTestHelper
|
|
2
|
+
# Sets the current <%= file_name %> in the session from the <%= file_name %> fixtures.
|
|
3
|
+
def login_as(<%= file_name %>)
|
|
4
|
+
@request.session[:<%= file_name %>_id] = <%= file_name %> ? (<%= file_name %>.is_a?(<%= file_name.camelize %>) ? <%= file_name %>.id : <%= table_name %>(<%= file_name %>).id) : nil
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def authorize_as(<%= file_name %>)
|
|
8
|
+
@request.env["HTTP_AUTHORIZATION"] = <%= file_name %> ? ActionController::HttpAuthentication::Basic.encode_credentials(<%= table_name %>(<%= file_name %>).login, 'monkey') : nil
|
|
9
|
+
end
|
|
10
|
+
end
|
data/lib/generators/somatics/authenticated_controller/templates/config/initializers/site_keys.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
# A Site key gives additional protection against a dictionary attack if your
|
|
3
|
+
# DB is ever compromised. With no site key, we store
|
|
4
|
+
# DB_password = hash(user_password, DB_user_salt)
|
|
5
|
+
# If your database were to be compromised you'd be vulnerable to a dictionary
|
|
6
|
+
# attack on all your stupid users' passwords. With a site key, we store
|
|
7
|
+
# DB_password = hash(user_password, DB_user_salt, Code_site_key)
|
|
8
|
+
# That means an attacker needs access to both your site's code *and* its
|
|
9
|
+
# database to mount an "offline dictionary attack.":http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/web-authentication.html
|
|
10
|
+
#
|
|
11
|
+
# It's probably of minor importance, but recommended by best practices: 'defense
|
|
12
|
+
# in depth'. Needless to say, if you upload this to github or the youtubes or
|
|
13
|
+
# otherwise place it in public view you'll kinda defeat the point. Your users'
|
|
14
|
+
# passwords are still secure, and the world won't end, but defense_in_depth -= 1.
|
|
15
|
+
#
|
|
16
|
+
# Please note: if you change this, all the passwords will be invalidated, so DO
|
|
17
|
+
# keep it someplace secure. Use the random value given or type in the lyrics to
|
|
18
|
+
# your favorite Jay-Z song or something; any moderately long, unpredictable text.
|
|
19
|
+
REST_AUTH_SITE_KEY = '<%= $rest_auth_site_key_from_generator %>'
|
|
20
|
+
|
|
21
|
+
# Repeated applications of the hash make brute force (even with a compromised
|
|
22
|
+
# database and site key) harder, and scale with Moore's law.
|
|
23
|
+
#
|
|
24
|
+
# bq. "To squeeze the most security out of a limited-entropy password or
|
|
25
|
+
# passphrase, we can use two techniques [salting and stretching]... that are
|
|
26
|
+
# so simple and obvious that they should be used in every password system.
|
|
27
|
+
# There is really no excuse not to use them." http://tinyurl.com/37lb73
|
|
28
|
+
# Practical Security (Ferguson & Scheier) p350
|
|
29
|
+
#
|
|
30
|
+
# A modest 10 foldings (the default here) adds 3ms. This makes brute forcing 10
|
|
31
|
+
# times harder, while reducing an app that otherwise serves 100 reqs/s to 78 signin
|
|
32
|
+
# reqs/s, an app that does 10reqs/s to 9.7 reqs/s
|
|
33
|
+
#
|
|
34
|
+
# More:
|
|
35
|
+
# * http://www.owasp.org/index.php/Hashing_Java
|
|
36
|
+
# * "An Illustrated Guide to Cryptographic Hashes":http://www.unixwiz.net/techtips/iguide-crypto-hashes.html
|
|
37
|
+
|
|
38
|
+
REST_AUTH_DIGEST_STRETCHES = <%= $rest_auth_digest_stretches_from_generator %>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
class <%= controller_plural_name.camelize %>Controller < ApplicationController
|
|
2
|
+
# Be sure to include AuthenticationSystem in Application Controller instead
|
|
3
|
+
include <%= model_class_name %>AuthenticatedSystem
|
|
4
|
+
|
|
5
|
+
skip_before_filter :<%= file_name %>_login_required
|
|
6
|
+
|
|
7
|
+
def new
|
|
8
|
+
@<%= file_name %> = <%= model_class_name %>.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def create
|
|
12
|
+
<%= file_name %>_logout_keeping_session!
|
|
13
|
+
@<%= file_name %> = <%= model_class_name %>.new(params[:<%= file_name %>])
|
|
14
|
+
<% if options[:stateful] -%>
|
|
15
|
+
@<%= file_name %>.register! if @<%= file_name %> && @<%= file_name %>.valid?
|
|
16
|
+
success = @<%= file_name %> && @<%= file_name %>.valid?
|
|
17
|
+
<% else -%>
|
|
18
|
+
success = @<%= file_name %> && @<%= file_name %>.save
|
|
19
|
+
<% end -%>
|
|
20
|
+
if success && @<%= file_name %>.errors.empty?
|
|
21
|
+
<% if !options[:include_activation] -%>
|
|
22
|
+
# Protects against session fixation attacks, causes request forgery
|
|
23
|
+
# protection if visitor resubmits an earlier form using back
|
|
24
|
+
# button. Uncomment if you understand the tradeoffs.
|
|
25
|
+
# reset session
|
|
26
|
+
self.current_<%= file_name %> = @<%= file_name %> # !! now logged in
|
|
27
|
+
<% end -%>
|
|
28
|
+
redirect_back_or_default('/')
|
|
29
|
+
flash[:notice] = "Thanks for signing up! We're sending you an email with your activation code."
|
|
30
|
+
else
|
|
31
|
+
flash[:error] = "We couldn't set up that account, sorry. Please try again, or contact an admin (link is above)."
|
|
32
|
+
render :action => 'new'
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
<% if options[:include_activation] -%>
|
|
37
|
+
def activate
|
|
38
|
+
<%= file_name %>_logout_keeping_session!
|
|
39
|
+
<%= file_name %> = <%= model_class_name %>.find_by_activation_code(params[:activation_code]) unless params[:activation_code].blank?
|
|
40
|
+
case
|
|
41
|
+
when (!params[:activation_code].blank?) && <%= file_name %> && !<%= file_name %>.active?
|
|
42
|
+
<%= file_name %>.activate!
|
|
43
|
+
flash[:notice] = "Signup complete! Please sign in to continue."
|
|
44
|
+
redirect_to "/#{controller_plural_name}/login"
|
|
45
|
+
when params[:activation_code].blank?
|
|
46
|
+
flash[:error] = "The activation code was missing. Please follow the URL from your email."
|
|
47
|
+
redirect_back_or_default('/')
|
|
48
|
+
else
|
|
49
|
+
flash[:error] = "We couldn't find a <%= file_name %> with that activation code -- check your email? Or maybe you've already activated -- try signing in."
|
|
50
|
+
redirect_back_or_default('/')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
<% end -%>
|
|
55
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module <%= controller_class_name %>Helper
|
|
2
|
+
#
|
|
3
|
+
# Use this to wrap view elements that the user can't access.
|
|
4
|
+
# !! Note: this is an *interface*, not *security* feature !!
|
|
5
|
+
# You need to do all access control at the controller level.
|
|
6
|
+
#
|
|
7
|
+
# Example:
|
|
8
|
+
# <%%= if_authorized?(:index, User) do link_to('List all users', users_path) end %> |
|
|
9
|
+
# <%%= if_authorized?(:edit, @user) do link_to('Edit this user', edit_user_path) end %> |
|
|
10
|
+
# <%%= if_authorized?(:destroy, @user) do link_to 'Destroy', @user, :confirm => 'Are you sure?', :method => :delete end %>
|
|
11
|
+
#
|
|
12
|
+
#
|
|
13
|
+
def if_authorized?(action, resource, &block)
|
|
14
|
+
if authorized?(action, resource)
|
|
15
|
+
yield action, resource
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Link to user's page ('<%= table_name %>/1')
|
|
21
|
+
#
|
|
22
|
+
# By default, their login is used as link text and link title (tooltip)
|
|
23
|
+
#
|
|
24
|
+
# Takes options
|
|
25
|
+
# * :content_text => 'Content text in place of <%= file_name %>.login', escaped with
|
|
26
|
+
# the standard h() function.
|
|
27
|
+
# * :content_method => :<%= file_name %>_instance_method_to_call_for_content_text
|
|
28
|
+
# * :title_method => :<%= file_name %>_instance_method_to_call_for_title_attribute
|
|
29
|
+
# * as well as link_to()'s standard options
|
|
30
|
+
#
|
|
31
|
+
# Examples:
|
|
32
|
+
# link_to_<%= file_name %> @<%= file_name %>
|
|
33
|
+
# # => <a href="/<%= table_name %>/3" title="barmy">barmy</a>
|
|
34
|
+
#
|
|
35
|
+
# # if you've added a .name attribute:
|
|
36
|
+
# content_tag :span, :class => :vcard do
|
|
37
|
+
# (link_to_<%= file_name %> <%= file_name %>, :class => 'fn n', :title_method => :login, :content_method => :name) +
|
|
38
|
+
# ': ' + (content_tag :span, <%= file_name %>.email, :class => 'email')
|
|
39
|
+
# end
|
|
40
|
+
# # => <span class="vcard"><a href="/<%= table_name %>/3" title="barmy" class="fn n">Cyril Fotheringay-Phipps</a>: <span class="email">barmy@blandings.com</span></span>
|
|
41
|
+
#
|
|
42
|
+
# link_to_<%= file_name %> @<%= file_name %>, :content_text => 'Your user page'
|
|
43
|
+
# # => <a href="/<%= table_name %>/3" title="barmy" class="nickname">Your user page</a>
|
|
44
|
+
#
|
|
45
|
+
def link_to_<%= file_name %>(<%= file_name %>, options={})
|
|
46
|
+
raise "Invalid <%= file_name %>" unless <%= file_name %>
|
|
47
|
+
options.reverse_merge! :content_method => :login, :title_method => :login, :class => :nickname
|
|
48
|
+
content_text = options.delete(:content_text)
|
|
49
|
+
content_text ||= <%= file_name %>.send(options.delete(:content_method))
|
|
50
|
+
options[:title] ||= <%= file_name %>.send(options.delete(:title_method))
|
|
51
|
+
link_to h(content_text), <%= controller_routing_name.singularize %>_path(<%= file_name %>), options
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# Link to login page using remote ip address as link content
|
|
56
|
+
#
|
|
57
|
+
# The :title (and thus, tooltip) is set to the IP address
|
|
58
|
+
#
|
|
59
|
+
# Examples:
|
|
60
|
+
# link_to_login_with_IP
|
|
61
|
+
# # => <a href="/login" title="169.69.69.69">169.69.69.69</a>
|
|
62
|
+
#
|
|
63
|
+
# link_to_login_with_IP :content_text => 'not signed in'
|
|
64
|
+
# # => <a href="/login" title="169.69.69.69">not signed in</a>
|
|
65
|
+
#
|
|
66
|
+
def link_to_login_with_IP content_text=nil, options={}
|
|
67
|
+
ip_addr = request.remote_ip
|
|
68
|
+
content_text ||= ip_addr
|
|
69
|
+
options.reverse_merge! :title => ip_addr
|
|
70
|
+
if tag = options.delete(:tag)
|
|
71
|
+
content_tag tag, h(content_text), options
|
|
72
|
+
else
|
|
73
|
+
link_to h(content_text), login_path, options
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#
|
|
78
|
+
# Link to the current user's page (using link_to_<%= file_name %>) or to the login page
|
|
79
|
+
# (using link_to_login_with_IP).
|
|
80
|
+
#
|
|
81
|
+
def link_to_current_<%= file_name %>(options={})
|
|
82
|
+
if current_<%= file_name %>
|
|
83
|
+
link_to_<%= file_name %> current_<%= file_name %>, options
|
|
84
|
+
else
|
|
85
|
+
content_text = options.delete(:content_text) || 'not signed in'
|
|
86
|
+
# kill ignored options from link_to_<%= file_name %>
|
|
87
|
+
[:content_method, :title_method].each{|opt| options.delete(opt)}
|
|
88
|
+
link_to_login_with_IP content_text, options
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<%% form_tag <%= sessions_controller_routing_name %>_path, :id => 'login-form' do %>
|
|
2
|
+
<p><%%= flash[:error] %></p>
|
|
3
|
+
<table>
|
|
4
|
+
<tbody>
|
|
5
|
+
<tr>
|
|
6
|
+
<td align="right"><b><%%= <%= model_class_name %>.human_attribute_name(:login) %></b></td>
|
|
7
|
+
<td align="left"><%%= text_field_tag 'login', @login %></td>
|
|
8
|
+
</tr>
|
|
9
|
+
<tr>
|
|
10
|
+
<td align="right"><b><%%= <%= model_class_name %>.human_attribute_name(:password) %></b></td>
|
|
11
|
+
<td align="left"><%%= password_field_tag 'password', nil %></td>
|
|
12
|
+
</tr>
|
|
13
|
+
<!-- Uncomment this if you want this functionality
|
|
14
|
+
<tr>
|
|
15
|
+
<td align="right"><%%#= label_tag 'remember_me', 'Remember me' %></td>
|
|
16
|
+
<td align="left"><%%#= check_box_tag 'remember_me', '1', @remember_me %></td>
|
|
17
|
+
</tr>
|
|
18
|
+
-->
|
|
19
|
+
<tr>
|
|
20
|
+
<td align="right"></td>
|
|
21
|
+
<td align="left"></td>
|
|
22
|
+
</tr>
|
|
23
|
+
<tr>
|
|
24
|
+
<td align="left"></td>
|
|
25
|
+
<td align="right"><%%= submit_tag t('Log_in') %></td>
|
|
26
|
+
</tr>
|
|
27
|
+
</tbody>
|
|
28
|
+
</table>
|
|
29
|
+
<%% end %>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class <%= class_name %>Mailer < ActionMailer::Base
|
|
2
|
+
def signup_notification(<%= file_name %>)
|
|
3
|
+
setup_email(<%= file_name %>)
|
|
4
|
+
@subject += 'Please activate your new account'
|
|
5
|
+
<% if options[:include_activation] %>
|
|
6
|
+
@body[:url] = "http://YOURSITE/activate/#{<%= file_name %>.activation_code}"
|
|
7
|
+
<% else %>
|
|
8
|
+
@body[:url] = "http://YOURSITE/login/" <% end %>
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def activation(<%= file_name %>)
|
|
12
|
+
setup_email(<%= file_name %>)
|
|
13
|
+
@subject += 'Your account has been activated!'
|
|
14
|
+
@body[:url] = "http://YOURSITE/"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
protected
|
|
18
|
+
def setup_email(<%= file_name %>)
|
|
19
|
+
@recipients = "#{<%= file_name %>.email}"
|
|
20
|
+
@from = "ADMINEMAIL"
|
|
21
|
+
@subject = "[YOURSITE] "
|
|
22
|
+
@sent_on = Time.now
|
|
23
|
+
@body[:<%= file_name %>] = <%= file_name %>
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class <%= migration_name %> < ActiveRecord::Migration
|
|
2
|
+
def self.up
|
|
3
|
+
create_table "<%= table_name %>", :force => true do |t|
|
|
4
|
+
t.column :login, :string, :limit => 40
|
|
5
|
+
t.column :name, :string, :limit => 100, :default => '', :null => true
|
|
6
|
+
t.column :email, :string, :limit => 100
|
|
7
|
+
t.column :crypted_password, :string, :limit => 40
|
|
8
|
+
t.column :salt, :string, :limit => 40
|
|
9
|
+
t.column :created_at, :datetime
|
|
10
|
+
t.column :updated_at, :datetime
|
|
11
|
+
t.column :remember_token, :string, :limit => 40
|
|
12
|
+
t.column :remember_token_expires_at, :datetime
|
|
13
|
+
<% if options[:include_activation] -%>
|
|
14
|
+
t.column :activation_code, :string, :limit => 40
|
|
15
|
+
t.column :activated_at, :datetime<% end %>
|
|
16
|
+
<% for attribute in attributes -%>
|
|
17
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
|
18
|
+
<% end -%>
|
|
19
|
+
end
|
|
20
|
+
add_index :<%= table_name %>, :login, :unique => true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.down
|
|
24
|
+
drop_table "<%= table_name %>"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
|
|
3
|
+
class <%= class_name %> < ActiveRecord::Base
|
|
4
|
+
include Authentication
|
|
5
|
+
include Authentication::ByPassword
|
|
6
|
+
include Authentication::ByCookieToken
|
|
7
|
+
<% if options[:aasm] -%>
|
|
8
|
+
include Authorization::AasmRoles
|
|
9
|
+
<% elsif options[:stateful] -%>
|
|
10
|
+
include Authorization::StatefulRoles<% end %>
|
|
11
|
+
validates_presence_of :login
|
|
12
|
+
validates_length_of :login, :within => 3..40
|
|
13
|
+
validates_uniqueness_of :login
|
|
14
|
+
validates_format_of :login, :with => Authentication.login_regex, :message => Authentication.bad_login_message
|
|
15
|
+
|
|
16
|
+
validates_format_of :name, :with => Authentication.name_regex, :message => Authentication.bad_name_message, :allow_nil => true
|
|
17
|
+
validates_length_of :name, :maximum => 100
|
|
18
|
+
|
|
19
|
+
validates_presence_of :email
|
|
20
|
+
validates_length_of :email, :within => 6..100 #r@a.wk
|
|
21
|
+
validates_uniqueness_of :email
|
|
22
|
+
validates_format_of :email, :with => Authentication.email_regex, :message => Authentication.bad_email_message
|
|
23
|
+
|
|
24
|
+
<% if options[:include_activation] && !options[:stateful] %>before_create :make_activation_code <% end %>
|
|
25
|
+
|
|
26
|
+
# HACK HACK HACK -- how to do attr_accessible from here?
|
|
27
|
+
# prevents a user from submitting a crafted form that bypasses activation
|
|
28
|
+
# anything else you want your user to change should be added here.
|
|
29
|
+
attr_accessible :login, :email, :name, :password, :password_confirmation
|
|
30
|
+
|
|
31
|
+
<% if options[:include_activation] && !options[:stateful] %>
|
|
32
|
+
# Activates the user in the database.
|
|
33
|
+
def activate!
|
|
34
|
+
@activated = true
|
|
35
|
+
self.activated_at = Time.now.utc
|
|
36
|
+
self.activation_code = nil
|
|
37
|
+
save(false)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns true if the user has just been activated.
|
|
41
|
+
def recently_activated?
|
|
42
|
+
@activated
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def active?
|
|
46
|
+
# the existence of an activation code means they have not activated yet
|
|
47
|
+
activation_code.nil?
|
|
48
|
+
end<% end %>
|
|
49
|
+
|
|
50
|
+
# Authenticates a user by their login name and unencrypted password. Returns the user or nil.
|
|
51
|
+
#
|
|
52
|
+
# uff. this is really an authorization, not authentication routine.
|
|
53
|
+
# We really need a Dispatch Chain here or something.
|
|
54
|
+
# This will also let us return a human error message.
|
|
55
|
+
#
|
|
56
|
+
def self.authenticate(login, password)
|
|
57
|
+
return nil if login.blank? || password.blank?
|
|
58
|
+
u = <% if options[:stateful] %>find_in_state :first, :active, :conditions => {:login => login.downcase}<%
|
|
59
|
+
elsif options[:include_activation] %>find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login]<%
|
|
60
|
+
else %>find_by_login(login.downcase)<% end %> # need to get the salt
|
|
61
|
+
u && u.authenticated?(password) ? u : nil
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def login=(value)
|
|
65
|
+
write_attribute :login, (value ? value.downcase : nil)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def email=(value)
|
|
69
|
+
write_attribute :email, (value ? value.downcase : nil)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
protected
|
|
73
|
+
|
|
74
|
+
<% if options[:include_activation] -%>
|
|
75
|
+
def make_activation_code
|
|
76
|
+
<% if options[:stateful] -%>
|
|
77
|
+
self.deleted_at = nil
|
|
78
|
+
<% end -%>
|
|
79
|
+
self.activation_code = self.class.make_token
|
|
80
|
+
end
|
|
81
|
+
<% end %>
|
|
82
|
+
|
|
83
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class <%= class_name %>Observer < ActiveRecord::Observer
|
|
2
|
+
def after_create(<%= file_name %>)
|
|
3
|
+
<%= class_name %>Mailer.deliver_signup_notification(<%= file_name %>)
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def after_save(<%= file_name %>)
|
|
7
|
+
<% if options[:include_activation] %>
|
|
8
|
+
<%= class_name %>Mailer.deliver_activation(<%= file_name %>) if <%= file_name %>.recently_activated?
|
|
9
|
+
<% end %>
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# This controller handles the login/logout function of the site.
|
|
2
|
+
class <%= sessions_controller_class_name %>Controller < <%= options[:admin_authenticated] ? "Admin::AdminController" : "ApplicationController" %>
|
|
3
|
+
# Be sure to include AuthenticationSystem in Application Controller instead
|
|
4
|
+
include <%= model_class_name %>AuthenticatedSystem
|
|
5
|
+
skip_before_filter :<%= file_name %>_login_required
|
|
6
|
+
# render new.rhtml
|
|
7
|
+
def new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create
|
|
11
|
+
<%= file_name %>_logout_keeping_session!
|
|
12
|
+
<%= file_name %> = <%= model_class_name %>.authenticate(params[:login], params[:password])
|
|
13
|
+
if <%= file_name %>
|
|
14
|
+
# Protects against session fixation attacks, causes request forgery
|
|
15
|
+
# protection if user resubmits an earlier form using back
|
|
16
|
+
# button. Uncomment if you understand the tradeoffs.
|
|
17
|
+
# reset_session
|
|
18
|
+
self.current_<%= file_name %> = <%= file_name %>
|
|
19
|
+
new_cookie_flag = (params[:remember_me] == "1")
|
|
20
|
+
<%= file_name %>_handle_remember_cookie! new_cookie_flag
|
|
21
|
+
redirect_back_or_default('/')
|
|
22
|
+
flash[:notice] = "Logged in successfully"
|
|
23
|
+
else
|
|
24
|
+
note_failed_signin
|
|
25
|
+
@login = params[:login]
|
|
26
|
+
@remember_me = params[:remember_me]
|
|
27
|
+
redirect_to :action => 'new'
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def destroy
|
|
32
|
+
<%= file_name %>_logout_killing_session!
|
|
33
|
+
flash[:notice] = "You have been logged out."
|
|
34
|
+
redirect_back_or_default('/')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
# Track failed login attempts
|
|
39
|
+
def note_failed_signin
|
|
40
|
+
flash[:error] = "Couldn't log you in as '#{params[:login]}'"
|
|
41
|
+
logger.warn "Failed login for '#{params[:login]}' from #{request.remote_ip} at #{Time.now.utc}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<h1>Sign up as a new user</h1>
|
|
2
|
+
<%% @<%= file_name %>.password = @<%= file_name %>.password_confirmation = nil %>
|
|
3
|
+
|
|
4
|
+
<%% form_for :<%= file_name %>, :url => <%= file_name %>_register_path do |f| -%>
|
|
5
|
+
<%%= f.error_messages %>
|
|
6
|
+
<p><%%= label_tag 'login' %><br/>
|
|
7
|
+
<%%= f.text_field :login %></p>
|
|
8
|
+
|
|
9
|
+
<p><%%= label_tag 'email' %><br/>
|
|
10
|
+
<%%= f.text_field :email %></p>
|
|
11
|
+
|
|
12
|
+
<p><%%= label_tag 'password' %><br/>
|
|
13
|
+
<%%= f.password_field :password %></p>
|
|
14
|
+
|
|
15
|
+
<p><%%= label_tag 'password_confirmation', 'Confirm Password' %><br/>
|
|
16
|
+
<%%= f.password_field :password_confirmation %></p>
|
|
17
|
+
|
|
18
|
+
<p><%%= submit_tag 'Sign up' %></p>
|
|
19
|
+
<%% end -%>
|