Skip to content
Newer
Older
100644 405 lines (329 sloc) 11 KB
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 2, 2009
1 # This is separate from base because it's long and distracts
2 # from understanding the bigger picture. This is based on a mix
3 # of experience, the the authlogic rdoc (http://authlogic.rubyforge.org/)
4 # and a tutorial written by Ben Johnson, authlogic's author
5 # (http://www.binarylogic.com/2008/11/3/tutorial-authlogic-basic-setup)
6 #
7 # I understand that a lot of things in here are brittle and also that
8 # there are many other authentication ideas to consider. I just wanted
9 # to have a running start on this part of a new project, so here it is.
10
11
12 # Install/update the gem, if necessary
aef3052 @davidrichards Breaking authentication into its own template.
authored Apr 2, 2009
13 gem 'authlogic'
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
14
15 # Depend on the gem inside the environment.rb. Note, this is kind of
16 # brittle, and I should find a better way to do this.
aef3052 @davidrichards Breaking authentication into its own template.
authored Apr 3, 2009
17 file 'config/environment.rb',
18 %q{# Be sure to restart your server when you modify this file
19
20 # Specifies gem version of Rails to use when vendor/rails is not present
21 RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION
22
23 # Bootstrap the Rails environment, frameworks, and default configuration
24 require File.join(File.dirname(__FILE__), 'boot')
25
26 Rails::Initializer.run do |config|
27 # Settings in config/environments/* take precedence over those specified here.
28 # Application configuration should go into files in config/initializers
29 # -- all .rb files in that directory are automatically loaded.
30
31 # Add additional load paths for your own custom dirs
32 # config.load_paths += %W( #{RAILS_ROOT}/extras )
33
34 # Specify gems that this application depends on and have them installed with rake gems:install
35 # config.gem "bj"
36 # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
37 # config.gem "sqlite3-ruby", :lib => "sqlite3"
38 # config.gem "aws-s3", :lib => "aws/s3"
39
40 # Only load the plugins named here, in the order given (default is alphabetical).
41 # :all can be used as a placeholder for all plugins not explicitly named
42 # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
43
44 # Skip frameworks you're not going to use. To use Rails without a database,
45 # you must remove the Active Record framework.
46 # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
47
48 # Activate observers that should always be running
49 # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
50
51 # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
52 # Run "rake -D time" for a list of tasks for finding time zone names.
53 config.time_zone = 'UTC'
54
55 # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
56 # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')]
57 # config.i18n.default_locale = :de
58 config.gem "authlogic"
59 end
60 }
61
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
62 # Generate the user session
3d216e8 @davidrichards Got more of the auth logic stuff working.
authored Apr 7, 2009
63 generate "session user_session"
aef3052 @davidrichards Breaking authentication into its own template.
authored Apr 3, 2009
64
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
65 # Generate the user
aef3052 @davidrichards Breaking authentication into its own template.
authored Apr 3, 2009
66 file "db/migrate/#{Time.now.strftime('%Y%m%d%H%M%S_create_users.rb')}",
67 %q{class CreateUsers < ActiveRecord::Migration
68 def self.up
69 create_table :users do |t|
70 t.string :email, :null => false
71 t.string :crypted_password, :null => false
72 t.string :password_salt, :null => false
73 t.string :persistence_token, :null => false
74 t.string :single_access_token, :null => false
75 t.string :perishable_token, :null => false
76 t.integer :login_count, :null => false, :default => 0
77 t.integer :failed_login_count, :null => false, :default => 0
78 t.datetime :last_request_at
79 t.datetime :current_login_at
80 t.datetime :last_login_at
81 t.string :current_login_ip
82 t.string :last_login_ip
83 t.timestamps
84 end
85 end
86
87 def self.down
88 drop_table :users
89 end
90 end
91 }
92
93 run "mkdir -p app/models"
94
95 file "app/models/user.rb",
96 %q{class User < ActiveRecord::Base
97 acts_as_authentic do |c|
98 # c.my_config_option = my_value
99 end
100 end
101 }
102
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
103 # Create a spec stub for the user.
aef3052 @davidrichards Breaking authentication into its own template.
authored Apr 3, 2009
104 run "mkdir -p spec/models"
105
106 file "spec/models/user_spec.rb",
107 %q{require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
108
109 describe User do
110 before(:each) do
111 @valid_attributes = {
112 :email => "user@example.com",
113 :password => "password",
d36dc2c @davidrichards A few basic changes for workflow and authentication.
authored Jun 2, 2009
114 :password_confirmation => "password",
aef3052 @davidrichards Breaking authentication into its own template.
authored Apr 3, 2009
115 :persistence_token => "value for persistence_token",
116 :single_access_token => "value for single_access_token",
117 :perishable_token => "value for perishable_token"
118 }
119 end
120
121 it "should create a new instance given valid attributes" do
122 user_model
123 end
124 end
125
126 def user_model(opts={})
127 @user = User.create!(@valid_attributes.merge(opts))
128 end
129 }
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
130
131 # Create a user session controller
132 file "app/controllers/user_sessions_controller.rb",
133 %q{class UserSessionsController < ApplicationController
134
4071b7e @davidrichards Cleaning some more issues up, will probably leave some frayed edges t…
authored Apr 2, 2009
135 # before_filter :require_no_user, :only => [:new, :create]
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
136 before_filter :require_user, :only => :destroy
137
138 def new
139 @user_session = UserSession.new
140 end
141
142 def create
143 @user_session = UserSession.new(params[:user_session])
144 if @user_session.save
145 flash[:notice] = "Login successful!"
146 redirect_back_or_default account_url
147 else
148 render :action => :new
149 end
150 end
151
152 def destroy
153 current_user_session.destroy
154 flash[:notice] = "Logout successful!"
155 redirect_back_or_default new_user_session_url
156 end
157 end
158 }
159
160 # Create a users controller
161 file "app/controllers/users_controller.rb",
162 %q{class UsersController < ApplicationController
163
4071b7e @davidrichards Cleaning some more issues up, will probably leave some frayed edges t…
authored Apr 3, 2009
164 # before_filter :require_no_user, :only => [:new, :create]
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
165 before_filter :require_user, :only => [:show, :edit, :update]
166
167 def new
168 @user = User.new
169 end
170
171 def create
172 @user = User.new(params[:user])
173 if @user.save
174 flash[:notice] = "Account registered!"
175 redirect_back_or_default account_url
176 else
177 render :action => :new
178 end
179 end
180
181 def show
182 @user = @current_user
183 end
184
185 def edit
186 @user = @current_user
187 end
188
189 def update
190 @user = @current_user # makes our views "cleaner" and more consistent
191 if @user.update_attributes(params[:user])
192 flash[:notice] = "Account updated!"
193 redirect_to account_url
194 else
195 render :action => :edit
196 end
197 end
198 end
199 }
200
201 # Setup the views
202
203 run "mkdir -p app/views/password_resets"
204 file "app/views/password_resets/edit.html.erb",
205 %q{<h1>Change My Password</h1>
206
207 <% form_for @user, :url => password_reset_path, :method => :put do |f| %>
208 <%= f.error_messages %>
209 <%= f.label :password %><br />
210 <%= f.password_field :password %><br />
211 <br />
212 <%= f.label :password_confirmation %><br />
213 <%= f.password_field :password_confirmation %><br />
214 <br />
215 <%= f.submit "Update my password and log me in" %>
216 <% end %>
217 }
218
219 file "app/views/password_resets/new.html.erb",
220 %q{<h1>Forgot Password</h1>
221
222 Fill out the form below and instructions to reset your password will be emailed to you:<br />
223 <br />
224
225 <% form_tag password_resets_path do %>
226 <label>Email:</label><br />
227 <%= text_field_tag "email" %><br />
228 <br />
229 <%= submit_tag "Reset my password" %>
230 <% end %>
231 }
232
233 run "mkdir -p app/views/user_sessions"
234
235 file "app/views/user_sessions/new.html.erb",
236 %q{<h1>Login</h1>
237
238 <% form_for @user_session, :url => user_session_path do |f| %>
239 <%= f.error_messages %>
4071b7e @davidrichards Cleaning some more issues up, will probably leave some frayed edges t…
authored Apr 3, 2009
240 <%= f.label :email %><br />
241 <%= f.text_field :email %><br />
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
242 <br />
243 <%= f.label :password %><br />
244 <%= f.password_field :password %><br />
245 <br />
246 <%= f.check_box :remember_me %><%= f.label :remember_me %><br />
247 <br />
248 <%= f.submit "Login" %>
249 <% end %>
250 }
251
252 run "mkdir -p app/views/users"
253
254 file "app/views/users/_form.html.erb",
4071b7e @davidrichards Cleaning some more issues up, will probably leave some frayed edges t…
authored Apr 3, 2009
255 %q{<%= form.label :email %><br />
256 <%= form.text_field :email %><br />
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
257 <br />
258 <%= form.label :password, form.object.new_record? ? nil : "Change password" %><br />
259 <%= form.password_field :password %><br />
260 <br />
261 <%= form.label :password_confirmation %><br />
262 <%= form.password_field :password_confirmation %><br />
263 <br />
264 }
265
3d216e8 @davidrichards Got more of the auth logic stuff working.
authored Apr 8, 2009
266 file "app/views/users/edit.html.erb",
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
267 %q{<h1>Edit My Account</h1>
268
269 <% form_for @user, :url => account_path do |f| %>
270 <%= f.error_messages %>
271 <%= render :partial => "form", :object => f %>
272 <%= f.submit "Update" %>
273 <% end %>
274
275 <br /><%= link_to "My Profile", account_path %>
276 }
277
278 file "app/views/users/new.html.erb",
279 %q{<h1>Register</h1>
280
281 <% form_for @user, :url => account_path do |f| %>
282 <%= f.error_messages %>
283 <%= render :partial => "form", :object => f %>
284 <%= f.submit "Register" %>
285 <% end %>
286 }
287
288 file "app/views/users/show.html.erb",
289 %q{<p>
4071b7e @davidrichards Cleaning some more issues up, will probably leave some frayed edges t…
authored Apr 3, 2009
290 <b>Email:</b>
291 <%=h @user.email %>
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
292 </p>
293
294 <p>
295 <b>Login count:</b>
296 <%=h @user.login_count %>
297 </p>
298
299 <p>
300 <b>Last request at:</b>
301 <%=h @user.last_request_at %>
302 </p>
303
304 <p>
305 <b>Last login at:</b>
306 <%=h @user.last_login_at %>
307 </p>
308
309 <p>
310 <b>Current login at:</b>
311 <%=h @user.current_login_at %>
312 </p>
313
314 <p>
315 <b>Last login ip:</b>
316 <%=h @user.last_login_ip %>
317 </p>
318
319 <p>
320 <b>Current login ip:</b>
321 <%=h @user.current_login_ip %>
322 </p>
323
324
325 <%= link_to 'Edit', edit_account_path %>
63f9042 @davidrichards Fixing a syntax goof
authored Apr 2, 2009
326 }
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
327
328 # Create an authentication module
329 file "lib/authentication.rb",
4071b7e @davidrichards Cleaning some more issues up, will probably leave some frayed edges t…
authored Apr 3, 2009
330 %q{module Authentication
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
331
4071b7e @davidrichards Cleaning some more issues up, will probably leave some frayed edges t…
authored Apr 3, 2009
332 def self.included(base)
333 base.send(:filter_parameter_logging, :password, :password_confirmation)
334 base.send(:helper_method, :current_user_session, :current_user)
335 end
336
3d216e8 @davidrichards Got more of the auth logic stuff working.
authored Apr 8, 2009
337 # private
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
338 def current_user_session
339 return @current_user_session if defined?(@current_user_session)
340 @current_user_session = UserSession.find
341 end
342
343 def current_user
344 return @current_user if defined?(@current_user)
345 @current_user = current_user_session && current_user_session.user
346 end
347
348 def require_user
349 unless current_user
350 store_location
351 flash[:notice] = "You must be logged in to access this page"
352 redirect_to new_user_session_url
353 return false
354 end
355 end
356
357 def require_no_user
358 if current_user
359 store_location
360 flash[:notice] = "You must be logged out to access this page"
361 redirect_to account_url
362 return false
363 end
364 end
365
366 def store_location
367 session[:return_to] = request.request_uri
368 end
369
370 def redirect_back_or_default(default)
371 redirect_to(session[:return_to] || default)
372 session[:return_to] = nil
373 end
374
375 end
376 }
377
3d216e8 @davidrichards Got more of the auth logic stuff working.
authored Apr 8, 2009
378 # Adjust the application controller
379 file "app/controllers/application_controller.rb",
37d2317 @davidrichards Added a bunch of the authentication files, routes, etc.
authored Apr 3, 2009
380 %q{
381 # Filters added to this controller apply to all controllers in the application.
382 # Likewise, all the methods added will be available for all controllers.
383
384 class ApplicationController < ActionController::Base
385 helper :all # include all helpers, all the time
386 protect_from_forgery # See ActionController::RequestForgeryProtection for details
387
388 # An authlogic authentication module found in lib/authentication.rb
389 include Authentication
390
391 # Scrub sensitive parameters from your log
392 # filter_parameter_logging :password
393 end
394 }
395
396
397 # Create some routes
398 route "map.resource :user_session"
399 route "map.resource :account, :controller => 'users'"
400 route "map.resources :users"
401 route "map.register '/register', :controller => 'users', :action => 'new'"
402 route "map.signup '/signup', :controller => 'users', :action => 'new'"
403 route "map.login '/login', :controller => 'user_sessions', :action => 'new'"
404 route "map.logout '/logout', :controller => 'user_sessions', :action => 'destroy'"
Something went wrong with that request. Please try again.