<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>config/environments/staging.rb</filename>
    </added>
    <added>
      <filename>db/migrate/20081023115224_baseapp.rb</filename>
    </added>
    <added>
      <filename>lib/role_requirement_system.rb</filename>
    </added>
    <added>
      <filename>lib/role_requirement_test_helper.rb</filename>
    </added>
    <added>
      <filename>script/spec</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/.gitignore</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/CHANGELOG</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/MIT-LICENSE</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/README.rdoc</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/Rakefile</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/TODO</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/aasm.gemspec</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/aasm.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/doc/jamis.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/lib/aasm.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/lib/event.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/lib/persistence.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/lib/persistence/active_record_persistence.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/lib/state.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/lib/state_machine.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/lib/state_transition.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/lib/version.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/spec/functional/conversation.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/spec/functional/conversation_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/spec/spec_helper.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/spec/unit/aasm_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/spec/unit/active_record_persistence_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/spec/unit/event_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/spec/unit/state_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/aasm/spec/unit/state_transition_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/CHANGELOG</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/README</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/Rakefile</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/generators/open_id_authentication_tables/open_id_authentication_tables_generator.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/generators/open_id_authentication_tables/templates/migration.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/templates/migration.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/generators/upgrade_open_id_authentication_tables/upgrade_open_id_authentication_tables_generator.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/init.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/lib/open_id_authentication.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/lib/open_id_authentication/association.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/lib/open_id_authentication/db_store.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/lib/open_id_authentication/mem_cache_store.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/lib/open_id_authentication/nonce.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/lib/open_id_authentication/request.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/lib/open_id_authentication/timeout_fixes.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/tasks/open_id_authentication_tasks.rake</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/test/mem_cache_store_test.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/test/normalize_test.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/test/open_id_authentication_test.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/test/status_test.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/open_id_authentication/test/test_helper.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/.gitignore</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/CHANGELOG</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/README</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/Rakefile</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/TODO</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/USAGE</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/authenticated_generator.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/lib/insert_routes.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/_model_partial.html.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/activation.html.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/authenticated_system.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/authenticated_test_helper.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/controller.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/helper.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/login.html.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/mailer.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/migration.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/model.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/model_controller.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/model_helper.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/model_helper_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/observer.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/signup.html.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/signup_notification.html.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/site_keys.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/spec/controllers/access_control_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/spec/controllers/authenticated_system_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/spec/controllers/sessions_controller_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/spec/controllers/users_controller_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/spec/fixtures/users.yml</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/spec/helpers/users_helper_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/spec/models/user_spec.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/stories/rest_auth_stories.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/stories/rest_auth_stories_helper.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/stories/steps/ra_navigation_steps.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/stories/steps/ra_resource_steps.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/stories/steps/ra_response_steps.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/stories/steps/user_steps.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/stories/users/accounts.story</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/stories/users/sessions.story</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/test/functional_test.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/test/mailer_test.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/test/model_functional_test.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/generators/authenticated/templates/test/unit_test.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/init.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/install.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/lib/authentication.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/lib/authentication/by_cookie_token.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/lib/authentication/by_password.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/lib/authorization.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/lib/authorization/aasm_roles.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/lib/authorization/stateful_roles.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/lib/trustification.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/lib/trustification/email_validation.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/notes/AccessControl.txt</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/notes/Authentication.txt</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/notes/Authorization.txt</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/notes/RailsPlugins.txt</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/notes/SecurityFramework.graffle</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/notes/SecurityFramework.png</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/notes/SecurityPatterns.txt</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/notes/Tradeoffs.txt</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/notes/Trustification.txt</filename>
    </added>
    <added>
      <filename>vendor/plugins/restful_authentication/tasks/auth.rake</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/ChangeLog</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/MIT-LICENSE</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/README.textile</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/role_generator_helpers.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/roles_generator.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/templates/001_roles_migration.rb.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/templates/_user_functions.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/templates/hijacker.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/templates/role_model.rb.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/templates/role_requirement_system.rb.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/templates/role_requirement_test_helper.rb.erb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/templates/roles.yml</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/templates/roles_users.yml</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/generators/roles/templates/users_admin_fixture_with_roles.yml</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/init.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/test/authenticated_system.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/test/controller_stub.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/test/functional/test_role_controller.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/test/test_helper.rb</filename>
    </added>
    <added>
      <filename>vendor/plugins/role_requirement/test/user_stub.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -2,9 +2,10 @@
 # Likewise, all the methods added will be available for all controllers.
 class ApplicationController &lt; ActionController::Base
   include AuthenticatedSystem
-  include RoleRequirement
-    
+  include RoleRequirementSystem
+  
   helper :all # include all helpers, all the time
+  filter_parameter_logging :password, :password_confirmation
   
   # Return the value for a given setting
   def s(identifier)</diff>
      <filename>app/controllers/application.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,32 +1,63 @@
 # This controller handles the login/logout function of the site.  
 class SessionsController &lt; ApplicationController
+  skip_before_filter :verify_authenticity_token, :only =&gt; :create
+  
   layout 'login'
   
-  # render new.rhtml
   def new
   end
 
   def create
-    self.current_user = User.authenticate(params[:login], params[:password])
-    if logged_in?
-      if params[:remember_me] == &quot;1&quot;
-        self.current_user.remember_me
-        cookies[:auth_token] = { :value =&gt; self.current_user.remember_token , :expires =&gt; self.current_user.remember_token_expires_at }
-      end
-      redirect_back_or_default('/')
-      flash[:notice] = &quot;Welcome back to #{s(:site_name)}, #{self.current_user.login}!&quot;
+    logout_keeping_session!
+    if using_open_id?
+      open_id_authentication
     else
-      # TODO: (base_app) Add feature to resend the activation email, which might be caught as SPAM
-      flash.now[:error] = &quot;The login/password combination you provided is incorrect or your account has not yet been activated.&quot;
-      render :action =&gt; 'new'
+      password_authentication
     end
   end
 
   def destroy
-    self.current_user.forget_me if logged_in?
-    cookies.delete :auth_token
-    reset_session
-    flash[:notice] = &quot;You have been logged out. Goodbye!&quot;
-    redirect_back_or_default('/')
+    logout_killing_session!
+    flash[:notice] = &quot;You have been logged out.&quot;
+    redirect_back_or_default(root_path)
+  end
+
+  def open_id_authentication
+    authenticate_with_open_id do |result, identity_url|
+      if result.successful? &amp;&amp; self.current_user = User.find_by_identity_url(identity_url)
+        successful_login
+      else
+        flash[:error] = result.message || &quot;Sorry no user with that identity URL exists&quot;
+        @rememer_me = params[:remember_me]
+        render :action =&gt; :new
+      end
+    end
+  end
+  
+  protected
+
+  def password_authentication
+    user = User.authenticate(params[:login], params[:password])
+    if user
+      self.current_user = user
+      successful_login
+    else
+      note_failed_signin
+      @login = params[:login]
+      @remember_me = params[:remember_me]
+      render :action =&gt; :new
+    end
+  end
+  
+  def successful_login
+    new_cookie_flag = (params[:remember_me] == &quot;1&quot;)
+    handle_remember_cookie! new_cookie_flag
+    redirect_back_or_default(root_path)
+    flash[:notice] = &quot;Logged in successfully&quot;
+  end
+
+  def note_failed_signin
+    flash[:error] = &quot;Couldn't log you in as '#{params[:login]}'&quot;
+    logger.warn &quot;Failed login for '#{params[:login]}' from #{request.remote_ip} at #{Time.now.utc}&quot;
   end
 end</diff>
      <filename>app/controllers/sessions_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,14 +1,17 @@
 class UsersController &lt; ApplicationController
+  skip_before_filter :verify_authenticity_token, :only =&gt; :create
+  
   before_filter :find_user, 
     :only =&gt; [:profile, 
               :destroy, 
               :edit_password,   :update_password, 
               :edit_email,      :update_email ]
   
-  layout 'login' #, :except =&gt; [:edit_password, :update_password]
+  layout 'login'
   
   # render new.rhtml
   def new
+    @user = User.new
   end
 
   def troubleshooting
@@ -21,10 +24,15 @@ class UsersController &lt; ApplicationController
     render :layout =&gt; 'login'
   end
 
-  def forgot_login
+  def forgot_login    
     if request.put?
       begin
         @user = User.find_by_email(params[:email], :conditions =&gt; ['NOT state = ?', 'deleted'])
+        
+        if ! @user.not_using_openid?
+          flash[:notice] = &quot;You cannot help you, you're using OpenID!&quot;
+          redirect_to :back
+        end
       rescue
         @user = nil
       end
@@ -41,14 +49,19 @@ class UsersController &lt; ApplicationController
     render :layout =&gt; 'login'
   end
 
-  def forgot_password
+  def forgot_password    
     if request.put?
       @user = User.find_by_login_or_email(params[:email_or_login])
 
       if @user.nil?
         flash.now[:error] = 'No account was found by that login or email address.'
       else
-        @user.forgot_password if @user.active?
+        if ! @user.not_using_openid?
+          flash[:notice] = &quot;You cannot reset your password here. You are using OpenID!&quot;
+          redirect_to :back
+        else
+          @user.forgot_password if @user.active?
+        end
       end
     else
       # Render forgot_password.html.erb
@@ -57,7 +70,7 @@ class UsersController &lt; ApplicationController
     render :layout =&gt; 'login'
   end
   
-  def reset_password
+  def reset_password    
     begin
       @user = User.find_by_password_reset_code(params[:password_reset_code])
     rescue
@@ -72,31 +85,53 @@ class UsersController &lt; ApplicationController
   end
 
   def create
-    cookies.delete :auth_token
-    @user = User.new(params[:user])
-    raise ActiveRecord::RecordInvalid.new(@user) unless @user.valid?
-    @user.register!
-    
-    redirect_back_or_default('/')
-    flash[:notice] = &quot;Thanks for signing up!&lt;br /&gt;You will receive an email in a few minutes with further instructions on how to activate your account.&quot;
-  rescue ActiveRecord::RecordInvalid
-    render :action =&gt; 'new'
+    logout_keeping_session!
+    if using_open_id?
+      authenticate_with_open_id(params[:open_id_url], :return_to =&gt; open_id_create_url,
+        :required =&gt; [:nickname, :email]) do |result, identity_url, registration|
+        if result.successful?
+          create_new_user(:identity_url =&gt; identity_url, :login =&gt; registration['nickname'], :email =&gt; registration['email'])
+        else
+          failed_creation(result.message || &quot;Sorry, something went wrong&quot;)
+        end
+      end
+    else
+      create_new_user(params[:user])
+    end
   end
 
   def activate
-    self.current_user = params[:activation_code].blank? ? :false : User.find_by_activation_code(params[:activation_code])
-    if logged_in? &amp;&amp; !current_user.active?
-      current_user.activate!
-      flash[:notice] = &quot;Your account is now ready.&lt;br /&gt;Thanks for signing up!&quot;
+    logout_keeping_session!
+    user = User.find_by_activation_code(params[:activation_code]) unless params[:activation_code].blank?
+    case
+    when (!params[:activation_code].blank?) &amp;&amp; user &amp;&amp; !user.active?
+      user.activate!
+      flash[:notice] = &quot;Signup complete! Please sign in to continue.&quot;
+      redirect_to login_path
+    when params[:activation_code].blank?
+      flash[:error] = &quot;The activation code was missing.  Please follow the URL from your email.&quot;
+      redirect_back_or_default(root_path)
+    else 
+      flash[:error]  = &quot;We couldn't find a user with that activation code -- check your email? Or maybe you've already activated -- try signing in.&quot;
+      redirect_back_or_default(root_path)
     end
-    redirect_back_or_default('/')
   end
   
   def edit_password
+    if ! @user.not_using_openid?
+      flash[:notice] = &quot;You cannot update your password. You are using OpenID!&quot;
+      redirect_to :back
+    end
+    
     # render edit_password.html.erb
   end
   
   def update_password    
+    if ! @user.not_using_openid?
+      flash[:notice] = &quot;You cannot update your password. You are using OpenID!&quot;
+      redirect_to :back
+    end
+    
     if current_user == @user
       current_password, new_password, new_password_confirmation = params[:current_password], params[:new_password], params[:new_password_confirmation]
       
@@ -127,10 +162,20 @@ class UsersController &lt; ApplicationController
   end
   
   def edit_email
+    if ! @user.not_using_openid?
+      flash[:notice] = &quot;You cannot update your email address. You are using OpenID!&quot;
+      redirect_to :back
+    end
+    
     # render edit_email.html.erb
   end
   
   def update_email
+    if ! @user.not_using_openid?
+      flash[:notice] = &quot;You cannot update your email address. You are using OpenID!&quot;
+      redirect_to :back
+    end
+    
     if current_user == @user
       if @user.update_attributes(:email =&gt; params[:email])
         flash[:notice] = &quot;Your email address has been updated.&quot;
@@ -151,4 +196,32 @@ class UsersController &lt; ApplicationController
     @user = User.find(params[:id])
   end
 
+  def create_new_user(attributes)
+    @user = User.new(attributes)
+    if @user &amp;&amp; @user.valid?
+      if @user.not_using_openid?
+        @user.register!
+      else
+        @user.register_openid!
+      end
+    end
+    
+    if @user.errors.empty?
+      successful_creation(@user)
+    else
+      failed_creation
+    end
+  end
+  
+  def successful_creation(user)
+    redirect_back_or_default(root_path)
+    flash[:notice] = &quot;Thanks for signing up!&quot;
+    flash[:notice] &lt;&lt; &quot; We're sending you an email with your activation code.&quot; if @user.not_using_openid?
+    flash[:notice] &lt;&lt; &quot; You can now login with your OpenID.&quot; if ! @user.not_using_openid?
+  end
+  
+  def failed_creation(message = 'Sorry, there was an error creating your account')
+    flash[:error] = message
+    render :action =&gt; :new
+  end
 end</diff>
      <filename>app/controllers/users_controller.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,75 +1,64 @@
 require 'digest/sha1'
+
 class User &lt; ActiveRecord::Base
+  include Authentication
+  include Authentication::ByPassword
+  include Authentication::ByCookieToken
+  include Authorization::AasmRoles
+  
+  # Validations
+  validates_presence_of :login, :if =&gt; :not_using_openid?
+  validates_length_of :login, :within =&gt; 3..40, :if =&gt; :not_using_openid?
+  validates_uniqueness_of :login, :case_sensitive =&gt; false, :if =&gt; :not_using_openid?
+  validates_format_of :login, :with =&gt; RE_LOGIN_OK, :message =&gt; MSG_LOGIN_BAD, :if =&gt; :not_using_openid?
+  validates_format_of :name, :with =&gt; RE_NAME_OK, :message =&gt; MSG_NAME_BAD, :allow_nil =&gt; true
+  validates_length_of :name, :maximum =&gt; 100
+  validates_presence_of :email, :if =&gt; :not_using_openid?
+  validates_length_of :email, :within =&gt; 6..100, :if =&gt; :not_using_openid?
+  validates_uniqueness_of :email, :case_sensitive =&gt; false, :if =&gt; :not_using_openid?
+  validates_format_of :email, :with =&gt; RE_EMAIL_OK, :message =&gt; MSG_EMAIL_BAD, :if =&gt; :not_using_openid?
+  validates_uniqueness_of :identity_url, :unless =&gt; :not_using_openid?
+  validate :normalize_identity_url
   
+  # Relations
   has_and_belongs_to_many :roles
   has_one :profile
   
-  # has_role? simply needs to return true or false whether a user has a role or not.  
-  # It may be a good idea to have &quot;admin&quot; roles return true always
-  def has_role?(role_in_question)
-    @_list ||= self.roles.collect(&amp;:name)
-    return true if @_list.include?(&quot;admin&quot;)
-    (@_list.include?(role_in_question.to_s) )
-  end
-
-  # Virtual attribute for the unencrypted password
-  attr_accessor :password
-  
-  # Per page pagination
-  cattr_reader :per_page
-  @@per_page = 25
-
-  validates_presence_of     :login, :email
-  validates_presence_of     :password,                   :if =&gt; :password_required?
-  validates_presence_of     :password_confirmation,      :if =&gt; :password_required?
-  validates_length_of       :password, :within =&gt; 4..40, :if =&gt; :password_required?
-  validates_confirmation_of :password,                   :if =&gt; :password_required?
-  validates_length_of       :login,    :within =&gt; 3..40
-  validates_length_of       :email,    :within =&gt; 3..100
-  validates_uniqueness_of   :login, :email, :case_sensitive =&gt; false
-  before_save :encrypt_password
-  
-  after_create :create_environment
+  # Hooks
+  after_create :create_profile
   
+  # HACK HACK HACK -- how to do attr_accessible from here?
   # 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
-
-  acts_as_state_machine :initial =&gt; :pending
-  state :passive
-  state :pending, :enter =&gt; :make_activation_code
-  state :unactivated
-  state :active,  :enter =&gt; :do_activate
-  state :suspended
-  state :deleted, :enter =&gt; :do_delete
-
-  event :register do
-    transitions :from =&gt; :passive, :to =&gt; :pending, :guard =&gt; Proc.new {|u| !(u.crypted_password.blank? &amp;&amp; u.password.blank?) }
-  end
+  attr_accessible :login, :email, :name, :password, :password_confirmation, :identity_url
   
-  event :activate do
-    transitions :from =&gt; :pending, :to =&gt; :active 
+  # has_role? simply needs to return true or false whether a user has a role or not.  
+  # It may be a good idea to have &quot;admin&quot; roles return true always
+  def has_role?(role)
+    list ||= self.roles.collect(&amp;:name)
+    list.include?(role.to_s) || list.include?('admin')
   end
-  
-  event :send_activation do
-    transitions :from =&gt; :pending, :to =&gt; :unactivated
+
+  # Authenticates a user by their login name and unencrypted password.  Returns the user or nil.
+  def self.authenticate(login, password)
+    u = find_in_state :first, :active, :conditions =&gt; {:login =&gt; login} # need to get the salt
+    u &amp;&amp; u.authenticated?(password) ? u : nil
   end
-  
-  event :suspend do
-    transitions :from =&gt; [:passive, :pending, :active, :unactivated], :to =&gt; :suspended
+
+  def not_using_openid?
+    identity_url.blank?
   end
   
-  event :delete do
-    transitions :from =&gt; [:passive, :pending, :active, :unactivated, :suspended], :to =&gt; :deleted
+  def password_required?
+    new_record? ? not_using_openid? &amp;&amp; (crypted_password.blank? || !password.blank?) : !password.blank?
   end
 
-  event :unsuspend do
-    transitions :from =&gt; :suspended, :to =&gt; :active,  :guard =&gt; Proc.new {|u| !u.activated_at.blank? }
-    transitions :from =&gt; :suspended, :to =&gt; :pending, :guard =&gt; Proc.new {|u| u.activated_at.blank? &amp;&amp; u.activation_code.blank? }
-    transitions :from =&gt; :suspended, :to =&gt; :unactivated, :guard =&gt; Proc.new {|u| u.activated_at.blank? &amp;&amp; !u.activation_code.blank? }
-    transitions :from =&gt; :suspended, :to =&gt; :passive
+  def normalize_identity_url
+    self.identity_url = OpenIdAuthentication.normalize_url(identity_url) unless not_using_openid?
+  rescue
+    errors.add_to_base(&quot;Invalid OpenID URL&quot;)
   end
-
+  
   # Creates a new password for the user, and notifies him with an email
   def reset_password!
     password = PasswordGenerator.random_pronouncable_password(3)
@@ -80,99 +69,74 @@ class User &lt; ActiveRecord::Base
     
     UserMailer.deliver_reset_password(self)
   end
-
-  # Authenticates a user by their login name and unencrypted password.  Returns the user or nil.
-  def self.authenticate(login, password)
-    u = find_in_state :first, :active, :conditions =&gt; {:login =&gt; login} # need to get the salt
-    u &amp;&amp; u.authenticated?(password) ? u : nil
+  
+  def forgot_password
+    self.make_password_reset_code
+    save
+    UserMailer.deliver_forgot_password(self)
   end
-
-  # Encrypts some data with the salt.
-  def self.encrypt(password, salt)
-    Digest::SHA1.hexdigest(&quot;--#{salt}--#{password}--&quot;)
+  
+  def self.find_by_login_or_email(login_or_email)
+    find(:first, :conditions =&gt; ['login = ? OR email = ?', login_or_email, login_or_email])
+  rescue
+    nil
   end
+    
+protected
 
-  # Encrypts the password with the user salt
-  def encrypt(password)
-    self.class.encrypt(password, salt)
+  def make_activation_code
+    self.deleted_at = nil
+    self.activation_code = self.class.make_token
   end
 
-  def authenticated?(password)
-    crypted_password == encrypt(password)
+  def make_password_reset_code
+    self.password_reset_code = self.class.make_token
   end
-
-  def remember_token?
-    remember_token_expires_at &amp;&amp; Time.now.utc &lt; remember_token_expires_at 
+  
+  def create_profile
+    # Give the user a profile
+    self.profile = Profile.create    
   end
+  
+# --------
 
-  # These create and unset the fields required for remembering users between browser closes
-  def remember_me
-    remember_me_for 2.weeks
-  end
+  # Virtual attribute for the unencrypted password
+  # attr_accessor :password
+  
+  # Per page pagination
+  # TODO: Replace with searchgasm
+  # cattr_reader :per_page
+  # @@per_page = 25
 
-  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(&quot;#{email}--#{remember_token_expires_at}&quot;)
-    save(false)
-  end
 
-  def forget_me
-    self.remember_token_expires_at = nil
-    self.remember_token            = nil
-    save(false)
-  end
 
-  def forgot_password
-    self.make_password_reset_code
-    save
-    UserMailer.deliver_forgot_password(self)
-  end
+  # Encrypts some data with the salt.
+  # def self.encrypt(password, salt)
+  #   Digest::SHA1.hexdigest(&quot;--#{salt}--#{password}--&quot;)
+  # end
+
+
   
-  def self.find_by_login_or_email(login_or_email)
-    find(:first, :conditions =&gt; ['login = ? OR email = ?', login_or_email, login_or_email])
-  rescue
-    nil
-  end
+
   
-  protected
     # before filter 
-    def encrypt_password
-      return if password.blank?
-      self.salt = Digest::SHA1.hexdigest(&quot;--#{Time.now.to_s}--#{login}--&quot;) if new_record?
-      self.crypted_password = encrypt(password)
-    end
-      
-    def password_required?
-      crypted_password.blank? || !password.blank?
-    end
-    
-    def make_activation_code
-      self.deleted_at = nil
-      self.activation_code = Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by {rand}.join )
-    end
+    # def encrypt_password
+    #   return if password.blank?
+    #   self.salt = Digest::SHA1.hexdigest(&quot;--#{Time.now.to_s}--#{login}--&quot;) if new_record?
+    #   self.crypted_password = encrypt(password)
+    # end
     
-    def make_password_reset_code
-      self.password_reset_code = Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by {rand}.join )
-    end
+
     
-    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
+    # 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
     
-    def create_environment
-      # Give the user a profile
-      self.profile = Profile.create
-      
-      # Give the defaul 'user' role
-      self.roles &lt;&lt; Role.find_by_name('user')
-    end
+
 end</diff>
      <filename>app/models/user.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,9 +1,9 @@
 class UserObserver &lt; ActiveRecord::Observer
   def after_create(user)
-    UserMailer.deliver_signup_notification(user)
+    UserMailer.deliver_signup_notification(user) if user.not_using_openid?
   end
 
   def after_save(user)
-    UserMailer.deliver_activation(user) if user.unactivated?
+    UserMailer.deliver_activation(user) if user.recently_activated? &amp;&amp; user.not_using_openid?
   end
 end</diff>
      <filename>app/models/user_observer.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,11 +1,19 @@
 &lt;h3&gt;Account details&lt;/h3&gt;
 &lt;table class=&quot;overview&quot;&gt;
 	&lt;%= cell &quot;Login&quot;, h(@user.login) %&gt;
-
+	
+	&lt;% if ! @user.not_using_openid? %&gt;
+	&lt;%= cell &quot;OpenID URL&quot;, h(@user.identity_url) %&gt;
+	&lt;% end %&gt;
+	
 	&lt;%= cell_separator %&gt;
 	
-	&lt;%= cell &quot;Email&quot;, &quot;#{h(@user.email)} &lt;small&gt;#{link_to &quot;change&quot;, edit_email_user_url(@user)}&lt;/small&gt;&quot; %&gt;
+	&lt;% change_email_text = @user.not_using_openid? ? &quot; &lt;small&gt;#{link_to &quot;change&quot;, edit_email_user_url(@user)}&lt;/small&gt;&quot; : &quot;&quot; %&gt;
+	
+	&lt;%= cell &quot;Email&quot;, &quot;#{h(@user.email)}#{change_email_text}&quot; %&gt;
+	&lt;% if @user.not_using_openid? %&gt;
 	&lt;%= cell &quot;Password&quot;, &quot;#{&quot;*&quot;*8} &lt;small&gt;#{link_to &quot;change&quot;, edit_password_user_url(@user)}&lt;/small&gt;&quot; %&gt;
+	&lt;% end %&gt;
 	
 	&lt;%= cell_separator %&gt;
 	</diff>
      <filename>app/views/profiles/_account_details.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -1,15 +1,21 @@
 &lt;% content_for :sidebar do -%&gt;
 &lt;h2&gt;My account&lt;/h2&gt;
 
+&lt;div id=&quot;gravatar&quot;&gt;
+	&lt;%= gravatar_for @user, :size =&gt; 100 %&gt;
+&lt;/div&gt;
+
 &lt;ul&gt;
 	&lt;li&gt;&lt;%= link_to &quot;Update my profile&quot;, edit_profile_url(current_user) %&gt;&lt;/li&gt;
 	&lt;li&gt;&lt;%= link_to &quot;Update my avatar&quot;, edit_avatar_user_url(current_user) %&gt;&lt;/li&gt;
 &lt;/ul&gt;
 
+&lt;% if @user.not_using_openid? %&gt;
 &lt;ul&gt;
 	&lt;li&gt;&lt;%= link_to &quot;Change my email address&quot;, edit_email_user_url(@user) %&gt;&lt;/li&gt;
 	&lt;li&gt;&lt;%= link_to &quot;Change my password&quot;, edit_password_user_url(@user) %&gt;&lt;/li&gt;
 &lt;/ul&gt;
+&lt;% end %&gt;
 
 &lt;% unless admin? -%&gt;
 &lt;ul&gt;</diff>
      <filename>app/views/profiles/_my_account.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -4,11 +4,7 @@
 	&lt;% end -%&gt;
 	
 	&lt;p&gt;The profile you requested does not exist.&lt;/p&gt;
-&lt;% else -%&gt;
-	&lt;div style=&quot;float: right; margin: 10px&quot;&gt;
-		&lt;%= gravatar_for @user %&gt;
-	&lt;/div&gt;
-	
+&lt;% else -%&gt;	
 	&lt;% content_for :header do -%&gt;
 		&lt;% if current_user == @user -%&gt;
 			My Account</diff>
      <filename>app/views/profiles/show.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -9,15 +9,25 @@
 &lt;% end -%&gt;
 
 &lt;% form_tag session_path do -%&gt;
-&lt;p&gt;&lt;label for=&quot;login&quot;&gt;Login&lt;/label&gt;&lt;br/&gt;
-&lt;%= text_field_tag 'login' %&gt;&lt;/p&gt;
+	&lt;fieldset&gt;
+		&lt;legend&gt;Your Details&lt;/legend&gt;
+		
+		&lt;p&gt;&lt;label for=&quot;login&quot;&gt;Login&lt;/label&gt;&lt;br/&gt;
+		&lt;%= text_field_tag 'login' %&gt;&lt;/p&gt;
 
-&lt;p&gt;&lt;label for=&quot;password&quot;&gt;Password&lt;/label&gt;&lt;br/&gt;
-&lt;%= password_field_tag 'password' %&gt;&lt;/p&gt;
-
-&lt;p&gt;&lt;label for=&quot;remember_me&quot;&gt;Remember me:&lt;/label&gt;
-&lt;%= check_box_tag 'remember_me' %&gt;&lt;/p&gt;
+		&lt;p&gt;&lt;label for=&quot;password&quot;&gt;Password&lt;/label&gt;&lt;br/&gt;
+		&lt;%= password_field_tag 'password' %&gt;&lt;/p&gt;
 
+		&lt;p&gt;&lt;label for=&quot;remember_me&quot;&gt;Remember me:&lt;/label&gt;
+		&lt;%= check_box_tag 'remember_me' %&gt;&lt;/p&gt;
+	&lt;/fieldset&gt;
+	&lt;fieldset&gt;
+		&lt;legend&gt;Login with OpenID&lt;/legend&gt;
+		
+		&lt;p&gt;&lt;label for=&quot;openid_url&quot;&gt;OpenID URL&lt;/label&gt;&lt;br/&gt;
+		&lt;%= text_field_tag 'openid_url' %&gt;&lt;/p&gt;		
+	&lt;/fieldset&gt;
+	
 &lt;ul&gt;
 	&lt;li&gt;&lt;%= link_to &quot;Sign up for an account now&quot;, signup_url %&gt;&lt;/li&gt;
 	&lt;li&gt;&lt;%= link_to &quot;Having trouble logging in?&quot;, user_troubleshooting_url %&gt;&lt;/li&gt;</diff>
      <filename>app/views/sessions/new.rhtml</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,5 @@
+&lt;% @user.password = @user.password_confirmation = nil %&gt;
+
 &lt;% content_for :header do -%&gt;
 Create a new &lt;%= s(:site_name) %&gt; account
 &lt;% end -%&gt;
@@ -10,22 +12,29 @@ Create a new &lt;%= s(:site_name) %&gt; account
 	Already have an account? &lt;%= link_to(&quot;Login here&quot;, login_url)%&gt;
 &lt;/p&gt;
 
-&lt;%= error_messages_for :user %&gt;
 &lt;% form_for :user, :url =&gt; users_path do |f| -%&gt;
-&lt;p&gt;&lt;label for=&quot;login&quot;&gt;Login&lt;/label&gt;&lt;br/&gt;
-&lt;%= f.text_field :login %&gt;&lt;/p&gt;
-
-&lt;p&gt;&lt;label for=&quot;email&quot;&gt;Email&lt;/label&gt;&lt;br/&gt;
-&lt;%= f.text_field :email %&gt;&lt;/p&gt;
-
-&lt;p&gt;&lt;label for=&quot;password&quot;&gt;Password&lt;/label&gt;&lt;br/&gt;
-&lt;%= f.password_field :password %&gt;&lt;/p&gt;
-
-&lt;p&gt;&lt;label for=&quot;password_confirmation&quot;&gt;Confirm Password&lt;/label&gt;&lt;br/&gt;
-&lt;%= f.password_field :password_confirmation %&gt;&lt;/p&gt;
-
-
-&lt;div id=&quot;submitbutton&quot;&gt;
-	&lt;p&gt;&lt;%= submit_tag 'Sign up' %&gt;&lt;/p&gt;
-&lt;/div&gt;
-&lt;% end -%&gt;
+	&lt;%= error_messages_for :user %&gt;
+	&lt;fieldset&gt;	
+		&lt;legend&gt;Your Details&lt;/legend&gt;
+		&lt;p&gt;&lt;label for=&quot;login&quot;&gt;Login&lt;/label&gt;&lt;br/&gt;
+		&lt;%= f.text_field :login %&gt;&lt;/p&gt;
+
+		&lt;p&gt;&lt;label for=&quot;email&quot;&gt;Email&lt;/label&gt;&lt;br/&gt;
+		&lt;%= f.text_field :email %&gt;&lt;/p&gt;
+
+		&lt;p&gt;&lt;label for=&quot;password&quot;&gt;Password&lt;/label&gt;&lt;br/&gt;
+		&lt;%= f.password_field :password %&gt;&lt;/p&gt;
+
+		&lt;p&gt;&lt;label for=&quot;password_confirmation&quot;&gt;Confirm Password&lt;/label&gt;&lt;br/&gt;
+		&lt;%= f.password_field :password_confirmation %&gt;&lt;/p&gt;
+	&lt;/fieldset&gt;
+	&lt;fieldset&gt;
+		&lt;legend&gt;Signup with OpenID&lt;/legend&gt;
+		&lt;p&gt;&lt;label for=&quot;openid_url&quot;&gt;OpenID URL&lt;/label&gt;&lt;br/&gt;
+		&lt;%= text_field_tag :openid_url, params[:openid_url] || params['openid.identity'] %&gt;&lt;/p&gt;
+	&lt;/fieldset&gt;
+	
+	&lt;div id=&quot;submitbutton&quot;&gt;
+		&lt;p&gt;&lt;%= submit_tag 'Sign up' %&gt;&lt;/p&gt;
+	&lt;/div&gt;
+&lt;% end %&gt;</diff>
      <filename>app/views/users/new.rhtml</filename>
    </modified>
    <modified>
      <diff>@@ -15,4 +15,8 @@ config.action_controller.perform_caching             = false
 config.action_view.cache_template_extensions         = false
 
 # Don't care if the mailer can't send
-config.action_mailer.raise_delivery_errors = false
\ No newline at end of file
+config.action_mailer.raise_delivery_errors = false
+
+# Restful Authentication
+REST_AUTH_SITE_KEY = '5a5e73a69a893311f859ccff1ffd0fa2d7ea25fd'
+REST_AUTH_DIGEST_STRETCHES = 15
\ No newline at end of file</diff>
      <filename>config/environments/development.rb</filename>
    </modified>
    <modified>
      <diff>@@ -17,3 +17,7 @@ config.action_view.cache_template_loading            = true
 
 # Disable delivery errors, bad email addresses will be ignored
 # config.action_mailer.raise_delivery_errors = false
+
+# Restful Authentication
+REST_AUTH_SITE_KEY = '5a5e73a69a893311f859ccff1ffd0fa2d7ea25fd'
+REST_AUTH_DIGEST_STRETCHES = 15
\ No newline at end of file</diff>
      <filename>config/environments/production.rb</filename>
    </modified>
    <modified>
      <diff>@@ -20,3 +20,7 @@ config.action_controller.allow_forgery_protection    = false
 # The :test delivery method accumulates sent emails in the
 # ActionMailer::Base.deliveries array.
 config.action_mailer.delivery_method = :test
+
+# Restful Authentication
+REST_AUTH_SITE_KEY = '5a5e73a69a893311f859ccff1ffd0fa2d7ea25fd'
+REST_AUTH_DIGEST_STRETCHES = 15
\ No newline at end of file</diff>
      <filename>config/environments/test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,13 +1,22 @@
 # See how all your routes lay out with &quot;rake routes&quot;
 ActionController::Routing::Routes.draw do |map|
   
-  # Non RESTful routes for user management.
+  # RESTful rewrites
+  
+  map.signup   '/signup',   :controller =&gt; 'users',    :action =&gt; 'new'
+  map.activate '/activate/:activation_code', :controller =&gt; 'users',    :action =&gt; 'activate'
+  map.login    '/login',    :controller =&gt; 'sessions', :action =&gt; 'new'
+  map.logout   '/logout',   :controller =&gt; 'sessions', :action =&gt; 'destroy', :conditions =&gt; {:method =&gt; :delete}
+  
   map.user_troubleshooting '/users/troubleshooting', :controller =&gt; 'users', :action =&gt; 'troubleshooting'
   map.user_forgot_password '/users/forgot_password', :controller =&gt; 'users', :action =&gt; 'forgot_password'
   map.user_reset_password  '/users/reset_password/:password_reset_code', :controller =&gt; 'users', :action =&gt; 'reset_password'
   map.user_forgot_login    '/users/forgot_login',    :controller =&gt; 'users', :action =&gt; 'forgot_login'
   map.user_clueless        '/users/clueless',        :controller =&gt; 'users', :action =&gt; 'clueless'
   
+  map.open_id_complete '/opensession', :controller =&gt; &quot;sessions&quot;, :action =&gt; &quot;create&quot;, :requirements =&gt; { :method =&gt; :get }
+  map.open_id_create '/opencreate', :controller =&gt; &quot;users&quot;, :action =&gt; &quot;create&quot;, :requirements =&gt; { :method =&gt; :get }
+    
   map.resources :users, :member =&gt; { :edit_password =&gt; :get,
                                      :update_password =&gt; :put,
                                      :edit_email =&gt; :get,
@@ -16,13 +25,7 @@ ActionController::Routing::Routes.draw do |map|
                                      :update_avatar =&gt; :put }
                             
   map.resource :session
-  
-  # Account shortcuts
-  map.signup   '/signup',   :controller =&gt; 'users',    :action =&gt; 'new'
-  map.activate '/activate/:activation_code', :controller =&gt; 'users',    :action =&gt; 'activate'
-  map.login    '/login',    :controller =&gt; 'sessions', :action =&gt; 'new'
-  map.logout   '/logout',   :controller =&gt; 'sessions', :action =&gt; 'destroy', :conditions =&gt; {:method =&gt; :delete}
-  
+    
   # Profiles
   map.resources :profiles
   </diff>
      <filename>config/routes.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,22 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version =&gt; 20080101000005) do
