Thursday, April 29, 2010

Changing erroneous git commit message...

Just the other day, I was making a few small changes to my new site and noticed -- just before I pushed them to github -- that I had created a bad commit message: somehow I had copied the text from the previous commit. Not Good. I figured that would be easy to change and -- while it turned out to be quite easy -- it wasn't easy to find how to do it. Googling under various phrases kept getting me things like:

"...just use git rebase -i and 'edit' the commit." While that's quite true, unless you really get git, it's like the old Microsoft helicopter joke. (I suppose if I really read through the excellent documentation provided for git, I would have been able to figure it out, but that's a lot of reading for a quick fix.)

I finally had some help from my friend Wolf Arnold and with a little bit of trial and error, I was able to modify my commit message and then push my 3 commits to github. Here's how to do it. NOTE: This procedure only works if you have not pushed your commits. Once pushed, the commit message is inviolable - by design - as far as I can tell.
  1. First, make sure you know which commit you want to change. I used gitk (for Linux; gitx on the Mac), which gives you a visual display of your commits and the status of the remotes you are pushing to. Find the relative position of the commit you want to change. In my case, it was the 2nd on the list -- that is, one down from the top.
  2. In your root project directory (where you normally type your "git status" and other commands), type the following:
    git rebase -i HEAD~n
    
    where 'n' is equal to your commit's position on the list, counting from 1 at the top of the list. Notice that the character between HEAD and n is the "twiddle" character or "tilde".
  3. Once you enter that command, you are presented with a screen (in your favorite editor) that looks something like this (the numbers following 'pick' are the internal ids for your commits):
    pick <lots of numbers>
    pick <lots of different numbers>
    # Rebase 9a122e0..9a122e0 onto 9a122e0
    #
    # Commands:
    #  p, pick = use commit
    #  e, edit = use commit, but stop for amending 
    #  s, squash = use commit, but meld into previous commit 
    # # If you remove a line here THAT COMMIT WILL BE LOST.
    # However, if you remove everything, the rebase will be aborted.
    #
    
  4. At this point, you can do one of several things:
    1. Edit the file and change the word "pick" to "edit" on the top line of the file. That's the commit that you want to change. Save the file and exit the editor. That will set you up to make the changes in your commit.
    2. Delete every line in the file and save/close it. That's equivalent to a No-Op" and will terminate the rebase.
    3. There are more options, as you can see from the instructions in the file itself, but we'll leave that for another day.
  5. When the edit finishes, you will receive instructions at the command line.  The next step in the process is to run the command:
    git commit --amend
    
    and you will again be presented with an edit screen where you can change the commit message (or other things, but I didn't get into that either). Just change the line with the commit message to what you want it to be.
  6. Once that's done and you've saved/closed the file, run the command:
    git rebase --continue
    
    and it'll be done. You can use gitk to check things out and then push to whatever remote you're using.

Enjoy...

Tuesday, April 27, 2010

Authlogic login error messages...

I've been using autthlogic to provide login/signup features for my new web application, and I really like it. It provides lots of great features and has a fair number of plugins and tutorials to add functionality.

A few weeks past, I added a password reset feature. This was quite straight-forward: I just followed the password-reset tutorial and was up & running pretty quickly.

However, when I did some additional testing on the basic authlogic functionality, I noticed that it took a very simplistic approach to providing error messages for login failures: it would report "Invalid email address" or "Invalid password" if either of those fields were in error. This is not good security: an attacker could determine a valid email address and then use it for social engineering to gain further information.

Support to fix this is already in Authlogic -- it's just not the default behavior. You have to add the following method call to your UserSession class:

     class UserSession < Authlogic::Session::Base

       generalize_credentials_error_messages true

     end

More details can be found at: http://railsapi.com/doc/authlogic-v2.1.3/classes/Authlogic/Session/Password/Config.html#M000178

This post is mostly about collecting the various sources of information about Authlogic -- it's such a popular Rails plugin, that there are many search results, some of them dead or not very helpful. I spent almost an hour googling to find the right stuff, and figured I'd post what I found in case it might save someone else some time.

General github/authlogic documentation page: http://rdoc.info/projects/binarylogic/authlogic. The "documentation" link sends you to an RDoc Info page: the main page is an overview, and you get more detail by clicking on the 3 buttons in the upper right-hand corner: "Namespace list", "Method list", and "File list".

More documentation can also be found at: http://railsapi.com/doc/authlogic-v2.1.3/ .

All in all, really good stuff!

Wednesday, April 14, 2010

Using PostgreSQL

Now that PostgreSQL is installed and running on my Mac, I need to do something useful with it, like create my database and get it migrated through Rails.  The terminology and approach is a tad different from MySQL, but after a bit of googling, I found this PostgreSQL documentation page which got me rolling. This page on creating a database was actually the starting point, because it worked through the various errors which might occur.

The key difference for me was that the PostgreSQL superuser is called 'postgres', not 'root' as in MySQL. Prior to digging out this piece of information, everything I tried got the following error:

createdb: could not connect to database postgres: 
FATAL:  role "jseidel" does not exist

The other thing that was a minor roadblock was getting out of psql (PostgreSQL's interactive SQL command program). The usual MySQL/bash suspects (quit; exit; bye; {Ctrl-C}) didn't work. With psql you either type "\q" or {ctrl-D} and you're out.

Finally, since I'm using MacPorts, the location of the PostgreSQL files are different than documented in the PostgreSQL guide: my files are rooted off /opt/local/lib/postgresql84 instead of /usr/local/pgsql as is indicated in that guide.

Now I'm able to create my database and see if it connects with Rails...

Monday, April 12, 2010

Getting PostgreSQL to run on a Mac...

So I decided to switch to PostgreSQL from MySQL. First off, it's what's used by default at Heroku, and I'm so far loving Heroku, its great integration with git, and the resulting ease of deployment. Secondly, I'm a tad concerned about what might happen in the future since Oracle now owns MySQL: could be 'interesting'.

Anyway, I'd always heard that installing PostgreSQL was more challenging than installing MySQL: "MySQL put more effort into making things easier for first-time users" is what my friends have told me. But I also heard that PostgreSQL had better and more standard SQL support (for example, support for foreign keys).

Anyway, with a bit of searching, I finally found this RubyOnRails page which seemed to do a great job of laying things out for all 3 platforms. Seemed pretty straight-forward: 

Install the server:
sudo port install postgresql83-server

Start the server:
sudo launchctl load -w /Library/LaunchDaemons/org.macports.postgresql83-server.plist

Setup the database:
sudo mkdir -p /opt/local/var/db/postgresql83/defaultdb
sudo chown postgres:postgres /opt/local/var/db/postgresql83/defaultdb
sudo su postgres -c '/opt/local/lib/postgresql83/bin/initdb -D /opt/local/var/db/postgresql83/defaultdb'

Two problems:
  1. It failed installing the database -- complaining that it couldn't find the header file libpq-fe.h. 
  2. It installed version 8.3 and version 8.4 is now current.

More searching led me to the MacPorts site which has the required library:
sudo port install libpqxx

However, it also wound up installing the 8.4 version of PostgreSQL, but version 8.3 still is the one that gets launched... seems to work, but certainly not as clean as I would like.

Given the problems I had in the past before I cleaned my machine and installed Ruby & Rails "from scratch" with MacPorts (see my previous post on this issue) as I could easily get PostgreSQL with relatively little hassle.

So far, so good...

PS Check out "Enterprise Rails" (Dan Chak, O'Reilly). He does a really nice job of discussing Rails' scaling and reliability issues and does it all in the context of PostgreSQL. Good book!