Auth Module

Revision as of 20:40, 20 January 2011 by Scotdalton (Talk | contribs)

Revision as of 20:40, 20 January 2011 by Scotdalton (Talk | contribs)

Auth Module (Developer Notes)

The Auth module extends functionality available from the [Authlogic|http://github.com/binarylogic/authlogic] (version 2.1.0) gem and included in the lib directory based on the [Authlogic OpenID add-on|http://github.com/binarylogic/authlogic_openid].'

The idea is to allow services to be customized based on a logged in user's attributes. Some examples could be:

  • Store a user's mobile phone number or email address to default the txt/email values for those services.
  • Provide extended request or paging functionality that is only available to a subset of patrons.
  • Allow faculty members to place items on reserve from the Umlaut screen.

Currently the Auth module requires existing Umlaut users to install the authlogic gem and perform a rails migration to update the user model to work with authlogic and the auth module. After these two steps have been taken, the auth module should only take effect if a particular instance has defined a auth module in their local config.

Umlaut Files Added or Updated

Several core Umlaut files were added and updated in order to support the Auth module.

app/controller/application.rb

The ApplicationController filters passwords and provides two methods for accessing the current user session and the current user.

  1. current_user_session (aliased as has_logged_in_user) - returns nil if no user session has been established
  2. current_user (aliased as logged_in_user) - returns either nil or the current logged in user

The application calls current_user_session as a before filter on every request.

app/controllers/user_sessions_controller.rb

The UserSessionsController manages the routing of user session requests and provides three methods.

  1. new - renders the login screen or redirects to external login screen
  2. validate - validates the user upon login
  3. destroy - processes logout

app/controllers/users_controller.rb

The UsersController manages the routing of user related requests and provides two methods.

  1. edit (also called from show) - renders the user preferences screen
  2. update - processes updates to user preferences (not yet implemented)

app/models/user_sessions.rb

UserSessions extends Authlogic::Session::Base

app/models/user.rb

User serializes user_attributes and adds acts_as_authentic functionality to leverage the Authlogic gem. Also sets to_param to username rather than id for prettier urls.

app/views/user_sessions/new.html.rb

The default login screen, doesn't currently do anything.

app/views/users/edit.html.rb

The default user preferences screen. Users can update mobile phone numbers and the like (not yet implemented)

config/environment.rb

Added authlogic gem:

#require 'authlogic'
config.gem 'authlogic', :version => "= 2.1.0"

config/routes.rb

Added url routes:

  map.login "login", :controller => "user_sessions", :action => "new"
  map.logout "logout", :controller => "user_sessions", :action => "destroy"
  map.validate "validate", :controller => "user_sessions", :action => "validate"
  map.resources :user_sessions
  map.resources :users

db/schema.rb

Modified the user table to use with authlogic. Included column for mobile phone, user attributes and a refreshed_at date to track age of a particular record for better performance. By default, data expires after 1 week.

lib/service.rb

Make the user accessible from a particular user via the session_user method.

  # Returns the currently logged in user, if available, based on the user_credentials_id in the 
  # session from AuthLogic.  May want to make this more sophisticated and check user_credentials
  # against db.
  def session_user
    return User.find(session["user_credentials_id"]) unless session["user_credentials_id"].nil?
  end

Auth Module

The following files makeup the Auth module to extend the functionality of Authlogic for our purposes.

lib/auth/acts_as_authentic.rb

The ActsAsAuthentic module extends the authlogic user model to ignore passwords, reset_persistence_token when the username changes, manage stale data (via refreshed_at date), and handle user attributes hash.

lib/auth/session.rb

The Session module establishes the Auth module callback functions and can serve as a template for further localizations. Callback functions to be overridden locally as appropriate:

  1. before_login - called when a new user session is being established, before the actual login is called
  2. login_url - called if before_login isn't defined or returns false, convenience method for redirecting to an external login url
  3. after_login - called after login user has been validated, provides mechanism for authorization
  4. before_logout - called before current user session is destroyed
  5. after_logout - called after current user session is destroyed
  6. on_every_request - called on every request

The module also has two private methods for use in extended local classes.

  1. validate_url - generates the return url to send to external logins services
  2. session_user - facilitates saving user attributes to the user model

Configuring Local Auth Modules

Auth Module Example

AuthPDS was developed at NYU as an example of generating a plugin and populating the stub methods provided.

lib/auth/local/auth_pds.rb

The AuthPDS module gets mixed in with the Session module to log in via PDS (customized for NYU). It implements the following callback functions:

  1. login_url - provides PDS login URL to redirect to
  2. after_login - checks authorization, stores some cookies to improve performance, saves some user data when appropriate
  3. logout_url - provides PDS logout URL
  4. after_logout - destroys some cookies that were stored to improve performance
  5. on_every_request - checks if the user has logged in (e.g. from another PDS SSO system)

config/umlaut_config/environment.rb

The auth configuration settings are added to the local environment.rb to establish the appropriate class to mix in and to pass various options to the module.

  config.app_config.login = {
    # File name
    :id => "auth_pds",
    # Class name
    :module => :AuthPDS,
    :options => {
      # Make expiration date configurable
      :expiration_date => lambda {return 1.week.ago},
      # OpenSSO URL, specific to NYU's implementation of PDS.
      # Could easily be removed to make the local PDS module more generic.
      :opensso_path => "https://login.nyu.edu:443/sso",
      # PDS URL
      :pds_url => "https://pds.library.institution.edu:443/",
      # System name since the module is used in many different contexts and different apps
      :system_name => :umlaut,
      # Cookie name that is used to help with performance since the module is used in 
      # many different contexts and different apps
      :cookie_name => :nyulibrary_opensso_umlaut,
      :additional_user_attributes => lambda do |user_session|
        h = {}
        # NYU is using this module for several of our ruby apps 
        # and this mechanism allows us to include different user attributes per system.
        # It's included here to give an idea of the flexibility of the module.
        return h
      end
    }
  }