+ActiveRecord::Schema.define(:version =&gt; 20081023115224) do
+
+  create_table &quot;open_id_authentication_associations&quot;, :force =&gt; true do |t|
+    t.integer &quot;issued&quot;
+    t.integer &quot;lifetime&quot;
+    t.string  &quot;handle&quot;
+    t.string  &quot;assoc_type&quot;
+    t.binary  &quot;server_url&quot;
+    t.binary  &quot;secret&quot;
+  end
+
+  create_table &quot;open_id_authentication_nonces&quot;, :force =&gt; true do |t|
+    t.integer &quot;timestamp&quot;,                  :null =&gt; false
+    t.string  &quot;server_url&quot;
+    t.string  &quot;salt&quot;,       :default =&gt; &quot;&quot;, :null =&gt; false
+  end
 
   create_table &quot;profiles&quot;, :force =&gt; true do |t|
     t.integer  &quot;user_id&quot;
@@ -29,9 +44,6 @@ ActiveRecord::Schema.define(:version =&gt; 20080101000005) do
     t.integer &quot;user_id&quot;
   end
 
-  add_index &quot;roles_users&quot;, [&quot;role_id&quot;], :name =&gt; &quot;index_roles_users_on_role_id&quot;
-  add_index &quot;roles_users&quot;, [&quot;user_id&quot;], :name =&gt; &quot;index_roles_users_on_user_id&quot;
-
   create_table &quot;settings&quot;, :force =&gt; true do |t|
     t.string   &quot;label&quot;
     t.string   &quot;identifier&quot;
