Skip to content

Instantly share code, notes, and snippets.

@baygross
Created March 17, 2012 04:17
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save baygross/2054898 to your computer and use it in GitHub Desktop.
Save baygross/2054898 to your computer and use it in GitHub Desktop.
Yale CAS + LDAP integration with Rails
Add or append these files to your Rails app to integrate with Yale's CAS + LDAP servers.
# Add this before filter to force CAS Authentication on all controllers + actions
before_filter CASClient::Frameworks::Rails::Filter, :unless => :skip_login?
# Add this before filter to set a local variable for the current user from CAS session
before_filter :getMe
# And their protected methods
protected
def getMe
@me = User.find_or_create_by_netid( session[:cas_user] )
if !@me
redirect_to :root
return false
end
end
# hack for skip_before_filter with CAS
# overwrite this method (with 'true') in any controller you want to skip CAS authentication
def skip_login?
false
end
#
## Add this block to the bottom of your environment.rb file
#
CASClient::Frameworks::Rails::Filter.configure(
:cas_base_url => "https://secure.its.yale.edu/cas/",
:username_session_key => :cas_user,
:extra_attributes_session_key => :cas_extra_attributes
)
#
## Add these gems to your Gemfile, and be sure to 'bundle install'
#
gem 'net-ldap'
gem 'rubycas-client'
class User < ActiveRecord::Base
require 'net/ldap'
# Associations
# Validations
validates_uniqueness_of :email, :message => "Conflicting email address."
# Callbacks
after_create :populateLDAP
# Accessors
def name
self.fname.capitalize + " " + self.lname.capitalize
end
protected
#populate contact fields from LDAP
def populateLDAP
#quit if no email or netid to work with
self.email ||= ''
return if !self.email.include?('@yale.edu') && !self.netid
begin
ldap = Net::LDAP.new( :host =>"directory.yale.edu" , :port =>"389" )
#set e filter
if !self.email.blank?
f = Net::LDAP::Filter.eq('mail', self.email)
else #netid
f = Net::LDAP::Filter.eq('uid', self.netid)
end
b = 'ou=People,o=yale.edu'
p = ldap.search(:base => b, :filter => f, :return_result => true).first
rescue Exception => e
logger.debug :text => e
logger.debug :text => "*** ERROR with LDAP"
guessFromEmail
end
self.netid = ( p['uid'] ? p['uid'][0] : '' )
self.fname = ( p['knownAs'] ? p['knownAs'][0] : '' )
if self.fname.blank?
self.fname = ( p['givenname'] ? p['givenname'][0] : '' )
end
self.lname = ( p['sn'] ? p['sn'][0] : '' )
self.email = ( p['mail'] ? p['mail'][0] : '' )
self.year = ( p['class'] ? p['class'][0].to_i : 0 )
self.college = ( p['college'] ? p['college'][0] : '' )
self.save!
end
# not a yale email, just make best guess at it
def guessFromEmail
name = self.email[ /[^@]+/ ]
return false if !name
name = name.split( "." )
self.fname = name[0].downcase
self.lname = name[1].downcase || ''
self.save
end
end
@geoffreylitt
Copy link

This was really useful! Thanks.

@vivecamorris
Copy link

Awesome, thanks! We're using this for our first Tech Bootcamp Rails app.

@ncasti
Copy link

ncasti commented Jul 7, 2014

^ Same here!

@aarongertler
Copy link

I used this last year for a Tech Bootcamp app! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment