Software Development - Ruby, Rails, Authentication - RoboProg's

RoboProg's / Software Development

Feb 18, 2009

More Input Than Output.

I had some hardware problems this week (involving a broken laptop), so I have not had any "quiet time" to do any development this week. Instead, I think I will share some reading, as well as listening, that I have been doing.

First, the listening. I would like to thank Paul Williams (who really should put something on his site, hint, hint) for introducing me to the IT Conversations site. There are podcasts for a variety of topics available there. I spend a lot of time in the car commuting every day, so it is useful to have something else to listen to besides the radio. In particular, some keynote speeches from past RailsConfs are there. Several of these I found interesting for my own contrary way.

One of these is about comparing Ruby to Smalltalk, and some of the implementation history that Ruby is likely to repeat. Also of interest in this discussion is some talk of making very stateful application code and using the objects themselves as the persistance mechanism. Perhaps there are some situations in which such an iconoclastic approach would be what was needed to simplify a problem.

The other that I found intriguing was about Sun's support for Ruby, such as adopting the JRuby project (which is faster than ruby 1.8), and providing a Ruby plugin for Netbeans. If anybody gets a chance to try the netbeans IDE with ruby, please let me know how that goes. Also, in regards to speed, if you poke around on the debian shootout page, you may notice that Ruby seems to prefer small code and a small memory footprint, while Java prefers to run fast (and use gobs of memory).

I have been reading through the book Enterprise Rails. FWIW, you can get it Amazon for quite a bit less than I did. Too bad I don't get paid for the link. One of the things I liked about this book was the use of PostgreSQL, rather than the seemingly obligatory MySQL. I have been using Postgres at home since late 2000. It is reasonably comparable to Oracle. That other thing was definitely not then, and I'm not so sure it is now, either. I guess I am not the only person who prefers to use PostgreSQL, either.

The early part of the book focuses on building a good data model, and some guidelines to make sure the data is in a reasonably (3rd) normalized form, before charging in and generating a bunch of boilerplate MVC code. It also briefly covered writing your own plugins as a way to standardize whatever hacks you need to add to Rails for your project. I will probably have more to say about the book in the near future, if not next week.

Feb 12, 2009

The Less than Complete Rails Login.

It turns out that the initial setup of Acts_as_authenticated is relatively easy. By the way, I am using Ubuntu this year (rather than Red Hat or Slackware, in years past), which uses the Debian package management system, so I have kept notes in terms of that system. First, some prerequisites:

  1. Use Ubuntu (Debian) apt-get to install ruby and gem.

    (I am assuming that you have already done this and this)

  2. Use gem to install rails.

    (I am assuming that you have already done this)

  3. Use apt-get to install git / git-core.

    (even though I use Subversion this year, rails needs Git)

    	$ sudo apt-get install git
    	. . .
    	$ sudo apt-get install git-core
    	. . .

  4. Use rails to install the authenticated plugin via git.

    	$ cd . . . # root directory of your rails project
    	$ ./script/plugin install git://
    	. . .

Still with me? You now have the packages needed, and you are ready to add the basic login setup to your project!

