changelog shortlog tags manifest raw

changeset: add plugin restful_authentication.

changeset 4: 43c5e6930eee
parent 3:584d445b6069
child 5:233c1cbacd12
author: moriq@moriq.com
date: Wed Mar 05 01:17:41 2008 +0900 (16 years ago)
files: vendor/plugins/restful_authentication/README vendor/plugins/restful_authentication/Rakefile vendor/plugins/restful_authentication/generators/authenticated/USAGE vendor/plugins/restful_authentication/generators/authenticated/authenticated_generator.rb vendor/plugins/restful_authentication/generators/authenticated/templates/activation.html.erb vendor/plugins/restful_authentication/generators/authenticated/templates/authenticated_system.rb vendor/plugins/restful_authentication/generators/authenticated/templates/authenticated_test_helper.rb vendor/plugins/restful_authentication/generators/authenticated/templates/controller.rb vendor/plugins/restful_authentication/generators/authenticated/templates/fixtures.yml vendor/plugins/restful_authentication/generators/authenticated/templates/functional_spec.rb vendor/plugins/restful_authentication/generators/authenticated/templates/functional_test.rb vendor/plugins/restful_authentication/generators/authenticated/templates/helper.rb vendor/plugins/restful_authentication/generators/authenticated/templates/login.html.erb vendor/plugins/restful_authentication/generators/authenticated/templates/mailer.rb vendor/plugins/restful_authentication/generators/authenticated/templates/mailer_test.rb vendor/plugins/restful_authentication/generators/authenticated/templates/migration.rb vendor/plugins/restful_authentication/generators/authenticated/templates/model.rb vendor/plugins/restful_authentication/generators/authenticated/templates/model_controller.rb vendor/plugins/restful_authentication/generators/authenticated/templates/model_functional_spec.rb vendor/plugins/restful_authentication/generators/authenticated/templates/model_functional_test.rb vendor/plugins/restful_authentication/generators/authenticated/templates/model_helper.rb vendor/plugins/restful_authentication/generators/authenticated/templates/observer.rb vendor/plugins/restful_authentication/generators/authenticated/templates/signup.html.erb vendor/plugins/restful_authentication/generators/authenticated/templates/signup_notification.html.erb vendor/plugins/restful_authentication/generators/authenticated/templates/unit_spec.rb vendor/plugins/restful_authentication/generators/authenticated/templates/unit_test.rb vendor/plugins/restful_authentication/install.rb vendor/plugins/restful_authentication/lib/restful_authentication/rails_commands.rb
description: 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 -%>
+<p><label for="login">Login</label><br/>
+<%%= text_field_tag 'login' %></p>
+
+<p><label for="password">Password</label><br/>
+<%%= password_field_tag 'password' %></p>
+
+<!-- Uncomment this if you want this functionality
+<p><label for="remember_me">Remember me:</label>
+<%%= check_box_tag 'remember_me' %></p>
+-->
+
+<p><%%= submit_tag 'Log in' %></p>
+<%% 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| -%>
+<p><label for="login">Login</label><br/>
+<%%= f.text_field :login %></p>
+
+<p><label for="email">Email</label><br/>
+<%%= f.text_field :email %></p>
+
+<p><label for="password">Password</label><br/>
+<%%= f.password_field :password %></p>
+
+<p><label for="password_confirmation">Confirm Password</label><br/>
+<%%= f.password_field :password_confirmation %></p>
+
+<p><%%= submit_tag 'Sign up' %></p>
+<%% 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