    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>vaporbase :: stateful authentication</title>
        <link>http://www.vaporbase.com/</link>
        <description>the knowledge base that almost is</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Vaporbase Admin</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:admin@parkerhill.com" /> 
       <sy:updatePeriod>hourly</sy:updatePeriod> 
       <sy:updateFrequency>1</sy:updateFrequency> 
       <docs>http://backend.userland.com/rss</docs>

<!-- show a header for the current publication type -->
        <h2>Postings</h2>


<div class="xar-mod-head"><span class="xar-mod-title">rails</span></div>

<table border="0" cellpadding="1" cellspacing="0">
<tr>
    <td valign="top">
        Browse in :
   </td>
   <td valign="top">

                                    <a href="http://www.vaporbase.com/postings/">All</a>

                 &gt;                     <a href="http://www.vaporbase.com/postings/c36/">subjects</a>

                 &gt;                     <a href="http://www.vaporbase.com/postings/c42/">rails</a>
<br />
</td>
</tr>
</table>






<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xd</em>
and <em>user-summary-[publicationtype].xd</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles
The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;stateful authentication</h1>
<p><strong>Author:</strong>&nbsp;linoj</p>
<p>
<strong>Date:</strong> September 21, 2007 12:40:18 PM  or Fri, 21 September 2007 12:40:18 </p>
<p><strong>Summary:</strong>&nbsp;I wanted user records in my app to have various statuses. Here's how I modified restful_authentication with acts_as_state_machine to accomplish this. I'll call it stateful_authentication</p>
<p><strong>Body:</strong>&nbsp;<h4>Overview </h4><p>The idea is to enhance restful_authentication with additional user statuses.</p><ul><li>:passive - not authorized to log in, but known to the system, such as for mailing lists</li><li>:pending - user has registered but has not activated his account yet<br /></li><li>:active - user account is active, user can log in<br /></li><li>:suspended - user account suspended, not allowed to log in, can be re-enabled</li><li>:deleted - user id remains valid but account deleted, login name and email can be reused </li></ul><p>Passive users may have signed up on the system, given their email and name or whatever, but don&#39;t have the right to log in. Passive users can register later with login privileges.</p><p>An active user can log in. (As for roles, authorization is handled separately from authentication, see <a href="postings/Authorization_in_Rails">my earlier post</a> ). </p><p>Any user can be suspended by the administrator, for whatever reason. Suspended accounts can be re-enabled (un-suspended). </p><p>Keeping deleted user records is handy, for example, if some other objects such as a Comment references this user id, you can still retrieve some info about the poster even if he&#39;s no longer around. (A separate admin purge action can actually call destroy on deleted users). A deleted user will have its login and email changed with the string &quot;[DELETED <em>datetime</em>]&quot; appended, so they can be reused in a new user record. </p><pre>&quot;john@gmail.com [DELETED Fri Sep 21 13:35:07 -0400 2007]&quot; </pre><p>In restful_authentication, the User model includes columns for <em>login</em> name, <em>email</em>, <em>crypted_password</em>, <em>activation_code</em> (allows user to active the account), and <em>activated_at</em> date (once account is activated). You could say an :active status is implied when <em>activated_at</em> is not blank?; and a :pending status is implied when <em>activation_code</em> is not blank?.  </p><p>Our case extends this. You could say a :passive status is when both <em>activated_at</em> and <em>activation_code</em> are nil. But any user can be suspended or deleted regardless of these attribute values.</p><h4>Setup </h4><p>This article assumes you have installed the restful_authentication plugin and the acts_as_state_machine plugin. Note, I generated RA to require user activation (--include-activation).</p><pre>  $ script/plugin source <a href="http://svn.techno-weenie.net/projects/plugins" target="_blank">http://svn.techno-weenie.net/projects/plugins</a></pre><pre>  $ script/plugin install restful_authentication</pre><pre>  $ script/generate authenticated user sessions --include-activation</pre><pre>  $ rake db:migrate </pre><pre>add observer to environment.rb </pre><pre>add named routes to routes.rb</pre><pre>move lines from users_controller.rb to application.rb</pre><pre>edit user_notifier.rb as needed </pre><pre>  $ script/plugin install <a href="http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/" target="_blank">http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/</a> </pre><p>I&#39;ll leave other details to others, e.g.</p><p>  <a href="http://svn.techno-weenie.net/projects/plugins/restful_authentication/README" target="_blank">http://svn.techno-weenie.net/projects/plugins/restful_authentication/README</a> </p><p>  <a href="http://weblog.techno-weenie.net/2006/8/1/restful-authentication-plugin" target="_blank">http://weblog.techno-weenie.net/2006/8/1/restful-authentication-plugin</a></p><p>  <a href="http://agilewebdevelopment.com/plugins/restful_authentication" target="_blank">http://agilewebdevelopment.com/plugins/restful_authentication</a></p><p>    <a href="http://www.urbanpuddle.com/articles/2007/03/05/restful-authentication-for-ruby-on-rails-apps" target="_blank">http://www.urbanpuddle.com/articles/2007/03/05/restful-authentication-for-ruby-on-rails-apps</a></p><p>  <a href="http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/README" target="_blank">http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk/README</a> </p><p>  <a href="http://rails.aizatto.com/2007/05/24/ruby-on-rails-finite-state-machine-plugin-acts_as_state_machine/" target="_blank">http://rails.aizatto.com/2007/05/24/ruby-on-rails-finite-state-machine-plugin-acts_as_state_machine/</a></p><p>  <a href="http://www.slideshare.net/dhpeterson/a-simple-workflow-system-using-state-machines" target="_blank">http://www.slideshare.net/dhpeterson/a-simple-workflow-system-using-state-machines</a> </p><p>  <a href="http://iamruinous.com/2007/3/6/automatically-calling-acts_as_state_machine-events-on-update" target="_blank">http://iamruinous.com/2007/3/6/automatically-calling-acts_as_state_machine-events-on-update</a> <br /><br /></p><p>Maybe I should consider making this a whole new plugin, but for now here&#39;s instructions to DIY (do it yourself).</p><h4>User model</h4><p>Make the User a state-machine. First, add a status attribute to the User model (we&#39;ll call it <em>status</em> rather than <em>state</em>)<br /></p><pre>$ script/generate migration add_status_to_users</pre><p>edit with</p><pre>add_column :users, :status, :string, :null =&gt; :no, :default =&gt; &quot;passive&quot; </pre><p>and then<br /></p><pre>$ rake db:migrate </pre><p>&nbsp;</p><p>To models/user.rb, add:</p><pre>  acts_as_state_machine :initial =&gt; :passive, :column =&gt; :status<br />  state :passive<br />  state :pending, :enter =&gt; :make_activation_code<br />  state :active, :enter =&gt; :do_activate<br />  state :suspended<br />  state :deleted, :enter =&gt; :do_delete<br /></pre><p>Add the state machine transition events:</p><pre>  event :register do<br />    transitions :from =&gt; :passive, :to =&gt; :pending, :guard =&gt; Proc.new {|u| !u.crypted_password.blank? }<br />  end<br />  <br />  event :activate do<br />    transitions :from =&gt; :pending, :to =&gt; :active <br />  end<br />  <br />  event :suspend do<br />    transitions :from =&gt; [:passive, :pending, :active], :to =&gt; :suspended<br />  end<br />  <br />  event :delete do<br />    transitions :from =&gt; [:passive, :pending, :active, :suspended], :to =&gt; :deleted<br />  end<br /><br />  event :unsuspend do<br />    transitions :from =&gt; :suspended, :to =&gt; :active, :guard =&gt; Proc.new {|u| !u.activated_at.blank? }<br />    transitions :from =&gt; :suspended, :to =&gt; :pending, :guard =&gt; Proc.new {|u| !u.activation_code.blank? }<br />    transitions :from =&gt; :suspended, :to =&gt; :passive<br />  end<br /> </pre><pre> </pre><p>Thus when a new user is created, it&#39;s :passive. Then, user.register! will move a user from :passive to :pending (provided it has a password), and an activation_code is generated). </p><p>user.activate! will activate the account. To avoid confusion with the original #activate method, rename the old one to #do_activate. And make a small change to preserve the activated_at date (like when transitioning from suspended back to active). <br /> </p><pre>  # rename old activate to do_activate<br />  def do_activate</pre><pre>    @activated = true</pre><pre><em>    self.activated_at ||= Time.now.utc</em></pre><pre><em>    self.activation_code = nil</em><br /> end</pre><p>Also, now the activated? method is handled by our new active? method: <br /></p><pre>  # retain for compatibility, redundant with active?</pre><pre>  def activated?<br />    <em>active?</em></pre><pre>  end</pre><br /><p>Add a do_delete method (can be in protected)</p><pre>    def do_delete<br />      t = Time.now.to_s </pre><pre>      self.login += &quot; [DELETED #{t}]&quot;</pre><pre>      self.email += &quot; [DELETED #{t}]&quot;</pre><pre>    end</pre><p>Comment out the following because a new passive user doesn&#39;t need an activation code. Rather, this gets called in the :pending <em>:enter</em> callback: </p><pre>#before_create :make_activation_code</pre><p>When is password required? In original RA, it was always required if the crypted_password attribute is blank (new user) or if the password is being changed. Now, users don&#39;t need a password unless they&#39;re going to be activating an account, and guard that in the :register event transition. So the password (and password_confirmation) is validated only if it is present, thus, change password_required to</p><pre>    def password_required?</pre><pre>      <em>!password.blank?</em></pre><pre>    end </pre><p>One last thing, we only want to authenticate users who are active. Change self.authenticate to check:</p><pre>  def self.authenticate(login, password)</pre><pre>    <em>u = find :first, :conditions =&gt; [&#39;login = ? and status = &quot;active&quot;&#39;, login]</em></pre><pre>    u &amp;&amp; u.authenticated?(password) ? u : nil</pre><pre>  end</pre><p> Note that anywhere in your code that you do a Users.find, you now need to scope that by the requested state, such as</p><pre>users = User.find_all_by_status(:active)</pre><p>&nbsp;</p><h4>UsersController </h4><p>Okeydokey, next is the controller... </p><p>In users_controller.rb, the create action can now create either a passive or pending user. We&#39;ll use the presence of a password field to signal a new registration otherwise its a passive signup. Note, create does double duty, if the user exists as passive, it still moves ahead (or you could add an update action if this disturbs your REST, see <a href="http://iamruinous.com/2007/3/6/automatically-calling-acts_as_state_machine-events-on-update">this</a> ).  </p><pre>  def create</pre><pre>    @user = User.find_by_email_and_status(params[:user][:email], :passive) if params[:user][:email]</pre><pre>    if @user.nil?</pre><pre>      @user = User.new(params[:user])</pre><pre>      @user.save!</pre><pre>    end</pre><pre>    @user.register! if params[:password]</pre><pre>    self.current_user = @user if @user.pending? # lets user be logged in before activating</pre><pre>    redirect_back_or_default(&#39;/&#39;)</pre><pre>    flash[:notice] = &quot;Thanks for signing up!&quot;</pre><pre>  rescue ActiveRecord::RecordInvalid</pre><pre>    render :action =&gt; &#39;new&#39;</pre><pre>  end</pre><p>(Notes: I decided to key off a unique email rather than login name, seems more intuitive. Could be either. #create must fail if there&#39;s no params[:email]; we let the User.new handle that validation and rescue). </p><p>In the activate action, the only change is call the new <em>#activate!</em> rather than <em>#activate</em></p><pre>  def activate</pre><pre>    self.current_user = User.find_by_activation_code(params[:activation_code])</pre><pre>    if logged_in? &amp;&amp; !current_user.activated?</pre><pre>      <em>current_user.activate!</em></pre><pre>      flash[:notice] = &quot;Signup complete!&quot;</pre><pre>    end</pre><pre>    redirect_back_or_default(&#39;/&#39;)</pre><pre>  end</pre><p> If you&#39;ve included the <a href="http://technoweenie.stikipad.com/plugins/show/Allow+users+to+edit+reset+and+change+passwords">forgot password stuff</a>  then in #forgot_password, change this line:</p><pre>    #if @user = User.find_by_email(params[:user][:email])</pre><pre>    if @user = User.find_by_email_and_status(params[:user][:email], &quot;active&quot;) </pre><p>Finally, we can add #suspend, #unsuspend, #destroy and #purge actions (which should be available only to authorized admin users-- you&#39;ll need your own :admin_required helper for this). <br /> </p><pre>before_filter :admin_required, :only =&gt; [:suspend, :unsuspend, :destroy, :purge]<br /></pre><pre> </pre><pre>  # PUT /users/1/suspend<br />  def suspend<br />    @user = User.find(params[:id])<br />    @user.suspend! <br />    redirect_to(users_url)<br />  end<br /><br />  # PUT /users/1/unsuspend<br />  def unsuspend<br />    @user = User.find(params[:id])<br />    @user.unsuspend! <br />    redirect_to(users_url)<br />  end<br /><br />  # DELETE /users/1<br />  def destroy<br />    @user = User.find(params[:id])<br />    @user.delete!<br />    redirect_to(users_url)<br />  end<br /><br />  # DELETE /users/1/purge<br />  def purge<br />    @user = User.find(params[:id])<br />    @user.destroy<br />    redirect_to(users_url)<br />  end<br /></pre><pre> </pre>Make sure the corresponding routes are mapped in routes.rb. This is how I&#39;m doing it,<pre>    map.resources :users, <br />                :member =&gt; { :suspend =&gt; :put,<br />                             :unsuspend =&gt; :put,<br />                             :purge =&gt; :delete }<br /><br /></pre><p>along with all the other named routes for the RA plugin (e.g. map.signup, map.activate, etc). </p><h4>Observer / Notifier</h4><p>The signup notification email (with activation_code) should be sent only when the user is pending. In user_observer.rb, remove the entire after_create method and add the following line to after_save</p><pre>UserNotifier.deliver_signup_notification(user) if user.pending?</pre><h4>Views </h4><p>You could also adjust your views, but basically now a user can sign up with or without a password. When password is omitted, a passive user is captured (say, for subscription to a newsletter). When password is provided, he goes through full registration. Passive users can register later by supplying his email and a new password.  <br /></p><h4>Tests</h4><p>To get the restful_authentication tests to work with our changes, do the following:</p><p>in users.yml, </p><blockquote><p>    add &quot;status: active&quot; to the quentin user record</p><p>    add &quot;status: pending&quot; to the aaron user record</p></blockquote><p>in user_test.rb:</p><blockquote><p>remove the test_should_require_password, since its not required </p></blockquote><p>in users_controller_test.rb: </p><blockquote><p>    remove the test_should_require_password_on_signup, since its not required </p></blockquote><p>To extend the tests for our new features... well, yes you should do that. Here&#39;s a handful that&#39;d go into user_test.rb, certainly not full coverage.</p><pre>    def test_should_create_passive_user</pre><pre>      assert_difference User, :count do</pre><pre>        user = create_user(:password =&gt; nil, :password_confirmation =&gt; nil)</pre><pre>        assert !user.new_record?, &quot;#{user.errors.full_messages.to_sentence}&quot;</pre><pre>        assert user.passive?</pre><pre>      end</pre><pre>    end     </pre><pre>    def test_should_register_passive_user</pre><pre>        user = create_user(:password =&gt; nil, :password_confirmation =&gt; nil)</pre><pre>        assert user.passive?</pre><pre>        user.update_attributes(:password =&gt; &#39;new password&#39;, :password_confirmation =&gt; &#39;new password&#39;)</pre><pre>        user.register!</pre><pre>        assert user.pending?</pre><pre>    end  </pre><pre>    def test_should_suspend_user</pre><pre>      users(:quentin).suspend!</pre><pre>      assert users(:quentin).suspended?</pre><pre>    end   </pre><pre>    def test_suspended_user_should_not_authenticate</pre><pre>      users(:quentin).suspend!</pre><pre>      assert_not_equal users(:quentin), User.authenticate(&#39;quentin&#39;, &#39;test&#39;)</pre><pre>    end   </pre><pre>    def test_should_unsuspend_user</pre><pre>      users(:quentin).suspend!</pre><pre>      assert users(:quentin).suspended?</pre><pre>      users(:quentin).unsuspend!</pre><pre>      assert users(:quentin).active?</pre><pre>    end   </pre><pre>    def test_should_delete_user</pre><pre>      users(:quentin).delete!</pre><pre>      assert_not_equal users(:quentin).login, &#39;quentin&#39;</pre><pre>      assert_not_equal users(:quentin).email, &#39;quentin@example.com&#39;</pre><pre>      assert users(:quentin).deleted?</pre><pre>    end</pre><p>&nbsp;</p><p>&nbsp;</p></p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
        <p>Last modified on Sep 24, 2007 1:39:31 PM by <a href="http://www.vaporbase.com/roles/3">linoj</a></p>
        <p>



<div>
   <p class="xar-cm-note xar-sub">
 Note: Comments are owned by the poster. We are not responsible for their content. </p>
</div>
    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="177"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="177" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply177" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 November 06, 2007 12:34 PM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                I would suggest using a datetime column &quot;deleted_at&quot; rather than modifying the fields directly (appending string datetime) if state is deleted.

Using a dedicated &quot;deleted_at&quot; column, not only is the datetime directly retrievable; but developer can still add unique index with two columns (i.e. email and deleted_at). So there can only be one active user with that email, but there can be many deleted users with exact same email. (i.e. the email is reusable if deleted)
                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=177" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="178"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="178" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply178" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     linoj on                 November 06, 2007 01:05 PM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                Hendy, I agree that seems cleaner. We'd also need to change the email validation, perhaps something like (I havent tried this yet)

validates_uniqueness_of :email ,  :if =&gt; Proc.new { |u| !u.deleted_at.blank? } 
                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=178" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="179"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="179" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply179" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     linoj on                 November 06, 2007 03:16 PM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                maybe also override find_by_email to actually call find_by_email_and_deleted_at( email, nil )                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=179" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="217"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="217" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply217" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 December 08, 2007 03:28 PM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                Just so you know, I'm adding this to restful auth with a few tweaks (using the deleted_at suggestion, and keeping the aasm default column name 'state'.                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=217" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="228"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="228" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply228" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 December 10, 2007 11:19 PM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                Thanks for doing this.

One note: I think the user_observer should be changed to UserMailer.deliver_activation(user) if user.active?

Otherwise, since 'pending' is the default, you get the signup email and the activation email both at the same time even though the user hasn't activated the account yet.                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=228" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="229"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="229" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply229" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 December 10, 2007 11:23 PM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                Sorry, spoke too soon. Rick, it's in your user_observer.rb for the restful authentication plugin.                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=229" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="238"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="238" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply238" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 December 13, 2007 06:18 AM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                If you change to &quot;UserMailer.deliver_activation(user) if user.active?&quot; it then generates an activation mail each time there's a save on the user record for an active user. This is not good.

Taking the observer out of the equation and wiring the UserMailer calls into the User model kinda works.... (generates 2 activation mails currently... working on that)...





                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=238" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="247"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="247" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply247" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 December 17, 2007 06:40 AM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                I am keeping 'UserMailer.deliver_activation(user) if user.pending?' (out of the box config) but receive both at the same time notification and activation mails automatically. Where is the user.save that triggers the activation mail before the user really activates through the notification link?                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=247" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="248"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="248" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply248" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 December 18, 2007 01:28 AM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                In case you're interested, I think I have a solution to the activation email problem: <a href="http://harrylove.org/2007/12/17/activation-emails-with-restful-authentication-an" target="_blank">http://harrylove.org/2007/12/17/activation-emails-with-restful-authentication-an</a> d-acts_as_state_machine                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=248" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="290"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="290" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply290" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 January 06, 2008 09:51 AM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                i tried figuring this out.  it didn't work for me.  the authentication code was never sent to users, becuase you deleted the before_save.  adding that code back into this, helped there.  but in my app, passive is useless.  i guess i can change wherever you have passive to pending and see what happens.  I mean, in my app, no matter how i tried to authenticate a user, the database had my users as passive.  always. thanks                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=290" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="291"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="291" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply291" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 January 09, 2008 10:36 AM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                Seems to me that acts_as_state_machine is somewhat lacking since it doesn't trigger the code associated with the initial state until AFTER it's saved.  Shouldn't it call said logic on the model just after it's created, but before it's saved?  (I'm trying to sort out the details of what's described above as well (changing active? to pending?, replacing the observer with all-state-machine code, etc.)).  Things are definitely not working as they are.  (of course, thanks to all of those who've gotten us this far!)                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=291" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="317"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="317" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply317" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 January 25, 2008 09:14 AM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                In my view, the fundamental problem here is that UserObserver is triggered by things like after_save, etc, but what we really want to observe is changes in the state of the state machine. That's why things get complicated and stop working.
