omniauth-ldap 2.0.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +202 -0
- data/CITATION.cff +20 -0
- data/CODE_OF_CONDUCT.md +134 -0
- data/CONTRIBUTING.md +213 -0
- data/FUNDING.md +66 -0
- data/LICENSE.txt +23 -0
- data/README.md +813 -67
- data/REEK +0 -0
- data/RUBOCOP.md +71 -0
- data/SECURITY.md +21 -0
- data/lib/omniauth/strategies/ldap.rb +159 -53
- data/lib/omniauth-ldap/adaptor.rb +162 -54
- data/lib/omniauth-ldap/version.rb +4 -1
- data/lib/omniauth-ldap.rb +6 -1
- data/sig/omniauth/ldap/adaptor.rbs +54 -0
- data/sig/omniauth/ldap/version.rbs +11 -0
- data/sig/omniauth/strategies/ldap.rbs +32 -0
- data/sig/omniauth-ldap.rbs +5 -0
- data/sig/rbs/net-ldap.rbs +19 -0
- data/sig/rbs/net-ntlm.rbs +16 -0
- data/sig/rbs/sasl.rbs +12 -0
- data.tar.gz.sig +0 -0
- metadata +332 -47
- metadata.gz.sig +0 -0
- data/.gitignore +0 -3
- data/.rspec +0 -1
- data/Gemfile +0 -11
- data/Guardfile +0 -11
- data/Rakefile +0 -9
- data/omniauth-ldap.gemspec +0 -26
- data/spec/omniauth/strategies/ldap_spec.rb +0 -200
- data/spec/omniauth-ldap/adaptor_spec.rb +0 -86
- data/spec/spec_helper.rb +0 -14
data/Rakefile
DELETED
data/omniauth-ldap.gemspec
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
|
-
require File.expand_path('../lib/omniauth-ldap/version', __FILE__)
|
|
3
|
-
|
|
4
|
-
Gem::Specification.new do |gem|
|
|
5
|
-
gem.authors = ["Ping Yu", "Tom Milewski"]
|
|
6
|
-
gem.email = ["ping@intridea.com", "tmilewski@gmail.com"]
|
|
7
|
-
gem.description = %q{A LDAP strategy for OmniAuth.}
|
|
8
|
-
gem.summary = %q{A LDAP strategy for OmniAuth.}
|
|
9
|
-
gem.homepage = "https://github.com/intridea/omniauth-ldap"
|
|
10
|
-
gem.license = "MIT"
|
|
11
|
-
|
|
12
|
-
gem.add_runtime_dependency 'omniauth', '~> 1.8.1'
|
|
13
|
-
gem.add_runtime_dependency 'net-ldap', '~> 0.16'
|
|
14
|
-
gem.add_runtime_dependency 'pyu-ruby-sasl', '~> 0.0.3.3'
|
|
15
|
-
gem.add_runtime_dependency 'rubyntlm', '~> 0.6.2'
|
|
16
|
-
gem.add_development_dependency 'rspec', '~> 3.0'
|
|
17
|
-
gem.add_development_dependency 'simplecov'
|
|
18
|
-
gem.add_development_dependency 'rack-test'
|
|
19
|
-
|
|
20
|
-
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
21
|
-
gem.files = `git ls-files`.split("\n")
|
|
22
|
-
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
23
|
-
gem.name = "omniauth-ldap"
|
|
24
|
-
gem.require_paths = ["lib"]
|
|
25
|
-
gem.version = OmniAuth::LDAP::VERSION
|
|
26
|
-
end
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
describe "OmniAuth::Strategies::LDAP" do
|
|
3
|
-
# :title => "My LDAP",
|
|
4
|
-
# :host => '10.101.10.1',
|
|
5
|
-
# :port => 389,
|
|
6
|
-
# :method => :plain,
|
|
7
|
-
# :base => 'dc=intridea, dc=com',
|
|
8
|
-
# :uid => 'sAMAccountName',
|
|
9
|
-
# :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')}
|
|
10
|
-
# :bind_dn => 'default_bind_dn'
|
|
11
|
-
# :password => 'password'
|
|
12
|
-
class MyLdapProvider < OmniAuth::Strategies::LDAP; end
|
|
13
|
-
|
|
14
|
-
let(:app) do
|
|
15
|
-
Rack::Builder.new {
|
|
16
|
-
use OmniAuth::Test::PhonySession
|
|
17
|
-
use MyLdapProvider, :name => 'ldap', :title => 'MyLdap Form', :host => '192.168.1.145', :base => 'dc=score, dc=local', :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')}
|
|
18
|
-
run lambda { |env| [404, {'Content-Type' => 'text/plain'}, [env.key?('omniauth.auth').to_s]] }
|
|
19
|
-
}.to_app
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
let(:session) do
|
|
23
|
-
last_request.env['rack.session']
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it 'should add a camelization for itself' do
|
|
27
|
-
expect(OmniAuth::Utils.camelize('ldap')).to eq 'LDAP'
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
describe '/auth/ldap' do
|
|
31
|
-
before(:each){ get '/auth/ldap' }
|
|
32
|
-
|
|
33
|
-
it 'should display a form' do
|
|
34
|
-
expect(last_response.status).to eq 200
|
|
35
|
-
expect(last_response.body).to include("<form")
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it 'should have the callback as the action for the form' do
|
|
39
|
-
expect(last_response.body).to include("action='/auth/ldap/callback'")
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it 'should have a text field for each of the fields' do
|
|
43
|
-
expect(last_response.body.scan('<input').size).to eq 2
|
|
44
|
-
end
|
|
45
|
-
it 'should have a label of the form title' do
|
|
46
|
-
expect(last_response.body.scan('MyLdap Form').size).to be > 1
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
describe 'post /auth/ldap/callback' do
|
|
51
|
-
before(:each) do
|
|
52
|
-
@adaptor = double(OmniAuth::LDAP::Adaptor, {:uid => 'ping'})
|
|
53
|
-
|
|
54
|
-
allow(@adaptor).to receive(:filter)
|
|
55
|
-
allow(OmniAuth::LDAP::Adaptor).to receive(:new) { @adaptor }
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
context 'failure' do
|
|
59
|
-
before(:each) do
|
|
60
|
-
allow(@adaptor).to receive(:bind_as) { false }
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
context "when username is not preset" do
|
|
64
|
-
it 'should redirect to error page' do
|
|
65
|
-
post('/auth/ldap/callback', {})
|
|
66
|
-
|
|
67
|
-
# expect(last_response).to be redirect
|
|
68
|
-
expect(last_response).to be_redirect
|
|
69
|
-
expect(last_response.headers['Location']).to match %r{missing_credentials}
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
context "when username is empty" do
|
|
74
|
-
it 'should redirect to error page' do
|
|
75
|
-
post('/auth/ldap/callback', { username: "" })
|
|
76
|
-
|
|
77
|
-
expect(last_response).to be_redirect
|
|
78
|
-
expect(last_response.headers['Location']).to match %r{missing_credentials}
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
context "when username is present" do
|
|
83
|
-
context "and password is not preset" do
|
|
84
|
-
it 'should redirect to error page' do
|
|
85
|
-
post('/auth/ldap/callback', { username: "ping" })
|
|
86
|
-
|
|
87
|
-
expect(last_response).to be_redirect
|
|
88
|
-
expect(last_response.headers['Location']).to match %r{missing_credentials}
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
context "and password is empty" do
|
|
93
|
-
it 'should redirect to error page' do
|
|
94
|
-
post('/auth/ldap/callback', { username: "ping", password: "" })
|
|
95
|
-
|
|
96
|
-
expect(last_response).to be_redirect
|
|
97
|
-
expect(last_response.headers['Location']).to match %r{missing_credentials}
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
context "when username and password are present" do
|
|
103
|
-
context "and bind on LDAP server failed" do
|
|
104
|
-
it 'should redirect to error page' do
|
|
105
|
-
post('/auth/ldap/callback', { username: 'ping', password: 'password' })
|
|
106
|
-
|
|
107
|
-
expect(last_response).to be_redirect
|
|
108
|
-
expect(last_response.headers['Location']).to match %r{invalid_credentials}
|
|
109
|
-
end
|
|
110
|
-
context 'and filter is set' do
|
|
111
|
-
it 'should bind with filter' do
|
|
112
|
-
allow(@adaptor).to receive(:filter) { 'uid=%{username}' }
|
|
113
|
-
expect(Net::LDAP::Filter).to receive(:construct).with('uid=ping')
|
|
114
|
-
post('/auth/ldap/callback', { username: 'ping', password: 'password' })
|
|
115
|
-
|
|
116
|
-
expect(last_response).to be_redirect
|
|
117
|
-
expect(last_response.headers['Location']).to match %r{invalid_credentials}
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
context "and communication with LDAP server caused an exception" do
|
|
124
|
-
before :each do
|
|
125
|
-
allow(@adaptor).to receive(:bind_as).and_throw(Exception.new('connection_error'))
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
it 'should redirect to error page' do
|
|
129
|
-
post('/auth/ldap/callback', { username: "ping", password: "password" })
|
|
130
|
-
|
|
131
|
-
expect(last_response).to be_redirect
|
|
132
|
-
expect(last_response.headers['Location']).to match %r{ldap_error}
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
context 'success' do
|
|
139
|
-
let(:auth_hash){ last_request.env['omniauth.auth'] }
|
|
140
|
-
|
|
141
|
-
before(:each) do
|
|
142
|
-
allow(@adaptor).to receive(:filter)
|
|
143
|
-
allow(@adaptor).to receive(:bind_as) { Net::LDAP::Entry.from_single_ldif_string(
|
|
144
|
-
%Q{dn: cn=ping, dc=intridea, dc=com
|
|
145
|
-
mail: ping@intridea.com
|
|
146
|
-
givenname: Ping
|
|
147
|
-
sn: Yu
|
|
148
|
-
telephonenumber: 555-555-5555
|
|
149
|
-
mobile: 444-444-4444
|
|
150
|
-
uid: ping
|
|
151
|
-
title: dev
|
|
152
|
-
address: k street
|
|
153
|
-
l: Washington
|
|
154
|
-
st: DC
|
|
155
|
-
co: U.S.A
|
|
156
|
-
postofficebox: 20001
|
|
157
|
-
wwwhomepage: www.intridea.com
|
|
158
|
-
jpegphoto: http://www.intridea.com/ping.jpg
|
|
159
|
-
description: omniauth-ldap
|
|
160
|
-
}
|
|
161
|
-
)}
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
it 'should not redirect to error page' do
|
|
165
|
-
post('/auth/ldap/callback', {:username => 'ping', :password => 'password'})
|
|
166
|
-
expect(last_response).to_not be_redirect
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
context 'and filter is set' do
|
|
170
|
-
it 'should bind with filter' do
|
|
171
|
-
allow(@adaptor).to receive(:filter) { 'uid=%{username}' }
|
|
172
|
-
expect(Net::LDAP::Filter).to receive(:construct).with('uid=ping')
|
|
173
|
-
post('/auth/ldap/callback', { username: 'ping', password: 'password' })
|
|
174
|
-
|
|
175
|
-
expect(last_response).to_not be_redirect
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
it 'should map user info to Auth Hash' do
|
|
180
|
-
post('/auth/ldap/callback', { username: 'ping', password: 'password' })
|
|
181
|
-
|
|
182
|
-
expect(auth_hash.uid).to eq 'cn=ping, dc=intridea, dc=com'
|
|
183
|
-
|
|
184
|
-
info = auth_hash.info
|
|
185
|
-
|
|
186
|
-
expect(info.email).to eq 'ping@intridea.com'
|
|
187
|
-
expect(info.first_name).to eq 'Ping'
|
|
188
|
-
expect(info.last_name).to eq 'Yu'
|
|
189
|
-
expect(info.phone).to eq '555-555-5555'
|
|
190
|
-
expect(info.mobile).to eq '444-444-4444'
|
|
191
|
-
expect(info.nickname).to eq 'ping'
|
|
192
|
-
expect(info.title).to eq 'dev'
|
|
193
|
-
expect(info.location).to eq 'k street, Washington, DC, U.S.A 20001'
|
|
194
|
-
expect(info.url).to eq 'www.intridea.com'
|
|
195
|
-
expect(info.image).to eq 'http://www.intridea.com/ping.jpg'
|
|
196
|
-
expect(info.description).to eq 'omniauth-ldap'
|
|
197
|
-
end
|
|
198
|
-
end
|
|
199
|
-
end
|
|
200
|
-
end
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
describe "OmniAuth::LDAP::Adaptor" do
|
|
3
|
-
|
|
4
|
-
describe 'initialize' do
|
|
5
|
-
it 'should throw exception when must have field is not set' do
|
|
6
|
-
#[:host, :port, :method, :bind_dn]
|
|
7
|
-
expect {
|
|
8
|
-
OmniAuth::LDAP::Adaptor.new({ host: "192.168.1.145", method: 'plain' })
|
|
9
|
-
}.to raise_error(ArgumentError)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
it 'should throw exception when method is not supported' do
|
|
13
|
-
expect {
|
|
14
|
-
OmniAuth::LDAP::Adaptor.new({ host: "192.168.1.145", method: 'myplain', uid: 'uid', port: 389, base: 'dc=com' })
|
|
15
|
-
}.to raise_error(OmniAuth::LDAP::Adaptor::ConfigurationError)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it 'should setup ldap connection with anonymous' do
|
|
19
|
-
adaptor = OmniAuth::LDAP::Adaptor.new({ host: "192.168.1.145", method: 'plain', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName' })
|
|
20
|
-
expect(adaptor.connection).to_not be_nil
|
|
21
|
-
expect(adaptor.connection.host).to eq '192.168.1.145'
|
|
22
|
-
expect(adaptor.connection.port).to eq 389
|
|
23
|
-
expect(adaptor.connection.base).to eq 'dc=intridea, dc=com'
|
|
24
|
-
expect(adaptor.connection.instance_variable_get('@auth')).to eq({ method: :anonymous, username: nil, password: nil })
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it 'should setup ldap connection with simple' do
|
|
28
|
-
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' })
|
|
29
|
-
expect(adaptor.connection).to_not be_nil
|
|
30
|
-
expect(adaptor.connection.host).to eq '192.168.1.145'
|
|
31
|
-
expect(adaptor.connection.port).to eq 389
|
|
32
|
-
expect(adaptor.connection.base).to eq 'dc=intridea, dc=com'
|
|
33
|
-
expect(adaptor.connection.instance_variable_get('@auth')).to eq({ method: :simple, username: 'bind_dn', password: 'password' })
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it 'should setup ldap connection with sasl-md5' do
|
|
37
|
-
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' })
|
|
38
|
-
expect(adaptor.connection).to_not be_nil
|
|
39
|
-
expect(adaptor.connection.host).to eq '192.168.1.145'
|
|
40
|
-
expect(adaptor.connection.port).to eq 389
|
|
41
|
-
expect(adaptor.connection.base).to eq 'dc=intridea, dc=com'
|
|
42
|
-
expect(adaptor.connection.instance_variable_get('@auth')[:method]).to eq :sasl
|
|
43
|
-
expect(adaptor.connection.instance_variable_get('@auth')[:mechanism]).to eq 'DIGEST-MD5'
|
|
44
|
-
expect(adaptor.connection.instance_variable_get('@auth')[:initial_credential]).to eq ''
|
|
45
|
-
expect(adaptor.connection.instance_variable_get('@auth')[:challenge_response]).to_not be_nil
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it 'should setup ldap connection with sasl-gss' do
|
|
49
|
-
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'})
|
|
50
|
-
expect(adaptor.connection).to_not be_nil
|
|
51
|
-
expect(adaptor.connection.host).to eq '192.168.1.145'
|
|
52
|
-
expect(adaptor.connection.port).to eq 389
|
|
53
|
-
expect(adaptor.connection.base).to eq 'dc=intridea, dc=com'
|
|
54
|
-
expect(adaptor.connection.instance_variable_get('@auth')[:method]).to eq :sasl
|
|
55
|
-
expect(adaptor.connection.instance_variable_get('@auth')[:mechanism]).to eq 'GSS-SPNEGO'
|
|
56
|
-
expect(adaptor.connection.instance_variable_get('@auth')[:initial_credential]).to match /^NTLMSSP/
|
|
57
|
-
expect(adaptor.connection.instance_variable_get('@auth')[:challenge_response]).to_not be_nil
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it 'should set the encryption method correctly' do
|
|
61
|
-
adaptor = OmniAuth::LDAP::Adaptor.new({ host: "192.168.1.145", method: 'tls', base: 'dc=intridea, dc=com', port: 389, uid: 'sAMAccountName' })
|
|
62
|
-
expect(adaptor.connection.instance_variable_get('@encryption')).to include method: :start_tls
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
describe 'bind_as' do
|
|
67
|
-
let(:args) { { :filter => Net::LDAP::Filter.eq('sAMAccountName', 'username'), :password => 'password', :size => 1 } }
|
|
68
|
-
let(:rs) { Struct.new(:dn).new('new dn') }
|
|
69
|
-
|
|
70
|
-
it 'should bind simple' do
|
|
71
|
-
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' })
|
|
72
|
-
expect(adaptor.connection).to receive(:open).and_yield(adaptor.connection)
|
|
73
|
-
expect(adaptor.connection).to receive(:search).with(args).and_return([rs])
|
|
74
|
-
expect(adaptor.connection).to receive(:bind).with({ :username => 'new dn', :password => args[:password], :method => :simple }).and_return(true)
|
|
75
|
-
expect(adaptor.bind_as(args)).to eq rs
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
it 'should bind sasl' do
|
|
79
|
-
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' })
|
|
80
|
-
expect(adaptor.connection).to receive(:open).and_yield(adaptor.connection)
|
|
81
|
-
expect(adaptor.connection).to receive(:search).with(args).and_return([rs])
|
|
82
|
-
expect(adaptor.connection).to receive(:bind).and_return(true)
|
|
83
|
-
expect(adaptor.bind_as(args)).to eq rs
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
data/spec/spec_helper.rb
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
$:.unshift File.expand_path('..', __FILE__)
|
|
2
|
-
$:.unshift File.expand_path('../../lib', __FILE__)
|
|
3
|
-
require 'simplecov'
|
|
4
|
-
SimpleCov.start
|
|
5
|
-
require 'rspec'
|
|
6
|
-
require 'rack/test'
|
|
7
|
-
require 'omniauth'
|
|
8
|
-
require 'omniauth-ldap'
|
|
9
|
-
|
|
10
|
-
RSpec.configure do |config|
|
|
11
|
-
config.include Rack::Test::Methods
|
|
12
|
-
config.extend OmniAuth::Test::StrategyMacros, :type => :strategy
|
|
13
|
-
end
|
|
14
|
-
|