gitlab_omniauth-ldap 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/Gemfile.lock +1 -1
- data/README.md +7 -0
- data/gitlab_omniauth-ldap.gemspec +1 -0
- data/lib/omniauth-ldap/adaptor.rb +10 -11
- data/lib/omniauth-ldap/version.rb +1 -1
- data/lib/omniauth/strategies/ldap.rb +19 -10
- data/spec/omniauth-ldap/adaptor_spec.rb +22 -17
- data/spec/omniauth/strategies/ldap_spec.rb +158 -13
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b48ec03b34b4a57a425012c7f7c9ba8e03c28e7
|
4
|
+
data.tar.gz: 67489322e17adf7275e62ca90dfebabbe3e25e39
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9590a17c3b9dd2f20a0a6b9385956c494e25a7e84394ae433eb1c6a242c8cd2fc433abadc200ce4f7569df270ef07997051fa88e456f2babe2bb9bc7f73c156c
|
7
|
+
data.tar.gz: d09c215229636599c244d0b78f94e5b5a8291437331b02043ae40773d6693f65ba4f8cf2cd70a119b968713320c8998771c80ceaf7be2f045d21e004c2387157
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -11,6 +11,10 @@ Use the LDAP strategy as a middleware in your application:
|
|
11
11
|
:method => :plain,
|
12
12
|
:base => 'dc=intridea, dc=com',
|
13
13
|
:uid => 'sAMAccountName',
|
14
|
+
:name_proc => Proc.new {|name| name.gsub(/@.*$/,'')},
|
15
|
+
:bind_dn => 'default_bind_dn',
|
16
|
+
# Or, alternatively:
|
17
|
+
#:filter => '(&(uid=%{username})(memberOf=cn=myapp-users,ou=groups,dc=example,dc=com))'
|
14
18
|
:name_proc => Proc.new {|name| name.gsub(/@.*$/,'')}
|
15
19
|
:bind_dn => 'default_bind_dn'
|
16
20
|
:password => 'password'
|
@@ -29,6 +33,9 @@ Allowed values of :method are: :plain, :ssl, :tls.
|
|
29
33
|
:uid is the LDAP attribute name for the user name in the login form.
|
30
34
|
typically AD would be 'sAMAccountName' or 'UserPrincipalName', while OpenLDAP is 'uid'.
|
31
35
|
|
36
|
+
:filter is the LDAP filter used to search the user entry. It can be used in place of :uid for more flexibility.
|
37
|
+
`%{username}` will be replaced by the user name processed by :name_proc.
|
38
|
+
|
32
39
|
:name_proc allows you to match the user name entered with the format of the :uid attributes.
|
33
40
|
For example, value of 'sAMAccountName' in AD contains only the windows user name. If your user prefers using
|
34
41
|
email to login, a name_proc as above will trim the email string down to just the windows login name.
|
@@ -7,6 +7,7 @@ Gem::Specification.new do |gem|
|
|
7
7
|
gem.description = %q{A LDAP strategy for OmniAuth.}
|
8
8
|
gem.summary = %q{A LDAP strategy for OmniAuth.}
|
9
9
|
gem.homepage = "https://github.com/gitlabhq/omniauth-ldap"
|
10
|
+
gem.license = "MIT"
|
10
11
|
|
11
12
|
gem.add_runtime_dependency 'omniauth', '~> 1.0'
|
12
13
|
gem.add_runtime_dependency 'net-ldap', '~> 0.3.1'
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'rack'
|
4
4
|
require 'net/ldap'
|
5
5
|
require 'net/ntlm'
|
6
|
-
require 'uri'
|
7
6
|
require 'sasl'
|
8
7
|
require 'kconv'
|
9
8
|
module OmniAuth
|
@@ -14,9 +13,10 @@ module OmniAuth
|
|
14
13
|
class AuthenticationError < StandardError; end
|
15
14
|
class ConnectionError < StandardError; end
|
16
15
|
|
17
|
-
VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :bind_dn, :password, :try_sasl, :sasl_mechanisms, :uid, :base, :allow_anonymous]
|
16
|
+
VALID_ADAPTER_CONFIGURATION_KEYS = [:host, :port, :method, :bind_dn, :password, :try_sasl, :sasl_mechanisms, :uid, :base, :allow_anonymous, :filter]
|
18
17
|
|
19
|
-
|
18
|
+
# A list of needed keys. Possible alternatives are specified using sub-lists.
|
19
|
+
MUST_HAVE_KEYS = [:host, :port, :method, [:uid, :filter], :base]
|
20
20
|
|
21
21
|
METHOD = {
|
22
22
|
:ssl => :simple_tls,
|
@@ -25,11 +25,15 @@ module OmniAuth
|
|
25
25
|
}
|
26
26
|
|
27
27
|
attr_accessor :bind_dn, :password
|
28
|
-
attr_reader :connection, :uid, :base, :auth
|
28
|
+
attr_reader :connection, :uid, :base, :auth, :filter
|
29
29
|
def self.validate(configuration={})
|
30
30
|
message = []
|
31
|
-
MUST_HAVE_KEYS.each do |
|
32
|
-
|
31
|
+
MUST_HAVE_KEYS.each do |names|
|
32
|
+
names = [names].flatten
|
33
|
+
missing_keys = names.select{|name| configuration[name].nil?}
|
34
|
+
if missing_keys == names
|
35
|
+
message << names.join(' or ')
|
36
|
+
end
|
33
37
|
end
|
34
38
|
raise ArgumentError.new(message.join(",") +" MUST be provided") unless message.empty?
|
35
39
|
end
|
@@ -48,7 +52,6 @@ module OmniAuth
|
|
48
52
|
:encryption => method,
|
49
53
|
:base => @base
|
50
54
|
}
|
51
|
-
@uri = construct_uri(@host, @port, @method != :plain)
|
52
55
|
|
53
56
|
@bind_method = @try_sasl ? :sasl : (@allow_anonymous||!@bind_dn||!@password ? :anonymous : :simple)
|
54
57
|
|
@@ -140,10 +143,6 @@ module OmniAuth
|
|
140
143
|
[Net::NTLM::Message::Type1.new.serialize, nego]
|
141
144
|
end
|
142
145
|
|
143
|
-
def construct_uri(host, port, ssl)
|
144
|
-
protocol = ssl ? "ldaps" : "ldap"
|
145
|
-
URI.parse("#{protocol}://#{host}:#{port}").to_s
|
146
|
-
end
|
147
146
|
end
|
148
147
|
end
|
149
148
|
end
|
@@ -3,7 +3,6 @@ require 'omniauth'
|
|
3
3
|
module OmniAuth
|
4
4
|
module Strategies
|
5
5
|
class LDAP
|
6
|
-
class MissingCredentialsError < StandardError; end
|
7
6
|
include OmniAuth::Strategy
|
8
7
|
@@config = {
|
9
8
|
'name' => 'cn',
|
@@ -38,14 +37,10 @@ module OmniAuth
|
|
38
37
|
def callback_phase
|
39
38
|
@adaptor = OmniAuth::LDAP::Adaptor.new @options
|
40
39
|
|
40
|
+
return fail!(:missing_credentials) if missing_credentials?
|
41
41
|
begin
|
42
|
-
|
43
|
-
# Dont allow blank password for ldap auth
|
44
|
-
if request['username'].nil? || request['username'].empty? || request['password'].nil? || request['password'].empty?
|
45
|
-
raise MissingCredentialsError.new("Missing login credentials")
|
46
|
-
end
|
42
|
+
@ldap_user_info = @adaptor.bind_as(:filter => filter(@adaptor), :size => 1, :password => request['password'])
|
47
43
|
|
48
|
-
@ldap_user_info = @adaptor.bind_as(:filter => Net::LDAP::Filter.eq(@adaptor.uid, @options[:name_proc].call(request['username'])),:size => 1, :password => request['password'])
|
49
44
|
return fail!(:invalid_credentials) if !@ldap_user_info
|
50
45
|
|
51
46
|
@user_info = self.class.map_user(@@config, @ldap_user_info)
|
@@ -55,6 +50,14 @@ module OmniAuth
|
|
55
50
|
end
|
56
51
|
end
|
57
52
|
|
53
|
+
def filter adaptor
|
54
|
+
if adaptor.filter and !adaptor.filter.empty?
|
55
|
+
Net::LDAP::Filter.construct(adaptor.filter % {username: @options[:name_proc].call(request['username'])})
|
56
|
+
else
|
57
|
+
Net::LDAP::Filter.eq(adaptor.uid, @options[:name_proc].call(request['username']))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
58
61
|
uid {
|
59
62
|
@user_info["uid"]
|
60
63
|
}
|
@@ -70,14 +73,14 @@ module OmniAuth
|
|
70
73
|
mapper.each do |key, value|
|
71
74
|
case value
|
72
75
|
when String
|
73
|
-
user[key] = object[value.downcase.to_sym].first if object
|
76
|
+
user[key] = object[value.downcase.to_sym].first if object.respond_to? value.downcase.to_sym
|
74
77
|
when Array
|
75
|
-
value.each {|v| (user[key] = object[v.downcase.to_sym].first; break;) if object
|
78
|
+
value.each {|v| (user[key] = object[v.downcase.to_sym].first; break;) if object.respond_to? v.downcase.to_sym}
|
76
79
|
when Hash
|
77
80
|
value.map do |key1, value1|
|
78
81
|
pattern = key1.dup
|
79
82
|
value1.each_with_index do |v,i|
|
80
|
-
part = ''; v.collect(&:downcase).collect(&:to_sym).each {|v1| (part = object[v1].first; break;) if object
|
83
|
+
part = ''; v.collect(&:downcase).collect(&:to_sym).each {|v1| (part = object[v1].first; break;) if object.respond_to? v1}
|
81
84
|
pattern.gsub!("%#{i}",part||'')
|
82
85
|
end
|
83
86
|
user[key] = pattern
|
@@ -86,6 +89,12 @@ module OmniAuth
|
|
86
89
|
end
|
87
90
|
user
|
88
91
|
end
|
92
|
+
|
93
|
+
protected
|
94
|
+
|
95
|
+
def missing_credentials?
|
96
|
+
request['username'].nil? or request['username'].empty? or request['password'].nil? or request['password'].empty?
|
97
|
+
end # missing_credentials?
|
89
98
|
end
|
90
99
|
end
|
91
100
|
end
|
@@ -2,13 +2,13 @@ require 'spec_helper'
|
|
2
2
|
describe "OmniAuth::LDAP::Adaptor" do
|
3
3
|
|
4
4
|
describe 'initialize' do
|
5
|
-
|
6
5
|
it 'should throw exception when must have field is not set' do
|
7
6
|
#[:host, :port, :method, :bind_dn]
|
8
|
-
lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain'})}.should raise_error(ArgumentError)
|
7
|
+
lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain'})}.should raise_error(ArgumentError)
|
9
8
|
end
|
9
|
+
|
10
10
|
it 'should throw exception when method is not supported' do
|
11
|
-
lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'myplain', uid: 'uid', port: 389, base: 'dc=com'})}.should raise_error(OmniAuth::LDAP::Adaptor::ConfigurationError)
|
11
|
+
lambda { OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'myplain', uid: 'uid', port: 389, base: 'dc=com'})}.should raise_error(OmniAuth::LDAP::Adaptor::ConfigurationError)
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'should setup ldap connection with anonymous' do
|
@@ -17,54 +17,59 @@ describe "OmniAuth::LDAP::Adaptor" do
|
|
17
17
|
adaptor.connection.host.should == '192.168.1.145'
|
18
18
|
adaptor.connection.port.should == 389
|
19
19
|
adaptor.connection.base.should == 'dc=intridea, dc=com'
|
20
|
-
adaptor.connection.instance_variable_get('@auth').should == {:method => :anonymous, :username => nil, :password => nil}
|
20
|
+
adaptor.connection.instance_variable_get('@auth').should == {:method => :anonymous, :username => nil, :password => nil}
|
21
21
|
end
|
22
|
+
|
22
23
|
it 'should setup ldap connection with simple' do
|
23
24
|
adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password'})
|
24
25
|
adaptor.connection.should_not == nil
|
25
26
|
adaptor.connection.host.should == '192.168.1.145'
|
26
27
|
adaptor.connection.port.should == 389
|
27
28
|
adaptor.connection.base.should == 'dc=intridea, dc=com'
|
28
|
-
adaptor.connection.instance_variable_get('@auth').should == {:method => :simple, :username => 'bind_dn', :password => 'password'}
|
29
|
-
end
|
29
|
+
adaptor.connection.instance_variable_get('@auth').should == {:method => :simple, :username => 'bind_dn', :password => 'password'}
|
30
|
+
end
|
31
|
+
|
30
32
|
it 'should setup ldap connection with sasl-md5' do
|
31
33
|
adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', try_sasl: true, sasl_mechanisms: ["DIGEST-MD5"], bind_dn: 'bind_dn', password: 'password'})
|
32
34
|
adaptor.connection.should_not == nil
|
33
35
|
adaptor.connection.host.should == '192.168.1.145'
|
34
36
|
adaptor.connection.port.should == 389
|
35
37
|
adaptor.connection.base.should == 'dc=intridea, dc=com'
|
36
|
-
adaptor.connection.instance_variable_get('@auth')[:method].should == :sasl
|
37
|
-
adaptor.connection.instance_variable_get('@auth')[:mechanism].should == 'DIGEST-MD5'
|
38
|
-
adaptor.connection.instance_variable_get('@auth')[:initial_credential].should == ''
|
39
|
-
adaptor.connection.instance_variable_get('@auth')[:challenge_response].should_not be_nil
|
38
|
+
adaptor.connection.instance_variable_get('@auth')[:method].should == :sasl
|
39
|
+
adaptor.connection.instance_variable_get('@auth')[:mechanism].should == 'DIGEST-MD5'
|
40
|
+
adaptor.connection.instance_variable_get('@auth')[:initial_credential].should == ''
|
41
|
+
adaptor.connection.instance_variable_get('@auth')[:challenge_response].should_not be_nil
|
40
42
|
end
|
43
|
+
|
41
44
|
it 'should setup ldap connection with sasl-gss' do
|
42
45
|
adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: 'bind_dn', password: 'password'})
|
43
46
|
adaptor.connection.should_not == nil
|
44
47
|
adaptor.connection.host.should == '192.168.1.145'
|
45
48
|
adaptor.connection.port.should == 389
|
46
49
|
adaptor.connection.base.should == 'dc=intridea, dc=com'
|
47
|
-
adaptor.connection.instance_variable_get('@auth')[:method].should == :sasl
|
48
|
-
adaptor.connection.instance_variable_get('@auth')[:mechanism].should == 'GSS-SPNEGO'
|
49
|
-
adaptor.connection.instance_variable_get('@auth')[:initial_credential].should =~ /^NTLMSSP/
|
50
|
-
adaptor.connection.instance_variable_get('@auth')[:challenge_response].should_not be_nil
|
50
|
+
adaptor.connection.instance_variable_get('@auth')[:method].should == :sasl
|
51
|
+
adaptor.connection.instance_variable_get('@auth')[:mechanism].should == 'GSS-SPNEGO'
|
52
|
+
adaptor.connection.instance_variable_get('@auth')[:initial_credential].should =~ /^NTLMSSP/
|
53
|
+
adaptor.connection.instance_variable_get('@auth')[:challenge_response].should_not be_nil
|
51
54
|
end
|
52
55
|
end
|
53
|
-
|
56
|
+
|
54
57
|
describe 'bind_as' do
|
55
58
|
let(:args) { {:filter => Net::LDAP::Filter.eq('sAMAccountName', 'username'), :password => 'password', :size => 1} }
|
56
59
|
let(:rs) { Struct.new(:dn).new('new dn') }
|
60
|
+
|
57
61
|
it 'should bind simple' do
|
58
62
|
adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.126", method: 'plain', base: 'dc=score, dc=local', port: 389, uid: 'sAMAccountName', bind_dn: 'bind_dn', password: 'password'})
|
59
63
|
adaptor.connection.should_receive(:open).and_yield(adaptor.connection)
|
60
|
-
adaptor.connection.should_receive(:search).with(args).and_return([rs])
|
64
|
+
adaptor.connection.should_receive(:search).with(args).and_return([rs])
|
61
65
|
adaptor.connection.should_receive(:bind).with({:username => 'new dn', :password => args[:password], :method => :simple}).and_return(true)
|
62
66
|
adaptor.bind_as(args).should == rs
|
63
67
|
end
|
68
|
+
|
64
69
|
it 'should bind sasl' do
|
65
70
|
adaptor = OmniAuth::LDAP::Adaptor.new({host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName', try_sasl: true, sasl_mechanisms: ["GSS-SPNEGO"], bind_dn: 'bind_dn', password: 'password'})
|
66
71
|
adaptor.connection.should_receive(:open).and_yield(adaptor.connection)
|
67
|
-
adaptor.connection.should_receive(:search).with(args).and_return([rs])
|
72
|
+
adaptor.connection.should_receive(:search).with(args).and_return([rs])
|
68
73
|
adaptor.connection.should_receive(:bind).and_return(true)
|
69
74
|
adaptor.bind_as(args).should == rs
|
70
75
|
end
|
@@ -12,7 +12,7 @@ describe "OmniAuth::Strategies::LDAP" do
|
|
12
12
|
# :password => 'password'
|
13
13
|
class MyLdapProvider < OmniAuth::Strategies::LDAP; end
|
14
14
|
|
15
|
-
|
15
|
+
let(:app) do
|
16
16
|
Rack::Builder.new {
|
17
17
|
use OmniAuth::Test::PhonySession
|
18
18
|
use MyLdapProvider, :name => 'ldap', :title => 'MyLdap Form', :host => '192.168.1.145', :base => 'dc=score, dc=local', :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')}
|
@@ -20,7 +20,7 @@ describe "OmniAuth::Strategies::LDAP" do
|
|
20
20
|
}.to_app
|
21
21
|
end
|
22
22
|
|
23
|
-
|
23
|
+
let(:session) do
|
24
24
|
last_request.env['rack.session']
|
25
25
|
end
|
26
26
|
|
@@ -46,12 +46,12 @@ describe "OmniAuth::Strategies::LDAP" do
|
|
46
46
|
it 'should have a label of the form title' do
|
47
47
|
last_response.body.scan('MyLdap Form').size.should > 1
|
48
48
|
end
|
49
|
-
|
50
49
|
end
|
51
50
|
|
52
51
|
describe 'post /auth/ldap/callback' do
|
53
52
|
before(:each) do
|
54
|
-
@adaptor =
|
53
|
+
@adaptor = double(OmniAuth::LDAP::Adaptor, {:uid => 'ping'})
|
54
|
+
@adaptor.stub(:filter)
|
55
55
|
OmniAuth::LDAP::Adaptor.stub(:new).and_return(@adaptor)
|
56
56
|
end
|
57
57
|
|
@@ -60,10 +60,10 @@ describe "OmniAuth::Strategies::LDAP" do
|
|
60
60
|
@adaptor.stub(:bind_as).and_return(false)
|
61
61
|
end
|
62
62
|
|
63
|
-
it 'should
|
63
|
+
it 'should fail with missing_credentials' do
|
64
64
|
post('/auth/ldap/callback', {})
|
65
65
|
last_response.should be_redirect
|
66
|
-
last_response.headers['Location'].should =~ %r{
|
66
|
+
last_response.headers['Location'].should =~ %r{missing_credentials}
|
67
67
|
end
|
68
68
|
|
69
69
|
it 'should redirect to error page' do
|
@@ -78,22 +78,167 @@ describe "OmniAuth::Strategies::LDAP" do
|
|
78
78
|
last_response.should be_redirect
|
79
79
|
last_response.headers['Location'].should =~ %r{ldap_error}
|
80
80
|
end
|
81
|
+
|
82
|
+
context "when username is not preset" do
|
83
|
+
it 'should redirect to error page' do
|
84
|
+
post('/auth/ldap/callback', {})
|
85
|
+
|
86
|
+
last_response.should be_redirect
|
87
|
+
last_response.headers['Location'].should =~ %r{missing_credentials}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when username is empty" do
|
92
|
+
it 'should redirect to error page' do
|
93
|
+
post('/auth/ldap/callback', {:username => ""})
|
94
|
+
|
95
|
+
last_response.should be_redirect
|
96
|
+
last_response.headers['Location'].should =~ %r{missing_credentials}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when username is present" do
|
101
|
+
context "and password is not preset" do
|
102
|
+
it 'should redirect to error page' do
|
103
|
+
post('/auth/ldap/callback', {:username => "ping"})
|
104
|
+
|
105
|
+
last_response.should be_redirect
|
106
|
+
last_response.headers['Location'].should =~ %r{missing_credentials}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "and password is empty" do
|
111
|
+
it 'should redirect to error page' do
|
112
|
+
post('/auth/ldap/callback', {:username => "ping", :password => ""})
|
113
|
+
|
114
|
+
last_response.should be_redirect
|
115
|
+
last_response.headers['Location'].should =~ %r{missing_credentials}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "when username and password are present" do
|
121
|
+
context "and bind on LDAP server failed" do
|
122
|
+
it 'should redirect to error page' do
|
123
|
+
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
|
124
|
+
|
125
|
+
last_response.should be_redirect
|
126
|
+
last_response.headers['Location'].should =~ %r{invalid_credentials}
|
127
|
+
end
|
128
|
+
context 'and filter is set' do
|
129
|
+
it 'should bind with filter' do
|
130
|
+
@adaptor.stub(:filter).and_return('uid=%{username}')
|
131
|
+
Net::LDAP::Filter.should_receive(:construct).with('uid=ping')
|
132
|
+
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
|
133
|
+
|
134
|
+
last_response.should be_redirect
|
135
|
+
last_response.headers['Location'].should =~ %r{invalid_credentials}
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
context "and communication with LDAP server caused an exception" do
|
142
|
+
before :each do
|
143
|
+
@adaptor.stub(:bind_as).and_throw(Exception.new('connection_error'))
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should redirect to error page' do
|
147
|
+
post('/auth/ldap/callback', {:username => "ping", :password => "password"})
|
148
|
+
|
149
|
+
last_response.should be_redirect
|
150
|
+
last_response.headers['Location'].should =~ %r{ldap_error}
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
81
154
|
end
|
82
155
|
|
83
156
|
context 'success' do
|
84
157
|
let(:auth_hash){ last_request.env['omniauth.auth'] }
|
158
|
+
|
85
159
|
before(:each) do
|
86
|
-
@adaptor.stub(:
|
87
|
-
|
88
|
-
|
89
|
-
|
160
|
+
@adaptor.stub(:filter)
|
161
|
+
@adaptor.stub(:bind_as).and_return(Net::LDAP::Entry.from_single_ldif_string(
|
162
|
+
%Q{dn: cn=ping, dc=intridea, dc=com
|
163
|
+
mail: ping@intridea.com
|
164
|
+
givenname: Ping
|
165
|
+
sn: Yu
|
166
|
+
telephonenumber: 555-555-5555
|
167
|
+
mobile: 444-444-4444
|
168
|
+
uid: ping
|
169
|
+
title: dev
|
170
|
+
address: k street
|
171
|
+
l: Washington
|
172
|
+
st: DC
|
173
|
+
co: U.S.A
|
174
|
+
postofficebox: 20001
|
175
|
+
wwwhomepage: www.intridea.com
|
176
|
+
jpegphoto: http://www.intridea.com/ping.jpg
|
177
|
+
description: omniauth-ldap
|
178
|
+
}
|
179
|
+
))
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should not redirect to error page' do
|
90
183
|
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
|
184
|
+
last_response.should_not be_redirect
|
91
185
|
end
|
92
186
|
|
93
|
-
|
94
|
-
|
187
|
+
context 'and filter is set' do
|
188
|
+
it 'should bind with filter' do
|
189
|
+
@adaptor.stub(:filter).and_return('uid=%{username}')
|
190
|
+
Net::LDAP::Filter.should_receive(:construct).with('uid=ping')
|
191
|
+
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
|
192
|
+
|
193
|
+
last_response.should_not be_redirect
|
194
|
+
end
|
95
195
|
end
|
96
|
-
|
196
|
+
|
197
|
+
it 'should map user info to Auth Hash' do
|
198
|
+
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
|
199
|
+
auth_hash.uid.should == 'cn=ping, dc=intridea, dc=com'
|
200
|
+
auth_hash.info.email.should == 'ping@intridea.com'
|
201
|
+
auth_hash.info.first_name.should == 'Ping'
|
202
|
+
auth_hash.info.last_name.should == 'Yu'
|
203
|
+
auth_hash.info.phone.should == '555-555-5555'
|
204
|
+
auth_hash.info.mobile.should == '444-444-4444'
|
205
|
+
auth_hash.info.nickname.should == 'ping'
|
206
|
+
auth_hash.info.title.should == 'dev'
|
207
|
+
auth_hash.info.location.should == 'k street, Washington, DC, U.S.A 20001'
|
208
|
+
auth_hash.info.url.should == 'www.intridea.com'
|
209
|
+
auth_hash.info.image.should == 'http://www.intridea.com/ping.jpg'
|
210
|
+
auth_hash.info.description.should == 'omniauth-ldap'
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'alternate fields' do
|
215
|
+
let(:auth_hash){ last_request.env['omniauth.auth'] }
|
216
|
+
|
217
|
+
before(:each) do
|
218
|
+
@adaptor.stub(:filter)
|
219
|
+
@adaptor.stub(:bind_as).and_return(Net::LDAP::Entry.from_single_ldif_string(
|
220
|
+
%Q{dn: cn=ping, dc=intridea, dc=com
|
221
|
+
userprincipalname: ping@intridea.com
|
222
|
+
givenname: Ping
|
223
|
+
sn: Yu
|
224
|
+
telephonenumber: 555-555-5555
|
225
|
+
mobile: 444-444-4444
|
226
|
+
uid: ping
|
227
|
+
title: dev
|
228
|
+
address: k street
|
229
|
+
l: Washington
|
230
|
+
st: DC
|
231
|
+
co: U.S.A
|
232
|
+
postofficebox: 20001
|
233
|
+
wwwhomepage: www.intridea.com
|
234
|
+
jpegphoto: http://www.intridea.com/ping.jpg
|
235
|
+
description: omniauth-ldap
|
236
|
+
}
|
237
|
+
))
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'should map user info to Auth Hash' do
|
241
|
+
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
|
97
242
|
auth_hash.uid.should == 'cn=ping, dc=intridea, dc=com'
|
98
243
|
auth_hash.info.email.should == 'ping@intridea.com'
|
99
244
|
auth_hash.info.first_name.should == 'Ping'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitlab_omniauth-ldap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ping Yu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: omniauth
|
@@ -90,7 +90,8 @@ files:
|
|
90
90
|
- spec/omniauth/strategies/ldap_spec.rb
|
91
91
|
- spec/spec_helper.rb
|
92
92
|
homepage: https://github.com/gitlabhq/omniauth-ldap
|
93
|
-
licenses:
|
93
|
+
licenses:
|
94
|
+
- MIT
|
94
95
|
metadata: {}
|
95
96
|
post_install_message:
|
96
97
|
rdoc_options: []
|
@@ -108,8 +109,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
109
|
version: '0'
|
109
110
|
requirements: []
|
110
111
|
rubyforge_project:
|
111
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.1.11
|
112
113
|
signing_key:
|
113
114
|
specification_version: 4
|
114
115
|
summary: A LDAP strategy for OmniAuth.
|
115
|
-
test_files:
|
116
|
+
test_files:
|
117
|
+
- spec/omniauth-ldap/adaptor_spec.rb
|
118
|
+
- spec/omniauth/strategies/ldap_spec.rb
|
119
|
+
- spec/spec_helper.rb
|