Skip to content
Snippets Groups Projects
Commit 7aa13868 authored by Ping Yu's avatar Ping Yu
Browse files

Merge branch 'master' of github.com:webagecorp/omniauth-ldap into webagecorp-master

Conflicts:
	README.md
	spec/omniauth/strategies/ldap_spec.rb
parents efa1abc9 7f66cffb
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -13,6 +13,10 @@ Use the LDAP strategy as a middleware in your application:
:uid => 'sAMAccountName',
:name_proc => Proc.new {|name| name.gsub(/@.*$/,'')},
:bind_dn => 'default_bind_dn',
# Or, alternatively:
#:filter => '(&(uid=%{username})(memberOf=cn=myapp-users,ou=groups,dc=example,dc=com))'
:name_proc => Proc.new {|name| name.gsub(/@.*$/,'')}
:bind_dn => 'default_bind_dn'
:password => 'password'
 
All of the listed options are required, with the exception of :title, :name_proc, :bind_dn, and :password.
Loading
Loading
@@ -29,6 +33,9 @@ Allowed values of :method are: :plain, :ssl, :tls.
:uid is the LDAP attribute name for the user name in the login form.
typically AD would be 'sAMAccountName' or 'UserPrincipalName', while OpenLDAP is 'uid'.
 
:filter is the LDAP filter used to search the user entry. It can be used in place of :uid for more flexibility.
`%{username}` will be replaced by the user name processed by :name_proc.
:name_proc allows you to match the user name entered with the format of the :uid attributes.
For example, value of 'sAMAccountName' in AD contains only the windows user name. If your user prefers using
email to login, a name_proc as above will trim the email string down to just the windows login name.
Loading
Loading
Loading
Loading
@@ -13,9 +13,10 @@ module OmniAuth
class AuthenticationError < StandardError; end
class ConnectionError < StandardError; end
 
VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :bind_dn, :password, :try_sasl, :sasl_mechanisms, :uid, :base, :allow_anonymous]
VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :bind_dn, :password, :try_sasl, :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter]
 
MUST_HAVE_KEYS = [:host, :port, :method, :uid, :base]
# A list of needed keys. Possible alternatives are specified using sub-lists.
MUST_HAVE_KEYS = [:host, :port, :method, [:uid, :filter], :base]
 
METHOD = {
:ssl => :simple_tls,
Loading
Loading
@@ -24,11 +25,15 @@ module OmniAuth
}
 
attr_accessor :bind_dn, :password
attr_reader :connection, :uid, :base, :auth
attr_reader :connection, :uid, :base, :auth, :filter
def self.validate(configuration={})
message = []
MUST_HAVE_KEYS.each do |name|
message << name if configuration[name].nil?
MUST_HAVE_KEYS.each do |names|
names = [names].flatten
missing_keys = names.select{|name| configuration[name].nil?}
if missing_keys == names
message << names.join(' or ')
end
end
raise ArgumentError.new(message.join(",") +" MUST be provided") unless message.empty?
end
Loading
Loading
Loading
Loading
@@ -39,7 +39,7 @@ module OmniAuth
 
return fail!(:missing_credentials) if missing_credentials?
begin
@ldap_user_info = @adaptor.bind_as(:filter => Net::LDAP::Filter.eq(@adaptor.uid, @options[:name_proc].call(request['username'])),:size => 1, :password => request['password'])
@ldap_user_info = @adaptor.bind_as(:filter => filter(@adaptor), :size => 1, :password => request['password'])
return fail!(:invalid_credentials) if !@ldap_user_info
 
@user_info = self.class.map_user(@@config, @ldap_user_info)
Loading
Loading
@@ -49,6 +49,14 @@ module OmniAuth
end
end
 
def filter adaptor
if adaptor.filter and !adaptor.filter.empty?
Net::LDAP::Filter.construct(adaptor.filter % {username: @options[:name_proc].call(request['username'])})
else
Net::LDAP::Filter.eq(adaptor.uid, @options[:name_proc].call(request['username']))
end
end
uid {
@user_info["uid"]
}
Loading
Loading
Loading
Loading
@@ -50,6 +50,7 @@ describe "OmniAuth::Strategies::LDAP" do
describe 'post /auth/ldap/callback' do
before(:each) do
@adaptor = double(OmniAuth::LDAP::Adaptor, {:uid => 'ping'})
@adaptor.stub(:filter)
OmniAuth::LDAP::Adaptor.stub(:new).and_return(@adaptor)
end
 
Loading
Loading
@@ -104,6 +105,17 @@ describe "OmniAuth::Strategies::LDAP" do
last_response.should be_redirect
last_response.headers['Location'].should =~ %r{invalid_credentials}
end
context 'and filter is set' do
it 'should bind with filter' do
@adaptor.stub(:filter).and_return('uid=%{username}')
Net::LDAP::Filter.should_receive(:construct).with('uid=ping')
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
last_response.should be_redirect
last_response.headers['Location'].should =~ %r{invalid_credentials}
end
end
end
 
context "and communication with LDAP server caused an exception" do
Loading
Loading
@@ -125,6 +137,7 @@ describe "OmniAuth::Strategies::LDAP" do
let(:auth_hash){ last_request.env['omniauth.auth'] }
 
before(:each) do
@adaptor.stub(:filter)
@adaptor.stub(:bind_as).and_return(Net::LDAP::Entry.from_single_ldif_string(
%Q{dn: cn=ping, dc=intridea, dc=com
mail: ping@intridea.com
Loading
Loading
@@ -144,14 +157,25 @@ jpegphoto: http://www.intridea.com/ping.jpg
description: omniauth-ldap
}
))
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
end
 
it 'should not redirect to error page' do
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
last_response.should_not be_redirect
end
 
context 'and filter is set' do
it 'should bind with filter' do
@adaptor.stub(:filter).and_return('uid=%{username}')
Net::LDAP::Filter.should_receive(:construct).with('uid=ping')
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
last_response.should_not be_redirect
end
end
it 'should map user info to Auth Hash' do
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
auth_hash.uid.should == 'cn=ping, dc=intridea, dc=com'
auth_hash.info.email.should == 'ping@intridea.com'
auth_hash.info.first_name.should == 'Ping'
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment