Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added authentication using bind_as and filter #25

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
90 changes: 51 additions & 39 deletions lib/devise_ldap_authenticatable/ldap_adapter.rb
Expand Up @@ -3,38 +3,38 @@
module Devise

module LdapAdapter

def self.valid_credentials?(login, password_plaintext)
options = {:login => login,
:password => password_plaintext,
options = {:login => login,
:password => password_plaintext,
:ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
:admin => ::Devise.ldap_use_admin_to_bind}

resource = LdapConnect.new(options)
resource.authorized?
end

def self.update_password(login, new_password)
options = {:login => login,
:new_password => new_password,
:ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
:admin => ::Devise.ldap_use_admin_to_bind}

resource = LdapConnect.new(options)
resource.change_password! if new_password.present?
resource.change_password! if new_password.present?
end

def self.get_groups(login)
options = {:login => login,
options = {:login => login,
:ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
:admin => ::Devise.ldap_use_admin_to_bind}

ldap = LdapConnect.new(options)
ldap.user_groups
end

def self.get_dn(login)
options = {:login => login,
options = {:login => login,
:ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
:admin => ::Devise.ldap_use_admin_to_bind}
resource = LdapConnect.new(options)
Expand All @@ -56,16 +56,17 @@ def initialize(params = {})
@ldap.base = ldap_config["base"]
@attribute = ldap_config["attribute"]
@ldap_auth_username_builder = params[:ldap_auth_username_builder]

@group_base = ldap_config["group_base"]
@required_groups = ldap_config["required_groups"]
@required_groups = ldap_config["required_groups"]
@required_attributes = ldap_config["require_attribute"]
@ldap.auth ldap_config["admin_user"], ldap_config["admin_password"] if params[:admin]

@ldap.auth ldap_config["admin_user"], ldap_config["admin_password"]

@login = params[:login]
@password = params[:password]
@new_password = params[:new_password]
@authentication_type = ldap_config["authentication_type"]
end

def dn
Expand All @@ -86,26 +87,36 @@ def authenticate!
end

def authenticated?
authenticate!
if @authentication_type && @authentication_type != ""
send("#{@authentication_type}")
else
authenticate!
end
end

def authorized?
DeviseLdapAuthenticatable::Logger.send("Authorizing user #{dn}")
authenticated? && in_required_groups? && has_required_attribute?
end


def authenticate_bind_as!
@ldap.bind_as(:base => @ldap.base,
:filter => "(sAMAccountName=#{@login})",
:password => @password)
end

def change_password!
update_ldap(:userpassword => Net::LDAP::Password.generate(:sha, @new_password))
end

def in_required_groups?
def in_required_groups?
return true unless ::Devise.ldap_check_group_membership

## FIXME set errors here, the ldap.yml isn't set properly.
return false if @required_groups.nil?
return false if @required_groups.nil?

admin_ldap = LdapConnect.admin

for group in @required_groups
if group.is_a?(Array)
group_attribute, group_name = group
Expand All @@ -120,53 +131,53 @@ def in_required_groups?
end
end
end

return true
end

def has_required_attribute?
return true unless ::Devise.ldap_check_attributes

admin_ldap = LdapConnect.admin

user = find_ldap_user(admin_ldap)

@required_attributes.each do |key,val|
unless user[key].include? val
DeviseLdapAuthenticatable::Logger.send("User #{dn} did not match attribute #{key}:#{val}")
return false
return false
end
end

return true
end

def user_groups
admin_ldap = LdapConnect.admin

DeviseLdapAuthenticatable::Logger.send("Getting groups for #{dn}")
filter = Net::LDAP::Filter.eq("uniqueMember", dn)
admin_ldap.search(:filter => filter, :base => @group_base).collect(&:dn)
end

private

def self.admin
ldap = LdapConnect.new(:admin => true).ldap

unless ldap.bind
DeviseLdapAuthenticatable::Logger.send("Cannot bind to admin LDAP user")
raise DeviseLdapAuthenticatable::LdapException, "Cannot connect to admin LDAP user"
end

return ldap
end

def find_ldap_user(ldap)
DeviseLdapAuthenticatable::Logger.send("Finding user: #{dn}")
ldap.search(:base => dn, :scope => Net::LDAP::SearchScope_BaseObject).try(:first)
end

def update_ldap(ops)
operations = []
if ops.is_a? Hash
Expand All @@ -178,7 +189,7 @@ def update_ldap(ops)
end

admin_ldap = LdapConnect.admin

DeviseLdapAuthenticatable::Logger.send("Modifying user #{dn}")
admin_ldap.modify(:dn => dn, :operations => operations)
end
Expand All @@ -188,3 +199,4 @@ def update_ldap(ops)
end

end

Expand Up @@ -25,6 +25,7 @@ development:
port: 389
attribute: cn
base: ou=people,dc=test,dc=com
#authentication_type: authenticate_bind_as!
admin_user: cn=admin,dc=test,dc=com
admin_password: admin_password
ssl: false
Expand All @@ -35,6 +36,7 @@ test:
port: 3389
attribute: cn
base: ou=people,dc=test,dc=com
#authentication_type: authenticate_bind_as!
admin_user: cn=admin,dc=test,dc=com
admin_password: admin_password
ssl: false
Expand All @@ -45,7 +47,9 @@ production:
port: 636
attribute: cn
base: ou=people,dc=test,dc=com
#authentication_type: authenticate_bind_as!
admin_user: cn=admin,dc=test,dc=com
admin_password: admin_password
ssl: true
# <<: *AUTHORIZATIONS
# <<: *AUTHORIZATIONS