@@ -43,19 +55,23 @@ ActiveRecord::Schema.define(:version =&gt; 20080101000005) do
   end
 
   create_table &quot;users&quot;, :force =&gt; true do |t|
-    t.string   &quot;login&quot;
-    t.string   &quot;email&quot;
+    t.string   &quot;login&quot;,                     :limit =&gt; 40
+    t.string   &quot;identity_url&quot;
+    t.string   &quot;name&quot;,                      :limit =&gt; 100, :default =&gt; &quot;&quot;
+    t.string   &quot;email&quot;,                     :limit =&gt; 100
     t.string   &quot;crypted_password&quot;,          :limit =&gt; 40
     t.string   &quot;salt&quot;,                      :limit =&gt; 40
-    t.datetime &quot;created_at&quot;
-    t.datetime &quot;updated_at&quot;
-    t.string   &quot;remember_token&quot;
-    t.datetime &quot;remember_token_expires_at&quot;
+    t.string   &quot;remember_token&quot;,            :limit =&gt; 40
     t.string   &quot;activation_code&quot;,           :limit =&gt; 40
+    t.string   &quot;state&quot;,                                    :default =&gt; &quot;passive&quot;
+    t.datetime &quot;remember_token_expires_at&quot;
+    t.string   &quot;password_reset_cod&quot;
     t.datetime &quot;activated_at&quot;
