<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Leancode &#187; ruby</title>
	<atom:link href="http://leancode.com/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://leancode.com</link>
	<description>bernie's small batches of software goodness</description>
	<lastBuildDate>Tue, 01 Nov 2011 16:37:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Tomorrow: The First Annual D Language Conference</title>
		<link>http://leancode.com/2007/08/22/tomorrow-the-first-annual-d-language-conference/</link>
		<comments>http://leancode.com/2007/08/22/tomorrow-the-first-annual-d-language-conference/#comments</comments>
		<pubDate>Thu, 23 Aug 2007 08:57:26 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[dlanguage]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[techbits]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/08/22/tomorrow-the-first-annual-d-language-conference/</guid>
		<description><![CDATA[This week Amazon is hosting the first annual D Programming Language Conference here in Seattle. Looks like the conference will have just over 50 people attending. There&#8217;s a single track of speakers, so I hope to attend most/all the sessions, and blog some notes and thoughts here. There is so much rich thinking going on [...]]]></description>
			<content:encoded><![CDATA[<p>This week Amazon is hosting the first annual <a href="http://d.puremagic.com/conference2007/">D Programming Language Conference</a> here in Seattle.  Looks like the conference will have just over 50 people attending.  There&#8217;s a <a href="http://d.puremagic.com/conference2007/speakers.html">single track of speakers</a>, so I hope to attend most/all the sessions, and blog some notes and thoughts here.</p>
<p>There is so much rich thinking going on with dynamic languages like Ruby, etc. This can be a much more expressive, productive way to program, compared to the more verbose and brittle static-typed language world.  And with the web at the forefront, they have attracted a great community that is pushing the envelope in many areas.</p>
<p>But with Ruby, I often I feel like I&#8217;m building a house on shifting sands. And there is much that C/C++ can do to improve. Where Ruby is flexible and concise, but loose and slow &#8212; C/C++ is fast and strong but verbose and brittle.  [That seeming contradiction of being both strong and brittle is a truth, but one that's sometimes not immediately obvious]</p>
<p>D is a tight, elegant evolution of C/C++ that retains the strength, but attacks the verbosity and brittleness from several angles, especially with its metaprogramming features.  It is C++ completely rethought, simplified, and done right.</p>
<p>As a device driver developer, the language has features that I often wished I had (like static ifs, better templatized functions, and compile-time code execution).  And they are syntactically elegant, unlike C++.</p>
<p>The first talk of the morning starts it off right, given by Walter Bright, D&#8217;s designer and mind behind the Zortech C++ compiler and others; and Andre Alexandrescu, the C++ guru and author of the brilliant, dense <a href="http://www.amazon.com/gp/product/0201704315?ie=UTF8&#038;tag=bernieblog1-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=0201704315">Modern C++ Design: Generic Programming and Design Patterns Applied</a><img src="http://www.assoc-amazon.com/e/ir?t=bernieblog1-20&#038;l=as2&#038;o=1&#038;a=0201704315" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, among many other things.  D already has the signs of attracting its own great community.  These are two minds to follow, and I&#8217;m looking forward to this talk and others.</p>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/08/22/tomorrow-the-first-annual-d-language-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Paul Dowman&#8217;s Rails image for EC2</title>
		<link>http://leancode.com/2007/06/24/paul-dowmans-rails-image-for-ec2/</link>
		<comments>http://leancode.com/2007/06/24/paul-dowmans-rails-image-for-ec2/#comments</comments>
		<pubDate>Mon, 25 Jun 2007 02:40:34 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[techbits]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/06/24/paul-dowmans-rails-image-for-ec2/</guid>
		<description><![CDATA[Paul Dowman has created what looks to be a very promising Ubuntu+Rails image for Amazon&#8217;s EC2 platform. He has support for capistrano deployment, mongrel_cluster, mysql backup to Amazon&#8217;s S3 service, and a few other nifty features. When multiple server support is completed (said to be soon), this will be a great package. Definitely worth following. [...]]]></description>
			<content:encoded><![CDATA[<p>Paul Dowman has created what looks to be a <a href="http://pauldowman.com/projects/ruby-on-rails-ec2/">very promising Ubuntu+Rails image</a> for Amazon&#8217;s EC2 platform. He has support for capistrano deployment, mongrel_cluster, mysql backup to Amazon&#8217;s S3 service, and a few other nifty features.  When multiple server support is completed (said to be soon), this will be a great package. Definitely worth following. </p>
<p>An Amazon Machine Image is basically a filesystem image that then gets loaded in Amazon&#8217;s farm of Xen servers.  Does anyone know of existing scripts that can create a Xen image from an AMI?  It&#8217;d be nice have the ability to test and stage locally with the same image used for any of your EC2 hosted test, staging, or production instances.</p>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/06/24/paul-dowmans-rails-image-for-ec2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scaling rails: nginx plus mongrel cluster</title>
		<link>http://leancode.com/2007/05/20/scaling-rails-nginx-plus-mongrel-cluster/</link>
		<comments>http://leancode.com/2007/05/20/scaling-rails-nginx-plus-mongrel-cluster/#comments</comments>
		<pubDate>Sun, 20 May 2007 05:06:30 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/05/20/scaling-rails-nginx-plus-mongrel-cluster/</guid>
		<description><![CDATA[Ezra just put up a nice set of slides for his RailsConf 2007 presentation. Scaling Rails apps is tricky, and the state of the art has been moving fast (just seems like months ago that apache was back at the front of the pack). Ezra provides background and a picture, based on hard-won experience with [...]]]></description>
			<content:encoded><![CDATA[<p>Ezra just put up a <a href="http://brainspl.at/articles/2007/05/20/my-xen-and-the-art-of-rails-deployment-talk-slides">nice set of slides</a> for his RailsConf 2007 presentation.  Scaling Rails apps is tricky, and the state of the art has been moving fast (just seems like months ago that <a href="http://leancode.com/2006/09/20/site-monitoring-shared-host-vs-dedicated/">apache was back at the front of the pack</a>).  Ezra provides background and a picture, based on hard-won experience with <a href="http://engineyard.com/">EngineYard</a>, on things have been, and where they&#8217;re headed.</p>
<p>Ezra recommends <a href="http://wiki.codemongers.com/Nginx">Nginx</a> as the load balancing reverse proxy (replacing Apache or lighttpd), and <a href="http://mongrel.rubyforge.org/docs/mongrel_cluster.html">Mongrel</a> (cluster) as the clustered application server for dynamic pages.  And he introduces more about <a href="http://swiftiply.swiftcore.org/index.html">Swiftiply</a> to increase Mongrel&#8217;s already excellent performance.</p>
<p>There are warnings and some suggestions to attack Ruby/Rails weak spot &#8211; memory consumption.  And some great thoughts on making use of VMs to partition your applications for scaling and maintenance from day 1. A presentation worth reading through.</p>
<p>I haven&#8217;t been doing much with VMs in the past year.  It&#8217;s the source of some guilt, since <a href="http://leancode.com/2006/05/06/ruby-on-rails-virtual-machine-for-vmware-rorvmv010/">my RORVM post</a> still gets search-related hits every day.  And I haven&#8217;t had anything useful &#038; additional to say, since I develop on my Macbook, then deploy to hosted accounts where I can&#8217;t load an arbitrary VM image.</p>
<p>Nginx, Mongrel, <a href="http://deprec.rubyforge.org/">Deprec</a>, and <a href="http://amazon.com/aws">Amazon&#8217;s hosting services</a> are all great innovations for scaling Rails apps.  I&#8217;m looking forward to following their evolution.</p>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/05/20/scaling-rails-nginx-plus-mongrel-cluster/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>open_id_authentication (part 2)</title>
		<link>http://leancode.com/2007/04/04/open_id_authentication-part-2/</link>
		<comments>http://leancode.com/2007/04/04/open_id_authentication-part-2/#comments</comments>
		<pubDate>Wed, 04 Apr 2007 20:37:22 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[openid]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/04/04/open_id_authentication-part-2/</guid>
		<description><![CDATA[In part 1, we looked at some changes to DHH&#8217;s OpenID plugin for rails. Now we look at the app&#8217;s authenticated sessions controller, which uses that library code. The goals were: Support both OpenID and password authentication Support all the usual login goodies, including before_filter :login_required, remember me functionality (with cookies), HTTP basic authentication, etc. [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://leancode.com/2007/04/02/open_id_authentication-part-1/">part 1</a>, we looked at some changes to DHH&#8217;s OpenID plugin for rails.  Now we look at the app&#8217;s authenticated sessions controller, which uses that library code. The goals were:</p>
<ul>
<li>Support both OpenID and password authentication</li>
<li>Support all the usual login goodies, including before_filter :login_required, remember me functionality (with cookies), HTTP basic authentication, etc.</li>
<li>Get this by integrating the <a href="http://agilewebdevelopment.com/plugins/restful_authentication">restful_authentication</a> plugin/generation and <a href="http://agilewebdevelopment.com/plugins/openidauthentication">open_id_authentication</a> plugin</li>
</ul>
<p>First, I installed both plugins and ran the restful_authentication generator</p>
<pre>
./script/generate authenticated user authenticated_sessions
</pre>
<p>I chose the name &#8220;authenticated_sessions&#8221; to distinguish from the built-in (non-authenticated) Rails sessions functionality.  </p>
<p>routes.rb adds</p>
<pre>
  map.resource :authenticated_session, :member => { :complete => :get }
  map.resources :users
</pre>
<p>Then it&#8217;s a matter of some substantial edits to the generated app/controllers/authenticated_session_controller.rb  Here&#8217;s where it would be nice to have a combined generator like <a href="http://identity.eastmedia.com/identity/show/Restful+OpenID+Authentication">Eastmedia&#8217;s</a>. If you&#8217;re just trying to get an app and and running, you don&#8217;t want to be reading a blog posting like this. <img src='http://leancode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The smartest design decisions in the file below (which all came from DHH&#8217;s code), are having centralized successful_login(), failed_login(), and destroy() functions, which are common across the otherwise separate openid/password authentication paths.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#008000; font-style:italic;"># This controller handles the login/logout function of the site. </span>
<span style="color:#008000; font-style:italic;"># File created with restful_authentication generator </span>
<span style="color:#9966CC; font-weight:bold;">class</span> AuthenticatedSessionController &lt; ApplicationController
&nbsp;
  <span style="color:#008000; font-style:italic;"># render new.rhtml</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> new
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Added after restful_authentication generator, using code from http://www.loudthinking.com/arc/000604.html</span>
  <span style="color:#008000; font-style:italic;"># Complete arrives to us via a browser redirect from the OpenID provider, which happens after create/begin.</span>
  <span style="color:#008000; font-style:italic;"># Obviously only called in the OpenID path through authentication.</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> complete
    complete_open_id_authentication<span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:openid_url</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> |result, identity_url, sreg|
      <span style="color:#9966CC; font-weight:bold;">case</span> result
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:canceled</span>
        failed_login <span style="color:#996600;">&quot;OpenID verification was canceled&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:failed</span>
        failed_login <span style="color:#996600;">&quot;Sorry, the OpenID verification failed&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:successful</span>
        <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">current_user</span> = User.<span style="color:#9900CC;">find_by_openid_url</span><span style="color:#006600; font-weight:bold;">&#40;</span>identity_url<span style="color:#006600; font-weight:bold;">&#41;</span> || User.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:openid_url</span> =&gt; identity_url, <span style="color:#ff3333; font-weight:bold;">:login</span> =&gt; sreg<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'nickname'</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:email</span> =&gt; sreg<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'email'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          successful_login
        <span style="color:#9966CC; font-weight:bold;">else</span>
          failed_login <span style="color:#996600;">&quot;Sorry, no user by that identity URL exists (#{identity_url})&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        failed_login <span style="color:#996600;">&quot;Unknown error logging in #{identity_url}&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Handle the creation of a new authenticated session, OpenID or password authentication path</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#9966CC; font-weight:bold;">if</span> using_open_id?
      begin_open_id_authentication<span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:openid_url</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:required</span> =&gt; <span style="color:#996600;">&quot;nickname, email&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> |result, identity_url|
        <span style="color:#9966CC; font-weight:bold;">case</span> result
        <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#ff3333; font-weight:bold;">:missing</span>
          failed_login <span style="color:#996600;">&quot;Sorry, the OpenID server couldn’t be found&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">else</span>
          failed_login <span style="color:#996600;">&quot;Unknown error in openid begin for #{identity_url}&quot;</span>        
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">elsif</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:login</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      password_authentication<span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:login</span><span style="color:#006600; font-weight:bold;">&#93;</span>, params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:password</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      failed_login <span style="color:#996600;">&quot;No valid credentials passed to create authenticated session&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> destroy
    logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;logging out #{self.current_user.inspect}&quot;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">current_user</span>.<span style="color:#9900CC;">forget_me</span> <span style="color:#9966CC; font-weight:bold;">if</span> logged_in?
    cookies.<span style="color:#9900CC;">delete</span> <span style="color:#ff3333; font-weight:bold;">:auth_token</span>
    <span style="color:#0066ff; font-weight:bold;">@session</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
    flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;You have been logged out.&quot;</span>
    redirect_back_or_default<span style="color:#006600; font-weight:bold;">&#40;</span>calls_path<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
protected
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> password_authentication<span style="color:#006600; font-weight:bold;">&#40;</span>login, password<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">current_user</span> = User.<span style="color:#9900CC;">authenticate</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:login</span><span style="color:#006600; font-weight:bold;">&#93;</span>, params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:password</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      successful_login
    <span style="color:#9966CC; font-weight:bold;">else</span>
      failed_login<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Invalid login or password&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
private
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> successful_login
    logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;sucessful login for #{self.current_user.inspect}&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:remember_me</span><span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#996600;">&quot;1&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">current_user</span>.<span style="color:#9900CC;">remember_me</span>
      cookies<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:auth_token</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:value</span> =&gt; <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">current_user</span>.<span style="color:#9900CC;">remember_token</span> , <span style="color:#ff3333; font-weight:bold;">:expires</span> =&gt; <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">current_user</span>.<span style="color:#9900CC;">remember_token_expires_at</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    redirect_back_or_default<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;#{self.current_user.login} Logged in successfully&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> failed_login<span style="color:#006600; font-weight:bold;">&#40;</span>message<span style="color:#006600; font-weight:bold;">&#41;</span>
    logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">'Login failed. '</span> + message
    flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = message
    redirect_to new_authenticated_session_path<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Lastly, views/authenticated_session/new.rhtml is where the initial form is presented when users are redirected from an action that requires authentication.  I chose to put the password and openid authentication forms on the same page, but within their own divs with IDs and a common rounding class, so the styles can be tuned in the .css file to make it look nice.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">&lt;div id=<span style="color:#996600;">'password-login'</span> <span style="color:#9966CC; font-weight:bold;">class</span>=<span style="color:#996600;">'rounded'</span>&gt;
	&lt;% form_tag authenticated_session_path <span style="color:#9966CC; font-weight:bold;">do</span> -%&gt;
	&lt;p&gt;&lt;label <span style="color:#9966CC; font-weight:bold;">for</span>=<span style="color:#996600;">&quot;login&quot;</span>&gt;Login&lt;/label&gt;&lt;br/&gt;
	&lt;%= text_field_tag <span style="color:#996600;">'login'</span> %&gt;&lt;/p&gt;
&nbsp;
	&lt;p&gt;&lt;label <span style="color:#9966CC; font-weight:bold;">for</span>=<span style="color:#996600;">&quot;password&quot;</span>&gt;Password&lt;/label&gt;&lt;br/&gt;
	&lt;%= password_field_tag <span style="color:#996600;">'password'</span> %&gt;&lt;/p&gt;
	&lt;p&gt;&lt;label <span style="color:#9966CC; font-weight:bold;">for</span>=<span style="color:#996600;">&quot;remember_me&quot;</span>&gt;Remember Me&lt;/label&gt;&lt;%= check_box_tag <span style="color:#996600;">'remember_me'</span> %&gt;&lt;/p&gt;
	&lt;p&gt;&lt;%= submit_tag <span style="color:#996600;">'Log in'</span> %&gt;&lt;/p&gt;
	&lt;% <span style="color:#9966CC; font-weight:bold;">end</span> -%&gt;
&lt;/div&gt;
&nbsp;
&lt;div id=<span style="color:#996600;">'openid-login'</span> <span style="color:#9966CC; font-weight:bold;">class</span>=<span style="color:#996600;">'rounded'</span>&gt;
	&lt;% form_tag authenticated_session_path <span style="color:#9966CC; font-weight:bold;">do</span> %&gt;
	  &lt;p&gt;&lt;label <span style="color:#9966CC; font-weight:bold;">for</span>=<span style="color:#996600;">&quot;openid_url&quot;</span>&gt;OpenID&lt;/label&gt;&lt;%= text_field_tag <span style="color:#996600;">'openid_url'</span> %&gt;&lt;/p&gt;
	  &lt;p&gt;&lt;label <span style="color:#9966CC; font-weight:bold;">for</span>=<span style="color:#996600;">&quot;remember_me&quot;</span>&gt;Remember Me&lt;/label&gt;&lt;%= check_box_tag <span style="color:#996600;">'remember_me'</span> %&gt;&lt;/p&gt;
	  &lt;%= submit_tag <span style="color:#996600;">'Login'</span> %&gt;
	&lt;% <span style="color:#9966CC; font-weight:bold;">end</span> %&gt;
&lt;/div&gt;</pre></div></div>

<p>You&#8217;ll notice that most of my postings and a lot of the plugins have headed in the direction of making authenticated sessions a REST resource, using the newer RESTful support in Rails.  Reflecting back on it all, it isn&#8217;t the best conceptual or practical match.  As long as the end-user functionality is the same (support for remember_me, HTTP basic authentication, etc.) &#8212; it seems more strightforward to implement authenticated sessions as a traditional controller, not a REST resource. </p>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/04/04/open_id_authentication-part-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>open_id_authentication (Part 1)</title>
		<link>http://leancode.com/2007/04/02/open_id_authentication-part-1/</link>
		<comments>http://leancode.com/2007/04/02/open_id_authentication-part-1/#comments</comments>
		<pubDate>Mon, 02 Apr 2007 18:43:30 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[openid]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/04/02/open_id_authentication-part-1/</guid>
		<description><![CDATA[open_id_authentication is the OpenID consumer plugin for Rails, being written by DHH and some on the Rails core team. This plugin was getting some quick updates at first, but things have slowed down as the 37signals crew has focused on launching the app they developed it for &#8212; highrise. So, in the absence of other [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://agilewebdevelopment.com/plugins/openidauthentication">open_id_authentication</a> is the OpenID consumer plugin for Rails, being written by DHH and some on the Rails core team.  </p>
<p>This plugin was getting some <a href="http://leancode.com/2007/03/05/openidauthentication-tutorial/">quick updates</a> at first, but things have slowed down as the 37signals crew has focused on launching the app they developed it for &#8212; <a href="http://www.highrisehq.com/">highrise</a>.</p>
<p>So, in the absence of other updates over the last few weeks, here are some changes I made for one of my own Rails apps.  In part one of two posts, we look here at what changes were made on the library side. In part two, we&#8217;ll look at the the library client (rails controller) side.</p>
<p>On the left is http://svn.rubyonrails.org/rails/plugins/open_id_authentication lib/open_id_authentication.rb revision 6452.</p>
<p> On the right (or down below, if the browser isn&#8217;t wide enough) is the modified version used for my rails app.</p>
<div style="width:320px; float:left">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
</pre></td><td class="code"><pre class="ruby">  protected
    <span style="color:#9966CC; font-weight:bold;">def</span> normalize_url<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
      OpenIdAuthentication.<span style="color:#9900CC;">normalize_url</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># The parameter name of &quot;openid_url&quot; is used rather than the Rails convention &quot;open_id_url&quot;</span>
    <span style="color:#008000; font-style:italic;"># because that's what the specification dictates in order to get browser auto-complete working across sites</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> using_open_id?<span style="color:#006600; font-weight:bold;">&#40;</span>identity_url = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:openid_url</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#:doc:</span>
      !identity_url.<span style="color:#9900CC;">blank</span>? || params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:open_id_complete</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> authenticate_with_open_id<span style="color:#006600; font-weight:bold;">&#40;</span>identity_url = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:openid_url</span><span style="color:#006600; font-weight:bold;">&#93;</span>, fields = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>, &amp;block<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#:doc:</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:open_id_complete</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
        begin_open_id_authentication<span style="color:#006600; font-weight:bold;">&#40;</span>normalize_url<span style="color:#006600; font-weight:bold;">&#40;</span>identity_url<span style="color:#006600; font-weight:bold;">&#41;</span>, fields, &amp;block<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        complete_open_id_authentication<span style="color:#006600; font-weight:bold;">&#40;</span>&amp;block<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</div>
<div style="width:320px; float:left;">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>60
61
62
63
64
65
66
67
68
69
</pre></td><td class="code"><pre class="ruby">  protected
    <span style="color:#9966CC; font-weight:bold;">def</span> normalize_url<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
      OpenIdAuthentication.<span style="color:#9900CC;">normalize_url</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># The parameter name of &quot;openid_url&quot; is used rather than the Rails convention &quot;open_id_url&quot;</span>
    <span style="color:#008000; font-style:italic;"># because that's what the specification dictates in order to get browser auto-complete working across sites</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> using_open_id?<span style="color:#006600; font-weight:bold;">&#40;</span>identity_url = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:openid_url</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#:doc:</span>
      !identity_url.<span style="color:#9900CC;">blank</span>? || params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:open_id_complete</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</div>
<div style="clear:both">In these diffs, you see authenticate_with_open_id has been removed. The original plugin code on the left routes OpenID&#8217;s begin and complete operations through this single function and keys off an HTTP parameter to know which operation we&#8217;re really doing.  In the implementation on the right, the client calls directly into the appropriate (and newly un-private) begin &#038; complete methods, and we&#8217;ll now have to make sure to normalize the url in those functions, as necessary.</div>
<div style="width:320px; float:left">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>80
81
82
83
84
85
86
87
88
89
90
91
</pre></td><td class="code"><pre class="ruby">  private
    <span style="color:#9966CC; font-weight:bold;">def</span> begin_open_id_authentication<span style="color:#006600; font-weight:bold;">&#40;</span>identity_url, fields = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      open_id_response = timeout_protection_from_identity_server <span style="color:#006600; font-weight:bold;">&#123;</span> open_id_consumer.<span style="color:#9966CC; font-weight:bold;">begin</span><span style="color:#006600; font-weight:bold;">&#40;</span>identity_url<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">case</span> open_id_response.<span style="color:#9900CC;">status</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::FAILURE</span>
        <span style="color:#9966CC; font-weight:bold;">yield</span> Result<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:missing</span><span style="color:#006600; font-weight:bold;">&#93;</span>, identity_url, <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::SUCCESS</span>
        add_simple_registration_fields<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_response, fields<span style="color:#006600; font-weight:bold;">&#41;</span>
        redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_redirect_url<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_response<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</div>
<div style="width:320px; float:left">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>70
71
72
73
74
75
76
77
78
79
80
81
82
83
</pre></td><td class="code"><pre class="ruby">&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> begin_open_id_authentication<span style="color:#006600; font-weight:bold;">&#40;</span>identity_url, fields = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      identity_url = normalize_url<span style="color:#006600; font-weight:bold;">&#40;</span>identity_url<span style="color:#006600; font-weight:bold;">&#41;</span>
      logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;beginning openid authentication for #{identity_url}&quot;</span>
      open_id_response = timeout_protection_from_identity_server <span style="color:#006600; font-weight:bold;">&#123;</span> open_id_consumer.<span style="color:#9966CC; font-weight:bold;">begin</span><span style="color:#006600; font-weight:bold;">&#40;</span>identity_url<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">case</span> open_id_response.<span style="color:#9900CC;">status</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::FAILURE</span>
        <span style="color:#9966CC; font-weight:bold;">yield</span> Result<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:missing</span><span style="color:#006600; font-weight:bold;">&#93;</span>, identity_url, <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::SUCCESS</span>
        add_simple_registration_fields<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_response, fields<span style="color:#006600; font-weight:bold;">&#41;</span>
        redirect_to<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_redirect_url<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_response, identity_url<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</div>
<div style="clear:both">
Notice the &#8220;private&#8221; is gone on the right &#8212; it&#8217;s moved down below the begin and complete methods.  Otherwise nothing too exciting here.  Just added the url normalization and a log message to help illuminate looking back on a failed or successful login.
</div>
<div style="width:320px; float:left">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>93
94
95
96
97
98
99
100
101
102
103
104
105
106
</pre></td><td class="code"><pre class="ruby">    <span style="color:#9966CC; font-weight:bold;">def</span> complete_open_id_authentication
      open_id_response = timeout_protection_from_identity_server <span style="color:#006600; font-weight:bold;">&#123;</span> open_id_consumer.<span style="color:#9900CC;">complete</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      identity_url     = normalize_url<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_response.<span style="color:#9900CC;">identity_url</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> open_id_response.<span style="color:#9900CC;">identity_url</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">case</span> open_id_response.<span style="color:#9900CC;">status</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::CANCEL</span>
        <span style="color:#9966CC; font-weight:bold;">yield</span> Result<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:canceled</span><span style="color:#006600; font-weight:bold;">&#93;</span>, identity_url, <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::FAILURE</span>
        logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;OpenID authentication failed: #{open_id_response.msg}&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">yield</span> Result<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:failed</span><span style="color:#006600; font-weight:bold;">&#93;</span>, identity_url, <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::SUCCESS</span>
        <span style="color:#9966CC; font-weight:bold;">yield</span> Result<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:successful</span><span style="color:#006600; font-weight:bold;">&#93;</span>, identity_url, open_id_response.<span style="color:#9900CC;">extension_response</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'sreg'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>      
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</div>
<div style="width:320px; float:left">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
</pre></td><td class="code"><pre class="ruby">    <span style="color:#9966CC; font-weight:bold;">def</span> complete_open_id_authentication<span style="color:#006600; font-weight:bold;">&#40;</span>identity_url<span style="color:#006600; font-weight:bold;">&#41;</span>
      identity_url = normalize_url<span style="color:#006600; font-weight:bold;">&#40;</span>identity_url<span style="color:#006600; font-weight:bold;">&#41;</span>
      logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;completing openid authentication for #{identity_url}&quot;</span>
      open_id_response = timeout_protection_from_identity_server <span style="color:#006600; font-weight:bold;">&#123;</span> open_id_consumer.<span style="color:#9900CC;">complete</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">case</span> open_id_response.<span style="color:#9900CC;">status</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::CANCEL</span>
        <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#ff3333; font-weight:bold;">:canceled</span>, identity_url, <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::FAILURE</span>
        logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;OpenID authentication failed: #{open_id_response.msg}&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#ff3333; font-weight:bold;">:failed</span>, identity_url, <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#6666ff; font-weight:bold;">OpenID::SUCCESS</span>
        <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#ff3333; font-weight:bold;">:successful</span>, identity_url, open_id_response.<span style="color:#9900CC;">extension_response</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'sreg'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</div>
<div style="clear:both">
The Result[] class on the left was added in one of the last few changes, and broke the plugin (at least for me and <a href="http://www.bencurtis.com/archives/2007/03/rails-openid-and-acts-as-authenticated/">Ben</a>).  So the code on the right just reverts back to the previous working code, which returns the result code directly as a ruby symbol.  As the plugin gets updates from the core team, I&#8217;m sure this&#8217;ll get a fix.
</div>
<div style="width:320px; float:left">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
</pre></td><td class="code"><pre class="ruby">&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> open_id_consumer
      <span style="color:#6666ff; font-weight:bold;">OpenID::Consumer</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>session, <span style="color:#6666ff; font-weight:bold;">OpenID::FilesystemStore</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>OPEN_ID_AUTHENTICATION_DIR<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> add_simple_registration_fields<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_response, fields<span style="color:#006600; font-weight:bold;">&#41;</span>
      open_id_response.<span style="color:#9900CC;">add_extension_arg</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'sreg'</span>, <span style="color:#996600;">'required'</span>, <span style="color:#006600; font-weight:bold;">&#91;</span> fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:required</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">flatten</span> * <span style="color:#996600;">','</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:required</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      open_id_response.<span style="color:#9900CC;">add_extension_arg</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'sreg'</span>, <span style="color:#996600;">'optional'</span>, <span style="color:#006600; font-weight:bold;">&#91;</span> fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:optional</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">flatten</span> * <span style="color:#996600;">','</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:optional</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> open_id_redirect_url<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_response<span style="color:#006600; font-weight:bold;">&#41;</span>
      open_id_response.<span style="color:#9900CC;">redirect_url</span><span style="color:#006600; font-weight:bold;">&#40;</span>
        request.<span style="color:#9900CC;">protocol</span> + request.<span style="color:#9900CC;">host_with_port</span> + <span style="color:#996600;">&quot;/&quot;</span>,
        open_id_response.<span style="color:#9900CC;">return_to</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{request.url}?open_id_complete=1&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#006600; font-weight:bold;">&#41;</span>     
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</div>
<div style="width:320px; float:left">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
</pre></td><td class="code"><pre class="ruby">private
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> open_id_consumer
      <span style="color:#6666ff; font-weight:bold;">OpenID::Consumer</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>session, <span style="color:#6666ff; font-weight:bold;">OpenID::FilesystemStore</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>OPEN_ID_AUTHENTICATION_DIR<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> add_simple_registration_fields<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_response, fields<span style="color:#006600; font-weight:bold;">&#41;</span>
      open_id_response.<span style="color:#9900CC;">add_extension_arg</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'sreg'</span>, <span style="color:#996600;">'required'</span>, <span style="color:#006600; font-weight:bold;">&#91;</span> fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:required</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">flatten</span> * <span style="color:#996600;">','</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:required</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      open_id_response.<span style="color:#9900CC;">add_extension_arg</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'sreg'</span>, <span style="color:#996600;">'optional'</span>, <span style="color:#006600; font-weight:bold;">&#91;</span> fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:optional</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">flatten</span> * <span style="color:#996600;">','</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:optional</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> open_id_redirect_url<span style="color:#006600; font-weight:bold;">&#40;</span>open_id_response, identity_url<span style="color:#006600; font-weight:bold;">&#41;</span>
      open_id_response.<span style="color:#9900CC;">redirect_url</span><span style="color:#006600; font-weight:bold;">&#40;</span>
        request.<span style="color:#9900CC;">protocol</span> + request.<span style="color:#9900CC;">host_with_port</span> + <span style="color:#996600;">&quot;/&quot;</span>,
        open_id_response.<span style="color:#9900CC;">return_to</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{request.url};complete?openid_url=#{identity_url}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#006600; font-weight:bold;">&#41;</span>     
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

</div>
<div style="clear:both">
<p>The openid_redirect_url function is where the interesting change is.  Both left and right code contain a convention (as Rails is wont to do) on how the HTTP request is formatted to distinguish the OpenID complete operation from begin.</p>
<p>The code on the right uses an explicit, separate action instead of one action and a param switch to encode the complete.  This is cleaner IMHO, and allows begin and complete to have distinct Rails routing signatures. For the code on the left, the Rails routing is</p>
<pre>
map.open_id_complete 'session', :controller => "session", :action => "create", :requirements => { :method => :get }
</pre>
<p>And for the code on the right, it&#8217;s</p>
<pre>
  map.resource :authenticated_session, :member => { :complete => :get }
</pre>
</p>
<p>Note, the code on the right is bad in that it doesn&#8217;t use the recommended path helper, so now, as of a <a href="http://www.ryandaigle.com/articles/2007/3/29/what-s-new-in-edge-rails-restful-routes-get-a-new-custom-delimiter">recent edge rails change</a>, the resource &#8216;;complete&#8217; action should be &#8216;/complete&#8217; (so I should use that helper!)</p>
<p>Why pass the identity_url from the begin operation to complete?  Because in the case of link rel redirection, we want to make sure to have our identity url reflect what the user gave us (e.g. his blog URI), not what it later resolves to (the provider URI) &#8212; or else, we&#8217;ll break user&#8217;s ability to <a href="http://www.intertwingly.net/blog/2007/01/03/OpenID-for-non-SuperUsers">switch providers transparently with redirection</a>.</p>
<p>There we go.  Let me know which of my decisions were good, bad, or broken.  And next, we&#8217;ll see what this looks like from the client perspective.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/04/02/open_id_authentication-part-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>An OpenID screencast for developers</title>
		<link>http://leancode.com/2007/03/08/an-openid-screencast-for-developers/</link>
		<comments>http://leancode.com/2007/03/08/an-openid-screencast-for-developers/#comments</comments>
		<pubDate>Thu, 08 Mar 2007 23:35:02 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[openid]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/03/08/an-openid-screencast-for-developers/</guid>
		<description><![CDATA[Simon Willison&#8217;s &#8220;How to Use OpenID&#8221; screencast did a lot of good &#8212; raising the awareness of OpenID and how it works for users. Today, the major bottleneck is getting more web applications to support OpenID logins. Here&#8217;s a screencast and a set of resources targeted at that, with a focus on Rails but some [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://simonwillison.net/2006/openid-screencast/">Simon Willison&#8217;s &#8220;How to Use OpenID&#8221; screencast</a> did a lot of good &#8212; raising the awareness of OpenID and how it works for users.  Today, the major bottleneck is getting more web applications to support OpenID logins.  </p>
<p>Here&#8217;s a screencast and a set of resources targeted at that, with a focus on Rails but some general applicability.</p>
<p><a href="http://leancode.com/openid-for-rails/">http://leancode.com/openid-for-rails/</a></p>
<p>It&#8217;s not quite as polished as Simon&#8217;s and I tripped on a few things &#8212; e.g. OpenID Identifier &#8212; but check it out and feel free to forward it on to anyone who might want a deeper picture of how OpenID does what it does.</p>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/03/08/an-openid-screencast-for-developers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>8 Steps to your first OpenID enabled app</title>
		<link>http://leancode.com/2007/03/07/8-steps-to-your-first-openid-enabled-app/</link>
		<comments>http://leancode.com/2007/03/07/8-steps-to-your-first-openid-enabled-app/#comments</comments>
		<pubDate>Wed, 07 Mar 2007 08:00:09 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[openid]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/03/07/8-steps-to-your-first-openid-enabled-app/</guid>
		<description><![CDATA[openid_login_generator isn&#8217;t the only game in town for creating an OpenID-enabled Rails application, and it&#8217;s certainly not the best for real-world apps. But it is the simplest. The generator doesn&#8217;t even generate migrations for you, yet it&#8217;s only 8 steps to your first OpenID enabled app (ok, you had to install ruby, rails and sqlite3 [...]]]></description>
			<content:encoded><![CDATA[<p>openid_login_generator isn&#8217;t the only game in town for creating an OpenID-enabled Rails application, and it&#8217;s certainly not the best for real-world apps.  But it is the simplest.  The generator doesn&#8217;t even generate migrations for you, yet it&#8217;s only 8 steps to your first OpenID enabled app (ok, you had to install ruby, rails and sqlite3 first). Here&#8217;s a cheat sheet length tutorial.</p>
<pre><code>$ rails your_app -d sqlite3; cd your_app
$ sudo gem install openid_login_generator -y
$ script/generate openid_login openid_account
$ ${EDITOR} app/controllers/application.rb
  require_dependency "openid_login_system"

  class ApplicationController &lt; ActionController::Base
    include OpenidLoginSystem
    model :user
$ script/generate migration create_user_model
$ ${EDITOR} db/migrate/001_create_user_model.rb
  def self.up
    create_table :users do |t|
         t.column <img src='http://leancode.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> penid_url, :string
    end
  end

  def self.down
    drop_table :users
  end
$ rake db:migrate
$ script/server</code></pre>
<p>Now browse to http://localhost:3000/openid_account/login and test your new openid login-enabled app.  You&#8217;re good and ready to add &#8220;before_filter :login_required&#8221; to controllers to limit access. See the <a href="http://www.openidenabled.com/resources/repos/ruby/openid/examples/rails_openid_login_generator/templates/README">readme</a> for more.</p>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/03/07/8-steps-to-your-first-openid-enabled-app/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>OpenIDAuthentication tutorial</title>
		<link>http://leancode.com/2007/03/05/openidauthentication-tutorial/</link>
		<comments>http://leancode.com/2007/03/05/openidauthentication-tutorial/#comments</comments>
		<pubDate>Mon, 05 Mar 2007 23:44:58 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[openid]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/03/05/openidauthentication-tutorial/</guid>
		<description><![CDATA[DHH&#8217;s OpenIDAuthentication plugin for Rails is evolving and progressing quickly. Over the weekend, David updated the plugin to no longer assume an overloaded login form. Removed open_id? as the idea of using the same input box for both OpenID and username has died &#8212; use using_open_id? instead (which checks for the presence of params[:openid_url] by [...]]]></description>
			<content:encoded><![CDATA[<p>DHH&#8217;s <a href="http://agilewebdevelopment.com/plugins/openidauthentication">OpenIDAuthentication plugin</a> for Rails is evolving and progressing quickly.  Over the weekend, David updated the plugin to no longer assume an overloaded login form.</p>
<blockquote><p>Removed open_id? as the idea of using the same input box for both OpenID and username has died &#8212; use using_open_id? instead (which checks for the presence of params[:openid_url] by default) [DHH - Revision 6631]</p></blockquote>
<p>This morning, Ben Curtis put up an <a href="http://www.bencurtis.com/archives/2007/03/rails-openid-and-acts-as-authenticated/">excellent, short tutorial</a> on using this plugin on an existing site.</p>
<p>It&#8217;s wonderful having the creator of Rails working on OpenID. <img src='http://leancode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  The design of DHH&#8217;s plugin is small, simple and clean &#8212; it doesn&#8217;t rely on a lot of generated code like openid_login_generator and has a much cleaner abstraction on top of ruby-openid, as compared to Eastmedia&#8217;s OpenID+Consumer plugin/generator.</p>
<p>The barriers to implementing OpenID for a Rails site are falling quickly.</p>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/03/05/openidauthentication-tutorial/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Overloading username and openid_url</title>
		<link>http://leancode.com/2007/02/28/overloading-username-and-openid_url/</link>
		<comments>http://leancode.com/2007/02/28/overloading-username-and-openid_url/#comments</comments>
		<pubDate>Wed, 28 Feb 2007 22:24:28 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[openid]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/02/28/overloading-username-and-openid_url/</guid>
		<description><![CDATA[DHH, who is promisingly writing a Rails plugin for OpenID with Rick and others, has made a case for applications to store a user&#8217;s openid_url in place of their username, and present a unified login form which hides or reveals the different processing of openid &#038; password logins, based on the presence of the http [...]]]></description>
			<content:encoded><![CDATA[<p>DHH, who is promisingly writing a Rails plugin for OpenID with Rick and others, has made a case for applications to <a href="http://www.loudthinking.com/arc/000604.html">store a user&#8217;s openid_url in place of their username</a>, and <a href="http://www.loudthinking.com/arc/000606.html">present a unified login form</a> which hides or reveals the different processing of openid &#038; password logins, based on the presence of the http prefix.  </p>
<p>When users start typing an OpenID identifier URL into the username field, the web app transparently turns it into an OpenID login action.</p>
<p>The common implementation today is to add an openid_url field alongside the existing user data, provide a login screen that offers regular and OpenID login, and often internally maps OpenID&#8217;s nickname (from the Simple Registration Extention) to the username/login.  </p>
<p>What are some pros/cons to the proposed overloading approach?</p>
<p><strong>Pros</strong></p>
<ul>
<li>For users, the the login or signup screens aren&#8217;t complicated further with another visible alternative</li>
<li>As a developer, you don&#8217;t have to use an additional field in the database</li>
<li>As a developer, you don&#8217;t have to deal with potential uniqueness conflicts between one person&#8217;s OpenID nickname, and another person&#8217;s username (which may require an additional username/email form to be presented during account creation in the case of a conflict)</li>
</ul>
<p><strong>Cons</strong></p>
<ul>
<li>According to <a href="http://openid.net/specs/openid-authentication-1_1.html">Spec (s 3.2.1)</a>, the user shouldn&#8217;t be required to prefix their identifier with http (basically, a usability issue)</li>
<li>The gentleman&#8217;s standard (also in the spec) of naming the form field &#8220;openid_url&#8221; to allow it to be auto-populated across sites is lost.</li>
<li>Both OpenID users and traditional users may be confused by the overloaded form.  If the OpenID logo is displayed, it doesn&#8217;t have a natural home which won&#8217;t confuse one party or the other</li>
<li>The application no longer has a place to store a friendly name for the user. So views display a URL, which will typically be much longer than a username, and require some additional view logic to turn into a link</li>
<li>OpenID accounts are at a privacy disadvantage vs. username/password accounts, because their visible username tracks directly back to them</li>
<li>For the developer, the code for the two authentication methods (password, openid) becomes even more coupled</li>
</ul>
<p>Wrong on anything? And other major pro/cons missed?</p>
<p>On the whole, what&#8217;s common with current implementations (separate openid form on the login page for the user, separate openid field in the database for the application) is both in line with the spec, and still the better compromise.  As the <a href="http://dev.rubyonrails.org/browser/plugins/open_id_authentication">core team&#8217;s Rails Plugin quickly evolves</a>, expect details and directions to change.</p>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/02/28/overloading-username-and-openid_url/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Why the lack of OpenID-enabled Rails apps?</title>
		<link>http://leancode.com/2007/02/20/why-the-lack-of-openid-enabled-rails-apps/</link>
		<comments>http://leancode.com/2007/02/20/why-the-lack-of-openid-enabled-rails-apps/#comments</comments>
		<pubDate>Tue, 20 Feb 2007 00:25:10 +0000</pubDate>
		<dc:creator>Bernie Thompson</dc:creator>
				<category><![CDATA[openid]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://leancode.com/2007/02/20/why-the-lack-of-openid-enabled-rails-apps/</guid>
		<description><![CDATA[OpenID has been quickly gaining momentum this year, with Microsoft&#8217;s future role as an identity provider, and AOL&#8217;s sudden, wonderful announcement that all 60+ million AOL/AIM users now have an identity provider. But where are the OpenID-enabled web applications to log into? What we have so far is nice, but it&#8217;s not the kind of [...]]]></description>
			<content:encoded><![CDATA[<p>OpenID has been quickly gaining momentum this year, with Microsoft&#8217;s future role as an identity provider, and AOL&#8217;s sudden, wonderful announcement that all <a href="http://blogs.zdnet.com/BTL/?p=4513">60+ million AOL/AIM users now have an identity provider</a>.</p>
<p>But where are the OpenID-enabled web applications to log into?  <a href="http://www.lifewiki.net/openid/OpenIDConsumers">What we have so far is nice</a>, but it&#8217;s not the kind of riches we&#8217;re seeing on the provider side of the OpenID equation.</p>
<p>With Rails being the platform of choice for many new &#038; emerging web sites, you&#8217;d expect to see OpenID support here first.  So really the question is &#8212; Why don&#8217;t we see more Rails apps with OpenID support?</p>
<ul>
<li><strong>Most OpenID-enabled sites still need to support password authentication</strong>.  There are some good choices today for creating a new Rails app that only supports OpenID login (the ruby-openid gem&#8217;s generator is good for that), but it&#8217;ll be some time before all users are comfortable with OpenID.  So sites need to be able to add OpenID support alongside password login &#8212; and that&#8217;s a non-trivial challenge today (see <a href="http://identity.eastmedia.com/identity/show/Bookmarks+Demo+Application">bookmarks</a> for one example, but it&#8217;s not yet solid). </li>
<li><strong>Competing authentication plug-ins</strong>.  For OpenID, there are two major competing plugins: <a href="http://www.openidenabled.com/openid/libraries/ruby">JanRain&#8217;s generator that is included in the ruby-openid gem</a>, and <a href="http://www.agilewebdevelopment.com/plugins/openid_consumer">Eastmedia&#8217;s generator</a> (used in the bookmarks example).  And to combine with password authentication, there&#8217;s a more confusing <a href="http://www.agilewebdevelopment.com/plugins/search?search=authentication">jumble of choices</a>. If you&#8217;re running Rails 1.2, <a href="http://www.agilewebdevelopment.com/plugins/restful_authentication">restful_authentication</a> is currently the strongest choice for password login because of its cleanliness, tests, and feature support for remembered logins (cookies) and optional email activation, etc (<1.2, acts_as_authenticated is strongest). And on the OpenID side, Eastmedia's generator is better configured to mashup with other login systems, but it still requires a substantial amount of customization, and it suffers from lack of tests and some out of sync code.</li>
<li><strong>The right user interface hasn&#8217;t been settled on</strong>. Should we present password &#038; openid login on the same page?  A set of choices with fancy UI (tabs)? Should account creation be automatic for OpenID? Should OpenID SRE nickname and email be assumed to be configured?</li>
<li><strong>The right internal structure involves some difficult tradeoffs</strong>. Just at the top level &#8212; should different authentication methods all store their data in a unified user model?  Should the application&#8217;s login and OpenID&#8217;s nickname be treated as equivalent? If so, how to handle uniqueness? etc. etc.</li>
<li><strong>Disagreements on the wisdom of drop-in authentication</strong>. The best hope for making this all more approachable is better plugin support, including authentication plugins that play well together so a single application can support multiple authentication mechanisms. But there has been some disagreement among the community &#8212; some would argue that authentication of this type is too tied to unique aspects of the application and too important from a security point of view to be realistic as a dynamic plugin or works-out-of-the-box generator.  But without out-of-the-box ease (like what aaa or restful_authentication provides for password authentication), combined OpenID+password authentication will trail in adoption.</li>
<li><strong>In short, the killer OpenID plugin has yet to be written</strong>. For an excellent spec for what is needed and an incomplete implementation, see <a href="http://www.ruby-forum.com/topic/81980">Hark</a>.</li>
</ul>
<p>OpenID is poised to take off.  Support from an army of up-and-coming Rails sites could be the turning point. </p>
<p>Are there other tools that make this more approachable for Rails developers?</p>
]]></content:encoded>
			<wfw:commentRss>http://leancode.com/2007/02/20/why-the-lack-of-openid-enabled-rails-apps/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.622 seconds -->

