Auth Module
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.
- current_user_session (aliased as has_logged_in_user) - returns nil if no user session has been established
- 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.
- new - renders the login screen or redirects to external login screen
- validate - validates the user upon login
- destroy - processes logout
app/controllers/users_controller.rb
The UsersController manages the routing of user related requests and provides two methods.
- edit (also called from show) - renders the user preferences screen
- 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:
- before_login - called when a new user session is being established, before the actual login is called
- login_url - called if before_login isn't defined or returns false, convenience method for redirecting to an external login url
- after_login - called after login user has been validated, provides mechanism for authorization
- before_logout - called before current user session is destroyed
- after_logout - called after current user session is destroyed
- on_every_request - called on every request
The module also has two private methods for use in extended local classes.
- validate_url - generates the return url to send to external logins services
- 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.
At NYU we're currently using the Auth module in our holdings table to offer request functionality based on "patron status". We display a request button, if the patron has the appropriate status to be able to request/page items and use a custom controller to provide this functionality seamlessly. Screenshots of this functionality can be seen below.
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:
- login_url - provides PDS login URL to redirect to
- after_login - checks authorization, stores some cookies to improve performance, saves some user data when appropriate
- logout_url - provides PDS logout URL
- after_logout - destroys some cookies that were stored to improve performance
- 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 } }
Screenshots of Request Functionality
Not logged in, no request
Logged in, request
Now the request button appears because I have permission to request available items.