Acts_as_state_machine already gives us the mechanism to listen for state changes. So a better solution might to send emails directly User, or create a new type of observer class that listens for state changes in acts_as_state_machine model like User. (Although I'm not sure how this would be done technically.) It seems this is in line with that Jamie said above.                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=317" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="347"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="347" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply347" value="Reply" />
                   </div>
               </form>

                <h4>stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 February 28, 2008 05:38 PM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                I shared this on Harry's blog linked above, where emil posted some code for eliminating the Observer (which is a much cleaner and more sensible approach, thanks!), but for those landing here from Google or Rick Olson's README:

<a href="http://rails.aizatto.com/category/plugins/acts_as_state_machine/" target="_blank">http://rails.aizatto.com/category/plugins/acts_as_state_machine/</a>

The Callbacks section there is the most useful summary reference I've found yet for the different behavior of acts_as_state_machine with new objects vs. existing (saved) records. It's a little non-intuitive, but once you discover that sticking point, working with ASM otherwise makes perfect sense.

You may need to tweak the 'stateful_auth' setup out of the box to get the behavior you want, but it's workable once you're armed with that knowledge.                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=347" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

    <div class="xar-accent-outline xar-cm-comment">
    <div>
         <a name="556"></a>
                <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" class="xar-cm-actions">
                    <div>
                        <input type="hidden" name="header[modid]" value="151" />
                        <input type="hidden" name="header[itemtype]" value="9" />
                        <input type="hidden" name="header[objectid]" value="141" />
                        <input type="hidden" name="header[pid]" value="556" />
                        <input type="hidden" name="receipt[returnurl][decoded]" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
                        <input type="hidden" name="receipt[returnurl][encoded]" value="http%3A%2F%2Fwww.vaporbase.com%2Fpostings%2Fstateful_authentication%3F%26amp%3Bdepth%3D1%26amp%3Border%3D1%26amp%3Bsortby%3D2%26amp%3Brender%3Dflat" />
                        <input type="hidden" name="receipt[action]" value="reply" /> 
                        <input type="submit" name="submit" id="submit-reply556" value="Reply" />
                   </div>
               </form>

                <h4>Re: stateful authentication</h4>
<!-- show changelog -->
<!-- end changelog -->
           <span class="xar-sub">
 Posted by:                     Anonymous on                 March 15, 2009 07:26 AM</span>
       </div>
       <div class="xar-accent xar-cm-comment">
                87                <p>
                    <a href="http://www.vaporbase.com/?module=comments&amp;func=display&amp;cid=556" title="Permalink" rel="bookmark">
                       #
                   </a>
               </p>

       </div>

</div>

<script type="text/javascript" src="modules/base/xartemplates/includes/submitonce.js"></script>
  <h3>Post a new comment</h3> 
  <form action="http://www.vaporbase.com/?module=comments&amp;func=reply" method="post" name="post" id="post" onSubmit="submitonce(this)" id="post"
 >
   <div class="xar-ib-wrapper xar-accent-outline">
<div class="xar-ib-actionpanel xar-accent">
         <span>
 BBCode Actions             : 
          </span>
          <span>
            <!-- New xaraya style link tag <xar:set name="$stylesheet">xarTplAddStyleLink('bbcode', 'bbcode')</xar:set> -->

<span>
    <input type="button" accesskey="z" name="addbbcode18" value=" p " onclick="bbstyle(18)" onmouseover="document.post.helpbox.value='Paragraph: [p]text[/p] (alt+z)'; return true" />
    <input type="button" accesskey="b" name="addbbcode0" value=" b " style="font-weight:bold;" onclick="bbstyle(0)" onmouseover="document.post.helpbox.value='Bold text: [b]text[/b] (alt+b)'; return true" />
    <input type="button" accesskey="i" name="addbbcode2" value=" i " style="font-style:italic;" onclick="bbstyle(2)" onmouseover="document.post.helpbox.value='Italic text: [i]text[/i] (alt+i)'; return true" />
    <input type="button" accesskey="u" name="addbbcode4" value=" u " style="font-style: underline;" onclick="bbstyle(4)" onmouseover="document.post.helpbox.value='Underline text: [u]text[/u] (alt+u)'; return true" />
    <input type="button" accesskey="q" name="addbbcode6" value="Quote" onclick="bbstyle(6)" onmouseover="document.post.helpbox.value='Quote text: [quote]text[/quote] (alt+q)'; return true" />
    <input type="button" accesskey="c" name="addbbcode8" value="Code" onclick="bbstyle(8)" onmouseover="document.post.helpbox.value='Code display: [code=xml]code[/code] (alt+c)'; return true" />
    <input type="button" accesskey="p" name="addbbcode14" value="Img" onclick="bbstyle(14)" onmouseover="document.post.helpbox.value='Insert image: [img]http://image_url[/img] (alt+p)'; return true" />
    <input type="button" accesskey="w" name="addbbcode16" value="URL" style="text-decoration: underline;" onclick="bbstyle(16)" onmouseover="document.post.helpbox.value='Insert URL: [url]http://url[/url] or [url=http://url]URL text[/url] (alt+w)'; return true" />
</span>
<label for="addbbcode20">
 Font color     :
</label>
<select name="addbbcode20" onchange="bbfontstyle('[color=' + this.form.addbbcode20.options[this.form.addbbcode20.selectedIndex].value + ']', '[/color]');this.selectedIndex=0;" onmouseover="document.post.helpbox.value='Font color: [color=red]text[/color] Tip: you can also use color=#FF0000'; return true">
   <option style="color:black; background-color: #FAFAFA" value="#444444" class="xar-bbcode-genmed">
 Default </option>
   <option style="color:darkred; background-color: #FAFAFA" value="darkred" class="xar-bbcode-genmed">
 Dark Red </option>
   <option style="color:red; background-color: #FAFAFA" value="red" class="xar-bbcode-genmed">
 Red </option>
   <option style="color:orange; background-color: #FAFAFA" value="orange" class="xar-bbcode-genmed">
 Orange </option>
   <option style="color:brown; background-color: #FAFAFA" value="brown" class="xar-bbcode-genmed">
 Brown </option>
   <option style="color:yellow; background-color: #FAFAFA" value="yellow" class="xar-bbcode-genmed">
 Yellow </option>
   <option style="color:green; background-color: #FAFAFA" value="green" class="xar-bbcode-genmed">
 Green </option>
   <option style="color:olive; background-color: #FAFAFA" value="olive" class="xar-bbcode-genmed">
 Olive </option>
   <option style="color:cyan; background-color: #FAFAFA" value="cyan" class="xar-bbcode-genmed">
 Cyan </option>
   <option style="color:blue; background-color: #FAFAFA" value="blue" class="xar-bbcode-genmed">
 Blue </option>
   <option style="color:darkblue; background-color: #FAFAFA" value="darkblue" class="xar-bbcode-genmed">
 Dark Blue </option>
   <option style="color:indigo; background-color: #FAFAFA" value="indigo" class="xar-bbcode-genmed">
 Indigo </option>
   <option style="color:violet; background-color: #FAFAFA" value="violet" class="xar-bbcode-genmed">
 Violet </option>
   <option style="color:white; background-color: #FAFAFA" value="white" class="xar-bbcode-genmed">
 White </option>
   <option style="color:black; background-color: #FAFAFA" value="black" class="xar-bbcode-genmed">
 Black </option>
</select>
<label for="addbbcode22">
 Font size     :
</label>
<select name="addbbcode22" onchange="bbfontstyle('[size=' + this.form.addbbcode22.options[this.form.addbbcode22.selectedIndex].value + ']', '[/size]')" onmouseover="document.post.helpbox.value='Font size: [size=x-small]small text[/size]'; return true">
   <option value="7" class="xar-bbcode-genmed">
 Tiny </option>
   <option value="9" class="xar-bbcode-genmed">
 Small </option>
   <option value="12" selected="selected" class="xar-bbcode-genmed">
 Normal </option>
   <option value="18" class="xar-bbcode-genmed">
 Large </option>
   <option value="24" class="xar-bbcode-genmed">
 Huge     </option>
</select>
<a href="javascript:bbstyle(-1)" class="xar-bbcode-genmed" onmouseover="document.post.helpbox.value='Close all open bbCode tags'; return true">Close Tags</a>
<span class="gensmall">
    <input type="text" name="helpbox" size="50" maxlength="100" class="helpline" value="Tip: Styles can be applied quickly to selected text." />
</span>         </span>
       </div>
       <div class="xar-ib-leftpanelshort">
         <p>
 Name :
              Anonymous</p>
         <label for="package-title">
 Title: </label>
            <input class="xar-ib-field" type="text" name="package[title]" id="package-title" value="stateful authentication" tabindex="1" />
         <label for="package-text">
 Comment: </label>
<textarea class="xar-ib-fieldtext" name="package[text]" id="package-text" tabindex="2"></textarea>

          <input type="hidden" name="header[modid]" id="header-modid" value="151" /> 
          <input type="hidden" name="header[objectid]" id="header-objectid" value="141" /> 
          <input type="hidden" name="header[itemtype]" id="header-itemtype" value="9" />
<input type="hidden" name="header[pid]" id="header-pid" value="0" />
          <input type="hidden" name="receipt[returnurl][decoded]" id="receipt-returnurl-decoded" value="http://www.vaporbase.com/postings/stateful_authentication?&amp;depth=1&amp;order=1&amp;sortby=2&amp;render=flat" />
          <!--<input type="hidden" name="receipt[returnurl][encoded]" id="receipt-returnurl-encoded" value="#$receipt['returnurl']['encoded']#" />-->
          <input type="hidden" name="receipt[action]" id="receipt-action" /> 
          <input type="submit" id="receipt-action-preview" onclick="document.getElementById('receipt-action').value='preview'" value="Preview" /> 
          <input type="submit" id="receipt-action-submit" onclick="document.getElementById('receipt-action').value='submit'" value="Submit" />
       </div>
</div>
 </form>
</p>
        <p></p>
        <p><br/>
<b>Keywords :</b>
<div style="margin-left: 1em; margin-right: 1em; text-align:left;">
    <li><a href="http://www.vaporbase.com/keywords/acts as state machine/">acts as state machine</a></li>
    <li><a href="http://www.vaporbase.com/keywords/restful authentication/">restful authentication</a></li>
</div>
<br/>

</p>
</div>
   </channel>
</rss>