This is what I had to do to get the login stub code up and running:

  1. Run the plugin to generate the boiler plate code.

    	$ cd . . . # root directory of your rails project
    	$ ./script/generate authenticated user account
    	. . .

    If you commit the plugin installation and generation in subversion (at the same time), you will see changes something like the ones shown below. I have culled out the file header lines from a "diff" listing as an after the fact "status" command.

    	$ svn diff -r 2:3 | grep '^Index'
    	Index: test/unit/user_test.rb
    	Index: test/functional/account_controller_test.rb
    	Index: test/fixtures/users.yml
    	Index: app/helpers/account_helper.rb
    	Index: app/models/user.rb
    	Index: app/controllers/account_controller.rb
    	Index: app/views/account/signup.html.erb
    	Index: app/views/account/index.html.erb
    	Index: app/views/account/login.html.erb
    	Index: db/schema.rb
    	Index: db/migrate/20090210202825_create_users.rb
    	Index: lib/authenticated_test_helper.rb
    	Index: lib/authenticated_system.rb
    	Index: vendor/plugins/acts_as_authenticated/CHANGELOG
    	Index: vendor/plugins/acts_as_authenticated/install.rb
    	. . .
    	Index: vendor/plugins/acts_as_authenticated/README

    Note that revision 3 was the revision that committed these changes, thus the "-r 2:3" argument. The timestamp in your migration script will of course differ as well.

  2. Modify your controller classes to use the authentication filter.

    	$ svn diff -r 2:3 app/controllers/application.rb app/controllers/shopitems_controller.rb
    	Index: app/controllers/application.rb
    	--- app/controllers/application.rb	(revision 2)
    	+++ app/controllers/application.rb	(revision 3)
    	@@ -2,6 +2,9 @@
    	 # Likewise, all the methods added will be available for all controllers.
    	 class ApplicationController < ActionController::Base
    	+  include AuthenticatedSystem
    	   helper :all # include all helpers, all the time
    	   # See ActionController::RequestForgeryProtection for details
    	Index: app/controllers/shopitems_controller.rb
    	--- app/controllers/shopitems_controller.rb	(revision 2)
    	+++ app/controllers/shopitems_controller.rb	(revision 3)
    	@@ -1,4 +1,7 @@
    	 class ShopitemsController < ApplicationController
    	+  before_filter :login_required
    	   # GET /shopitems
    	   # GET /shopitems.xml
    	   def index

    Note that app/controllers/shopitems_controller.rb is something specific to my application. Your controller(s) will have different names.

  3. Migrate your database(s) to include the new table.

    	$ rake db:migrate
    	. . .
    	$ RAILS_ENV=test rake db:migrate
    	. . .

The next time you start your application, any requests to the updated controllers will force a trip to the login page. Use the /account/signup URI to create a new login (or add a link to it in appropriate places)

For what it's worth, you can see what I have done so far here. Of course, it probably will not work well unless you do this first. Also, be aware that this site is far from done, and I will likely have to frequently remove the "vandalism" until things settle down. So, along that line of thought, what's next?

  1. OpenId. I do not have the mail-my-forgotten-password feature, or anything like that, implemented yet. I don't think I want to implement those kind of features. This "single sign on" interface allows me to piggy-back off of other internet sites' login facilities, such as Yahoo (where I have my email) or Google. SSO is another interesting thing to put on your resume, as well.
  2. Linking the items on the list to a user, and filtering the list to only those items for the user.
  3. Creation of a "household" list to bundle related users, and expansion of the filtering logic to show everthing for the household.
  4. Much more.

Feb 5, 2009

Ruby on Rails Authentication

I have been playing around with Ruby on Rails for a few months, here and there, as an alternative to the J2EE ("it's the new COBOL") stuff that I do at work. Most of the examples / books / tutorials that I have read so far focus on getting a CRUD system up and going to edit a table. This is pretty easy to do, and doubtless explains the popularity of Rails.

The problem is, as soon as you want to deploy ANYTHING, you need some kind of login mechanism to keep the riff-raff out, and to force people to accept spam from you, and all that good stuff.

Poking around a bit quickly reveals that Rails controllers have a session object (or at least something that quacks like one), like just about every other web app framework in the world. Well, that's good. It would sure be nice to associate a session with a persistant identity of some kind (hey, maybe even with some roles, eventually, why not).

Never fear! We have a solution. Well, if by "a solution", you mean "several available plugins", or numerous articles about rolling your own. Out of the box, Rails has no default login mechanism included. The books I have put this topic off until far too late, in my opinion. After searching around some, it looks like the best solution (or at least the most widely recognized one, since I am not in a position to compare them from experience) is "acts as authenticated".

I will probably have more to say on this next week. Keep in mind, there also seems to be quite a bit of thrashing going on, as Rails 2.x is still relatively new. Note: "about a year" is "new" to oldsters like me who do not resync their libraries every week, OK? It is also relatively new in relation to printed, coherent tutorial material that you can purchase. Even on line, much of what you google into is still written in terms of 1.x.

Yes, I know it's trivial if you personally have already done it.

Oh, and I'm now being threatened with "git", just when I was getting the hang of subversion. Subversion really does work well with Rails, by the way, as I am just too lazy to track all the files that Rails creates individually. (I know this must violate some ethic, but I only have so much time at home)

Contact me:

Copyright 2009, Robin R Anderson