rims-passwd-ldap 0.0.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 +7 -0
- data/.gitignore +14 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +54 -0
- data/Rakefile +52 -0
- data/docker/Rakefile +382 -0
- data/docker/build/Dockerfile +21 -0
- data/docker/build/auth.yml +1 -0
- data/docker/build/modconf.ldif +16 -0
- data/docker/container.yml +3 -0
- data/docker/users.yml +44 -0
- data/lib/rims/passwd/ldap.rb +223 -0
- data/lib/rims/passwd/ldap/version.rb +10 -0
- data/rims-passwd-ldap.gemspec +36 -0
- data/test/test_passwd_ldap.rb +614 -0
- metadata +132 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
# local OpenLDAP for rims-passwd-ldap
|
2
|
+
|
3
|
+
FROM ubuntu:18.04
|
4
|
+
MAINTAINER TOKI Yoshinori
|
5
|
+
|
6
|
+
RUN apt-get update
|
7
|
+
|
8
|
+
# slapd admin
|
9
|
+
ADD auth.yml auth.yml
|
10
|
+
RUN awk '/^pass:/{print "slapd","slapd/password1","password",$2}' auth.yml | debconf-set-selections
|
11
|
+
RUN awk '/^pass:/{print "slapd","slapd/password2","password",$2}' auth.yml | debconf-set-selections
|
12
|
+
|
13
|
+
# slapd and some useful tools
|
14
|
+
RUN apt-get -y install slapd ldap-utils rsyslog
|
15
|
+
|
16
|
+
# slapd setup
|
17
|
+
ADD modconf.ldif modconf.ldif
|
18
|
+
RUN service slapd start && ldapmodify -Y EXTERNAL -H ldapi:/// -f modconf.ldif && service slapd stop
|
19
|
+
|
20
|
+
CMD service rsyslog start && service slapd start && bash
|
21
|
+
EXPOSE 389
|
@@ -0,0 +1 @@
|
|
1
|
+
pass: 2dbb92b1-1fbb-43a2-9390-fe799b6fe8b9
|
@@ -0,0 +1,16 @@
|
|
1
|
+
dn: cn=config
|
2
|
+
changetype: modify
|
3
|
+
replace: olcLogLevel
|
4
|
+
olcLogLevel: 64 256
|
5
|
+
|
6
|
+
dn: cn=module{0},cn=config
|
7
|
+
changetype: modify
|
8
|
+
add: olcModuleLoad
|
9
|
+
olcModuleLoad: memberof
|
10
|
+
|
11
|
+
dn: olcOverlay=memberof,olcDatabase={1}mdb,cn=config
|
12
|
+
changetype: add
|
13
|
+
objectClass: olcMemberOf
|
14
|
+
objectClass: olcOverlayConfig
|
15
|
+
objectClass: olcConfig
|
16
|
+
objectClass: top
|
data/docker/users.yml
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
support:
|
2
|
+
- cn: search
|
3
|
+
userPassword: 4586d51f-2161-4fb2-a20a-9e03eaeba1e0
|
4
|
+
user:
|
5
|
+
- uid: einstein
|
6
|
+
userPassword: cdb1a742-398f-4717-9fcd-fd700f734854
|
7
|
+
cn: Albert Einstein
|
8
|
+
sn: Einstein
|
9
|
+
group: physics
|
10
|
+
- uid: feynman
|
11
|
+
userPassword: 0ee33778-9b59-4983-a684-99d7e38c91e1
|
12
|
+
cn: Richard Phillips Feynman
|
13
|
+
sn: Feynman
|
14
|
+
group: physics
|
15
|
+
- uid: landau
|
16
|
+
userPassword: 35c40788-62c4-4b35-ba10-df737fabea99
|
17
|
+
cn: Lev Davidovich Landau
|
18
|
+
sn: Landau
|
19
|
+
group: physics
|
20
|
+
- uid: hawking
|
21
|
+
userPassword: b745ad68-dc3c-4b51-a730-590fb8f659f6
|
22
|
+
cn: Stephen William Hawking
|
23
|
+
sn: Hawking
|
24
|
+
group: physics
|
25
|
+
- uid: galileo
|
26
|
+
userPassword: aad39384-8888-46cd-825b-a2b4f2713a12
|
27
|
+
cn: Galileo Galilei
|
28
|
+
sn: Galilei
|
29
|
+
group: physics
|
30
|
+
- uid: galois
|
31
|
+
userPassword: d4af8bc9-fac8-4242-b7ac-42efefb253b9
|
32
|
+
cn: Evariste Galois
|
33
|
+
sn: Galois
|
34
|
+
group: mathematics
|
35
|
+
- uid: euler
|
36
|
+
userPassword: 2291ffeb-b1cd-478c-9625-ebd2746595f4
|
37
|
+
cn: Leonhard Euler
|
38
|
+
sn: Euler
|
39
|
+
group: mathematics
|
40
|
+
- uid: gauss
|
41
|
+
userPassword: 3f5c5559-b262-4c51-88ae-60e7c3022a36
|
42
|
+
cn: Carolus Fridericus Gauss
|
43
|
+
sn: Gauss
|
44
|
+
group: mathematics
|
@@ -0,0 +1,223 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'net/ldap'
|
4
|
+
require 'rims'
|
5
|
+
require 'rims/passwd/ldap/version'
|
6
|
+
require 'uri'
|
7
|
+
|
8
|
+
# to enable LDAP pass-source plug-in, add the entry of
|
9
|
+
# <tt>rims/passwd/ldap</tt> to <tt>load_libraries</tt> list.
|
10
|
+
#
|
11
|
+
# ex.
|
12
|
+
# load_libraries:
|
13
|
+
# - rims/passwd/ldap
|
14
|
+
#
|
15
|
+
class RIMS::Password::LDAPSource < RIMS::Password::Source
|
16
|
+
def initialize(host, port, base_dn, attr, scope: 'sub', filter: nil,
|
17
|
+
search_bind_auth: { :method => :anonymous },
|
18
|
+
search_bind_verification_skip: false,
|
19
|
+
encryption: false)
|
20
|
+
@host = host
|
21
|
+
@port = port
|
22
|
+
@base_dn = base_dn
|
23
|
+
@attr = attr
|
24
|
+
@scope_src = scope
|
25
|
+
@filter_src = filter
|
26
|
+
@search_bind_auth = search_bind_auth
|
27
|
+
@search_bind_verification_skip = search_bind_verification_skip
|
28
|
+
@encryption = encryption
|
29
|
+
end
|
30
|
+
|
31
|
+
def start
|
32
|
+
scheme = @encryption ? 'ldaps' : 'ldap'
|
33
|
+
@logger.info("LDAP pass-source: #{scheme}://#{@host}:#{@port}/#{@base_dn}?#{@attr}?#{@scope_src}?#{@filter_src}")
|
34
|
+
|
35
|
+
case (@scope_src)
|
36
|
+
when 'base'
|
37
|
+
@scope = Net::LDAP::SearchScope_BaseObject
|
38
|
+
when 'one'
|
39
|
+
@scope = Net::LDAP::SearchScope_SingleLevel
|
40
|
+
when 'sub'
|
41
|
+
@scope = Net::LDAP::SearchScope_WholeSubtree
|
42
|
+
else
|
43
|
+
raise "unknown ldap search scope: #{@scope_src}"
|
44
|
+
end
|
45
|
+
|
46
|
+
if (@filter_src) then
|
47
|
+
filter = Net::LDAP::Filter.construct(@filter_src)
|
48
|
+
@filter_factory = proc{|username|
|
49
|
+
Net::LDAP::Filter.eq(@attr, username) & filter
|
50
|
+
}
|
51
|
+
else
|
52
|
+
@filter_factory = proc{|username|
|
53
|
+
Net::LDAP::Filter.eq(@attr, username)
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def raw_password?
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
def ldap_open
|
63
|
+
options = { host: @host, port: @port }
|
64
|
+
if (@search_bind_verification_skip) then
|
65
|
+
options[:auth] = @search_bind_auth
|
66
|
+
end
|
67
|
+
if (@encryption) then
|
68
|
+
options[:encryption] = :simple_tls
|
69
|
+
end
|
70
|
+
|
71
|
+
Net::LDAP.open(options) {|ldap|
|
72
|
+
unless (@search_bind_verification_skip) then
|
73
|
+
# implicit bind of Net::LDAP.open has no error handling.
|
74
|
+
# explicit 2nd bind is required to check bind error.
|
75
|
+
if (@logger.debug?) then
|
76
|
+
auth = @search_bind_auth.dup
|
77
|
+
auth.delete(:password)
|
78
|
+
@logger.debug("LDAP bind: #{auth.inspect}")
|
79
|
+
end
|
80
|
+
ldap.bind(@search_bind_auth) or raise "failed to bind to search: #{ldap.get_operation_result}"
|
81
|
+
@logger.debug("LDAP bind OK")
|
82
|
+
end
|
83
|
+
|
84
|
+
yield(ldap)
|
85
|
+
}
|
86
|
+
end
|
87
|
+
private :ldap_open
|
88
|
+
|
89
|
+
def search(ldap, username)
|
90
|
+
user_filter = @filter_factory.call(username)
|
91
|
+
@logger.debug("LDAP search #{@base_dn} #{@attr} #{@scope} #{user_filter}") if @logger.debug?
|
92
|
+
if (users = ldap.search(base: @base_dn, attributes: [ @attr ], scope: @scope, filter: user_filter)) then
|
93
|
+
unless (users.empty?) then
|
94
|
+
user_dn = users.first.dn
|
95
|
+
@logger.info("found a LDAP user: #{user_dn}")
|
96
|
+
return user_dn
|
97
|
+
else
|
98
|
+
@logger.debug("LDAP search result: not found") if @logger.debug?
|
99
|
+
end
|
100
|
+
else
|
101
|
+
@logger.debug("LDAP search result: no entries") if @logger.debug?
|
102
|
+
end
|
103
|
+
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
private :search
|
107
|
+
|
108
|
+
def user?(username)
|
109
|
+
ldap_open{|ldap|
|
110
|
+
if (search(ldap, username)) then
|
111
|
+
true
|
112
|
+
else
|
113
|
+
false
|
114
|
+
end
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
def compare_password(username, password)
|
119
|
+
ldap_open{|ldap|
|
120
|
+
if (user_dn = search(ldap, username)) then
|
121
|
+
if (ldap.bind(method: :simple, username: user_dn, password: password)) then
|
122
|
+
true
|
123
|
+
else
|
124
|
+
false
|
125
|
+
end
|
126
|
+
end
|
127
|
+
}
|
128
|
+
end
|
129
|
+
|
130
|
+
class << self
|
131
|
+
def uri_decode(string)
|
132
|
+
string.gsub(/%(\h)(\h)/) { [$&[1, 2].hex].pack('C') }.force_encoding(string.encoding)
|
133
|
+
end
|
134
|
+
|
135
|
+
def parse_uri(uri_string)
|
136
|
+
ldap_params = {}
|
137
|
+
|
138
|
+
ldap_uri = URI.parse(uri_string)
|
139
|
+
case (ldap_uri)
|
140
|
+
when URI::LDAPS
|
141
|
+
ldap_params[:encryption] = true
|
142
|
+
when URI::LDAP
|
143
|
+
# OK
|
144
|
+
else
|
145
|
+
raise "not a LDAP URI: #{uri_string}"
|
146
|
+
end
|
147
|
+
|
148
|
+
ldap_params[:host] = ldap_uri.host || 'localhost'
|
149
|
+
ldap_params[:port] = ldap_uri.port or raise "required LDAP port: #{uri_string}"
|
150
|
+
ldap_params[:base_dn] = uri_decode(ldap_uri.dn) if (ldap_uri.dn && ! ldap_uri.dn.empty?)
|
151
|
+
ldap_params[:attribute] = uri_decode(ldap_uri.attributes) if ldap_uri.attributes
|
152
|
+
ldap_params[:scope] = uri_decode(ldap_uri.scope) if ldap_uri.scope
|
153
|
+
ldap_params[:filter] = uri_decode(ldap_uri.filter) if ldap_uri.filter
|
154
|
+
|
155
|
+
ldap_params
|
156
|
+
end
|
157
|
+
|
158
|
+
# configuration entries:
|
159
|
+
# * <tt>"ldap_uri"</tt>
|
160
|
+
# * <tt>"base_dn"</tt>
|
161
|
+
# * <tt>"attribute"</tt>
|
162
|
+
# * <tt>"scope"</tt>
|
163
|
+
# * <tt>"filter"</tt>
|
164
|
+
# * <tt>"search_bind_auth"</tt>
|
165
|
+
# * <tt>"method"</tt>
|
166
|
+
# * <tt>"username"</tt>
|
167
|
+
# * <tt>"password"</tt>
|
168
|
+
# * <tt>"search_bind_verification_skip"</tt>
|
169
|
+
#
|
170
|
+
def build_from_conf(config)
|
171
|
+
unless (config.key? 'ldap_uri') then
|
172
|
+
raise 'required ldap_uri parameter at LDAP pass-source configuration.'
|
173
|
+
end
|
174
|
+
ldap_params = parse_uri(config['ldap_uri'])
|
175
|
+
ldap_args = []
|
176
|
+
|
177
|
+
for name in [ :host, :port ]
|
178
|
+
value = ldap_params.delete(name) or raise "internal error: #{name}"
|
179
|
+
ldap_args << value
|
180
|
+
end
|
181
|
+
|
182
|
+
for name in [ :base_dn, :attribute ]
|
183
|
+
value = ldap_params.delete(name)
|
184
|
+
if (config.key? name.to_s) then
|
185
|
+
value = config[name.to_s]
|
186
|
+
end
|
187
|
+
unless (value) then
|
188
|
+
raise "required #{name} parameter at LDAP pass-source configuration."
|
189
|
+
end
|
190
|
+
ldap_args << value
|
191
|
+
end
|
192
|
+
|
193
|
+
for name in [ :scope, :filter, :search_bind_verification_skip ]
|
194
|
+
if (config.key? name.to_s) then
|
195
|
+
ldap_params[name] = config[name.to_s]
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
if (config.key? 'search_bind_auth') then
|
200
|
+
case (config['search_bind_auth']['method'])
|
201
|
+
when 'anonymous'
|
202
|
+
auth = { method: :anonymous }
|
203
|
+
when 'simple'
|
204
|
+
auth = { method: :simple }
|
205
|
+
auth[:username] = config['search_bind_auth']['username'] or raise 'required serach bind username at LDAP pass-source configuration.'
|
206
|
+
auth[:password] = config['search_bind_auth']['password'] or raise 'required search bind password at LDAP pass-source configuration.'
|
207
|
+
else
|
208
|
+
raise "unknown or unsupported bind method type: #{config['search_bind_auth'].inspect}"
|
209
|
+
end
|
210
|
+
ldap_params[:search_bind_auth] = auth
|
211
|
+
end
|
212
|
+
|
213
|
+
self.new(*ldap_args, **ldap_params)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
RIMS::Authentication.add_plug_in('ldap', self)
|
218
|
+
end
|
219
|
+
|
220
|
+
# Local Variables:
|
221
|
+
# mode: Ruby
|
222
|
+
# indent-tabs-mode: nil
|
223
|
+
# End:
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#-*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'rims/passwd/ldap/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "rims-passwd-ldap"
|
9
|
+
spec.version = RIMS::Password_LDAPSource_VERSION
|
10
|
+
spec.authors = ["TOKI Yoshinori"]
|
11
|
+
spec.email = ["toki@freedom.ne.jp"]
|
12
|
+
spec.summary = %q{RIMS password source plug-in for LDAP authentication}
|
13
|
+
spec.description = <<-'EOF'
|
14
|
+
RIMS password source plug-in for LDAP authentication.
|
15
|
+
By introducing this plug-in, RIMS IMAP server will be able to
|
16
|
+
authenticate users with LDAP.
|
17
|
+
EOF
|
18
|
+
spec.homepage = "https://github.com/y10k/rims-passwd-ldap"
|
19
|
+
spec.license = "MIT"
|
20
|
+
|
21
|
+
spec.files = `git ls-files -z`.split("\x0")
|
22
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_runtime_dependency "rims", ">= 0.2.0"
|
27
|
+
spec.add_runtime_dependency "net-ldap"
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
29
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
30
|
+
spec.add_development_dependency "test-unit"
|
31
|
+
end
|
32
|
+
|
33
|
+
# Local Variables:
|
34
|
+
# mode: Ruby
|
35
|
+
# indent-tabs-mode: nil
|
36
|
+
# End:
|
@@ -0,0 +1,614 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'logger'
|
5
|
+
require 'net/ldap'
|
6
|
+
require 'pp' if $DEBUG
|
7
|
+
require 'rims/passwd/ldap'
|
8
|
+
require 'test/unit'
|
9
|
+
require 'uri'
|
10
|
+
require 'yaml'
|
11
|
+
|
12
|
+
module RIMS::Password::LDAPSource::Test
|
13
|
+
module LDAPExample
|
14
|
+
DOCKER = ENV['DOCKER_COMMAND'] || 'docker'
|
15
|
+
AUTH = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'docker', 'build', 'auth.yml'))
|
16
|
+
CONTAINER = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'docker', 'container.yml'))
|
17
|
+
HOST = (ENV.key? 'DOCKER_HOST') ? URI(ENV['DOCKER_HOST']).host : 'localhost'
|
18
|
+
conf = JSON.parse(`#{DOCKER} inspect #{CONTAINER['name']}`)
|
19
|
+
exposed_port = conf[0]['Config']['ExposedPorts'].keys.first
|
20
|
+
published_port = Integer(conf[0]['NetworkSettings']['Ports'][exposed_port][0]['HostPort'])
|
21
|
+
PORT = published_port
|
22
|
+
USERS = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'docker', 'users.yml'))
|
23
|
+
SEARCH = USERS['support'].find{|role| role['cn'] == 'search' }
|
24
|
+
SEARCH_USER = "cn=#{SEARCH['cn']},ou=support,o=science,dc=nodomain"
|
25
|
+
SEARCH_PASS = SEARCH['userPassword']
|
26
|
+
end
|
27
|
+
|
28
|
+
module LDAPSourceTestMethod
|
29
|
+
include LDAPExample
|
30
|
+
|
31
|
+
def setup
|
32
|
+
@logger = Logger.new(STDOUT)
|
33
|
+
@logger.level = ($DEBUG) ? Logger::DEBUG : Logger::FATAL
|
34
|
+
@search_bind_verification_skip = false
|
35
|
+
@search_bind_auth = {
|
36
|
+
method: :simple,
|
37
|
+
username: SEARCH_USER,
|
38
|
+
password: SEARCH_PASS
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def open_ldap_src(ldap_uri, search_bind_auth: @search_bind_auth)
|
43
|
+
ldap_uri = URI.parse(ldap_uri)
|
44
|
+
|
45
|
+
host = ldap_uri.host
|
46
|
+
port = ldap_uri.port
|
47
|
+
base_dn = ldap_uri.dn
|
48
|
+
attr = ldap_uri.attributes
|
49
|
+
|
50
|
+
optional = {}
|
51
|
+
optional[:scope] = ldap_uri.scope if ldap_uri.scope
|
52
|
+
optional[:filter] = ldap_uri.filter if ldap_uri.filter
|
53
|
+
optional[:search_bind_auth] = search_bind_auth if search_bind_auth
|
54
|
+
optional[:search_bind_verification_skip] = @search_bind_verification_skip
|
55
|
+
case (ldap_uri.scheme)
|
56
|
+
when 'ldap'
|
57
|
+
# ok
|
58
|
+
when 'ldaps'
|
59
|
+
optional[:encryption] = true
|
60
|
+
else
|
61
|
+
raise "unknown URI scheme: #{ldap_uri}"
|
62
|
+
end
|
63
|
+
|
64
|
+
ldap_src = RIMS::Password::LDAPSource.new(host, port, base_dn, attr, **optional)
|
65
|
+
ldap_src.logger = @logger
|
66
|
+
|
67
|
+
ldap_src.start
|
68
|
+
begin
|
69
|
+
yield(ldap_src)
|
70
|
+
ensure
|
71
|
+
ldap_src.stop
|
72
|
+
end
|
73
|
+
end
|
74
|
+
private :open_ldap_src
|
75
|
+
|
76
|
+
def test_raw_password?
|
77
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid") {|ldap_src|
|
78
|
+
assert_false(ldap_src.raw_password?)
|
79
|
+
}
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_users
|
83
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid") {|ldap_src|
|
84
|
+
for user in USERS['user']
|
85
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
86
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
87
|
+
end
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_users_wrong_password
|
92
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid") {|ldap_src|
|
93
|
+
for user in USERS['user']
|
94
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
95
|
+
assert_false(ldap_src.compare_password(user['uid'], 'invalid_pass'), "uid: #{user.inspect}")
|
96
|
+
end
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_users_wrong_base_dn
|
101
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/o=science,dc=nodomain?uid") {|ldap_src|
|
102
|
+
for user in USERS['user']
|
103
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
104
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
105
|
+
end
|
106
|
+
}
|
107
|
+
|
108
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/o=no_org,dc=nodomain?uid") {|ldap_src|
|
109
|
+
for user in USERS['user']
|
110
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
111
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
112
|
+
end
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_users_scope_base
|
117
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid?base") {|ldap_src|
|
118
|
+
for user in USERS['user']
|
119
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
120
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
121
|
+
end
|
122
|
+
}
|
123
|
+
|
124
|
+
for user in USERS['user']
|
125
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/uid=#{user['uid']},ou=user,o=science,dc=nodomain?uid?base") {|ldap_src|
|
126
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
127
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
128
|
+
}
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_users_scope_one
|
133
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid?one") {|ldap_src|
|
134
|
+
for user in USERS['user']
|
135
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
136
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
137
|
+
end
|
138
|
+
}
|
139
|
+
|
140
|
+
for user in USERS['user']
|
141
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/uid=#{user['uid']},ou=user,o=science,dc=nodomain?uid?one") {|ldap_src|
|
142
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
143
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
144
|
+
}
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def test_users_scope_sub
|
149
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid?sub") {|ldap_src|
|
150
|
+
for user in USERS['user']
|
151
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
152
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
153
|
+
end
|
154
|
+
}
|
155
|
+
|
156
|
+
for user in USERS['user']
|
157
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/uid=#{user['uid']},ou=user,o=science,dc=nodomain?uid?sub") {|ldap_src|
|
158
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
159
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
160
|
+
}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_users_scope_invalid_error
|
165
|
+
assert_raise(RuntimeError) {
|
166
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid?unknown") {|ldap_src|
|
167
|
+
flunk
|
168
|
+
}
|
169
|
+
}
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_users_filter_physics
|
173
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid??(memberOf=cn=physics,ou=group,o=science,dc=nodomain)") {|ldap_src|
|
174
|
+
for user in USERS['user'].find_all{|user| user['group'] == 'physics' }
|
175
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
176
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
177
|
+
end
|
178
|
+
for user in USERS['user'].find_all{|user| user['group'] != 'physics' }
|
179
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
180
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
181
|
+
end
|
182
|
+
}
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_users_filter_mathematics
|
186
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid??(memberOf=cn=mathmatics,ou=group,o=science,dc=nodomain)") {|ldap_src|
|
187
|
+
for user in USERS['user'].find_all{|user| user['group'] == 'mathmatics' }
|
188
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
189
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
190
|
+
end
|
191
|
+
for user in USERS['user'].find_all{|user| user['group'] != 'mathmatics' }
|
192
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
193
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
194
|
+
end
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_users_filter_invalid
|
199
|
+
assert_raise(Net::LDAP::FilterSyntaxInvalidError) {
|
200
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid??unknown") {|ldap_src|
|
201
|
+
flunk
|
202
|
+
}
|
203
|
+
}
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
class LDAPSourceTest < Test::Unit::TestCase
|
208
|
+
include LDAPSourceTestMethod
|
209
|
+
|
210
|
+
def test_wrong_search_bind
|
211
|
+
auth = {
|
212
|
+
method: :simple,
|
213
|
+
username: 'no_dn',
|
214
|
+
password: ''
|
215
|
+
}
|
216
|
+
assert_raise(RuntimeError) {
|
217
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid", search_bind_auth: auth) {|ldap_src|
|
218
|
+
ldap_src.user? 'foo' # to bind
|
219
|
+
flunk
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
auth = {
|
224
|
+
method: :simple,
|
225
|
+
username: 'cn=no_role,ou=support,o=science,dc=nodomain',
|
226
|
+
password: 'open_sesame'
|
227
|
+
}
|
228
|
+
assert_raise(RuntimeError) {
|
229
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid", search_bind_auth: auth) {|ldap_src|
|
230
|
+
ldap_src.user? 'foo' # to bind
|
231
|
+
flunk
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
235
|
+
auth = {
|
236
|
+
method: :simple,
|
237
|
+
username: "cn=#{SEARCH['cn']},ou=support,o=science,dc=nodomain",
|
238
|
+
password: 'invalid_pass'
|
239
|
+
}
|
240
|
+
assert_raise(RuntimeError) {
|
241
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid", search_bind_auth: auth) {|ldap_src|
|
242
|
+
ldap_src.user? 'foo' # to bind
|
243
|
+
flunk
|
244
|
+
}
|
245
|
+
}
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
class LDAPSourceSearchBindVerificationSkipTest < Test::Unit::TestCase
|
250
|
+
include LDAPSourceTestMethod
|
251
|
+
|
252
|
+
def setup
|
253
|
+
super
|
254
|
+
@search_bind_verification_skip = true
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_wrong_search_bind_no_error
|
258
|
+
auth = {
|
259
|
+
method: :simple,
|
260
|
+
username: 'no_dn',
|
261
|
+
password: ''
|
262
|
+
}
|
263
|
+
#assert_raise(RuntimeError) {
|
264
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid", search_bind_auth: auth) {|ldap_src|
|
265
|
+
ldap_src.user? 'foo' # to bind
|
266
|
+
#flunk
|
267
|
+
}
|
268
|
+
#}
|
269
|
+
|
270
|
+
auth = {
|
271
|
+
method: :simple,
|
272
|
+
username: 'cn=no_role,ou=support,o=science,dc=nodomain',
|
273
|
+
password: 'open_sesame'
|
274
|
+
}
|
275
|
+
#assert_raise(RuntimeError) {
|
276
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid", search_bind_auth: auth) {|ldap_src|
|
277
|
+
ldap_src.user? 'foo' # to bind
|
278
|
+
#flunk
|
279
|
+
}
|
280
|
+
#}
|
281
|
+
|
282
|
+
auth = {
|
283
|
+
method: :simple,
|
284
|
+
username: "cn=#{SEARCH['cn']},ou=support,o=science,dc=nodomain",
|
285
|
+
password: 'invalid_pass'
|
286
|
+
}
|
287
|
+
#assert_raise(RuntimeError) {
|
288
|
+
open_ldap_src("ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid", search_bind_auth: auth) {|ldap_src|
|
289
|
+
ldap_src.user? 'foo' # to bind
|
290
|
+
#flunk
|
291
|
+
}
|
292
|
+
#}
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
class LDAPSourceConfigTest < Test::Unit::TestCase
|
297
|
+
include LDAPExample
|
298
|
+
|
299
|
+
def assert_decode_uri(expected_string, src_string)
|
300
|
+
assert_equal(expected_string, RIMS::Password::LDAPSource.uri_decode(src_string))
|
301
|
+
end
|
302
|
+
private :assert_decode_uri
|
303
|
+
|
304
|
+
def test_uri_decode
|
305
|
+
assert_decode_uri('ou=user,o=science,dc=nodomain', 'ou=user,o=science,dc=nodomain')
|
306
|
+
assert_decode_uri('(cn=Albert Einstein)', '(cn=Albert%20Einstein)')
|
307
|
+
assert_decode_uri('(&(cn=Albert Einstein)(memberOf=cn=physics,ou=group,o=science,dc=nodomain))',
|
308
|
+
'(%26(cn=Albert%20Einstein)(memberOf=cn=physics%2cou=group%2co=science%2cdc=nodomain))')
|
309
|
+
assert_decode_uri('+', '+')
|
310
|
+
end
|
311
|
+
|
312
|
+
def assert_parse_uri(expected_ldap_params, ldap_uri)
|
313
|
+
assert_equal(expected_ldap_params, RIMS::Password::LDAPSource.parse_uri(ldap_uri))
|
314
|
+
end
|
315
|
+
private :assert_parse_uri
|
316
|
+
|
317
|
+
def test_parse_uri
|
318
|
+
assert_parse_uri({ host: 'localhost', port: 389 }, 'ldap:///')
|
319
|
+
assert_parse_uri({ host: 'localhost', port: 636, encryption: true }, 'ldaps://')
|
320
|
+
assert_parse_uri({ host: 'mydomain', port: 389 }, 'ldap://mydomain')
|
321
|
+
assert_parse_uri({ host: 'mydomain', port: 38900 }, 'ldap://mydomain:38900')
|
322
|
+
assert_parse_uri({ host: 'mydomain',
|
323
|
+
port: 389,
|
324
|
+
base_dn: 'ou=user,o=science,dc=nodomain'
|
325
|
+
}, 'ldap://mydomain/ou=user,o=science,dc=nodomain')
|
326
|
+
assert_parse_uri({ host: 'mydomain',
|
327
|
+
port: 389,
|
328
|
+
base_dn: 'ou=user, o=science, dc=nodomain'
|
329
|
+
}, 'ldap://mydomain/ou=user,%20o=science,%20dc=nodomain')
|
330
|
+
assert_parse_uri({ host: 'mydomain', port: 389, attribute: 'uid' }, 'ldap://mydomain/?uid')
|
331
|
+
assert_parse_uri({ host: 'mydomain', port: 389, attribute: '?foo' }, 'ldap://mydomain/?%3ffoo')
|
332
|
+
assert_parse_uri({ host: 'mydomain', port: 389, scope: 'base' }, 'ldap://mydomain/??base')
|
333
|
+
assert_parse_uri({ host: 'mydomain', port: 389, scope: 'one' }, 'ldap://mydomain/??one')
|
334
|
+
assert_parse_uri({ host: 'mydomain', port: 389, scope: 'sub' }, 'ldap://mydomain/??sub')
|
335
|
+
assert_parse_uri({ host: 'mydomain', port: 389, filter: '(uid=einstein)' }, 'ldap://mydomain/???(uid=einstein)')
|
336
|
+
assert_parse_uri({ host: 'mydomain', port: 389, filter: '(cn=Albert Einstein)' }, 'ldap://mydomain/???(cn=Albert%20Einstein)')
|
337
|
+
assert_parse_uri({ host: 'mydomain',
|
338
|
+
port: 6360,
|
339
|
+
encryption: true,
|
340
|
+
base_dn: 'ou=user,o=science,dc=nodomain',
|
341
|
+
attribute: 'uid',
|
342
|
+
scope: 'base',
|
343
|
+
filter: '(uid=einstein)'
|
344
|
+
}, 'ldaps://mydomain:6360/ou=user,o=science,dc=nodomain?uid?base?(uid=einstein)')
|
345
|
+
end
|
346
|
+
|
347
|
+
def build_from_conf(config)
|
348
|
+
ldap_src = RIMS::Password::LDAPSource.build_from_conf(config)
|
349
|
+
|
350
|
+
logger = Logger.new(STDOUT)
|
351
|
+
logger.level = ($DEBUG) ? Logger::DEBUG : Logger::FATAL
|
352
|
+
ldap_src.logger = logger
|
353
|
+
|
354
|
+
ldap_src.start
|
355
|
+
begin
|
356
|
+
yield(ldap_src)
|
357
|
+
ensure
|
358
|
+
ldap_src.stop
|
359
|
+
end
|
360
|
+
end
|
361
|
+
private :build_from_conf
|
362
|
+
|
363
|
+
def test_build_from_conf
|
364
|
+
c = {
|
365
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
366
|
+
'base_dn' => 'ou=user,o=science,dc=nodomain',
|
367
|
+
'attribute' => 'uid',
|
368
|
+
'scope' => 'one',
|
369
|
+
'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
370
|
+
'search_bind_auth' => {
|
371
|
+
'method' => 'simple',
|
372
|
+
'username' => SEARCH_USER,
|
373
|
+
'password' => SEARCH_PASS
|
374
|
+
},
|
375
|
+
'search_bind_verification_skip' => false
|
376
|
+
}
|
377
|
+
build_from_conf(c) {|ldap_src|
|
378
|
+
for user in USERS['user'].find_all{|user| user['group'] == 'physics' }
|
379
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
380
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
381
|
+
end
|
382
|
+
for user in USERS['user'].find_all{|user| user['group'] != 'physics' }
|
383
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
384
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
385
|
+
end
|
386
|
+
}
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_build_from_conf_ldap_uri
|
390
|
+
c = {
|
391
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}/ou=user,o=science,dc=nodomain?uid?one?(memberOf=cn=physics,ou=group,o=science,dc=nodomain)",
|
392
|
+
'search_bind_auth' => {
|
393
|
+
'method' => 'simple',
|
394
|
+
'username' => SEARCH_USER,
|
395
|
+
'password' => SEARCH_PASS
|
396
|
+
},
|
397
|
+
'search_bind_verification_skip' => false
|
398
|
+
}
|
399
|
+
build_from_conf(c) {|ldap_src|
|
400
|
+
for user in USERS['user'].find_all{|user| user['group'] == 'physics' }
|
401
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
402
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
403
|
+
end
|
404
|
+
for user in USERS['user'].find_all{|user| user['group'] != 'physics' }
|
405
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
406
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
407
|
+
end
|
408
|
+
}
|
409
|
+
end
|
410
|
+
|
411
|
+
def test_build_from_conf_error_no_ldap_uri
|
412
|
+
c = {
|
413
|
+
#'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
414
|
+
'base_dn' => 'ou=user,o=science,dc=nodomain',
|
415
|
+
'attribute' => 'uid',
|
416
|
+
'scope' => 'one',
|
417
|
+
'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
418
|
+
'search_bind_auth' => {
|
419
|
+
'method' => 'simple',
|
420
|
+
'username' => SEARCH_USER,
|
421
|
+
'password' => SEARCH_PASS
|
422
|
+
},
|
423
|
+
'search_bind_verification_skip' => false
|
424
|
+
}
|
425
|
+
assert_raise(RuntimeError) {
|
426
|
+
build_from_conf(c) {|ldap_src|
|
427
|
+
flunk
|
428
|
+
}
|
429
|
+
}
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_build_from_conf_error_no_base_dn
|
433
|
+
c = {
|
434
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
435
|
+
#'base_dn' => 'ou=user,o=science,dc=nodomain',
|
436
|
+
'attribute' => 'uid',
|
437
|
+
'scope' => 'one',
|
438
|
+
'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
439
|
+
'search_bind_auth' => {
|
440
|
+
'method' => 'simple',
|
441
|
+
'username' => SEARCH_USER,
|
442
|
+
'password' => SEARCH_PASS
|
443
|
+
},
|
444
|
+
'search_bind_verification_skip' => false
|
445
|
+
}
|
446
|
+
assert_raise(RuntimeError) {
|
447
|
+
build_from_conf(c) {|ldap_src|
|
448
|
+
flunk
|
449
|
+
}
|
450
|
+
}
|
451
|
+
end
|
452
|
+
|
453
|
+
def test_build_from_conf_error_no_attribute
|
454
|
+
c = {
|
455
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
456
|
+
'base_dn' => 'ou=user,o=science,dc=nodomain',
|
457
|
+
#'attribute' => 'uid',
|
458
|
+
'scope' => 'one',
|
459
|
+
'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
460
|
+
'search_bind_auth' => {
|
461
|
+
'method' => 'simple',
|
462
|
+
'username' => SEARCH_USER,
|
463
|
+
'password' => SEARCH_PASS
|
464
|
+
},
|
465
|
+
'search_bind_verification_skip' => false
|
466
|
+
}
|
467
|
+
assert_raise(RuntimeError) {
|
468
|
+
build_from_conf(c) {|ldap_src|
|
469
|
+
flunk
|
470
|
+
}
|
471
|
+
}
|
472
|
+
end
|
473
|
+
|
474
|
+
def test_build_from_conf_scope_default
|
475
|
+
c = {
|
476
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
477
|
+
'base_dn' => 'ou=user,o=science,dc=nodomain',
|
478
|
+
'attribute' => 'uid',
|
479
|
+
#'scope' => 'one',
|
480
|
+
'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
481
|
+
'search_bind_auth' => {
|
482
|
+
'method' => 'simple',
|
483
|
+
'username' => SEARCH_USER,
|
484
|
+
'password' => SEARCH_PASS
|
485
|
+
},
|
486
|
+
'search_bind_verification_skip' => false
|
487
|
+
}
|
488
|
+
build_from_conf(c) {|ldap_src|
|
489
|
+
for user in USERS['user'].find_all{|user| user['group'] == 'physics' }
|
490
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
491
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
492
|
+
end
|
493
|
+
for user in USERS['user'].find_all{|user| user['group'] != 'physics' }
|
494
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
495
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
496
|
+
end
|
497
|
+
}
|
498
|
+
end
|
499
|
+
|
500
|
+
def test_build_from_conf_no_filter
|
501
|
+
c = {
|
502
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
503
|
+
'base_dn' => 'ou=user,o=science,dc=nodomain',
|
504
|
+
'attribute' => 'uid',
|
505
|
+
'scope' => 'one',
|
506
|
+
#'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
507
|
+
'search_bind_auth' => {
|
508
|
+
'method' => 'simple',
|
509
|
+
'username' => SEARCH_USER,
|
510
|
+
'password' => SEARCH_PASS
|
511
|
+
},
|
512
|
+
'search_bind_verification_skip' => false
|
513
|
+
}
|
514
|
+
build_from_conf(c) {|ldap_src|
|
515
|
+
for user in USERS['user']
|
516
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
517
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
518
|
+
end
|
519
|
+
}
|
520
|
+
end
|
521
|
+
|
522
|
+
def test_build_from_conf_search_bind_verification_skip_default
|
523
|
+
c = {
|
524
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
525
|
+
'base_dn' => 'ou=user,o=science,dc=nodomain',
|
526
|
+
'attribute' => 'uid',
|
527
|
+
'scope' => 'one',
|
528
|
+
'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
529
|
+
'search_bind_auth' => {
|
530
|
+
'method' => 'simple',
|
531
|
+
'username' => SEARCH_USER,
|
532
|
+
'password' => SEARCH_PASS
|
533
|
+
},
|
534
|
+
#'search_bind_verification_skip' => false
|
535
|
+
}
|
536
|
+
build_from_conf(c) {|ldap_src|
|
537
|
+
for user in USERS['user'].find_all{|user| user['group'] == 'physics' }
|
538
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
539
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
540
|
+
end
|
541
|
+
for user in USERS['user'].find_all{|user| user['group'] != 'physics' }
|
542
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
543
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
544
|
+
end
|
545
|
+
}
|
546
|
+
end
|
547
|
+
|
548
|
+
def test_build_from_conf_search_bind_verification_skip_enabled
|
549
|
+
c = {
|
550
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
551
|
+
'base_dn' => 'ou=user,o=science,dc=nodomain',
|
552
|
+
'attribute' => 'uid',
|
553
|
+
'scope' => 'one',
|
554
|
+
'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
555
|
+
'search_bind_auth' => {
|
556
|
+
'method' => 'simple',
|
557
|
+
'username' => SEARCH_USER,
|
558
|
+
'password' => SEARCH_PASS
|
559
|
+
},
|
560
|
+
'search_bind_verification_skip' => true
|
561
|
+
}
|
562
|
+
build_from_conf(c) {|ldap_src|
|
563
|
+
for user in USERS['user'].find_all{|user| user['group'] == 'physics' }
|
564
|
+
assert_true((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
565
|
+
assert_true(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
566
|
+
end
|
567
|
+
for user in USERS['user'].find_all{|user| user['group'] != 'physics' }
|
568
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
569
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
570
|
+
end
|
571
|
+
}
|
572
|
+
end
|
573
|
+
|
574
|
+
def test_build_from_conf_search_bind_auth_default_anonymous
|
575
|
+
c = {
|
576
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
577
|
+
'base_dn' => 'ou=user,o=science,dc=nodomain',
|
578
|
+
'attribute' => 'uid',
|
579
|
+
'scope' => 'one',
|
580
|
+
'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
581
|
+
'search_bind_verification_skip' => false
|
582
|
+
}
|
583
|
+
build_from_conf(c) {|ldap_src|
|
584
|
+
for user in USERS['user']
|
585
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
586
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
587
|
+
end
|
588
|
+
}
|
589
|
+
end
|
590
|
+
|
591
|
+
def test_build_from_conf_search_bind_auth_explicit_anonymous
|
592
|
+
c = {
|
593
|
+
'ldap_uri' => "ldap://#{HOST}:#{PORT}",
|
594
|
+
'base_dn' => 'ou=user,o=science,dc=nodomain',
|
595
|
+
'attribute' => 'uid',
|
596
|
+
'scope' => 'one',
|
597
|
+
'filter' => '(memberOf=cn=physics,ou=group,o=science,dc=nodomain)',
|
598
|
+
'search_bind_auth' => { 'method' => 'anonymous' },
|
599
|
+
'search_bind_verification_skip' => false
|
600
|
+
}
|
601
|
+
build_from_conf(c) {|ldap_src|
|
602
|
+
for user in USERS['user']
|
603
|
+
assert_false((ldap_src.user? user['uid']), "uid: #{user.inspect}")
|
604
|
+
assert_nil(ldap_src.compare_password(user['uid'], user['userPassword']), "uid: #{user.inspect}")
|
605
|
+
end
|
606
|
+
}
|
607
|
+
end
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
# Local Variables:
|
612
|
+
# mode: Ruby
|
613
|
+
# indent-tabs-mode: nil
|
614
|
+
# End:
|