Commit aacd378904604b60850dd9245c52331ea2d629aa
- Diff rendering mode:
- inline
- side by side
app/models/movement.rb
(1 / 1)
|   | |||
| 1 | 1 | # == Schema Information | |
| 2 | # Schema version: 7 | ||
| 2 | # Schema version: 10 | ||
| 3 | 3 | # | |
| 4 | 4 | # Table name: movements | |
| 5 | 5 | # |
app/models/realization.rb
(1 / 1)
|   | |||
| 1 | 1 | # == Schema Information | |
| 2 | # Schema version: 7 | ||
| 2 | # Schema version: 10 | ||
| 3 | 3 | # | |
| 4 | 4 | # Table name: realizations | |
| 5 | 5 | # |
app/models/scheduled_debt.rb
(5 / 5)
|   | |||
| 1 | 1 | # == Schema Information | |
| 2 | # Schema version: 7 | ||
| 2 | # Schema version: 10 | ||
| 3 | 3 | # | |
| 4 | 4 | # Table name: scheduled_debts | |
| 5 | 5 | # | |
| 6 | 6 | # id :integer not null, primary key | |
| 7 | 7 | # description :string(255) not null | |
| 8 | # scheduled_day :integer not null | ||
| 9 | # scheduled_month :integer not null | ||
| 10 | # confirmed_date :date not null | ||
| 8 | # day :integer not null | ||
| 9 | # month :integer not null | ||
| 11 | 10 | # scheduled_value :decimal(, ) not null | |
| 12 | # confirmed_value :decimal(, ) | ||
| 13 | 11 | # comments :text | |
| 12 | # start_date :date | ||
| 13 | # end_date :date | ||
| 14 | 14 | # | |
| 15 | 15 | ||
| 16 | 16 | class ScheduledDebt < ActiveRecord::Base |
|   | |||
| 1 | 1 | # == Schema Information | |
| 2 | # Schema version: 7 | ||
| 2 | # Schema version: 10 | ||
| 3 | 3 | # | |
| 4 | 4 | # Table name: scheduled_profits | |
| 5 | 5 | # | |
| 6 | 6 | # id :integer not null, primary key | |
| 7 | 7 | # source :string(255) not null | |
| 8 | 8 | # scheduled_value :decimal(, ) not null | |
| 9 | # confirmed_value :decimal(, ) | ||
| 10 | # auto :boolean not null | ||
| 11 | 9 | # month :integer not null | |
| 12 | 10 | # day :integer default(10), not null | |
| 11 | # start_date :date | ||
| 12 | # end_date :date | ||
| 13 | 13 | # | |
| 14 | 14 | ||
| 15 | 15 | class ScheduledProfit < ActiveRecord::Base |
app/models/user.rb
(16 / 0)
|   | |||
| 1 | # == Schema Information | ||
| 2 | # Schema version: 10 | ||
| 3 | # | ||
| 4 | # Table name: users | ||
| 5 | # | ||
| 6 | # id :integer not null, primary key | ||
| 7 | # login :string(255) | ||
| 8 | # email :string(255) | ||
| 9 | # crypted_password :string(40) | ||
| 10 | # salt :string(40) | ||
| 11 | # created_at :datetime | ||
| 12 | # updated_at :datetime | ||
| 13 | # remember_token :string(255) | ||
| 14 | # remember_token_expires_at :datetime | ||
| 15 | # | ||
| 16 | |||
| 1 | 17 | require 'digest/sha1' | |
| 2 | 18 | class User < ActiveRecord::Base | |
| 3 | 19 | # Virtual attribute for the unencrypted password |
test/fixtures/movements.yml
(1 / 1)
|   | |||
| 1 | 1 | # == Schema Information | |
| 2 | # Schema version: 7 | ||
| 2 | # Schema version: 10 | ||
| 3 | 3 | # | |
| 4 | 4 | # Table name: movements | |
| 5 | 5 | # |
test/fixtures/users.yml
(16 / 0)
|   | |||
| 1 | # == Schema Information | ||
| 2 | # Schema version: 10 | ||
| 3 | # | ||
| 4 | # Table name: users | ||
| 5 | # | ||
| 6 | # id :integer not null, primary key | ||
| 7 | # login :string(255) | ||
| 8 | # email :string(255) | ||
| 9 | # crypted_password :string(40) | ||
| 10 | # salt :string(40) | ||
| 11 | # created_at :datetime | ||
| 12 | # updated_at :datetime | ||
| 13 | # remember_token :string(255) | ||
| 14 | # remember_token_expires_at :datetime | ||
| 15 | # | ||
| 16 | |||
| 1 | 17 | quentin: | |
| 2 | 18 | id: 1 | |
| 3 | 19 | login: quentin |
|   | |||
| 1 | Restful Authentication Generator | ||
| 2 | ==== | ||
| 3 | |||
| 4 | This is a basic restful authentication generator for rails, taken | ||
| 5 | from acts as authenticated. Currently it requires Rails 1.2.6 or above. | ||
| 6 | |||
| 7 | To use: | ||
| 8 | |||
| 9 | ./script/generate authenticated user sessions \ | ||
| 10 | --include-activation \ | ||
| 11 | --stateful | ||
| 12 | |||
| 13 | The first parameter specifies the model that gets created in signup | ||
| 14 | (typically a user or account model). A model with migration is | ||
| 15 | created, as well as a basic controller with the create method. | ||
| 16 | |||
| 17 | The second parameter specifies the sessions controller name. This is | ||
| 18 | the controller that handles the actual login/logout function on the | ||
| 19 | site. | ||
| 20 | |||
| 21 | The third parameter (--include-activation) generates the code for a | ||
| 22 | ActionMailer and its respective Activation Code through email. | ||
| 23 | |||
| 24 | The fourth (--stateful) builds in support for acts_as_state_machine | ||
| 25 | and generates activation code. This was taken from: | ||
| 26 | |||
| 27 | http://www.vaporbase.com/postings/stateful_authentication | ||
| 28 | |||
| 29 | You can pass --skip-migration to skip the user migration. | ||
| 30 | |||
| 31 | If you're using acts_as_state_machine, define your users resource like this: | ||
| 32 | |||
| 33 | map.resources :users, :member => { :suspend => :put, | ||
| 34 | :unsuspend => :put, | ||
| 35 | :purge => :delete } | ||
| 36 | |||
| 37 | Also, add an observer to config/environment.rb if you chose the | ||
| 38 | --include-activation option | ||
| 39 | |||
| 40 | config.active_record.observers = :user_observer # or whatever you | ||
| 41 | # named your model | ||
| 42 | |||
| 43 | Security Alert | ||
| 44 | ==== | ||
| 45 | |||
| 46 | I introduced a change to the model controller that's been tripping | ||
| 47 | folks up on Rails 2.0. The change was added as a suggestion to help | ||
| 48 | combat session fixation attacks. However, this resets the Form | ||
| 49 | Authentication token used by Request Forgery Protection. I've left | ||
| 50 | it out now, since Rails 1.2.6 and Rails 2.0 will both stop session | ||
| 51 | fixation attacks anyway. |
|   | |||
| 1 | require 'rake' | ||
| 2 | require 'rake/testtask' | ||
| 3 | require 'rake/rdoctask' | ||
| 4 | |||
| 5 | desc 'Default: run unit tests.' | ||
| 6 | task :default => :test | ||
| 7 | |||
| 8 | desc 'Test the restful_authentication plugin.' | ||
| 9 | Rake::TestTask.new(:test) do |t| | ||
| 10 | t.libs << 'lib' | ||
| 11 | t.pattern = 'test/**/*_test.rb' | ||
| 12 | t.verbose = true | ||
| 13 | end | ||
| 14 | |||
| 15 | desc 'Generate documentation for the restful_authentication plugin.' | ||
| 16 | Rake::RDocTask.new(:rdoc) do |rdoc| | ||
| 17 | rdoc.rdoc_dir = 'rdoc' | ||
| 18 | rdoc.title = 'RestfulAuthentication' | ||
| 19 | rdoc.options << '--line-numbers' << '--inline-source' | ||
| 20 | rdoc.rdoc_files.include('README') | ||
| 21 | rdoc.rdoc_files.include('lib/**/*.rb') | ||
| 22 | end |
|   | |||
| 1 | ./script/generate authenticated USERMODEL CONTROLLERNAME |
|   | |||
| 1 | require 'restful_authentication/rails_commands' | ||
| 2 | class AuthenticatedGenerator < Rails::Generator::NamedBase | ||
| 3 | default_options :skip_migration => false, | ||
| 4 | :include_activation => false | ||
| 5 | |||
| 6 | attr_reader :controller_name, | ||
| 7 | :controller_class_path, | ||
| 8 | :controller_file_path, | ||
| 9 | :controller_class_nesting, | ||
| 10 | :controller_class_nesting_depth, | ||
| 11 | :controller_class_name, | ||
| 12 | :controller_singular_name, | ||
| 13 | :controller_plural_name, | ||
| 14 | :controller_file_name | ||
| 15 | alias_method :controller_table_name, :controller_plural_name | ||
| 16 | attr_reader :model_controller_name, | ||
| 17 | :model_controller_class_path, | ||
| 18 | :model_controller_file_path, | ||
| 19 | :model_controller_class_nesting, | ||
| 20 | :model_controller_class_nesting_depth, | ||
| 21 | :model_controller_class_name, | ||
| 22 | :model_controller_singular_name, | ||
| 23 | :model_controller_plural_name | ||
| 24 | alias_method :model_controller_file_name, :model_controller_singular_name | ||
| 25 | alias_method :model_controller_table_name, :model_controller_plural_name | ||
| 26 | |||
| 27 | def initialize(runtime_args, runtime_options = {}) | ||
| 28 | super | ||
| 29 | |||
| 30 | @rspec = has_rspec? | ||
| 31 | |||
| 32 | @controller_name = args.shift || 'sessions' | ||
| 33 | @model_controller_name = @name.pluralize | ||
| 34 | |||
| 35 | # sessions controller | ||
| 36 | base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name) | ||
| 37 | @controller_class_name_without_nesting, @controller_file_name, @controller_plural_name = inflect_names(base_name) | ||
| 38 | @controller_singular_name = @controller_file_name.singularize | ||
| 39 | |||
| 40 | if @controller_class_nesting.empty? | ||
| 41 | @controller_class_name = @controller_class_name_without_nesting | ||
| 42 | else | ||
| 43 | @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}" | ||
| 44 | end | ||
| 45 | |||
| 46 | # model controller | ||
| 47 | base_name, @model_controller_class_path, @model_controller_file_path, @model_controller_class_nesting, @model_controller_class_nesting_depth = extract_modules(@model_controller_name) | ||
| 48 | @model_controller_class_name_without_nesting, @model_controller_singular_name, @model_controller_plural_name = inflect_names(base_name) | ||
| 49 | |||
| 50 | if @model_controller_class_nesting.empty? | ||
| 51 | @model_controller_class_name = @model_controller_class_name_without_nesting | ||
| 52 | else | ||
| 53 | @model_controller_class_name = "#{@model_controller_class_nesting}::#{@model_controller_class_name_without_nesting}" | ||
| 54 | end | ||
| 55 | end | ||
| 56 | |||
| 57 | def manifest | ||
| 58 | recorded_session = record do |m| | ||
| 59 | # Check for class naming collisions. | ||
| 60 | m.class_collisions controller_class_path, "#{controller_class_name}Controller", # Sessions Controller | ||
| 61 | "#{controller_class_name}Helper" | ||
| 62 | m.class_collisions model_controller_class_path, "#{model_controller_class_name}Controller", # Model Controller | ||
| 63 | "#{model_controller_class_name}Helper" | ||
| 64 | m.class_collisions class_path, "#{class_name}", "#{class_name}Mailer", "#{class_name}MailerTest", "#{class_name}Observer" | ||
| 65 | m.class_collisions [], 'AuthenticatedSystem', 'AuthenticatedTestHelper' | ||
| 66 | |||
| 67 | # Controller, helper, views, and test directories. | ||
| 68 | m.directory File.join('app/models', class_path) | ||
| 69 | m.directory File.join('app/controllers', controller_class_path) | ||
| 70 | m.directory File.join('app/controllers', model_controller_class_path) | ||
| 71 | m.directory File.join('app/helpers', controller_class_path) | ||
| 72 | m.directory File.join('app/views', controller_class_path, controller_file_name) | ||
| 73 | m.directory File.join('app/views', class_path, "#{file_name}_mailer") if options[:include_activation] | ||
| 74 | |||
| 75 | m.directory File.join('app/controllers', model_controller_class_path) | ||
| 76 | m.directory File.join('app/helpers', model_controller_class_path) | ||
| 77 | m.directory File.join('app/views', model_controller_class_path, model_controller_file_name) | ||
| 78 | |||
| 79 | if @rspec | ||
| 80 | m.directory File.join('spec/controllers', controller_class_path) | ||
| 81 | m.directory File.join('spec/controllers', model_controller_class_path) | ||
| 82 | m.directory File.join('spec/models', class_path) | ||
| 83 | m.directory File.join('spec/fixtures', class_path) | ||
| 84 | else | ||
| 85 | m.directory File.join('test/functional', controller_class_path) | ||
| 86 | m.directory File.join('test/functional', model_controller_class_path) | ||
| 87 | m.directory File.join('test/unit', class_path) | ||
| 88 | end | ||
| 89 | |||
| 90 | m.template 'model.rb', | ||
| 91 | File.join('app/models', | ||
| 92 | class_path, | ||
| 93 | "#{file_name}.rb") | ||
| 94 | |||
| 95 | if options[:include_activation] | ||
| 96 | %w( mailer observer ).each do |model_type| | ||
| 97 | m.template "#{model_type}.rb", File.join('app/models', | ||
| 98 | class_path, | ||
| 99 | "#{file_name}_#{model_type}.rb") | ||
| 100 | end | ||
| 101 | end | ||
| 102 | |||
| 103 | m.template 'controller.rb', | ||
| 104 | File.join('app/controllers', | ||
| 105 | controller_class_path, | ||
| 106 | "#{controller_file_name}_controller.rb") | ||
| 107 | |||
| 108 | m.template 'model_controller.rb', | ||
| 109 | File.join('app/controllers', | ||
| 110 | model_controller_class_path, | ||
| 111 | "#{model_controller_file_name}_controller.rb") | ||
| 112 | |||
| 113 | m.template 'authenticated_system.rb', | ||
| 114 | File.join('lib', 'authenticated_system.rb') | ||
| 115 | |||
| 116 | m.template 'authenticated_test_helper.rb', | ||
| 117 | File.join('lib', 'authenticated_test_helper.rb') | ||
| 118 | |||
| 119 | if @rspec | ||
| 120 | m.template 'functional_spec.rb', | ||
| 121 | File.join('spec/controllers', | ||
| 122 | controller_class_path, | ||
| 123 | "#{controller_file_name}_controller_spec.rb") | ||
| 124 | m.template 'model_functional_spec.rb', | ||
| 125 | File.join('spec/controllers', | ||
| 126 | model_controller_class_path, | ||
| 127 | "#{model_controller_file_name}_controller_spec.rb") | ||
| 128 | m.template 'unit_spec.rb', | ||
| 129 | File.join('spec/models', | ||
| 130 | class_path, | ||
| 131 | "#{file_name}_spec.rb") | ||
| 132 | m.template 'fixtures.yml', | ||
| 133 | File.join('spec/fixtures', | ||
| 134 | "#{table_name}.yml") | ||
| 135 | else | ||
| 136 | m.template 'functional_test.rb', | ||
| 137 | File.join('test/functional', | ||
| 138 | controller_class_path, | ||
| 139 | "#{controller_file_name}_controller_test.rb") | ||
| 140 | m.template 'model_functional_test.rb', | ||
| 141 | File.join('test/functional', | ||
| 142 | model_controller_class_path, | ||
| 143 | "#{model_controller_file_name}_controller_test.rb") | ||
| 144 | m.template 'unit_test.rb', | ||
| 145 | File.join('test/unit', | ||
| 146 | class_path, | ||
| 147 | "#{file_name}_test.rb") | ||
| 148 | if options[:include_activation] | ||
| 149 | m.template 'mailer_test.rb', File.join('test/unit', class_path, "#{file_name}_mailer_test.rb") | ||
| 150 | end | ||
| 151 | m.template 'fixtures.yml', | ||
| 152 | File.join('test/fixtures', | ||
| 153 | "#{table_name}.yml") | ||
| 154 | end | ||
| 155 | |||
| 156 | m.template 'helper.rb', | ||
| 157 | File.join('app/helpers', | ||
| 158 | controller_class_path, | ||
| 159 | "#{controller_file_name}_helper.rb") | ||
| 160 | |||
| 161 | m.template 'model_helper.rb', | ||
| 162 | File.join('app/helpers', | ||
| 163 | model_controller_class_path, | ||
| 164 | "#{model_controller_file_name}_helper.rb") | ||
| 165 | |||
| 166 | |||
| 167 | # Controller templates | ||
| 168 | m.template 'login.html.erb', File.join('app/views', controller_class_path, controller_file_name, "new.html.erb") | ||
| 169 | m.template 'signup.html.erb', File.join('app/views', model_controller_class_path, model_controller_file_name, "new.html.erb") | ||
| 170 | |||
| 171 | if options[:include_activation] | ||
| 172 | # Mailer templates | ||
| 173 | %w( activation signup_notification ).each do |action| | ||
| 174 | m.template "#{action}.html.erb", | ||
| 175 | File.join('app/views', "#{file_name}_mailer", "#{action}.html.erb") | ||
| 176 | end | ||
| 177 | end | ||
| 178 | |||
| 179 | unless options[:skip_migration] | ||
| 180 | m.migration_template 'migration.rb', 'db/migrate', :assigns => { | ||
| 181 | :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}" | ||
| 182 | }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}" | ||
| 183 | end | ||
| 184 | |||
| 185 | m.route_resource controller_singular_name | ||
| 186 | m.route_resources model_controller_plural_name | ||
| 187 | end | ||
| 188 | |||
| 189 | action = nil | ||
| 190 | action = $0.split("/")[1] | ||
| 191 | case action | ||
| 192 | when "generate" | ||
| 193 | puts | ||
| 194 | puts ("-" * 70) | ||
| 195 | puts "Don't forget to:" | ||
| 196 | puts | ||
| 197 | if options[:include_activation] | ||
| 198 | puts " map.activate '/activate/:activation_code', :controller => '#{model_controller_file_name}', :action => 'activate'" | ||
| 199 | puts | ||
| 200 | puts " - add an observer to config/environment.rb" | ||
| 201 | puts " config.active_record.observers = :#{file_name}_observer" | ||
| 202 | puts | ||
| 203 | end | ||
| 204 | if options[:stateful] | ||
| 205 | puts "Also, don't forget to install the acts_as_state_machine plugin and set your resource:" | ||
| 206 | puts | ||
| 207 | puts " svn co http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk vendor/plugins/acts_as_state_machine" | ||
| 208 | puts | ||
| 209 | puts %w(map.resources :#{model_controller_file_name}, :member => { :suspend => :put, :unsuspend => :put, :purge => :delete }) | ||
| 210 | puts | ||
| 211 | end | ||
| 212 | puts "Try these for some familiar login URLs if you like:" | ||
| 213 | puts | ||
| 214 | puts %(map.activate '/activate/:activation_code', :controller => '#{model_controller_file_name}', :action => 'activate', :activation_code => nil) | ||
| 215 | puts %(map.signup '/signup', :controller => '#{model_controller_file_name}', :action => 'new') | ||
| 216 | puts %(map.login '/login', :controller => '#{controller_file_name}', :action => 'new') | ||
| 217 | puts %(map.logout '/logout', :controller => '#{controller_file_name}', :action => 'destroy') | ||
| 218 | puts | ||
| 219 | puts ("-" * 70) | ||
| 220 | puts | ||
| 221 | when "destroy" | ||
| 222 | puts | ||
| 223 | puts ("-" * 70) | ||
| 224 | puts | ||
| 225 | puts "Thanks for using restful_authentication" | ||
| 226 | puts | ||
| 227 | puts "Don't forget to comment out the observer line in environment.rb" | ||
| 228 | puts " (This was optional so it may not even be there)" | ||
| 229 | puts " # config.active_record.observers = :#{file_name}_observer" | ||
| 230 | puts | ||
| 231 | puts ("-" * 70) | ||
| 232 | puts | ||
| 233 | else | ||
| 234 | puts | ||
| 235 | end | ||
| 236 | |||
| 237 | recorded_session | ||
| 238 | end | ||
| 239 | |||
| 240 | def has_rspec? | ||
| 241 | options[:rspec] || (File.exist?('spec') && File.directory?('spec')) | ||
| 242 | end | ||
| 243 | |||
| 244 | protected | ||
| 245 | # Override with your own usage banner. | ||
| 246 | def banner | ||
| 247 | "Usage: #{$0} authenticated ModelName [ControllerName]" | ||
| 248 | end | ||
| 249 | |||
| 250 | def add_options!(opt) | ||
| 251 | opt.separator '' | ||
| 252 | opt.separator 'Options:' | ||
| 253 | opt.on("--skip-migration", | ||
| 254 | "Don't generate a migration file for this model") { |v| options[:skip_migration] = v } | ||
| 255 | opt.on("--include-activation", | ||
| 256 | "Generate signup 'activation code' confirmation via email") { |v| options[:include_activation] = true } | ||
| 257 | opt.on("--stateful", | ||
| 258 | "Use acts_as_state_machine. Assumes --include-activation") { |v| options[:include_activation] = options[:stateful] = true } | ||
| 259 | opt.on("--rspec", | ||
| 260 | "Force rspec mode (checks for RAILS_ROOT/spec by default)") { |v| options[:rspec] = true } | ||
| 261 | end | ||
| 262 | end |
|   | |||
| 1 | <%%= @<%= file_name %>.login %>, your account has been activated. You may now start adding your plugins: | ||
| 2 | |||
| 3 | <%%= @url %> |
vendor/plugins/restful_authentication/generators/authenticated/templates/authenticated_system.rb
(0 / 116)
|   | |||
| 1 | module 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 logged_in? | ||
| 6 | current_<%= file_name %> != :false | ||
| 7 | end | ||
| 8 | |||
| 9 | # Accesses the current <%= file_name %> from the session. Set it to :false if login fails | ||
| 10 | # so that future calls do not hit the database. | ||
| 11 | def current_<%= file_name %> | ||
| 12 | @current_<%= file_name %> ||= (login_from_session || login_from_basic_auth || login_from_cookie || :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 %>.nil? || new_<%= file_name %>.is_a?(Symbol)) ? nil : new_<%= file_name %>.id | ||
| 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 | def authorized? | ||
| 34 | logged_in? | ||
| 35 | end | ||
| 36 | |||
| 37 | # Filter method to enforce a login requirement. | ||
| 38 | # | ||
| 39 | # To require logins for all actions, use this in your controllers: | ||
| 40 | # | ||
| 41 | # before_filter :login_required | ||
| 42 | # | ||
| 43 | # To require logins for specific actions, use this in your controllers: | ||
| 44 | # | ||
| 45 | # before_filter :login_required, :only => [ :edit, :update ] | ||
| 46 | # | ||
| 47 | # To skip this in a subclassed controller: | ||
| 48 | # | ||
| 49 | # skip_before_filter :login_required | ||
| 50 | # | ||
| 51 | def login_required | ||
| 52 | authorized? || access_denied | ||
| 53 | end | ||
| 54 | |||
| 55 | # Redirect as appropriate when an access request fails. | ||
| 56 | # | ||
| 57 | # The default action is to redirect to the login screen. | ||
| 58 | # | ||
| 59 | # Override this method in your controllers if you want to have special | ||
| 60 | # behavior in case the <%= file_name %> is not authorized | ||
| 61 | # to access the requested action. For example, a popup window might | ||
| 62 | # simply close itself. | ||
| 63 | def access_denied | ||
| 64 | respond_to do |format| | ||
| 65 | format.html do | ||
| 66 | store_location | ||
| 67 | redirect_to new_<%= controller_singular_name %>_path | ||
| 68 | end | ||
| 69 | format.any do | ||
| 70 | request_http_basic_authentication 'Web Password' | ||
| 71 | end | ||
| 72 | end | ||
| 73 | end | ||
| 74 | |||
| 75 | # Store the URI of the current request in the session. | ||
| 76 | # | ||
| 77 | # We can return to this location by calling #redirect_back_or_default. | ||
| 78 | def store_location | ||
| 79 | session[:return_to] = request.request_uri | ||
| 80 | end | ||
| 81 | |||
| 82 | # Redirect to the URI stored by the most recent store_location call or | ||
| 83 | # to the passed default. | ||
| 84 | def redirect_back_or_default(default) | ||
| 85 | redirect_to(session[:return_to] || default) | ||
| 86 | session[:return_to] = nil | ||
| 87 | end | ||
| 88 | |||
| 89 | # Inclusion hook to make #current_<%= file_name %> and #logged_in? | ||
| 90 | # available as ActionView helper methods. | ||
| 91 | def self.included(base) | ||
| 92 | base.send :helper_method, :current_<%= file_name %>, :logged_in? | ||
| 93 | end | ||
| 94 | |||
| 95 | # Called from #current_<%= file_name %>. First attempt to login by the <%= file_name %> id stored in the session. | ||
| 96 | def login_from_session | ||
| 97 | self.current_<%= file_name %> = <%= class_name %>.find(session[:<%= file_name %>_id]) if session[:<%= file_name %>_id] | ||
| 98 | end | ||
| 99 | |||
| 100 | # Called from #current_<%= file_name %>. Now, attempt to login by basic authentication information. | ||
| 101 | def login_from_basic_auth | ||
| 102 | authenticate_with_http_basic do |username, password| | ||
| 103 | self.current_<%= file_name %> = <%= class_name %>.authenticate(username, password) | ||
| 104 | end | ||
| 105 | end | ||
| 106 | |||
| 107 | # Called from #current_<%= file_name %>. Finaly, attempt to login by an expiring token in the cookie. | ||
| 108 | def login_from_cookie | ||
| 109 | <%= file_name %> = cookies[:auth_token] && <%= class_name %>.find_by_remember_token(cookies[:auth_token]) | ||
| 110 | if <%= file_name %> && <%= file_name %>.remember_token? | ||
| 111 | <%= file_name %>.remember_me | ||
| 112 | cookies[:auth_token] = { :value => <%= file_name %>.remember_token, :expires => <%= file_name %>.remember_token_expires_at } | ||
| 113 | self.current_<%= file_name %> = <%= file_name %> | ||
| 114 | end | ||
| 115 | end | ||
| 116 | end |
|   | |||
| 1 | module 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 %> ? <%= table_name %>(<%= file_name %>).id : nil | ||
| 5 | end | ||
| 6 | |||
| 7 | def authorize_as(user) | ||
| 8 | @request.env["HTTP_AUTHORIZATION"] = user ? ActionController::HttpAuthentication::Basic.encode_credentials(users(user).login, 'test') : nil | ||
| 9 | end | ||
| 10 | end |
|   | |||
| 1 | # This controller handles the login/logout function of the site. | ||
| 2 | class <%= controller_class_name %>Controller < ApplicationController | ||
| 3 | # Be sure to include AuthenticationSystem in Application Controller instead | ||
| 4 | include AuthenticatedSystem | ||
| 5 | |||
| 6 | # render new.rhtml | ||
| 7 | def new | ||
| 8 | end | ||
| 9 | |||
| 10 | def create | ||
| 11 | self.current_<%= file_name %> = <%= class_name %>.authenticate(params[:login], params[:password]) | ||
| 12 | if logged_in? | ||
| 13 | if params[:remember_me] == "1" | ||
| 14 | self.current_<%= file_name %>.remember_me | ||
| 15 | cookies[:auth_token] = { :value => self.current_<%= file_name %>.remember_token , :expires => self.current_<%= file_name %>.remember_token_expires_at } | ||
| 16 | end | ||
| 17 | redirect_back_or_default('/') | ||
| 18 | flash[:notice] = "Logged in successfully" | ||
| 19 | else | ||
| 20 | render :action => 'new' | ||
| 21 | end | ||
| 22 | end | ||
| 23 | |||
| 24 | def destroy | ||
| 25 | self.current_<%= file_name %>.forget_me if logged_in? | ||
| 26 | cookies.delete :auth_token | ||
| 27 | reset_session | ||
| 28 | flash[:notice] = "You have been logged out." | ||
| 29 | redirect_back_or_default('/') | ||
| 30 | end | ||
| 31 | end |
|   | |||
| 1 | quentin: | ||
| 2 | id: 1 | ||
| 3 | login: quentin | ||
| 4 | email: quentin@example.com | ||
| 5 | salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd | ||
| 6 | crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test | ||
| 7 | created_at: <%%= 5.days.ago.to_s :db %> | ||
| 8 | <% if options[:include_activation] %> activation_code: 8f24789ae988411ccf33ab0c30fe9106fab32e9b <% end %> | ||
| 9 | <% if options[:include_activation] %> activated_at: <%%= 5.days.ago.to_s :db %> <% end %> | ||
| 10 | <% if options[:stateful] %> state: active<% end %> | ||
| 11 | aaron: | ||
| 12 | id: 2 | ||
| 13 | login: aaron | ||
| 14 | email: aaron@example.com | ||
| 15 | salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd | ||
| 16 | crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test | ||
| 17 | created_at: <%%= 1.days.ago.to_s :db %> | ||
| 18 | <% if options[:include_activation] %> activation_code: 8f24789ae988411ccf33ab0c30fe9106fab32e9a <% end %> | ||
| 19 | <% if options[:stateful] %> state: pending<% end %> |
|   | |||
| 1 | require File.dirname(__FILE__) + '/../spec_helper' | ||
| 2 | |||
| 3 | # Be sure to include AuthenticatedTestHelper in spec/spec_helper.rb instead | ||
| 4 | # Then, you can remove it from this and the units test. | ||
| 5 | include AuthenticatedTestHelper | ||
| 6 | |||
| 7 | describe <%= controller_class_name %>Controller do | ||
| 8 | fixtures :<%= table_name %> | ||
| 9 | |||
| 10 | it 'logins and redirects' do | ||
| 11 | post :create, :login => 'quentin', :password => 'test' | ||
| 12 | session[:<%= file_name %>_id].should_not be_nil | ||
| 13 | response.should be_redirect | ||
| 14 | end | ||
| 15 | |||
| 16 | it 'fails login and does not redirect' do | ||
| 17 | post :create, :login => 'quentin', :password => 'bad password' | ||
| 18 | session[:<%= file_name %>_id].should be_nil | ||
| 19 | response.should be_success | ||
| 20 | end | ||
| 21 | |||
| 22 | it 'logs out' do | ||
| 23 | login_as :quentin | ||
| 24 | get :destroy | ||
| 25 | session[:<%= file_name %>_id].should be_nil | ||
| 26 | response.should be_redirect | ||
| 27 | end | ||
| 28 | |||
| 29 | it 'remembers me' do | ||
| 30 | post :create, :login => 'quentin', :password => 'test', :remember_me => "1" | ||
| 31 | response.cookies["auth_token"].should_not be_nil | ||
| 32 | end | ||
| 33 | |||
| 34 | it 'does not remember me' do | ||
| 35 | post :create, :login => 'quentin', :password => 'test', :remember_me => "0" | ||
| 36 | response.cookies["auth_token"].should be_nil | ||
| 37 | end | ||
| 38 | |||
| 39 | it 'deletes token on logout' do | ||
| 40 | login_as :quentin | ||
| 41 | get :destroy | ||
| 42 | response.cookies["auth_token"].should == [] | ||
| 43 | end | ||
| 44 | |||
| 45 | it 'logs in with cookie' do | ||
| 46 | <%= table_name %>(:quentin).remember_me | ||
| 47 | request.cookies["auth_token"] = cookie_for(:quentin) | ||
| 48 | get :new | ||
| 49 | controller.send(:logged_in?).should be_true | ||
| 50 | end | ||
| 51 | |||
| 52 | it 'fails expired cookie login' do | ||
| 53 | <%= table_name %>(:quentin).remember_me | ||
| 54 | <%= table_name %>(:quentin).update_attribute :remember_token_expires_at, 5.minutes.ago | ||
| 55 | request.cookies["auth_token"] = cookie_for(:quentin) | ||
| 56 | get :new | ||
| 57 | controller.send(:logged_in?).should_not be_true | ||
| 58 | end | ||
| 59 | |||
| 60 | it 'fails cookie login' do | ||
| 61 | <%= table_name %>(:quentin).remember_me | ||
| 62 | request.cookies["auth_token"] = auth_token('invalid_auth_token') | ||
| 63 | get :new | ||
| 64 | controller.send(:logged_in?).should_not be_true | ||
| 65 | end | ||
| 66 | |||
| 67 | def auth_token(token) | ||
| 68 | CGI::Cookie.new('name' => 'auth_token', 'value' => token) | ||
| 69 | end | ||
| 70 | |||
| 71 | def cookie_for(<%= file_name %>) | ||
| 72 | auth_token <%= table_name %>(<%= file_name %>).remember_token | ||
| 73 | end | ||
| 74 | end |
|   | |||
| 1 | require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | require '<%= controller_file_name %>_controller' | ||
| 3 | |||
| 4 | # Re-raise errors caught by the controller. | ||
| 5 | class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end | ||
| 6 | |||
| 7 | class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase | ||
| 8 | # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead | ||
| 9 | # Then, you can remove it from this and the units test. | ||
| 10 | include AuthenticatedTestHelper | ||
| 11 | |||
| 12 | fixtures :<%= table_name %> | ||
| 13 | |||
| 14 | def setup | ||
| 15 | @controller = <%= controller_class_name %>Controller.new | ||
| 16 | @request = ActionController::TestRequest.new | ||
| 17 | @response = ActionController::TestResponse.new | ||
| 18 | end | ||
| 19 | |||
| 20 | def test_should_login_and_redirect | ||
| 21 | post :create, :login => 'quentin', :password => 'test' | ||
| 22 | assert session[:<%= file_name %>_id] | ||
| 23 | assert_response :redirect | ||
| 24 | end | ||
| 25 | |||
| 26 | def test_should_fail_login_and_not_redirect | ||
| 27 | post :create, :login => 'quentin', :password => 'bad password' | ||
| 28 | assert_nil session[:<%= file_name %>_id] | ||
| 29 | assert_response :success | ||
| 30 | end | ||
| 31 | |||
| 32 | def test_should_logout | ||
| 33 | login_as :quentin | ||
| 34 | get :destroy | ||
| 35 | assert_nil session[:<%= file_name %>_id] | ||
| 36 | assert_response :redirect | ||
| 37 | end | ||
| 38 | |||
| 39 | def test_should_remember_me | ||
| 40 | post :create, :login => 'quentin', :password => 'test', :remember_me => "1" | ||
| 41 | assert_not_nil @response.cookies["auth_token"] | ||
| 42 | end | ||
| 43 | |||
| 44 | def test_should_not_remember_me | ||
| 45 | post :create, :login => 'quentin', :password => 'test', :remember_me => "0" | ||
| 46 | assert_nil @response.cookies["auth_token"] | ||
| 47 | end | ||
| 48 | |||
| 49 | def test_should_delete_token_on_logout | ||
| 50 | login_as :quentin | ||
| 51 | get :destroy | ||
| 52 | assert_equal @response.cookies["auth_token"], [] | ||
| 53 | end | ||
| 54 | |||
| 55 | def test_should_login_with_cookie | ||
| 56 | <%= table_name %>(:quentin).remember_me | ||
| 57 | @request.cookies["auth_token"] = cookie_for(:quentin) | ||
| 58 | get :new | ||
| 59 | assert @controller.send(:logged_in?) | ||
| 60 | end | ||
| 61 | |||
| 62 | def test_should_fail_expired_cookie_login | ||
| 63 | <%= table_name %>(:quentin).remember_me | ||
| 64 | <%= table_name %>(:quentin).update_attribute :remember_token_expires_at, 5.minutes.ago | ||
| 65 | @request.cookies["auth_token"] = cookie_for(:quentin) | ||
| 66 | get :new | ||
| 67 | assert !@controller.send(:logged_in?) | ||
| 68 | end | ||
| 69 | |||
| 70 | def test_should_fail_cookie_login | ||
| 71 | <%= table_name %>(:quentin).remember_me | ||
| 72 | @request.cookies["auth_token"] = auth_token('invalid_auth_token') | ||
| 73 | get :new | ||
| 74 | assert !@controller.send(:logged_in?) | ||
| 75 | end | ||
| 76 | |||
| 77 | protected | ||
| 78 | def auth_token(token) | ||
| 79 | CGI::Cookie.new('name' => 'auth_token', 'value' => token) | ||
| 80 | end | ||
| 81 | |||
| 82 | def cookie_for(<%= file_name %>) | ||
| 83 | auth_token <%= table_name %>(<%= file_name %>).remember_token | ||
| 84 | end | ||
| 85 | end |
|   | |||
| 1 | module <%= controller_class_name %>Helper | ||
| 2 | end |
|   | |||
| 1 | <%% form_tag <%= controller_singular_name %>_path do -%> | ||
| 2 | <p><label for="login">Login</label><br/> | ||
| 3 | <%%= text_field_tag 'login' %></p> | ||
| 4 | |||
| 5 | <p><label for="password">Password</label><br/> | ||
| 6 | <%%= password_field_tag 'password' %></p> | ||
| 7 | |||
| 8 | <!-- Uncomment this if you want this functionality | ||
| 9 | <p><label for="remember_me">Remember me:</label> | ||
| 10 | <%%= check_box_tag 'remember_me' %></p> | ||
| 11 | --> | ||
| 12 | |||
| 13 | <p><%%= submit_tag 'Log in' %></p> | ||
| 14 | <%% end -%> |
|   | |||
| 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 |
|   | |||
| 1 | require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | require '<%= file_name %>_mailer' | ||
| 3 | |||
| 4 | class <%= class_name %>MailerTest < Test::Unit::TestCase | ||
| 5 | FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures' | ||
| 6 | CHARSET = "utf-8" | ||
| 7 | |||
| 8 | include ActionMailer::Quoting | ||
| 9 | |||
| 10 | def setup | ||
| 11 | ActionMailer::Base.delivery_method = :test | ||
| 12 | ActionMailer::Base.perform_deliveries = true | ||
| 13 | ActionMailer::Base.deliveries = [] | ||
| 14 | |||
| 15 | @expected = TMail::Mail.new | ||
| 16 | @expected.set_content_type "text", "plain", { "charset" => CHARSET } | ||
| 17 | end | ||
| 18 | |||
| 19 | def test_dummy_test | ||
| 20 | #do nothing | ||
| 21 | end | ||
| 22 | |||
| 23 | private | ||
| 24 | def read_fixture(action) | ||
| 25 | IO.readlines("#{FIXTURES_PATH}/<%= file_name %>_mailer/#{action}") | ||
| 26 | end | ||
| 27 | |||
| 28 | def encode(subject) | ||
| 29 | quoted_printable(subject, CHARSET) | ||
| 30 | end | ||
| 31 | end |
|   | |||
| 1 | class <%= migration_name %> < ActiveRecord::Migration | ||
| 2 | def self.up | ||
| 3 | create_table "<%= table_name %>", :force => true do |t| | ||
| 4 | t.column :login, :string | ||
| 5 | t.column :email, :string | ||
| 6 | t.column :crypted_password, :string, :limit => 40 | ||
| 7 | t.column :salt, :string, :limit => 40 | ||
| 8 | t.column :created_at, :datetime | ||
| 9 | t.column :updated_at, :datetime | ||
| 10 | t.column :remember_token, :string | ||
| 11 | t.column :remember_token_expires_at, :datetime | ||
| 12 | <% if options[:include_activation] %>t.column :activation_code, :string, :limit => 40 | ||
| 13 | t.column :activated_at, :datetime<% end %> | ||
| 14 | <% if options[:stateful] %>t.column :state, :string, :null => :no, :default => 'passive' | ||
| 15 | t.column :deleted_at, :datetime<% end %> | ||
| 16 | end | ||
| 17 | end | ||
| 18 | |||
| 19 | def self.down | ||
| 20 | drop_table "<%= table_name %>" | ||
| 21 | end | ||
| 22 | end |
|   | |||
| 1 | require 'digest/sha1' | ||
| 2 | class <%= class_name %> < ActiveRecord::Base | ||
| 3 | # Virtual attribute for the unencrypted password | ||
| 4 | attr_accessor :password | ||
| 5 | |||
| 6 | validates_presence_of :login, :email | ||
| 7 | validates_presence_of :password, :if => :password_required? | ||
| 8 | validates_presence_of :password_confirmation, :if => :password_required? | ||
| 9 | validates_length_of :password, :within => 4..40, :if => :password_required? | ||
| 10 | validates_confirmation_of :password, :if => :password_required? | ||
| 11 | validates_length_of :login, :within => 3..40 | ||
| 12 | validates_length_of :email, :within => 3..100 | ||
| 13 | validates_uniqueness_of :login, :email, :case_sensitive => false | ||
| 14 | before_save :encrypt_password | ||
| 15 | <% if options[:include_activation] && !options[:stateful] %>before_create :make_activation_code <% end %> | ||
| 16 | # prevents a user from submitting a crafted form that bypasses activation | ||
| 17 | # anything else you want your user to change should be added here. | ||
| 18 | attr_accessible :login, :email, :password, :password_confirmation | ||
| 19 | <% if options[:stateful] %> | ||
| 20 | acts_as_state_machine :initial => :pending | ||
| 21 | state :passive | ||
| 22 | state :pending, :enter => :make_activation_code | ||
| 23 | state :active, :enter => :do_activate | ||
| 24 | state :suspended | ||
| 25 | state :deleted, :enter => :do_delete | ||
| 26 | |||
| 27 | event :register do | ||
| 28 | transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| !(u.crypted_password.blank? && u.password.blank?) } | ||
| 29 | end | ||
| 30 | |||
| 31 | event :activate do | ||
| 32 | transitions :from => :pending, :to => :active | ||
| 33 | end | ||
| 34 | |||
| 35 | event :suspend do | ||
| 36 | transitions :from => [:passive, :pending, :active], :to => :suspended | ||
| 37 | end | ||
| 38 | |||
| 39 | event :delete do | ||
| 40 | transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted | ||
| 41 | end | ||
| 42 | |||
| 43 | event :unsuspend do | ||
| 44 | transitions :from => :suspended, :to => :active, :guard => Proc.new {|u| !u.activated_at.blank? } | ||
| 45 | transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| !u.activation_code.blank? } | ||
| 46 | transitions :from => :suspended, :to => :passive | ||
| 47 | end | ||
| 48 | <% elsif options[:include_activation] %> | ||
| 49 | # Activates the user in the database. | ||
| 50 | def activate | ||
| 51 | @activated = true | ||
| 52 | self.activated_at = Time.now.utc | ||
| 53 | self.activation_code = nil | ||
| 54 | save(false) | ||
| 55 | end | ||
| 56 | |||
| 57 | def active? | ||
| 58 | # the existence of an activation code means they have not activated yet | ||
| 59 | activation_code.nil? | ||
| 60 | end | ||
| 61 | |||
| 62 | # Returns true if the user has just been activated. | ||
| 63 | def pending? | ||
| 64 | @activated | ||
| 65 | end | ||
| 66 | <% end %> | ||
| 67 | # Authenticates a user by their login name and unencrypted password. Returns the user or nil. | ||
| 68 | def self.authenticate(login, password) | ||
| 69 | u = <% | ||
| 70 | if options[:stateful] %>find_in_state :first, :active, :conditions => {:login => login}<% | ||
| 71 | elsif options[:include_activation] %>find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login]<% | ||
| 72 | else %>find_by_login(login)<% | ||
| 73 | end %> # need to get the salt | ||
| 74 | u && u.authenticated?(password) ? u : nil | ||
| 75 | end | ||
| 76 | |||
| 77 | # Encrypts some data with the salt. | ||
| 78 | def self.encrypt(password, salt) | ||
| 79 | Digest::SHA1.hexdigest("--#{salt}--#{password}--") | ||
| 80 | end | ||
| 81 | |||
| 82 | # Encrypts the password with the user salt | ||
| 83 | def encrypt(password) | ||
| 84 | self.class.encrypt(password, salt) | ||
| 85 | end | ||
| 86 | |||
| 87 | def authenticated?(password) | ||
| 88 | crypted_password == encrypt(password) | ||
| 89 | end | ||
| 90 | |||
| 91 | def remember_token? | ||
| 92 | remember_token_expires_at && Time.now.utc < remember_token_expires_at | ||
| 93 | end | ||
| 94 | |||
| 95 | # These create and unset the fields required for remembering users between browser closes | ||
| 96 | def remember_me | ||
| 97 | remember_me_for 2.weeks | ||
| 98 | end | ||
| 99 | |||
| 100 | def remember_me_for(time) | ||
| 101 | remember_me_until time.from_now.utc | ||
| 102 | end | ||
| 103 | |||
| 104 | def remember_me_until(time) | ||
| 105 | self.remember_token_expires_at = time | ||
| 106 | self.remember_token = encrypt("#{email}--#{remember_token_expires_at}") | ||
| 107 | save(false) | ||
| 108 | end | ||
| 109 | |||
| 110 | def forget_me | ||
| 111 | self.remember_token_expires_at = nil | ||
| 112 | self.remember_token = nil | ||
| 113 | save(false) | ||
| 114 | end | ||
| 115 | |||
| 116 | protected | ||
| 117 | # before filter | ||
| 118 | def encrypt_password | ||
| 119 | return if password.blank? | ||
| 120 | self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? | ||
| 121 | self.crypted_password = encrypt(password) | ||
| 122 | end | ||
| 123 | |||
| 124 | def password_required? | ||
| 125 | crypted_password.blank? || !password.blank? | ||
| 126 | end | ||
| 127 | <% if options[:include_activation] %> | ||
| 128 | def make_activation_code | ||
| 129 | <% if options[:stateful] %> self.deleted_at = nil<% end %> | ||
| 130 | self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join ) | ||
| 131 | end<% end %> | ||
| 132 | <% if options[:stateful] %> | ||
| 133 | def do_delete | ||
| 134 | self.deleted_at = Time.now.utc | ||
| 135 | end | ||
| 136 | |||
| 137 | def do_activate | ||
| 138 | self.activated_at = Time.now.utc | ||
| 139 | self.deleted_at = self.activation_code = nil | ||
| 140 | end<% end %> | ||
| 141 | end |
vendor/plugins/restful_authentication/generators/authenticated/templates/model_controller.rb
(0 / 65)
|   | |||
| 1 | class <%= model_controller_class_name %>Controller < ApplicationController | ||
| 2 | # Be sure to include AuthenticationSystem in Application Controller instead | ||
| 3 | include AuthenticatedSystem | ||
| 4 | <% if options[:stateful] %> | ||
| 5 | # Protect these actions behind an admin login | ||
| 6 | # before_filter :admin_required, :only => [:suspend, :unsuspend, :destroy, :purge] | ||
| 7 | before_filter :find_<%= file_name %>, :only => [:suspend, :unsuspend, :destroy, :purge] | ||
| 8 | <% end %> | ||
| 9 | |||
| 10 | # render new.rhtml | ||
| 11 | def new | ||
| 12 | end | ||
| 13 | |||
| 14 | def create | ||
| 15 | cookies.delete :auth_token | ||
| 16 | # protects against session fixation attacks, wreaks havoc with | ||
| 17 | # request forgery protection. | ||
| 18 | # uncomment at your own risk | ||
| 19 | # reset_session | ||
| 20 | @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>]) | ||
| 21 | @<%= file_name %>.<% if options[:stateful] %>register! if @<%= file_name %>.valid?<% else %>save<% end %> | ||
| 22 | if @<%= file_name %>.errors.empty? | ||
| 23 | self.current_<%= file_name %> = @<%= file_name %> | ||
| 24 | redirect_back_or_default('/') | ||
| 25 | flash[:notice] = "Thanks for signing up!" | ||
| 26 | else | ||
| 27 | render :action => 'new' | ||
| 28 | end | ||
| 29 | end | ||
| 30 | <% if options[:include_activation] %> | ||
| 31 | def activate | ||
| 32 | self.current_<%= file_name %> = params[:activation_code].blank? ? :false : <%= class_name %>.find_by_activation_code(params[:activation_code]) | ||
| 33 | if logged_in? && !current_<%= file_name %>.active? | ||
| 34 | current_<%= file_name %>.activate<% if options[:stateful] %>!<% end %> | ||
| 35 | flash[:notice] = "Signup complete!" | ||
| 36 | end | ||
| 37 | redirect_back_or_default('/') | ||
| 38 | end | ||
| 39 | <% end %><% if options[:stateful] %> | ||
| 40 | def suspend | ||
| 41 | @<%= file_name %>.suspend! | ||
| 42 | redirect_to <%= table_name %>_path | ||
| 43 | end | ||
| 44 | |||
| 45 | def unsuspend | ||
| 46 | @<%= file_name %>.unsuspend! | ||
| 47 | redirect_to <%= table_name %>_path | ||
| 48 | end | ||
| 49 | |||
| 50 | def destroy | ||
| 51 | @<%= file_name %>.delete! | ||
| 52 | redirect_to <%= table_name %>_path | ||
| 53 | end | ||
| 54 | |||
| 55 | def purge | ||
| 56 | @<%= file_name %>.destroy | ||
| 57 | redirect_to <%= table_name %>_path | ||
| 58 | end | ||
| 59 | |||
| 60 | protected | ||
| 61 | def find_<%= file_name %> | ||
| 62 | @<%= file_name %> = <%= class_name %>.find(params[:id]) | ||
| 63 | end | ||
| 64 | <% end %> | ||
| 65 | end |
vendor/plugins/restful_authentication/generators/authenticated/templates/model_functional_spec.rb
(0 / 84)
|   | |||
| 1 | require File.dirname(__FILE__) + '/../spec_helper' | ||
| 2 | |||
| 3 | # Be sure to include AuthenticatedTestHelper in spec/spec_helper.rb instead | ||
| 4 | # Then, you can remove it from this and the units test. | ||
| 5 | include AuthenticatedTestHelper | ||
| 6 | |||
| 7 | describe <%= model_controller_class_name %>Controller do | ||
| 8 | fixtures :<%= table_name %> | ||
| 9 | |||
| 10 | it 'allows signup' do | ||
| 11 | lambda do | ||
| 12 | create_<%= file_name %> | ||
| 13 | response.should be_redirect | ||
| 14 | end.should change(<%= class_name %>, :count).by(1) | ||
| 15 | end | ||
| 16 | |||
| 17 | <% if options[:stateful] %> | ||
| 18 | it 'signs up user in pending state' do | ||
| 19 | create_user | ||
| 20 | assigns(:user).should be_pending | ||
| 21 | end<% end %> | ||
| 22 | |||
| 23 | <% if options[:include_activation] %> | ||
| 24 | it 'signs up user with activation code' do | ||
| 25 | create_user | ||
| 26 | assigns(:user).activation_code.should_not be_nil | ||
| 27 | end<% end %> | ||
| 28 | |||
| 29 | it 'requires login on signup' do | ||
| 30 | lambda do | ||
| 31 | create_<%= file_name %>(:login => nil) | ||
| 32 | assigns[:<%= file_name %>].errors.on(:login).should_not be_nil | ||
| 33 | response.should be_success | ||
| 34 | end.should_not change(<%= class_name %>, :count) | ||
| 35 | end | ||
| 36 | |||
| 37 | it 'requires password on signup' do | ||
| 38 | lambda do | ||
| 39 | create_<%= file_name %>(:password => nil) | ||
| 40 | assigns[:<%= file_name %>].errors.on(:password).should_not be_nil | ||
| 41 | response.should be_success | ||
| 42 | end.should_not change(<%= class_name %>, :count) | ||
| 43 | end | ||
| 44 | |||
| 45 | it 'requires password confirmation on signup' do | ||
| 46 | lambda do | ||
| 47 | create_<%= file_name %>(:password_confirmation => nil) | ||
| 48 | assigns[:<%= file_name %>].errors.on(:password_confirmation).should_not be_nil | ||
| 49 | response.should be_success | ||
| 50 | end.should_not change(<%= class_name %>, :count) | ||
| 51 | end | ||
| 52 | |||
| 53 | it 'requires email on signup' do | ||
| 54 | lambda do | ||
| 55 | create_<%= file_name %>(:email => nil) | ||
| 56 | assigns[:<%= file_name %>].errors.on(:email).should_not be_nil | ||
| 57 | response.should be_success | ||
| 58 | end.should_not change(<%= class_name %>, :count) | ||
| 59 | end | ||
| 60 | |||
| 61 | <% if options[:include_activation] %> | ||
| 62 | it 'activates user' do | ||
| 63 | <%= class_name %>.authenticate('aaron', 'test').should be_nil | ||
| 64 | get :activate, :activation_code => <%= table_name %>(:aaron).activation_code | ||
| 65 | response.should redirect_to('/') | ||
| 66 | flash[:notice].should_not be_nil | ||
| 67 | <%= class_name %>.authenticate('aaron', 'test').should == <%= table_name %>(:aaron) | ||
| 68 | end | ||
| 69 | |||
| 70 | it 'does not activate user without key' do | ||
| 71 | get :activate | ||
| 72 | flash[:notice].should be_nil | ||
| 73 | end | ||
| 74 | |||
| 75 | it 'does not activate user with blank key' do | ||
| 76 | get :activate, :activation_code => '' | ||
| 77 | flash[:notice].should be_nil | ||
| 78 | end<% end %> | ||
| 79 | |||
| 80 | def create_<%= file_name %>(options = {}) | ||
| 81 | post :create, :<%= file_name %> => { :login => 'quire', :email => 'quire@example.com', | ||
| 82 | :password => 'quire', :password_confirmation => 'quire' }.merge(options) | ||
| 83 | end | ||
| 84 | end |
vendor/plugins/restful_authentication/generators/authenticated/templates/model_functional_test.rb
(0 / 86)
|   | |||
| 1 | require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | require '<%= model_controller_file_name %>_controller' | ||
| 3 | |||
| 4 | # Re-raise errors caught by the controller. | ||
| 5 | class <%= model_controller_class_name %>Controller; def rescue_action(e) raise e end; end | ||
| 6 | |||
| 7 | class <%= model_controller_class_name %>ControllerTest < Test::Unit::TestCase | ||
| 8 | # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead | ||
| 9 | # Then, you can remove it from this and the units test. | ||
| 10 | include AuthenticatedTestHelper | ||
| 11 | |||
| 12 | fixtures :<%= table_name %> | ||
| 13 | |||
| 14 | def setup | ||
| 15 | @controller = <%= model_controller_class_name %>Controller.new | ||
| 16 | @request = ActionController::TestRequest.new | ||
| 17 | @response = ActionController::TestResponse.new | ||
| 18 | end | ||
| 19 | |||
| 20 | def test_should_allow_signup | ||
| 21 | assert_difference '<%= class_name %>.count' do | ||
| 22 | create_<%= file_name %> | ||
| 23 | assert_response :redirect | ||
| 24 | end | ||
| 25 | end | ||
| 26 | |||
| 27 | def test_should_require_login_on_signup | ||
| 28 | assert_no_difference '<%= class_name %>.count' do | ||
| 29 | create_<%= file_name %>(:login => nil) | ||
| 30 | assert assigns(:<%= file_name %>).errors.on(:login) | ||
| 31 | assert_response :success | ||
| 32 | end | ||
| 33 | end | ||
| 34 | |||
| 35 | def test_should_require_password_on_signup | ||
| 36 | assert_no_difference '<%= class_name %>.count' do | ||
| 37 | create_<%= file_name %>(:password => nil) | ||
| 38 | assert assigns(:<%= file_name %>).errors.on(:password) | ||
| 39 | assert_response :success | ||
| 40 | end | ||
| 41 | end | ||
| 42 | |||
| 43 | def test_should_require_password_confirmation_on_signup | ||
| 44 | assert_no_difference '<%= class_name %>.count' do | ||
| 45 | create_<%= file_name %>(:password_confirmation => nil) | ||
| 46 | assert assigns(:<%= file_name %>).errors.on(:password_confirmation) | ||
| 47 | assert_response :success | ||
| 48 | end | ||
| 49 | end | ||
| 50 | |||
| 51 | def test_should_require_email_on_signup | ||
| 52 | assert_no_difference '<%= class_name %>.count' do | ||
| 53 | create_<%= file_name %>(:email => nil) | ||
| 54 | assert assigns(:<%= file_name %>).errors.on(:email) | ||
| 55 | assert_response :success | ||
| 56 | end | ||
| 57 | end | ||
| 58 | <% if options[:include_activation] %> | ||
| 59 | def test_should_activate_user | ||
| 60 | assert_nil <%= class_name %>.authenticate('aaron', 'test') | ||
| 61 | get :activate, :activation_code => <%= table_name %>(:aaron).activation_code | ||
| 62 | assert_redirected_to '/' | ||
| 63 | assert_not_nil flash[:notice] | ||
| 64 | assert_equal <%= table_name %>(:aaron), <%= class_name %>.authenticate('aaron', 'test') | ||
| 65 | end | ||
| 66 | |||
| 67 | def test_should_not_activate_user_without_key | ||
| 68 | get :activate | ||
| 69 | assert_nil flash[:notice] | ||
| 70 | rescue ActionController::RoutingError | ||
| 71 | # in the event your routes deny this, we'll just bow out gracefully. | ||
| 72 | end | ||
| 73 | |||
| 74 | def test_should_not_activate_user_with_blank_key | ||
| 75 | get :activate, :activation_code => '' | ||
| 76 | assert_nil flash[:notice] | ||
| 77 | rescue ActionController::RoutingError | ||
| 78 | # well played, sir | ||
| 79 | end<% end %> | ||
| 80 | |||
| 81 | protected | ||
| 82 | def create_<%= file_name %>(options = {}) | ||
| 83 | post :create, :<%= file_name %> => { :login => 'quire', :email => 'quire@example.com', | ||
| 84 | :password => 'quire', :password_confirmation => 'quire' }.merge(options) | ||
| 85 | end | ||
| 86 | end |
|   | |||
| 1 | module <%= model_controller_class_name %>Helper | ||
| 2 | end |
|   | |||
| 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 %>.pending? | ||
| 9 | <% end %> | ||
| 10 | end | ||
| 11 | end |
|   | |||
| 1 | <%%= error_messages_for :<%= file_name %> %> | ||
| 2 | <%% form_for :<%= file_name %>, :url => <%= table_name %>_path do |f| -%> | ||
| 3 | <p><label for="login">Login</label><br/> | ||
| 4 | <%%= f.text_field :login %></p> | ||
| 5 | |||
| 6 | <p><label for="email">Email</label><br/> | ||
| 7 | <%%= f.text_field :email %></p> | ||
| 8 | |||
| 9 | <p><label for="password">Password</label><br/> | ||
| 10 | <%%= f.password_field :password %></p> | ||
| 11 | |||
| 12 | <p><label for="password_confirmation">Confirm Password</label><br/> | ||
| 13 | <%%= f.password_field :password_confirmation %></p> | ||
| 14 | |||
| 15 | <p><%%= submit_tag 'Sign up' %></p> | ||
| 16 | <%% end -%> |
|   | |||
| 1 | Your account has been created. | ||
| 2 | |||
| 3 | Username: <%%= @<%= file_name %>.login %> | ||
| 4 | Password: <%%= @<%= file_name %>.password %> | ||
| 5 | |||
| 6 | Visit this url to activate your account: | ||
| 7 | |||
| 8 | <%%= @url %> |
|   | |||
| 1 | require File.dirname(__FILE__) + '/../spec_helper' | ||
| 2 | |||
| 3 | # Be sure to include AuthenticatedTestHelper in spec/spec_helper.rb instead. | ||
| 4 | # Then, you can remove it from this and the functional test. | ||
| 5 | include AuthenticatedTestHelper | ||
| 6 | |||
| 7 | describe <%= class_name %> do | ||
| 8 | fixtures :<%= table_name %> | ||
| 9 | |||
| 10 | describe 'being created' do | ||
| 11 | before do | ||
| 12 | @<%= file_name %> = nil | ||
| 13 | @creating_<%= file_name %> = lambda do | ||
| 14 | @<%= file_name %> = create_<%= file_name %> | ||
| 15 | violated "#{@<%= file_name %>.errors.full_messages.to_sentence}" if @<%= file_name %>.new_record? | ||
| 16 | end | ||
| 17 | end | ||
| 18 | |||
| 19 | it 'increments User#count' do | ||
| 20 | @creating_<%= file_name %>.should change(<%= class_name %>, :count).by(1) | ||
| 21 | end | ||
| 22 | <% if options[:include_activation] %> | ||
| 23 | it 'initializes #activation_code' do | ||
| 24 | @creating_<%= file_name %>.call | ||
| 25 | @<%= file_name %>.reload.activation_code.should_not be_nil | ||
| 26 | end | ||
| 27 | <% end %><% if options[:stateful] %> | ||
| 28 | it 'starts in pending state' do | ||
| 29 | @creating_<%= file_name %>.call | ||
| 30 | @<%= file_name %>.should be_pending | ||
| 31 | end | ||
| 32 | <% end %> end | ||
| 33 | |||
| 34 | it 'requires login' do | ||
| 35 | lambda do | ||
| 36 | u = create_<%= file_name %>(:login => nil) | ||
| 37 | u.errors.on(:login).should_not be_nil | ||
| 38 | end.should_not change(<%= class_name %>, :count) | ||
| 39 | end | ||
| 40 | |||
| 41 | it 'requires password' do | ||
| 42 | lambda do | ||
| 43 | u = create_<%= file_name %>(:password => nil) | ||
| 44 | u.errors.on(:password).should_not be_nil | ||
| 45 | end.should_not change(<%= class_name %>, :count) | ||
| 46 | end | ||
| 47 | |||
| 48 | it 'requires password confirmation' do | ||
| 49 | lambda do | ||
| 50 | u = create_<%= file_name %>(:password_confirmation => nil) | ||
| 51 | u.errors.on(:password_confirmation).should_not be_nil | ||
| 52 | end.should_not change(<%= class_name %>, :count) | ||
| 53 | end | ||
| 54 | |||
| 55 | it 'requires email' do | ||
| 56 | lambda do | ||
| 57 | u = create_<%= file_name %>(:email => nil) | ||
| 58 | u.errors.on(:email).should_not be_nil | ||
| 59 | end.should_not change(<%= class_name %>, :count) | ||
| 60 | end | ||
| 61 | |||
| 62 | it 'resets password' do | ||
| 63 | <%= table_name %>(:quentin).update_attributes(:password => 'new password', :password_confirmation => 'new password') | ||
| 64 | <%= class_name %>.authenticate('quentin', 'new password').should == <%= table_name %>(:quentin) | ||
| 65 | end | ||
| 66 | |||
| 67 | it 'does not rehash password' do | ||
| 68 | <%= table_name %>(:quentin).update_attributes(:login => 'quentin2') | ||
| 69 | <%= class_name %>.authenticate('quentin2', 'test').should == <%= table_name %>(:quentin) | ||
| 70 | end | ||
| 71 | |||
| 72 | it 'authenticates <%= file_name %>' do | ||
| 73 | <%= class_name %>.authenticate('quentin', 'test').should == <%= table_name %>(:quentin) | ||
| 74 | end | ||
| 75 | |||
| 76 | it 'sets remember token' do | ||
| 77 | <%= table_name %>(:quentin).remember_me | ||
| 78 | <%= table_name %>(:quentin).remember_token.should_not be_nil | ||
| 79 | <%= table_name %>(:quentin).remember_token_expires_at.should_not be_nil | ||
| 80 | end | ||
| 81 | |||
| 82 | it 'unsets remember token' do | ||
| 83 | <%= table_name %>(:quentin).remember_me | ||
| 84 | <%= table_name %>(:quentin).remember_token.should_not be_nil | ||
| 85 | <%= table_name %>(:quentin).forget_me | ||
| 86 | <%= table_name %>(:quentin).remember_token.should be_nil | ||
| 87 | end | ||
| 88 | |||
| 89 | it 'remembers me for one week' do | ||
| 90 | before = 1.week.from_now.utc | ||
| 91 | <%= table_name %>(:quentin).remember_me_for 1.week | ||
| 92 | after = 1.week.from_now.utc | ||
| 93 | <%= table_name %>(:quentin).remember_token.should_not be_nil | ||
| 94 | <%= table_name %>(:quentin).remember_token_expires_at.should_not be_nil | ||
| 95 | <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after).should be_true | ||
| 96 | end | ||
| 97 | |||
| 98 | it 'remembers me until one week' do | ||
| 99 | time = 1.week.from_now.utc | ||
| 100 | <%= table_name %>(:quentin).remember_me_until time | ||
| 101 | <%= table_name %>(:quentin).remember_token.should_not be_nil | ||
| 102 | <%= table_name %>(:quentin).remember_token_expires_at.should_not be_nil | ||
| 103 | <%= table_name %>(:quentin).remember_token_expires_at.should == time | ||
| 104 | end | ||
| 105 | |||
| 106 | it 'remembers me default two weeks' do | ||
| 107 | before = 2.weeks.from_now.utc | ||
| 108 | <%= table_name %>(:quentin).remember_me | ||
| 109 | after = 2.weeks.from_now.utc | ||
| 110 | <%= table_name %>(:quentin).remember_token.should_not be_nil | ||
| 111 | <%= table_name %>(:quentin).remember_token_expires_at.should_not be_nil | ||
| 112 | <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after).should be_true | ||
| 113 | end | ||
| 114 | <% if options[:stateful] %> | ||
| 115 | it 'registers passive <%= file_name %>' do | ||
| 116 | <%= file_name %> = create_<%= file_name %>(:password => nil, :password_confirmation => nil) | ||
| 117 | <%= file_name %>.should be_passive | ||
| 118 | <%= file_name %>.update_attributes(:password => 'new password', :password_confirmation => 'new password') | ||
| 119 | <%= file_name %>.register! | ||
| 120 | <%= file_name %>.should be_pending | ||
| 121 | end | ||
| 122 | |||
| 123 | it 'suspends <%= file_name %>' do | ||
| 124 | <%= table_name %>(:quentin).suspend! | ||
| 125 | <%= table_name %>(:quentin).should be_suspended | ||
| 126 | end | ||
| 127 | |||
| 128 | it 'does not authenticate suspended <%= file_name %>' do | ||
| 129 | <%= table_name %>(:quentin).suspend! | ||
| 130 | <%= class_name %>.authenticate('quentin', 'test').should_not == <%= table_name %>(:quentin) | ||
| 131 | end | ||
| 132 | |||
| 133 | it 'deletes <%= file_name %>' do | ||
| 134 | <%= table_name %>(:quentin).deleted_at.should be_nil | ||
| 135 | <%= table_name %>(:quentin).delete! | ||
| 136 | <%= table_name %>(:quentin).deleted_at.should_not be_nil | ||
| 137 | <%= table_name %>(:quentin).should be_deleted | ||
| 138 | end | ||
| 139 | |||
| 140 | describe "being unsuspended" do | ||
| 141 | fixtures :<%= table_name %> | ||
| 142 | |||
| 143 | before do | ||
| 144 | @<%= file_name %> = <%= table_name %>(:quentin) | ||
| 145 | @<%= file_name %>.suspend! | ||
| 146 | end | ||
| 147 | |||
| 148 | it 'reverts to active state' do | ||
| 149 | @<%= file_name %>.unsuspend! | ||
| 150 | @<%= file_name %>.should be_active | ||
| 151 | end | ||
| 152 | |||
| 153 | it 'reverts to passive state if activation_code and activated_at are nil' do | ||
| 154 | <%= class_name %>.update_all :activation_code => nil, :activated_at => nil | ||
| 155 | @<%= file_name %>.reload.unsuspend! | ||
| 156 | @<%= file_name %>.should be_passive | ||
| 157 | end | ||
| 158 | |||
| 159 | it 'reverts to pending state if activation_code is set and activated_at is nil' do | ||
| 160 | <%= class_name %>.update_all :activation_code => 'foo-bar', :activated_at => nil | ||
| 161 | @<%= file_name %>.reload.unsuspend! | ||
| 162 | @<%= file_name %>.should be_pending | ||
| 163 | end | ||
| 164 | end | ||
| 165 | <% end %> | ||
| 166 | protected | ||
| 167 | def create_<%= file_name %>(options = {}) | ||
| 168 | record = <%= class_name %>.new({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) | ||
| 169 | record.<% if options[:stateful] %>register! if record.valid?<% else %>save<% end %> | ||
| 170 | record | ||
| 171 | end | ||
| 172 | end |
|   | |||
| 1 | require File.dirname(__FILE__) + '/../test_helper' | ||
| 2 | |||
| 3 | class <%= class_name %>Test < Test::Unit::TestCase | ||
| 4 | # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead. | ||
| 5 | # Then, you can remove it from this and the functional test. | ||
| 6 | include AuthenticatedTestHelper | ||
| 7 | fixtures :<%= table_name %> | ||
| 8 | |||
| 9 | def test_should_create_<%= file_name %> | ||
| 10 | assert_difference '<%= class_name %>.count' do | ||
| 11 | <%= file_name %> = create_<%= file_name %> | ||
| 12 | assert !<%= file_name %>.new_record?, "#{<%= file_name %>.errors.full_messages.to_sentence}" | ||
| 13 | end | ||
| 14 | end | ||
| 15 | <% if options[:include_activation] %> | ||
| 16 | def test_should_initialize_activation_code_upon_creation | ||
| 17 | <%= file_name %> = create_<%= file_name %> | ||
| 18 | assert_not_nil <%= file_name %>.reload.activation_code | ||
| 19 | end | ||
| 20 | <% end %><% if options[:stateful] %> | ||
| 21 | def test_should_create_and_start_in_pending_state | ||
| 22 | <%= file_name %> = create_<%= file_name %> | ||
| 23 | assert <%= file_name %>.pending? | ||
| 24 | end | ||
| 25 | |||
| 26 | <% end %> | ||
| 27 | def test_should_require_login | ||
| 28 | assert_no_difference '<%= class_name %>.count' do | ||
| 29 | u = create_<%= file_name %>(:login => nil) | ||
| 30 | assert u.errors.on(:login) | ||
| 31 | end | ||
| 32 | end | ||
| 33 | |||
| 34 | def test_should_require_password | ||
| 35 | assert_no_difference '<%= class_name %>.count' do | ||
| 36 | u = create_<%= file_name %>(:password => nil) | ||
| 37 | assert u.errors.on(:password) | ||
| 38 | end | ||
| 39 | end | ||
| 40 | |||
| 41 | def test_should_require_password_confirmation | ||
| 42 | assert_no_difference '<%= class_name %>.count' do | ||
| 43 | u = create_<%= file_name %>(:password_confirmation => nil) | ||
| 44 | assert u.errors.on(:password_confirmation) | ||
| 45 | end | ||
| 46 | end | ||
| 47 | |||
| 48 | def test_should_require_email | ||
| 49 | assert_no_difference '<%= class_name %>.count' do | ||
| 50 | u = create_<%= file_name %>(:email => nil) | ||
| 51 | assert u.errors.on(:email) | ||
| 52 | end | ||
| 53 | end | ||
| 54 | |||
| 55 | def test_should_reset_password | ||
| 56 | <%= table_name %>(:quentin).update_attributes(:password => 'new password', :password_confirmation => 'new password') | ||
| 57 | assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin', 'new password') | ||
| 58 | end | ||
| 59 | |||
| 60 | def test_should_not_rehash_password | ||
| 61 | <%= table_name %>(:quentin).update_attributes(:login => 'quentin2') | ||
| 62 | assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin2', 'test') | ||
| 63 | end | ||
| 64 | |||
| 65 | def test_should_authenticate_<%= file_name %> | ||
| 66 | assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin', 'test') | ||
| 67 | end | ||
| 68 | |||
| 69 | def test_should_set_remember_token | ||
| 70 | <%= table_name %>(:quentin).remember_me | ||
| 71 | assert_not_nil <%= table_name %>(:quentin).remember_token | ||
| 72 | assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at | ||
| 73 | end | ||
| 74 | |||
| 75 | def test_should_unset_remember_token | ||
| 76 | <%= table_name %>(:quentin).remember_me | ||
| 77 | assert_not_nil <%= table_name %>(:quentin).remember_token | ||
| 78 | <%= table_name %>(:quentin).forget_me | ||
| 79 | assert_nil <%= table_name %>(:quentin).remember_token | ||
| 80 | end | ||
| 81 | |||
| 82 | def test_should_remember_me_for_one_week | ||
| 83 | before = 1.week.from_now.utc | ||
| 84 | <%= table_name %>(:quentin).remember_me_for 1.week | ||
| 85 | after = 1.week.from_now.utc | ||
| 86 | assert_not_nil <%= table_name %>(:quentin).remember_token | ||
| 87 | assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at | ||
| 88 | assert <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after) | ||
| 89 | end | ||
| 90 | |||
| 91 | def test_should_remember_me_until_one_week | ||
| 92 | time = 1.week.from_now.utc | ||
| 93 | <%= table_name %>(:quentin).remember_me_until time | ||
| 94 | assert_not_nil <%= table_name %>(:quentin).remember_token | ||
| 95 | assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at | ||
| 96 | assert_equal <%= table_name %>(:quentin).remember_token_expires_at, time | ||
| 97 | end | ||
| 98 | |||
| 99 | def test_should_remember_me_default_two_weeks | ||
| 100 | before = 2.weeks.from_now.utc | ||
| 101 | <%= table_name %>(:quentin).remember_me | ||
| 102 | after = 2.weeks.from_now.utc | ||
| 103 | assert_not_nil <%= table_name %>(:quentin).remember_token | ||
| 104 | assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at | ||
| 105 | assert <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after) | ||
| 106 | end | ||
| 107 | <% if options[:stateful] %> | ||
| 108 | def test_should_register_passive_<%= file_name %> | ||
| 109 | <%= file_name %> = create_<%= file_name %>(:password => nil, :password_confirmation => nil) | ||
| 110 | assert <%= file_name %>.passive? | ||
| 111 | <%= file_name %>.update_attributes(:password => 'new password', :password_confirmation => 'new password') | ||
| 112 | <%= file_name %>.register! | ||
| 113 | assert <%= file_name %>.pending? | ||
| 114 | end | ||
| 115 | |||
| 116 | def test_should_suspend_<%= file_name %> | ||
| 117 | <%= table_name %>(:quentin).suspend! | ||
| 118 | assert <%= table_name %>(:quentin).suspended? | ||
| 119 | end | ||
| 120 | |||
| 121 | def test_suspended_<%= file_name %>_should_not_authenticate | ||
| 122 | <%= table_name %>(:quentin).suspend! | ||
| 123 | assert_not_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin', 'test') | ||
| 124 | end | ||
| 125 | |||
| 126 | def test_should_unsuspend_<%= file_name %>_to_active_state | ||
| 127 | <%= table_name %>(:quentin).suspend! | ||
| 128 | assert <%= table_name %>(:quentin).suspended? | ||
| 129 | <%= table_name %>(:quentin).unsuspend! | ||
| 130 | assert <%= table_name %>(:quentin).active? | ||
| 131 | end | ||
| 132 | |||
| 133 | def test_should_unsuspend_<%= file_name %>_with_nil_activation_code_and_activated_at_to_passive_state | ||
| 134 | <%= table_name %>(:quentin).suspend! | ||
| 135 | <%= class_name %>.update_all :activation_code => nil, :activated_at => nil | ||
| 136 | assert <%= table_name %>(:quentin).suspended? | ||
| 137 | <%= table_name %>(:quentin).reload.unsuspend! | ||
| 138 | assert <%= table_name %>(:quentin).passive? | ||
| 139 | end | ||
| 140 | |||
| 141 | def test_should_unsuspend_<%= file_name %>_with_activation_code_and_nil_activated_at_to_pending_state | ||
| 142 | <%= table_name %>(:quentin).suspend! | ||
| 143 | <%= class_name %>.update_all :activation_code => 'foo-bar', :activated_at => nil | ||
| 144 | assert <%= table_name %>(:quentin).suspended? | ||
| 145 | <%= table_name %>(:quentin).reload.unsuspend! | ||
| 146 | assert <%= table_name %>(:quentin).pending? | ||
| 147 | end | ||
| 148 | |||
| 149 | def test_should_delete_<%= file_name %> | ||
| 150 | assert_nil <%= table_name %>(:quentin).deleted_at | ||
| 151 | <%= table_name %>(:quentin).delete! | ||
| 152 | assert_not_nil <%= table_name %>(:quentin).deleted_at | ||
| 153 | assert <%= table_name %>(:quentin).deleted? | ||
| 154 | end | ||
| 155 | <% end %> | ||
| 156 | protected | ||
| 157 | def create_<%= file_name %>(options = {}) | ||
| 158 | <%= class_name %>.create({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) | ||
| 159 | end | ||
| 160 | end |
|   | |||
| 1 | puts IO.read(File.join(File.dirname(__FILE__), 'README')) |
|   | |||
| 1 | Rails::Generator::Commands::Create.class_eval do | ||
| 2 | def route_resource(*resources) | ||
| 3 | resource_list = resources.map { |r| r.to_sym.inspect }.join(', ') | ||
| 4 | sentinel = 'ActionController::Routing::Routes.draw do |map|' | ||
| 5 | |||
| 6 | logger.route "map.resource #{resource_list}" | ||
| 7 | unless options[:pretend] | ||
| 8 | gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match| | ||
| 9 | "#{match}\n map.resource #{resource_list}\n" | ||
| 10 | end | ||
| 11 | end | ||
| 12 | end | ||
| 13 | end | ||
| 14 | |||
| 15 | Rails::Generator::Commands::Destroy.class_eval do | ||
| 16 | def route_resource(*resources) | ||
| 17 | resource_list = resources.map { |r| r.to_sym.inspect }.join(', ') | ||
| 18 | look_for = "\n map.resource #{resource_list}\n" | ||
| 19 | logger.route "map.resource #{resource_list}" | ||
| 20 | gsub_file 'config/routes.rb', /(#{look_for})/mi, '' | ||
| 21 | end | ||
| 22 | end | ||
| 23 | |||
| 24 | Rails::Generator::Commands::List.class_eval do | ||
| 25 | def route_resource(*resources) | ||
| 26 | resource_list = resources.map { |r| r.to_sym.inspect }.join(', ') | ||
| 27 | logger.route "map.resource #{resource_list}" | ||
| 28 | end | ||
| 29 | end |