-    t.string   &quot;state&quot;,                                   :default =&gt; &quot;passive&quot;
     t.datetime &quot;deleted_at&quot;
-    t.string   &quot;password_reset_code&quot;
+    t.datetime &quot;created_at&quot;
+    t.datetime &quot;updated_at&quot;
   end
 
+  add_index &quot;users&quot;, [&quot;login&quot;], :name =&gt; &quot;index_users_on_login&quot;, :unique =&gt; true
+
 end</diff>
      <filename>db/schema.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,21 +3,21 @@ module AuthenticatedSystem
     # Returns true or false if the user is logged in.
     # Preloads @current_user with the user model if they're logged in.
     def logged_in?
-      current_user != :false
+      !!current_user
     end
-    
-    # Accesses the current user from the session.  Set it to :false if login fails
-    # so that future calls do not hit the database.
+
+    # Accesses the current user from the session.
+    # Future calls avoid the database because nil is not equal to false.
     def current_user
-      @current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie || :false)
+      @current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false
     end
-        
-    # Store the given user in the session.
+
+    # Store the given user id in the session.
     def current_user=(new_user)
-      session[:user] = (new_user.nil? || new_user.is_a?(Symbol)) ? nil : new_user.id
-      @current_user = new_user
+      session[:user_id] = new_user ? new_user.id : nil
+      @current_user = new_user || false
     end
-    
+
     # Check if the user is authorized
     #
     # Override this method in your controllers if you want to restrict access
@@ -30,7 +30,8 @@ module AuthenticatedSystem
     #  def authorized?
     #    current_user.login != &quot;bob&quot;
     #  end
-    def authorized?
+    #
+    def authorized?(action=nil, resource=nil, *args)
       logged_in?
     end
 
@@ -61,68 +62,126 @@ module AuthenticatedSystem
     # to access the requested action.  For example, a popup window might
     # simply close itself.
     def access_denied
-      respond_to do |accepts|
-        accepts.html do
+      respond_to do |format|
+        format.html do
           store_location
-          redirect_to :controller =&gt; '/sessions', :action =&gt; 'new'
+          redirect_to new_session_path
         end
-        accepts.xml do
-          headers[&quot;Status&quot;]           = &quot;Unauthorized&quot;
-          headers[&quot;WWW-Authenticate&quot;] = %(Basic realm=&quot;Web Password&quot;)
-          render :text =&gt; &quot;Could't authenticate you&quot;, :status =&gt; '401 Unauthorized'
+        # format.any doesn't work in rails version &lt; http://dev.rubyonrails.org/changeset/8987
+        # you may want to change format.any to e.g. format.any(:js, :xml)
+        format.any do
+          request_http_basic_authentication 'Web Password'
         end
       end
-      false
-    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.
+    # to the passed default.  Set an appropriately modified
+    #   after_filter :store_location, :only =&gt; [:index, :new, :show, :edit]
+    # for any controller you want to be bounce-backable.
     def redirect_back_or_default(default)
       redirect_to(session[:return_to] || default)
       session[:return_to] = nil
     end
-    
+
     # Inclusion hook to make #current_user and #logged_in?
     # available as ActionView helper methods.
     def self.included(base)
-      base.send :helper_method, :current_user, :logged_in?
+      base.send :helper_method, :current_user, :logged_in?, :authorized? if base.respond_to? :helper_method
     end
 
+    #
+    # Login
+    #
+
     # Called from #current_user.  First attempt to login by the user id stored in the session.
     def login_from_session
-      self.current_user = User.find_by_id(session[:user]) if session[:user]
+      self.current_user = User.find_by_id(session[:user_id]) if session[:user_id]
     end
 
     # Called from #current_user.  Now, attempt to login by basic authentication information.
     def login_from_basic_auth
-      username, passwd = get_auth_data
-      self.current_user = User.authenticate(username, passwd) if username &amp;&amp; passwd
+      authenticate_with_http_basic do |login, password|
+        self.current_user = User.authenticate(login, password)
+      end
     end
+    
+    #
+    # Logout
+    #
 
     # Called from #current_user.  Finaly, attempt to login by an expiring token in the cookie.
-    def login_from_cookie      
+    # for the paranoid: we _should_ be storing user_token = hash(cookie_token, request IP)
+    def login_from_cookie
       user = cookies[:auth_token] &amp;&amp; User.find_by_remember_token(cookies[:auth_token])
       if user &amp;&amp; user.remember_token?
-        user.remember_me
-        cookies[:auth_token] = { :value =&gt; user.remember_token, :expires =&gt; user.remember_token_expires_at }
         self.current_user = user
+        handle_remember_cookie! false # freshen cookie token (keeping date)
+        self.current_user
       end
     end
 
-  private
-    @@http_auth_headers = %w(Authorization HTTP_AUTHORIZATION X-HTTP_AUTHORIZATION X_HTTP_AUTHORIZATION REDIRECT_X_HTTP_AUTHORIZATION)
+    # This is ususally what you want; resetting the session willy-nilly wreaks
+    # havoc with forgery protection, and is only strictly necessary on login.
+    # However, **all session state variables should be unset here**.
+    def logout_keeping_session!
+      # Kill server-side auth cookie
+      @current_user.forget_me if @current_user.is_a? User
+      @current_user = false     # not logged in, and don't do it for me
+      kill_remember_cookie!     # Kill client-side auth cookie
+      session[:user_id] = nil   # keeps the session but kill our variable
+      # explicitly kill any other session variables you set
+    end
 
-    # gets BASIC auth info
-    def get_auth_data
-      auth_key  = @@http_auth_headers.detect { |h| request.env.has_key?(h) }
-      auth_data = request.env[auth_key].to_s.split unless auth_key.blank?
-      return auth_data &amp;&amp; auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil] 
+    # The session should only be reset at the tail end of a form POST --
+    # otherwise the request forgery protection fails. It's only really necessary
+    # when you cross quarantine (logged-out to logged-in).
+    def logout_killing_session!
+      logout_keeping_session!
+      reset_session
     end
+    
+    #
+    # Remember_me Tokens
+    #
+    # Cookies shouldn't be allowed to persist past their freshness date,
+    # and they should be changed at each login
+
+    # Cookies shouldn't be allowed to persist past their freshness date,
+    # and they should be changed at each login
+
+    def valid_remember_cookie?
+      return nil unless @current_user
+      (@current_user.remember_token?) &amp;&amp; 
+        (cookies[:auth_token] == @current_user.remember_token)
+    end
+    
+    # Refresh the cookie auth token if it exists, create it otherwise
+    def handle_remember_cookie! new_cookie_flag
+      return unless @current_user
+      case
+      when valid_remember_cookie? then @current_user.refresh_token # keeping same expiry date
+      when new_cookie_flag        then @current_user.remember_me 
+      else                             @current_user.forget_me
+      end
+      send_remember_cookie!
+    end
+  
+    def kill_remember_cookie!
+      cookies.delete :auth_token
+    end
+    
+    def send_remember_cookie!
+      cookies[:auth_token] = {
+        :value   =&gt; @current_user.remember_token,
+        :expires =&gt; @current_user.remember_token_expires_at }
+    end
+
 end</diff>
      <filename>lib/authenticated_system.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,10 +1,20 @@
 module AuthenticatedTestHelper
   # Sets the current user in the session from the user fixtures.
   def login_as(user)
-    @request.session[:user] = user ? users(user).id : nil
+    @request.session[:user_id] = user ? users(user).id : nil
   end
 
   def authorize_as(user)
-    @request.env[&quot;HTTP_AUTHORIZATION&quot;] = user ? &quot;Basic #{Base64.encode64(&quot;#{users(user).login}:test&quot;)}&quot; : nil
+    @request.env[&quot;HTTP_AUTHORIZATION&quot;] = user ? ActionController::HttpAuthentication::Basic.encode_credentials(users(user).login, 'monkey') : nil
   end
-end
\ No newline at end of file
+  
+  # rspec
+  def mock_user
+    user = mock_model(User, :id =&gt; 1,
+      :login  =&gt; 'user_name',
+      :name   =&gt; 'U. Surname',
+      :to_xml =&gt; &quot;User-in-XML&quot;, :to_json =&gt; &quot;User-in-JSON&quot;, 
+      :errors =&gt; [])
+    user
+  end  
+end</diff>
      <filename>lib/authenticated_test_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,3 +1,10 @@
+# To use the Bootstrap Rake task for you own application create
+# yaml files in db/bootstrap containing your data.
+#
+# E.g. to fill the 'users' table, create the yaml file db/bootstrap/users.yml
+# 
+# Next, run 'rake db:bootstrap' to re-initialize your database.
+#
 namespace :db do
   desc &quot;Recreates the development database and loads the bootstrap fixtures from db/boostrap.&quot;
   task :bootstrap do |task_args|
@@ -6,14 +13,7 @@ namespace :db do
     require 'rubygems' unless Object.const_defined?(:Gem)
         
     %w(environment db:drop db:create db:migrate db:bootstrap:load tmp:create).each { |t| Rake::Task[t].execute task_args}
-    
-    puts
-    puts '=' * 80
-    puts
-    puts &quot;You've been bootstrapped!&quot;
-    puts
-    puts &quot;Enjoy!&quot;
-    puts
+
   end
   
   namespace :bootstrap do</diff>
      <filename>lib/tasks/bootstrap.rake</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>config/initializers/gravatar.rb</filename>
    </removed>
    <removed>
      <filename>db/bootstrap/roles.yml</filename>
    </removed>
    <removed>
      <filename>db/bootstrap/roles_users.yml</filename>
    </removed>
    <removed>
      <filename>db/bootstrap/settings.yml</filename>
    </removed>
    <removed>
      <filename>db/bootstrap/users.yml</filename>
    </removed>
    <removed>
      <filename>db/migrate/20080101000001_create_users.rb</filename>
    </removed>
    <removed>
      <filename>db/migrate/20080101000002_create_profiles.rb</filename>
    </removed>
    <removed>
      <filename>db/migrate/20080101000003_create_roles.rb</filename>
    </removed>
    <removed>
      <filename>db/migrate/20080101000004_add_user_reset_password_code.rb</filename>
    </removed>
    <removed>
      <filename>db/migrate/20080101000005_create_settings.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>f0871d848857e63a3606a4df88094af53ce410fc</id>
    </parent>
  </parents>
  <author>
    <name>Ariejan de Vroom</name>
    <email>ariejan@ariejan.net</email>
  </author>
  <url>http://github.com/ariejan/baseapp/commit/4f78db2bd290c00acdc2c98f130d6eb78adcfa04</url>
  <id>4f78db2bd290c00acdc2c98f130d6eb78adcfa04</id>
  <committed-date>2008-10-23T03:43:20-07:00</committed-date>
  <authored-date>2008-10-23T03:43:20-07:00</authored-date>
  <message>Enabled OpenID sign up and login and made minor changes to the view</message>
  <tree>be872307b3bcb4c043586b4d6dbb22c13c9f075a</tree>
  <committer>
    <name>Ariejan de Vroom</name>
    <email>ariejan@ariejan.net</email>
  </committer>
</commit>
