# HG changeset patch # User moriq@moriq.com # Date 1204647461 -32400 # Node ID 43c5e6930eee7d9f148199fe08ac31f19ac06ee2 # Parent 584d445b6069924f828dc33739d0904160a44bc4 add plugin restful_authentication. --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/README Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,51 @@ +Restful Authentication Generator +==== + +This is a basic restful authentication generator for rails, taken +from acts as authenticated. Currently it requires Rails 1.2.6 or above. + +To use: + + ./script/generate authenticated user sessions \ + --include-activation \ + --stateful + +The first parameter specifies the model that gets created in signup +(typically a user or account model). A model with migration is +created, as well as a basic controller with the create method. + +The second parameter specifies the sessions controller name. This is +the controller that handles the actual login/logout function on the +site. + +The third parameter (--include-activation) generates the code for a +ActionMailer and its respective Activation Code through email. + +The fourth (--stateful) builds in support for acts_as_state_machine +and generates activation code. This was taken from: + +http://www.vaporbase.com/postings/stateful_authentication + +You can pass --skip-migration to skip the user migration. + +If you're using acts_as_state_machine, define your users resource like this: + + map.resources :users, :member => { :suspend => :put, + :unsuspend => :put, + :purge => :delete } + +Also, add an observer to config/environment.rb if you chose the +--include-activation option + + config.active_record.observers = :user_observer # or whatever you + # named your model + +Security Alert +==== + +I introduced a change to the model controller that's been tripping +folks up on Rails 2.0. The change was added as a suggestion to help +combat session fixation attacks. However, this resets the Form +Authentication token used by Request Forgery Protection. I've left +it out now, since Rails 1.2.6 and Rails 2.0 will both stop session +fixation attacks anyway. \ No newline at end of file --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/Rakefile Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,22 @@ +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' + +desc 'Default: run unit tests.' +task :default => :test + +desc 'Test the restful_authentication plugin.' +Rake::TestTask.new(:test) do |t| + t.libs << 'lib' + t.pattern = 'test/**/*_test.rb' + t.verbose = true +end + +desc 'Generate documentation for the restful_authentication plugin.' +Rake::RDocTask.new(:rdoc) do |rdoc| + rdoc.rdoc_dir = 'rdoc' + rdoc.title = 'RestfulAuthentication' + rdoc.options << '--line-numbers' << '--inline-source' + rdoc.rdoc_files.include('README') + rdoc.rdoc_files.include('lib/**/*.rb') +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/USAGE Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,1 @@ +./script/generate authenticated USERMODEL CONTROLLERNAME \ No newline at end of file --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/authenticated_generator.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,262 @@ +require 'restful_authentication/rails_commands' +class AuthenticatedGenerator < Rails::Generator::NamedBase + default_options :skip_migration => false, + :include_activation => false + + attr_reader :controller_name, + :controller_class_path, + :controller_file_path, + :controller_class_nesting, + :controller_class_nesting_depth, + :controller_class_name, + :controller_singular_name, + :controller_plural_name, + :controller_file_name + alias_method :controller_table_name, :controller_plural_name + attr_reader :model_controller_name, + :model_controller_class_path, + :model_controller_file_path, + :model_controller_class_nesting, + :model_controller_class_nesting_depth, + :model_controller_class_name, + :model_controller_singular_name, + :model_controller_plural_name + alias_method :model_controller_file_name, :model_controller_singular_name + alias_method :model_controller_table_name, :model_controller_plural_name + + def initialize(runtime_args, runtime_options = {}) + super + + @rspec = has_rspec? + + @controller_name = args.shift || 'sessions' + @model_controller_name = @name.pluralize + + # sessions controller + base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name) + @controller_class_name_without_nesting, @controller_file_name, @controller_plural_name = inflect_names(base_name) + @controller_singular_name = @controller_file_name.singularize + + if @controller_class_nesting.empty? + @controller_class_name = @controller_class_name_without_nesting + else + @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}" + end + + # model controller + base_name, @model_controller_class_path, @model_controller_file_path, @model_controller_class_nesting, @model_controller_class_nesting_depth = extract_modules(@model_controller_name) + @model_controller_class_name_without_nesting, @model_controller_singular_name, @model_controller_plural_name = inflect_names(base_name) + + if @model_controller_class_nesting.empty? + @model_controller_class_name = @model_controller_class_name_without_nesting + else + @model_controller_class_name = "#{@model_controller_class_nesting}::#{@model_controller_class_name_without_nesting}" + end + end + + def manifest + recorded_session = record do |m| + # Check for class naming collisions. + m.class_collisions controller_class_path, "#{controller_class_name}Controller", # Sessions Controller + "#{controller_class_name}Helper" + m.class_collisions model_controller_class_path, "#{model_controller_class_name}Controller", # Model Controller + "#{model_controller_class_name}Helper" + m.class_collisions class_path, "#{class_name}", "#{class_name}Mailer", "#{class_name}MailerTest", "#{class_name}Observer" + m.class_collisions [], 'AuthenticatedSystem', 'AuthenticatedTestHelper' + + # Controller, helper, views, and test directories. + m.directory File.join('app/models', class_path) + m.directory File.join('app/controllers', controller_class_path) + m.directory File.join('app/controllers', model_controller_class_path) + m.directory File.join('app/helpers', controller_class_path) + m.directory File.join('app/views', controller_class_path, controller_file_name) + m.directory File.join('app/views', class_path, "#{file_name}_mailer") if options[:include_activation] + + m.directory File.join('app/controllers', model_controller_class_path) + m.directory File.join('app/helpers', model_controller_class_path) + m.directory File.join('app/views', model_controller_class_path, model_controller_file_name) + + if @rspec + m.directory File.join('spec/controllers', controller_class_path) + m.directory File.join('spec/controllers', model_controller_class_path) + m.directory File.join('spec/models', class_path) + m.directory File.join('spec/fixtures', class_path) + else + m.directory File.join('test/functional', controller_class_path) + m.directory File.join('test/functional', model_controller_class_path) + m.directory File.join('test/unit', class_path) + end + + m.template 'model.rb', + File.join('app/models', + class_path, + "#{file_name}.rb") + + if options[:include_activation] + %w( mailer observer ).each do |model_type| + m.template "#{model_type}.rb", File.join('app/models', + class_path, + "#{file_name}_#{model_type}.rb") + end + end + + m.template 'controller.rb', + File.join('app/controllers', + controller_class_path, + "#{controller_file_name}_controller.rb") + + m.template 'model_controller.rb', + File.join('app/controllers', + model_controller_class_path, + "#{model_controller_file_name}_controller.rb") + + m.template 'authenticated_system.rb', + File.join('lib', 'authenticated_system.rb') + + m.template 'authenticated_test_helper.rb', + File.join('lib', 'authenticated_test_helper.rb') + + if @rspec + m.template 'functional_spec.rb', + File.join('spec/controllers', + controller_class_path, + "#{controller_file_name}_controller_spec.rb") + m.template 'model_functional_spec.rb', + File.join('spec/controllers', + model_controller_class_path, + "#{model_controller_file_name}_controller_spec.rb") + m.template 'unit_spec.rb', + File.join('spec/models', + class_path, + "#{file_name}_spec.rb") + m.template 'fixtures.yml', + File.join('spec/fixtures', + "#{table_name}.yml") + else + m.template 'functional_test.rb', + File.join('test/functional', + controller_class_path, + "#{controller_file_name}_controller_test.rb") + m.template 'model_functional_test.rb', + File.join('test/functional', + model_controller_class_path, + "#{model_controller_file_name}_controller_test.rb") + m.template 'unit_test.rb', + File.join('test/unit', + class_path, + "#{file_name}_test.rb") + if options[:include_activation] + m.template 'mailer_test.rb', File.join('test/unit', class_path, "#{file_name}_mailer_test.rb") + end + m.template 'fixtures.yml', + File.join('test/fixtures', + "#{table_name}.yml") + end + + m.template 'helper.rb', + File.join('app/helpers', + controller_class_path, + "#{controller_file_name}_helper.rb") + + m.template 'model_helper.rb', + File.join('app/helpers', + model_controller_class_path, + "#{model_controller_file_name}_helper.rb") + + + # Controller templates + m.template 'login.html.erb', File.join('app/views', controller_class_path, controller_file_name, "new.html.erb") + m.template 'signup.html.erb', File.join('app/views', model_controller_class_path, model_controller_file_name, "new.html.erb") + + if options[:include_activation] + # Mailer templates + %w( activation signup_notification ).each do |action| + m.template "#{action}.html.erb", + File.join('app/views', "#{file_name}_mailer", "#{action}.html.erb") + end + end + + unless options[:skip_migration] + m.migration_template 'migration.rb', 'db/migrate', :assigns => { + :migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}" + }, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}" + end + + m.route_resource controller_singular_name + m.route_resources model_controller_plural_name + end + + action = nil + action = $0.split("/")[1] + case action + when "generate" + puts + puts ("-" * 70) + puts "Don't forget to:" + puts + if options[:include_activation] + puts " map.activate '/activate/:activation_code', :controller => '#{model_controller_file_name}', :action => 'activate'" + puts + puts " - add an observer to config/environment.rb" + puts " config.active_record.observers = :#{file_name}_observer" + puts + end + if options[:stateful] + puts "Also, don't forget to install the acts_as_state_machine plugin and set your resource:" + puts + puts " svn co http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk vendor/plugins/acts_as_state_machine" + puts + puts %w(map.resources :#{model_controller_file_name}, :member => { :suspend => :put, :unsuspend => :put, :purge => :delete }) + puts + end + puts "Try these for some familiar login URLs if you like:" + puts + puts %(map.activate '/activate/:activation_code', :controller => '#{model_controller_file_name}', :action => 'activate', :activation_code => nil) + puts %(map.signup '/signup', :controller => '#{model_controller_file_name}', :action => 'new') + puts %(map.login '/login', :controller => '#{controller_file_name}', :action => 'new') + puts %(map.logout '/logout', :controller => '#{controller_file_name}', :action => 'destroy') + puts + puts ("-" * 70) + puts + when "destroy" + puts + puts ("-" * 70) + puts + puts "Thanks for using restful_authentication" + puts + puts "Don't forget to comment out the observer line in environment.rb" + puts " (This was optional so it may not even be there)" + puts " # config.active_record.observers = :#{file_name}_observer" + puts + puts ("-" * 70) + puts + else + puts + end + + recorded_session + end + + def has_rspec? + options[:rspec] || (File.exist?('spec') && File.directory?('spec')) + end + + protected + # Override with your own usage banner. + def banner + "Usage: #{$0} authenticated ModelName [ControllerName]" + end + + def add_options!(opt) + opt.separator '' + opt.separator 'Options:' + opt.on("--skip-migration", + "Don't generate a migration file for this model") { |v| options[:skip_migration] = v } + opt.on("--include-activation", + "Generate signup 'activation code' confirmation via email") { |v| options[:include_activation] = true } + opt.on("--stateful", + "Use acts_as_state_machine. Assumes --include-activation") { |v| options[:include_activation] = options[:stateful] = true } + opt.on("--rspec", + "Force rspec mode (checks for RAILS_ROOT/spec by default)") { |v| options[:rspec] = true } + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/activation.html.erb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,3 @@ +<%%= @<%= file_name %>.login %>, your account has been activated. You may now start adding your plugins: + + <%%= @url %> \ No newline at end of file --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/authenticated_system.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,116 @@ +module AuthenticatedSystem + protected + # Returns true or false if the <%= file_name %> is logged in. + # Preloads @current_<%= file_name %> with the <%= file_name %> model if they're logged in. + def logged_in? + current_<%= file_name %> != :false + end + + # Accesses the current <%= file_name %> from the session. Set it to :false if login fails + # so that future calls do not hit the database. + def current_<%= file_name %> + @current_<%= file_name %> ||= (login_from_session || login_from_basic_auth || login_from_cookie || :false) + end + + # Store the given <%= file_name %> id in the session. + def current_<%= file_name %>=(new_<%= file_name %>) + session[:<%= file_name %>_id] = (new_<%= file_name %>.nil? || new_<%= file_name %>.is_a?(Symbol)) ? nil : new_<%= file_name %>.id + @current_<%= file_name %> = new_<%= file_name %> || :false + end + + # Check if the <%= file_name %> is authorized + # + # Override this method in your controllers if you want to restrict access + # to only a few actions or if you want to check if the <%= file_name %> + # has the correct rights. + # + # Example: + # + # # only allow nonbobs + # def authorized? + # current_<%= file_name %>.login != "bob" + # end + def authorized? + logged_in? + end + + # Filter method to enforce a login requirement. + # + # To require logins for all actions, use this in your controllers: + # + # before_filter :login_required + # + # To require logins for specific actions, use this in your controllers: + # + # before_filter :login_required, :only => [ :edit, :update ] + # + # To skip this in a subclassed controller: + # + # skip_before_filter :login_required + # + def login_required + authorized? || access_denied + end + + # Redirect as appropriate when an access request fails. + # + # The default action is to redirect to the login screen. + # + # Override this method in your controllers if you want to have special + # behavior in case the <%= file_name %> is not authorized + # to access the requested action. For example, a popup window might + # simply close itself. + def access_denied + respond_to do |format| + format.html do + store_location + redirect_to new_<%= controller_singular_name %>_path + end + format.any do + request_http_basic_authentication 'Web Password' + end + end + end + + # Store the URI of the current request in the session. + # + # We can return to this location by calling #redirect_back_or_default. + def store_location + session[:return_to] = request.request_uri + end + + # Redirect to the URI stored by the most recent store_location call or + # to the passed default. + def redirect_back_or_default(default) + redirect_to(session[:return_to] || default) + session[:return_to] = nil + end + + # Inclusion hook to make #current_<%= file_name %> and #logged_in? + # available as ActionView helper methods. + def self.included(base) + base.send :helper_method, :current_<%= file_name %>, :logged_in? + end + + # Called from #current_<%= file_name %>. First attempt to login by the <%= file_name %> id stored in the session. + def login_from_session + self.current_<%= file_name %> = <%= class_name %>.find_by_id(session[:<%= file_name %>_id]) if session[:<%= file_name %>_id] + end + + # Called from #current_<%= file_name %>. Now, attempt to login by basic authentication information. + def login_from_basic_auth + authenticate_with_http_basic do |username, password| + self.current_<%= file_name %> = <%= class_name %>.authenticate(username, password) + end + end + + # Called from #current_<%= file_name %>. Finaly, attempt to login by an expiring token in the cookie. + def login_from_cookie + <%= file_name %> = cookies[:auth_token] && <%= class_name %>.find_by_remember_token(cookies[:auth_token]) + if <%= file_name %> && <%= file_name %>.remember_token? + <%= file_name %>.remember_me + cookies[:auth_token] = { :value => <%= file_name %>.remember_token, :expires => <%= file_name %>.remember_token_expires_at } + self.current_<%= file_name %> = <%= file_name %> + end + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/authenticated_test_helper.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,10 @@ +module AuthenticatedTestHelper + # Sets the current <%= file_name %> in the session from the <%= file_name %> fixtures. + def login_as(<%= file_name %>) + @request.session[:<%= file_name %>_id] = <%= file_name %> ? <%= table_name %>(<%= file_name %>).id : nil + end + + def authorize_as(user) + @request.env["HTTP_AUTHORIZATION"] = user ? ActionController::HttpAuthentication::Basic.encode_credentials(users(user).login, 'test') : nil + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/controller.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,31 @@ +# This controller handles the login/logout function of the site. +class <%= controller_class_name %>Controller < ApplicationController + # Be sure to include AuthenticationSystem in Application Controller instead + include AuthenticatedSystem + + # render new.rhtml + def new + end + + def create + self.current_<%= file_name %> = <%= class_name %>.authenticate(params[:login], params[:password]) + if logged_in? + if params[:remember_me] == "1" + self.current_<%= file_name %>.remember_me + cookies[:auth_token] = { :value => self.current_<%= file_name %>.remember_token , :expires => self.current_<%= file_name %>.remember_token_expires_at } + end + redirect_back_or_default('/') + flash[:notice] = "Logged in successfully" + else + render :action => 'new' + end + end + + def destroy + self.current_<%= file_name %>.forget_me if logged_in? + cookies.delete :auth_token + reset_session + flash[:notice] = "You have been logged out." + redirect_back_or_default('/') + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/fixtures.yml Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,19 @@ +quentin: + id: 1 + login: quentin + email: quentin@example.com + salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd + crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test + created_at: <%%= 5.days.ago.to_s :db %> +<% if options[:include_activation] %> activation_code: 8f24789ae988411ccf33ab0c30fe9106fab32e9b <% end %> +<% if options[:include_activation] %> activated_at: <%%= 5.days.ago.to_s :db %> <% end %> +<% if options[:stateful] %> state: active<% end %> +aaron: + id: 2 + login: aaron + email: aaron@example.com + salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd + crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test + created_at: <%%= 1.days.ago.to_s :db %> +<% if options[:include_activation] %> activation_code: 8f24789ae988411ccf33ab0c30fe9106fab32e9a <% end %> +<% if options[:stateful] %> state: pending<% end %> --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/functional_spec.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,74 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +# Be sure to include AuthenticatedTestHelper in spec/spec_helper.rb instead +# Then, you can remove it from this and the units test. +include AuthenticatedTestHelper + +describe <%= controller_class_name %>Controller do + fixtures :<%= table_name %> + + it 'logins and redirects' do + post :create, :login => 'quentin', :password => 'test' + session[:<%= file_name %>_id].should_not be_nil + response.should be_redirect + end + + it 'fails login and does not redirect' do + post :create, :login => 'quentin', :password => 'bad password' + session[:<%= file_name %>_id].should be_nil + response.should be_success + end + + it 'logs out' do + login_as :quentin + get :destroy + session[:<%= file_name %>_id].should be_nil + response.should be_redirect + end + + it 'remembers me' do + post :create, :login => 'quentin', :password => 'test', :remember_me => "1" + response.cookies["auth_token"].should_not be_nil + end + + it 'does not remember me' do + post :create, :login => 'quentin', :password => 'test', :remember_me => "0" + response.cookies["auth_token"].should be_nil + end + + it 'deletes token on logout' do + login_as :quentin + get :destroy + response.cookies["auth_token"].should == [] + end + + it 'logs in with cookie' do + <%= table_name %>(:quentin).remember_me + request.cookies["auth_token"] = cookie_for(:quentin) + get :new + controller.send(:logged_in?).should be_true + end + + it 'fails expired cookie login' do + <%= table_name %>(:quentin).remember_me + <%= table_name %>(:quentin).update_attribute :remember_token_expires_at, 5.minutes.ago + request.cookies["auth_token"] = cookie_for(:quentin) + get :new + controller.send(:logged_in?).should_not be_true + end + + it 'fails cookie login' do + <%= table_name %>(:quentin).remember_me + request.cookies["auth_token"] = auth_token('invalid_auth_token') + get :new + controller.send(:logged_in?).should_not be_true + end + + def auth_token(token) + CGI::Cookie.new('name' => 'auth_token', 'value' => token) + end + + def cookie_for(<%= file_name %>) + auth_token <%= table_name %>(<%= file_name %>).remember_token + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/functional_test.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,85 @@ +require File.dirname(__FILE__) + '/../test_helper' +require '<%= controller_file_name %>_controller' + +# Re-raise errors caught by the controller. +class <%= controller_class_name %>Controller; def rescue_action(e) raise e end; end + +class <%= controller_class_name %>ControllerTest < Test::Unit::TestCase + # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead + # Then, you can remove it from this and the units test. + include AuthenticatedTestHelper + + fixtures :<%= table_name %> + + def setup + @controller = <%= controller_class_name %>Controller.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + def test_should_login_and_redirect + post :create, :login => 'quentin', :password => 'test' + assert session[:<%= file_name %>_id] + assert_response :redirect + end + + def test_should_fail_login_and_not_redirect + post :create, :login => 'quentin', :password => 'bad password' + assert_nil session[:<%= file_name %>_id] + assert_response :success + end + + def test_should_logout + login_as :quentin + get :destroy + assert_nil session[:<%= file_name %>_id] + assert_response :redirect + end + + def test_should_remember_me + post :create, :login => 'quentin', :password => 'test', :remember_me => "1" + assert_not_nil @response.cookies["auth_token"] + end + + def test_should_not_remember_me + post :create, :login => 'quentin', :password => 'test', :remember_me => "0" + assert_nil @response.cookies["auth_token"] + end + + def test_should_delete_token_on_logout + login_as :quentin + get :destroy + assert_equal @response.cookies["auth_token"], [] + end + + def test_should_login_with_cookie + <%= table_name %>(:quentin).remember_me + @request.cookies["auth_token"] = cookie_for(:quentin) + get :new + assert @controller.send(:logged_in?) + end + + def test_should_fail_expired_cookie_login + <%= table_name %>(:quentin).remember_me + <%= table_name %>(:quentin).update_attribute :remember_token_expires_at, 5.minutes.ago + @request.cookies["auth_token"] = cookie_for(:quentin) + get :new + assert !@controller.send(:logged_in?) + end + + def test_should_fail_cookie_login + <%= table_name %>(:quentin).remember_me + @request.cookies["auth_token"] = auth_token('invalid_auth_token') + get :new + assert !@controller.send(:logged_in?) + end + + protected + def auth_token(token) + CGI::Cookie.new('name' => 'auth_token', 'value' => token) + end + + def cookie_for(<%= file_name %>) + auth_token <%= table_name %>(<%= file_name %>).remember_token + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/helper.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,2 @@ +module <%= controller_class_name %>Helper +end \ No newline at end of file --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/login.html.erb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,14 @@ +<%% form_tag <%= controller_singular_name %>_path do -%> +


+<%%= text_field_tag 'login' %>

+ +


+<%%= password_field_tag 'password' %>

+ + + +

<%%= submit_tag 'Log in' %>

+<%% end -%> --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/mailer.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,25 @@ +class <%= class_name %>Mailer < ActionMailer::Base + def signup_notification(<%= file_name %>) + setup_email(<%= file_name %>) + @subject += 'Please activate your new account' + <% if options[:include_activation] %> + @body[:url] = "http://YOURSITE/activate/#{<%= file_name %>.activation_code}" + <% else %> + @body[:url] = "http://YOURSITE/login/" <% end %> + end + + def activation(<%= file_name %>) + setup_email(<%= file_name %>) + @subject += 'Your account has been activated!' + @body[:url] = "http://YOURSITE/" + end + + protected + def setup_email(<%= file_name %>) + @recipients = "#{<%= file_name %>.email}" + @from = "ADMINEMAIL" + @subject = "[YOURSITE] " + @sent_on = Time.now + @body[:<%= file_name %>] = <%= file_name %> + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/mailer_test.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,31 @@ +require File.dirname(__FILE__) + '/../test_helper' +require '<%= file_name %>_mailer' + +class <%= class_name %>MailerTest < Test::Unit::TestCase + FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures' + CHARSET = "utf-8" + + include ActionMailer::Quoting + + def setup + ActionMailer::Base.delivery_method = :test + ActionMailer::Base.perform_deliveries = true + ActionMailer::Base.deliveries = [] + + @expected = TMail::Mail.new + @expected.set_content_type "text", "plain", { "charset" => CHARSET } + end + + def test_dummy_test + #do nothing + end + + private + def read_fixture(action) + IO.readlines("#{FIXTURES_PATH}/<%= file_name %>_mailer/#{action}") + end + + def encode(subject) + quoted_printable(subject, CHARSET) + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/migration.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,22 @@ +class <%= migration_name %> < ActiveRecord::Migration + def self.up + create_table "<%= table_name %>", :force => true do |t| + t.column :login, :string + t.column :email, :string + t.column :crypted_password, :string, :limit => 40 + t.column :salt, :string, :limit => 40 + t.column :created_at, :datetime + t.column :updated_at, :datetime + t.column :remember_token, :string + t.column :remember_token_expires_at, :datetime + <% if options[:include_activation] %>t.column :activation_code, :string, :limit => 40 + t.column :activated_at, :datetime<% end %> + <% if options[:stateful] %>t.column :state, :string, :null => :no, :default => 'passive' + t.column :deleted_at, :datetime<% end %> + end + end + + def self.down + drop_table "<%= table_name %>" + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/model.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,141 @@ +require 'digest/sha1' +class <%= class_name %> < ActiveRecord::Base + # Virtual attribute for the unencrypted password + attr_accessor :password + + validates_presence_of :login, :email + validates_presence_of :password, :if => :password_required? + validates_presence_of :password_confirmation, :if => :password_required? + validates_length_of :password, :within => 4..40, :if => :password_required? + validates_confirmation_of :password, :if => :password_required? + validates_length_of :login, :within => 3..40 + validates_length_of :email, :within => 3..100 + validates_uniqueness_of :login, :email, :case_sensitive => false + before_save :encrypt_password + <% if options[:include_activation] && !options[:stateful] %>before_create :make_activation_code <% end %> + # prevents a user from submitting a crafted form that bypasses activation + # anything else you want your user to change should be added here. + attr_accessible :login, :email, :password, :password_confirmation +<% if options[:stateful] %> + acts_as_state_machine :initial => :pending + state :passive + state :pending, :enter => :make_activation_code + state :active, :enter => :do_activate + state :suspended + state :deleted, :enter => :do_delete + + event :register do + transitions :from => :passive, :to => :pending, :guard => Proc.new {|u| !(u.crypted_password.blank? && u.password.blank?) } + end + + event :activate do + transitions :from => :pending, :to => :active + end + + event :suspend do + transitions :from => [:passive, :pending, :active], :to => :suspended + end + + event :delete do + transitions :from => [:passive, :pending, :active, :suspended], :to => :deleted + end + + event :unsuspend do + transitions :from => :suspended, :to => :active, :guard => Proc.new {|u| !u.activated_at.blank? } + transitions :from => :suspended, :to => :pending, :guard => Proc.new {|u| !u.activation_code.blank? } + transitions :from => :suspended, :to => :passive + end +<% elsif options[:include_activation] %> + # Activates the user in the database. + def activate + @activated = true + self.activated_at = Time.now.utc + self.activation_code = nil + save(false) + end + + def active? + # the existence of an activation code means they have not activated yet + activation_code.nil? + end + + # Returns true if the user has just been activated. + def pending? + @activated + end +<% end %> + # Authenticates a user by their login name and unencrypted password. Returns the user or nil. + def self.authenticate(login, password) + u = <% + if options[:stateful] %>find_in_state :first, :active, :conditions => {:login => login}<% + elsif options[:include_activation] %>find :first, :conditions => ['login = ? and activated_at IS NOT NULL', login]<% + else %>find_by_login(login)<% + end %> # need to get the salt + u && u.authenticated?(password) ? u : nil + end + + # Encrypts some data with the salt. + def self.encrypt(password, salt) + Digest::SHA1.hexdigest("--#{salt}--#{password}--") + end + + # Encrypts the password with the user salt + def encrypt(password) + self.class.encrypt(password, salt) + end + + def authenticated?(password) + crypted_password == encrypt(password) + end + + def remember_token? + remember_token_expires_at && Time.now.utc < remember_token_expires_at + end + + # These create and unset the fields required for remembering users between browser closes + def remember_me + remember_me_for 2.weeks + end + + def remember_me_for(time) + remember_me_until time.from_now.utc + end + + def remember_me_until(time) + self.remember_token_expires_at = time + self.remember_token = encrypt("#{email}--#{remember_token_expires_at}") + save(false) + end + + def forget_me + self.remember_token_expires_at = nil + self.remember_token = nil + save(false) + end + + protected + # before filter + def encrypt_password + return if password.blank? + self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? + self.crypted_password = encrypt(password) + end + + def password_required? + crypted_password.blank? || !password.blank? + end + <% if options[:include_activation] %> + def make_activation_code +<% if options[:stateful] %> self.deleted_at = nil<% end %> + self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join ) + end<% end %> + <% if options[:stateful] %> + def do_delete + self.deleted_at = Time.now.utc + end + + def do_activate + self.activated_at = Time.now.utc + self.deleted_at = self.activation_code = nil + end<% end %> +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/model_controller.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,65 @@ +class <%= model_controller_class_name %>Controller < ApplicationController + # Be sure to include AuthenticationSystem in Application Controller instead + include AuthenticatedSystem + <% if options[:stateful] %> + # Protect these actions behind an admin login + # before_filter :admin_required, :only => [:suspend, :unsuspend, :destroy, :purge] + before_filter :find_<%= file_name %>, :only => [:suspend, :unsuspend, :destroy, :purge] + <% end %> + + # render new.rhtml + def new + end + + def create + cookies.delete :auth_token + # protects against session fixation attacks, wreaks havoc with + # request forgery protection. + # uncomment at your own risk + # reset_session + @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>]) + @<%= file_name %>.<% if options[:stateful] %>register! if @<%= file_name %>.valid?<% else %>save<% end %> + if @<%= file_name %>.errors.empty? + self.current_<%= file_name %> = @<%= file_name %> + redirect_back_or_default('/') + flash[:notice] = "Thanks for signing up!" + else + render :action => 'new' + end + end +<% if options[:include_activation] %> + def activate + self.current_<%= file_name %> = params[:activation_code].blank? ? :false : <%= class_name %>.find_by_activation_code(params[:activation_code]) + if logged_in? && !current_<%= file_name %>.active? + current_<%= file_name %>.activate<% if options[:stateful] %>!<% end %> + flash[:notice] = "Signup complete!" + end + redirect_back_or_default('/') + end +<% end %><% if options[:stateful] %> + def suspend + @<%= file_name %>.suspend! + redirect_to <%= table_name %>_path + end + + def unsuspend + @<%= file_name %>.unsuspend! + redirect_to <%= table_name %>_path + end + + def destroy + @<%= file_name %>.delete! + redirect_to <%= table_name %>_path + end + + def purge + @<%= file_name %>.destroy + redirect_to <%= table_name %>_path + end + +protected + def find_<%= file_name %> + @<%= file_name %> = <%= class_name %>.find(params[:id]) + end +<% end %> +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/model_functional_spec.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,84 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +# Be sure to include AuthenticatedTestHelper in spec/spec_helper.rb instead +# Then, you can remove it from this and the units test. +include AuthenticatedTestHelper + +describe <%= model_controller_class_name %>Controller do + fixtures :<%= table_name %> + + it 'allows signup' do + lambda do + create_<%= file_name %> + response.should be_redirect + end.should change(<%= class_name %>, :count).by(1) + end + + <% if options[:stateful] %> + it 'signs up user in pending state' do + create_user + assigns(:user).should be_pending + end<% end %> + + <% if options[:include_activation] %> + it 'signs up user with activation code' do + create_user + assigns(:user).activation_code.should_not be_nil + end<% end %> + + it 'requires login on signup' do + lambda do + create_<%= file_name %>(:login => nil) + assigns[:<%= file_name %>].errors.on(:login).should_not be_nil + response.should be_success + end.should_not change(<%= class_name %>, :count) + end + + it 'requires password on signup' do + lambda do + create_<%= file_name %>(:password => nil) + assigns[:<%= file_name %>].errors.on(:password).should_not be_nil + response.should be_success + end.should_not change(<%= class_name %>, :count) + end + + it 'requires password confirmation on signup' do + lambda do + create_<%= file_name %>(:password_confirmation => nil) + assigns[:<%= file_name %>].errors.on(:password_confirmation).should_not be_nil + response.should be_success + end.should_not change(<%= class_name %>, :count) + end + + it 'requires email on signup' do + lambda do + create_<%= file_name %>(:email => nil) + assigns[:<%= file_name %>].errors.on(:email).should_not be_nil + response.should be_success + end.should_not change(<%= class_name %>, :count) + end + + <% if options[:include_activation] %> + it 'activates user' do + <%= class_name %>.authenticate('aaron', 'test').should be_nil + get :activate, :activation_code => <%= table_name %>(:aaron).activation_code + response.should redirect_to('/') + flash[:notice].should_not be_nil + <%= class_name %>.authenticate('aaron', 'test').should == <%= table_name %>(:aaron) + end + + it 'does not activate user without key' do + get :activate + flash[:notice].should be_nil + end + + it 'does not activate user with blank key' do + get :activate, :activation_code => '' + flash[:notice].should be_nil + end<% end %> + + def create_<%= file_name %>(options = {}) + post :create, :<%= file_name %> => { :login => 'quire', :email => 'quire@example.com', + :password => 'quire', :password_confirmation => 'quire' }.merge(options) + end +end \ No newline at end of file --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/model_functional_test.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,86 @@ +require File.dirname(__FILE__) + '/../test_helper' +require '<%= model_controller_file_name %>_controller' + +# Re-raise errors caught by the controller. +class <%= model_controller_class_name %>Controller; def rescue_action(e) raise e end; end + +class <%= model_controller_class_name %>ControllerTest < Test::Unit::TestCase + # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead + # Then, you can remove it from this and the units test. + include AuthenticatedTestHelper + + fixtures :<%= table_name %> + + def setup + @controller = <%= model_controller_class_name %>Controller.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + end + + def test_should_allow_signup + assert_difference '<%= class_name %>.count' do + create_<%= file_name %> + assert_response :redirect + end + end + + def test_should_require_login_on_signup + assert_no_difference '<%= class_name %>.count' do + create_<%= file_name %>(:login => nil) + assert assigns(:<%= file_name %>).errors.on(:login) + assert_response :success + end + end + + def test_should_require_password_on_signup + assert_no_difference '<%= class_name %>.count' do + create_<%= file_name %>(:password => nil) + assert assigns(:<%= file_name %>).errors.on(:password) + assert_response :success + end + end + + def test_should_require_password_confirmation_on_signup + assert_no_difference '<%= class_name %>.count' do + create_<%= file_name %>(:password_confirmation => nil) + assert assigns(:<%= file_name %>).errors.on(:password_confirmation) + assert_response :success + end + end + + def test_should_require_email_on_signup + assert_no_difference '<%= class_name %>.count' do + create_<%= file_name %>(:email => nil) + assert assigns(:<%= file_name %>).errors.on(:email) + assert_response :success + end + end + <% if options[:include_activation] %> + def test_should_activate_user + assert_nil <%= class_name %>.authenticate('aaron', 'test') + get :activate, :activation_code => <%= table_name %>(:aaron).activation_code + assert_redirected_to '/' + assert_not_nil flash[:notice] + assert_equal <%= table_name %>(:aaron), <%= class_name %>.authenticate('aaron', 'test') + end + + def test_should_not_activate_user_without_key + get :activate + assert_nil flash[:notice] + rescue ActionController::RoutingError + # in the event your routes deny this, we'll just bow out gracefully. + end + + def test_should_not_activate_user_with_blank_key + get :activate, :activation_code => '' + assert_nil flash[:notice] + rescue ActionController::RoutingError + # well played, sir + end<% end %> + + protected + def create_<%= file_name %>(options = {}) + post :create, :<%= file_name %> => { :login => 'quire', :email => 'quire@example.com', + :password => 'quire', :password_confirmation => 'quire' }.merge(options) + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/model_helper.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,2 @@ +module <%= model_controller_class_name %>Helper +end \ No newline at end of file --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/observer.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,11 @@ +class <%= class_name %>Observer < ActiveRecord::Observer + def after_create(<%= file_name %>) + <%= class_name %>Mailer.deliver_signup_notification(<%= file_name %>) + end + + def after_save(<%= file_name %>) + <% if options[:include_activation] %> + <%= class_name %>Mailer.deliver_activation(<%= file_name %>) if <%= file_name %>.pending? + <% end %> + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/signup.html.erb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,16 @@ +<%%= error_messages_for :<%= file_name %> %> +<%% form_for :<%= file_name %>, :url => <%= table_name %>_path do |f| -%> +


+<%%= f.text_field :login %>

+ +


+<%%= f.text_field :email %>

+ +


+<%%= f.password_field :password %>

+ +


+<%%= f.password_field :password_confirmation %>

+ +

<%%= submit_tag 'Sign up' %>

+<%% end -%> --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/signup_notification.html.erb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,8 @@ +Your account has been created. + + Username: <%%= @<%= file_name %>.login %> + Password: <%%= @<%= file_name %>.password %> + +Visit this url to activate your account: + + <%%= @url %> \ No newline at end of file --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/unit_spec.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,172 @@ +require File.dirname(__FILE__) + '/../spec_helper' + +# Be sure to include AuthenticatedTestHelper in spec/spec_helper.rb instead. +# Then, you can remove it from this and the functional test. +include AuthenticatedTestHelper + +describe <%= class_name %> do + fixtures :<%= table_name %> + + describe 'being created' do + before do + @<%= file_name %> = nil + @creating_<%= file_name %> = lambda do + @<%= file_name %> = create_<%= file_name %> + violated "#{@<%= file_name %>.errors.full_messages.to_sentence}" if @<%= file_name %>.new_record? + end + end + + it 'increments User#count' do + @creating_<%= file_name %>.should change(<%= class_name %>, :count).by(1) + end +<% if options[:include_activation] %> + it 'initializes #activation_code' do + @creating_<%= file_name %>.call + @<%= file_name %>.reload.activation_code.should_not be_nil + end +<% end %><% if options[:stateful] %> + it 'starts in pending state' do + @creating_<%= file_name %>.call + @<%= file_name %>.should be_pending + end +<% end %> end + + it 'requires login' do + lambda do + u = create_<%= file_name %>(:login => nil) + u.errors.on(:login).should_not be_nil + end.should_not change(<%= class_name %>, :count) + end + + it 'requires password' do + lambda do + u = create_<%= file_name %>(:password => nil) + u.errors.on(:password).should_not be_nil + end.should_not change(<%= class_name %>, :count) + end + + it 'requires password confirmation' do + lambda do + u = create_<%= file_name %>(:password_confirmation => nil) + u.errors.on(:password_confirmation).should_not be_nil + end.should_not change(<%= class_name %>, :count) + end + + it 'requires email' do + lambda do + u = create_<%= file_name %>(:email => nil) + u.errors.on(:email).should_not be_nil + end.should_not change(<%= class_name %>, :count) + end + + it 'resets password' do + <%= table_name %>(:quentin).update_attributes(:password => 'new password', :password_confirmation => 'new password') + <%= class_name %>.authenticate('quentin', 'new password').should == <%= table_name %>(:quentin) + end + + it 'does not rehash password' do + <%= table_name %>(:quentin).update_attributes(:login => 'quentin2') + <%= class_name %>.authenticate('quentin2', 'test').should == <%= table_name %>(:quentin) + end + + it 'authenticates <%= file_name %>' do + <%= class_name %>.authenticate('quentin', 'test').should == <%= table_name %>(:quentin) + end + + it 'sets remember token' do + <%= table_name %>(:quentin).remember_me + <%= table_name %>(:quentin).remember_token.should_not be_nil + <%= table_name %>(:quentin).remember_token_expires_at.should_not be_nil + end + + it 'unsets remember token' do + <%= table_name %>(:quentin).remember_me + <%= table_name %>(:quentin).remember_token.should_not be_nil + <%= table_name %>(:quentin).forget_me + <%= table_name %>(:quentin).remember_token.should be_nil + end + + it 'remembers me for one week' do + before = 1.week.from_now.utc + <%= table_name %>(:quentin).remember_me_for 1.week + after = 1.week.from_now.utc + <%= table_name %>(:quentin).remember_token.should_not be_nil + <%= table_name %>(:quentin).remember_token_expires_at.should_not be_nil + <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after).should be_true + end + + it 'remembers me until one week' do + time = 1.week.from_now.utc + <%= table_name %>(:quentin).remember_me_until time + <%= table_name %>(:quentin).remember_token.should_not be_nil + <%= table_name %>(:quentin).remember_token_expires_at.should_not be_nil + <%= table_name %>(:quentin).remember_token_expires_at.should == time + end + + it 'remembers me default two weeks' do + before = 2.weeks.from_now.utc + <%= table_name %>(:quentin).remember_me + after = 2.weeks.from_now.utc + <%= table_name %>(:quentin).remember_token.should_not be_nil + <%= table_name %>(:quentin).remember_token_expires_at.should_not be_nil + <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after).should be_true + end +<% if options[:stateful] %> + it 'registers passive <%= file_name %>' do + <%= file_name %> = create_<%= file_name %>(:password => nil, :password_confirmation => nil) + <%= file_name %>.should be_passive + <%= file_name %>.update_attributes(:password => 'new password', :password_confirmation => 'new password') + <%= file_name %>.register! + <%= file_name %>.should be_pending + end + + it 'suspends <%= file_name %>' do + <%= table_name %>(:quentin).suspend! + <%= table_name %>(:quentin).should be_suspended + end + + it 'does not authenticate suspended <%= file_name %>' do + <%= table_name %>(:quentin).suspend! + <%= class_name %>.authenticate('quentin', 'test').should_not == <%= table_name %>(:quentin) + end + + it 'deletes <%= file_name %>' do + <%= table_name %>(:quentin).deleted_at.should be_nil + <%= table_name %>(:quentin).delete! + <%= table_name %>(:quentin).deleted_at.should_not be_nil + <%= table_name %>(:quentin).should be_deleted + end + + describe "being unsuspended" do + fixtures :<%= table_name %> + + before do + @<%= file_name %> = <%= table_name %>(:quentin) + @<%= file_name %>.suspend! + end + + it 'reverts to active state' do + @<%= file_name %>.unsuspend! + @<%= file_name %>.should be_active + end + + it 'reverts to passive state if activation_code and activated_at are nil' do + <%= class_name %>.update_all :activation_code => nil, :activated_at => nil + @<%= file_name %>.reload.unsuspend! + @<%= file_name %>.should be_passive + end + + it 'reverts to pending state if activation_code is set and activated_at is nil' do + <%= class_name %>.update_all :activation_code => 'foo-bar', :activated_at => nil + @<%= file_name %>.reload.unsuspend! + @<%= file_name %>.should be_pending + end + end +<% end %> +protected + def create_<%= file_name %>(options = {}) + record = <%= class_name %>.new({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) + record.<% if options[:stateful] %>register! if record.valid?<% else %>save<% end %> + record + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/generators/authenticated/templates/unit_test.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,160 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class <%= class_name %>Test < Test::Unit::TestCase + # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead. + # Then, you can remove it from this and the functional test. + include AuthenticatedTestHelper + fixtures :<%= table_name %> + + def test_should_create_<%= file_name %> + assert_difference '<%= class_name %>.count' do + <%= file_name %> = create_<%= file_name %> + assert !<%= file_name %>.new_record?, "#{<%= file_name %>.errors.full_messages.to_sentence}" + end + end +<% if options[:include_activation] %> + def test_should_initialize_activation_code_upon_creation + <%= file_name %> = create_<%= file_name %> + assert_not_nil <%= file_name %>.reload.activation_code + end +<% end %><% if options[:stateful] %> + def test_should_create_and_start_in_pending_state + <%= file_name %> = create_<%= file_name %> + assert <%= file_name %>.pending? + end + +<% end %> + def test_should_require_login + assert_no_difference '<%= class_name %>.count' do + u = create_<%= file_name %>(:login => nil) + assert u.errors.on(:login) + end + end + + def test_should_require_password + assert_no_difference '<%= class_name %>.count' do + u = create_<%= file_name %>(:password => nil) + assert u.errors.on(:password) + end + end + + def test_should_require_password_confirmation + assert_no_difference '<%= class_name %>.count' do + u = create_<%= file_name %>(:password_confirmation => nil) + assert u.errors.on(:password_confirmation) + end + end + + def test_should_require_email + assert_no_difference '<%= class_name %>.count' do + u = create_<%= file_name %>(:email => nil) + assert u.errors.on(:email) + end + end + + def test_should_reset_password + <%= table_name %>(:quentin).update_attributes(:password => 'new password', :password_confirmation => 'new password') + assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin', 'new password') + end + + def test_should_not_rehash_password + <%= table_name %>(:quentin).update_attributes(:login => 'quentin2') + assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin2', 'test') + end + + def test_should_authenticate_<%= file_name %> + assert_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin', 'test') + end + + def test_should_set_remember_token + <%= table_name %>(:quentin).remember_me + assert_not_nil <%= table_name %>(:quentin).remember_token + assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at + end + + def test_should_unset_remember_token + <%= table_name %>(:quentin).remember_me + assert_not_nil <%= table_name %>(:quentin).remember_token + <%= table_name %>(:quentin).forget_me + assert_nil <%= table_name %>(:quentin).remember_token + end + + def test_should_remember_me_for_one_week + before = 1.week.from_now.utc + <%= table_name %>(:quentin).remember_me_for 1.week + after = 1.week.from_now.utc + assert_not_nil <%= table_name %>(:quentin).remember_token + assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at + assert <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after) + end + + def test_should_remember_me_until_one_week + time = 1.week.from_now.utc + <%= table_name %>(:quentin).remember_me_until time + assert_not_nil <%= table_name %>(:quentin).remember_token + assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at + assert_equal <%= table_name %>(:quentin).remember_token_expires_at, time + end + + def test_should_remember_me_default_two_weeks + before = 2.weeks.from_now.utc + <%= table_name %>(:quentin).remember_me + after = 2.weeks.from_now.utc + assert_not_nil <%= table_name %>(:quentin).remember_token + assert_not_nil <%= table_name %>(:quentin).remember_token_expires_at + assert <%= table_name %>(:quentin).remember_token_expires_at.between?(before, after) + end +<% if options[:stateful] %> + def test_should_register_passive_<%= file_name %> + <%= file_name %> = create_<%= file_name %>(:password => nil, :password_confirmation => nil) + assert <%= file_name %>.passive? + <%= file_name %>.update_attributes(:password => 'new password', :password_confirmation => 'new password') + <%= file_name %>.register! + assert <%= file_name %>.pending? + end + + def test_should_suspend_<%= file_name %> + <%= table_name %>(:quentin).suspend! + assert <%= table_name %>(:quentin).suspended? + end + + def test_suspended_<%= file_name %>_should_not_authenticate + <%= table_name %>(:quentin).suspend! + assert_not_equal <%= table_name %>(:quentin), <%= class_name %>.authenticate('quentin', 'test') + end + + def test_should_unsuspend_<%= file_name %>_to_active_state + <%= table_name %>(:quentin).suspend! + assert <%= table_name %>(:quentin).suspended? + <%= table_name %>(:quentin).unsuspend! + assert <%= table_name %>(:quentin).active? + end + + def test_should_unsuspend_<%= file_name %>_with_nil_activation_code_and_activated_at_to_passive_state + <%= table_name %>(:quentin).suspend! + <%= class_name %>.update_all :activation_code => nil, :activated_at => nil + assert <%= table_name %>(:quentin).suspended? + <%= table_name %>(:quentin).reload.unsuspend! + assert <%= table_name %>(:quentin).passive? + end + + def test_should_unsuspend_<%= file_name %>_with_activation_code_and_nil_activated_at_to_pending_state + <%= table_name %>(:quentin).suspend! + <%= class_name %>.update_all :activation_code => 'foo-bar', :activated_at => nil + assert <%= table_name %>(:quentin).suspended? + <%= table_name %>(:quentin).reload.unsuspend! + assert <%= table_name %>(:quentin).pending? + end + + def test_should_delete_<%= file_name %> + assert_nil <%= table_name %>(:quentin).deleted_at + <%= table_name %>(:quentin).delete! + assert_not_nil <%= table_name %>(:quentin).deleted_at + assert <%= table_name %>(:quentin).deleted? + end +<% end %> +protected + def create_<%= file_name %>(options = {}) + <%= class_name %>.create({ :login => 'quire', :email => 'quire@example.com', :password => 'quire', :password_confirmation => 'quire' }.merge(options)) + end +end --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/install.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,1 @@ +puts IO.read(File.join(File.dirname(__FILE__), 'README')) \ No newline at end of file --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/plugins/restful_authentication/lib/restful_authentication/rails_commands.rb Wed Mar 05 01:17:41 2008 +0900 @@ -0,0 +1,29 @@ +Rails::Generator::Commands::Create.class_eval do + def route_resource(*resources) + resource_list = resources.map { |r| r.to_sym.inspect }.join(', ') + sentinel = 'ActionController::Routing::Routes.draw do |map|' + + logger.route "map.resource #{resource_list}" + unless options[:pretend] + gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match| + "#{match}\n map.resource #{resource_list}\n" + end + end + end +end + +Rails::Generator::Commands::Destroy.class_eval do + def route_resource(*resources) + resource_list = resources.map { |r| r.to_sym.inspect }.join(', ') + look_for = "\n map.resource #{resource_list}\n" + logger.route "map.resource #{resource_list}" + gsub_file 'config/routes.rb', /(#{look_for})/mi, '' + end +end + +Rails::Generator::Commands::List.class_eval do + def route_resource(*resources) + resource_list = resources.map { |r| r.to_sym.inspect }.join(', ') + logger.route "map.resource #{resource_list}" + end +end \ No newline at end of file