Skip to content

Instantly share code, notes, and snippets.

@tyler-dot-earth
Created June 10, 2015 20:38
Show Gist options
  • Save tyler-dot-earth/9bc9ad26f82a23c7305d to your computer and use it in GitHub Desktop.
Save tyler-dot-earth/9bc9ad26f82a23c7305d to your computer and use it in GitHub Desktop.
ldap_authenticatable module for devise that checks if a member is in a group.
# add this to the Devise.setup block
config.warden do |manager|
manager.default_strategies(:scope => :admin).unshift :ldap_authenticatable
end
require 'net/ldap'
require 'devise/strategies/authenticatable'
module Devise
module Strategies
class LdapAuthenticatable < Authenticatable
def authenticate!
if params[:admin]
ldap = Net::LDAP.new(ldap_settings)
if ldap.bind
# User successfully authed via LDAP,
# but now we need to make sure they're in
# the correct group.
in_admin_group = false
filter = Net::LDAP::Filter.eq("cn", "REPLACE-ME*")
treebase = "cn=REPLACE-ME,ou=groups,dc=REPLACE-ME,dc=int"
# Searching this treebase will return a Net::LDAP::Entry object that looks like:
# <Net::LDAP::Entry:0x007fcae370af98
# @myhash={
# :dn=>["cn=REPLACE-ME,ou=groups,dc=REPLACE-ME,dc=int"],
# :gidnumber=>["508"],
# :cn=>["REPLACE-ME"],
# :objectclass=>["posixGroup", "top"],
# :memberuid=>["bob", "john", "henry"]
# }
# >
# ... so we're goign to loop through the memberuids and see if the username we
# just authenticated with is in the memberuids.
ldap.search(:base => treebase, :filter => filter) do |entries|
entries[:memberuid].each do |member|
if member == cn_username
in_admin_group = true
end
end
end
if in_admin_group
# They're an admin!
# .. Find or create an account in the portal DB for 'em.
admin = Admin.find_or_create_by(email: email)
# .. Log 'em in.
success!(admin)
else
fail(:invalid_login)
end
else
# User's credentials didn't auth at all.
fail(:invalid_login)
end
end
end
def email
params[:admin][:email]
end
def password
params[:admin][:password]
end
#TODO
# Auth doesn't work with mail right now,
# (or at least I can't figure it out)
# so let's just split their email.
def cn_username
email.split('@')[0]
end
def ldap_settings
{
:host => "REPLACE-ME",
:port => 389,
:base => "cn=REPLACE-ME,ou=groups,dc=REPLACE-ME,dc=int",
:auth => {
:method => :simple,
:username => "cn=#{cn_username},ou=users,dc=REPLACE-ME,dc=int",
:password => password
}
}
end
end
end
end
Warden::Strategies.add(:ldap_authenticatable, Devise::Strategies::LdapAuthenticatable)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment