Showing posts with label authlogic. Show all posts
Showing posts with label authlogic. Show all posts

Monday, September 05, 2011

Example app test failures from authlogic user sessions

This question on stackoverflow led me to believe that if I actually ran rake test that my example app's tests would fail--and they did, with the same error. (Why I wasn't running tests from the beginning? Meh!) The tests throw up wads of stack trace, headed with this:

SQLException: no such table: user_sessions: DELETE FROM "user_sessions" WHERE 1=1

What's causing this error? We created our user session object like this:

rails g authlogic:session UserSession

Unfortunately, this created a fixture file as well. During testing, fixture files normally map to tables, from which all data is deleted before subsequent reloading of the fixture.

But authlogic user sessions aren't ActiveRecord models, they're AR-like, and are actually authlogic-derived classes. No table: they serve as a link between users (which are in a table) and their authlogic sessions. My takeaway? Authlogic sessions should be created without a fixture file.

rails g authlogic:session UserSession --skip-fixture # Or --fixture=false

The file has been removed from the example app's github repository.

Two other minor changes were made to get the tests to pass (w/o any care to what they're testing). First, the user fixture file was tweaked (replace the old "login" property with the new "nickname" property, make the persistence tokens unique). Second, the HomeControllerTest stub was tweaked to expect a 302 when hitting the index page, which is the redirect encountered when the user isn't logged in.

Using email or nickname to log in using authlogic and Rails 3

This is a continuation of my first authlogic/Rails 3 post.

Authlogic users have both "login" and "email" properties by default. I wanted to allow users to log in via their email address or nickname. I tackled this in two steps. First, switch to logging in using the "email" property. Second, create a "nickname" property, and allow users to log in with either one. (Yes, I actually wanted to call it "nickname"; I probably could have just aliased it or something.)

In addition to the column-dropping migration, I needed to change the authlogic config to use the "email" property for user lookup, and to not validate the "login" property, since it no longer existed. This is handled in the acts_as_authentic configuration as discussed previously.
  acts_as_authentic do |c|
    c.login_field = :email
    c.validate_login_field = false
    c.require_password_confirmation = false
  end

Lines two and three do what we expect. These configuration fields are documented in the login field configuration section of the authlogic docs. Part the first, done.

If we want to allow users to log in by either email or nickname we need to change both the user and user session classes (in addition to adding the "nickname" property to our user model, of course).

First we add a user class method to look up users by nickname or email.
class User < ActiveRecord::Base
  # acts_as_authentic config removed for clarity.
  class << self
    def find_by_nickname_or_email(s)
      find_by_nickname(s) || find_by_email(s)
    end
  end
end

In the user session class we'll define the user lookup method. While we're here, we'll genericize the error message to something not tied to property names.
class UserSession < Authlogic::Session::Base
  # Use authlogic's default message
  # generalize_credentials_error_messages true
  # Use our own message
  generalize_credentials_error_messages "Login info is invalid!"
  find_by_login_method :find_by_nickname_or_email
end

This is documented in the session configuration section of the authlogic docs.

Users can now log in using either their email, or their nickname. As it stands, the sample app doesn't do much to enforce uniqueness (other than the authlogic defaults) of emails or nicknames.

(It also seems like we should disallow using someone else's email as a nickname, perhaps disallow emails-as-nicknames altogether.)

Sunday, September 04, 2011

Rails 3 + authlogic explorations

I've started a simple Rails 3 + authlogic example project on github, mostly for myself to experiment with. Right now it's basically a copy of this post's implementation (and unfinished at that), but I'll be expanding it over the next few days in various ways.

As it stands, the "application" (I use the term loosely) consists of a home page (root path) requiring login, and login/logout actions. You may follow the directions in the README file (and cut-and-paste some code), or fork it and do a DB create/migrate/seed, and have a user with a login ID of "plugh", password "xyzzy".

The example app will change its shape a bit as I poke authlogic with sticks, tailor the example to my specific needs, and see what all I can do with it. Ultimately, I'm not sure if I'll end up using devise, or if what I use depends on the app itself. (My own apps have different requirements than my work apps--I may use both!)

Part two; logging in using either a user's nickname or email.