ucb_ldap 2.0.0.pre1 → 2.0.0.pre3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/CHANGELOG +137 -135
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/{README → README.md} +82 -80
- data/Rakefile +38 -20
- data/lib/ucb_ldap.rb +238 -204
- data/lib/{ucb_ldap_address.rb → ucb_ldap/address.rb} +106 -106
- data/lib/{ucb_ldap_affiliation.rb → ucb_ldap/affiliation.rb} +16 -16
- data/lib/{ucb_ldap_entry.rb → ucb_ldap/entry.rb} +455 -448
- data/lib/{ucb_ldap_person_job_appointment.rb → ucb_ldap/job_appointment.rb} +77 -79
- data/lib/{ucb_ldap_namespace.rb → ucb_ldap/namespace.rb} +40 -50
- data/lib/{ucb_ldap_org.rb → ucb_ldap/org.rb} +427 -429
- data/lib/{ucb_ldap_person.rb → ucb_ldap/person.rb} +157 -148
- data/lib/{person → ucb_ldap/person}/affiliation_methods.rb +23 -22
- data/lib/ucb_ldap/person/common_attributes.rb +63 -0
- data/lib/{ucb_ldap_schema.rb → ucb_ldap/schema.rb} +28 -28
- data/lib/{ucb_ldap_schema_attribute.rb → ucb_ldap/schema_attribute.rb} +152 -153
- data/lib/{ucb_ldap_service.rb → ucb_ldap/service.rb} +17 -19
- data/lib/{ucb_ldap_student_term.rb → ucb_ldap/student_term.rb} +29 -31
- data/lib/ucb_ldap/version.rb +3 -0
- data/spec/rails_binds.yml +9 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/ucb_ldap/address_spec.rb +54 -0
- data/spec/ucb_ldap/affiliation_spec.rb +85 -0
- data/spec/ucb_ldap/entry_spec.rb +241 -0
- data/spec/ucb_ldap/job_appointment_spec.rb +65 -0
- data/spec/ucb_ldap/namespace_spec.rb +72 -0
- data/spec/ucb_ldap/org_spec.rb +217 -0
- data/spec/ucb_ldap/person_spec.rb +225 -0
- data/spec/ucb_ldap/schema_attribute_spec.rb +122 -0
- data/spec/ucb_ldap/schema_spec.rb +104 -0
- data/spec/ucb_ldap/service_spec.rb +127 -0
- data/spec/ucb_ldap/student_term_spec.rb +121 -0
- data/spec/ucb_ldap_spec.rb +182 -0
- data/ucb_ldap.gemspec +20 -27
- metadata +113 -64
- data/Manifest +0 -23
- data/TODO +0 -2
- data/lib/person/adv_con_person.rb +0 -0
- data/lib/person/generic_attributes.rb +0 -68
- data/lib/ucb_ldap_exceptions.rb +0 -27
- data/version.yml +0 -1
data/Rakefile
CHANGED
@@ -1,20 +1,38 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "bundler/gem_tasks"
|
5
|
+
require 'bundler/setup'
|
6
|
+
rescue LoadError => e
|
7
|
+
require('rubygems') && retry
|
8
|
+
puts "Please `gem install bundler' and run `bundle install' to ensure you have all dependencies"
|
9
|
+
raise e
|
10
|
+
end
|
11
|
+
|
12
|
+
Bundler::GemHelper.install_tasks
|
13
|
+
|
14
|
+
|
15
|
+
require 'rspec/core/rake_task'
|
16
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
17
|
+
t.rspec_opts = ['--color', "--format documentation"]
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Update schema file"
|
21
|
+
task :update_schema_file do
|
22
|
+
print 'rebuilding schema file ... '
|
23
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
24
|
+
require 'ucb_ldap'
|
25
|
+
include UCB::LDAP
|
26
|
+
File.open(Schema.schema_file, "w") do |file|
|
27
|
+
file.print Schema.yaml_from_url
|
28
|
+
end
|
29
|
+
puts 'done'
|
30
|
+
end
|
31
|
+
task :package => :update_schema_file
|
32
|
+
task :repackage => :update_schema_file
|
33
|
+
|
34
|
+
|
35
|
+
#desc "Performance tests"
|
36
|
+
#task :perf do
|
37
|
+
# require 'test/performance/_run_all'
|
38
|
+
#end
|
data/lib/ucb_ldap.rb
CHANGED
@@ -1,204 +1,238 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'net/ldap'
|
3
|
-
require 'time'
|
4
|
-
|
5
|
-
require
|
6
|
-
require '
|
7
|
-
require '
|
8
|
-
|
9
|
-
require 'person
|
10
|
-
require '
|
11
|
-
require '
|
12
|
-
|
13
|
-
require '
|
14
|
-
require '
|
15
|
-
require '
|
16
|
-
require '
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
#
|
88
|
-
#
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
def
|
97
|
-
@
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
#
|
106
|
-
|
107
|
-
#
|
108
|
-
#
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
#
|
123
|
-
#
|
124
|
-
#
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
#
|
145
|
-
#
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
#
|
154
|
-
#
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'net/ldap'
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
require "ucb_ldap/version"
|
6
|
+
require 'ucb_ldap/schema'
|
7
|
+
require 'ucb_ldap/schema_attribute'
|
8
|
+
require 'ucb_ldap/entry'
|
9
|
+
require 'ucb_ldap/person'
|
10
|
+
require 'ucb_ldap/job_appointment'
|
11
|
+
require 'ucb_ldap/org'
|
12
|
+
require 'ucb_ldap/namespace'
|
13
|
+
require 'ucb_ldap/address'
|
14
|
+
require 'ucb_ldap/student_term'
|
15
|
+
require 'ucb_ldap/affiliation'
|
16
|
+
require 'ucb_ldap/service'
|
17
|
+
|
18
|
+
|
19
|
+
module UCB
|
20
|
+
#:nodoc:
|
21
|
+
#
|
22
|
+
# =UCB::LDAP
|
23
|
+
#
|
24
|
+
# <b>If you are doing searches that don't require a privileged bind
|
25
|
+
# and are accessing the default (production) server
|
26
|
+
# you probably don't need to call any of the methods in this module.</b>
|
27
|
+
#
|
28
|
+
# Methods in this module are about making <em>connections</em>
|
29
|
+
# to the LDAP directory.
|
30
|
+
#
|
31
|
+
# Interaction with the directory (searches and updates) is usually through the search()
|
32
|
+
# and other methods of UCB::LDAP::Entry and its sub-classes.
|
33
|
+
#
|
34
|
+
module LDAP
|
35
|
+
|
36
|
+
BadAttributeNameException = Class.new(Exception) #:nodoc:
|
37
|
+
|
38
|
+
class BindFailedException < Exception #:nodoc:
|
39
|
+
def initialize
|
40
|
+
super("Failed to bind username '#{UCB::LDAP.username}' to '#{UCB::LDAP.host}'")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class ConnectionFailedException < Exception #:nodoc:
|
45
|
+
def initialize
|
46
|
+
super("Failed to connect to ldap host '#{UCB::LDAP.host}''")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class DirectoryNotUpdatedException < Exception #:nodoc:
|
51
|
+
def initialize
|
52
|
+
result = UCB::LDAP.net_ldap.get_operation_result
|
53
|
+
super("(Code=#{result.code}) #{result.message}")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
HOST_PRODUCTION = 'nds.berkeley.edu'
|
59
|
+
HOST_TEST = 'nds-test.berkeley.edu'
|
60
|
+
|
61
|
+
class << self
|
62
|
+
# Execute UCB::LDAP commands with a different username and password.
|
63
|
+
# Original credentials are restored.
|
64
|
+
def with_credentials(username_to_use, password_to_use)
|
65
|
+
original_username = username
|
66
|
+
original_password = password
|
67
|
+
|
68
|
+
UCB::LDAP.authenticate(username_to_use, password_to_use)
|
69
|
+
|
70
|
+
yield
|
71
|
+
ensure
|
72
|
+
UCB::LDAP.authenticate(original_username, original_password)
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Give (new) bind credentials to LDAP. An attempt will be made
|
77
|
+
# to bind and will raise BindFailedException if bind fails.
|
78
|
+
#
|
79
|
+
# Call clear_authentication() to remove privileged bind.
|
80
|
+
#
|
81
|
+
def authenticate(username, password)
|
82
|
+
@username, @password = username, password
|
83
|
+
new_net_ldap() # to force bind()
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Removes current bind (username, password).
|
88
|
+
#
|
89
|
+
def clear_authentication
|
90
|
+
authenticate(nil, nil)
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Returns LDAP host used for lookups. Default is HOST_PRODUCTION.
|
95
|
+
#
|
96
|
+
def host
|
97
|
+
@host || HOST_PRODUCTION
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# Setter for #host.
|
102
|
+
#
|
103
|
+
# Note: validation of host is deferred until a search is performed
|
104
|
+
# or #authenticate() is called at which time a bad host will
|
105
|
+
# raise ConnectionFailedException.
|
106
|
+
#---
|
107
|
+
# Don't want to reconnect unless host really changed.
|
108
|
+
#
|
109
|
+
def host=(host)
|
110
|
+
if host != @host
|
111
|
+
@host = host
|
112
|
+
@net_ldap = nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Returns Net::LDAP instance that is used by UCB::LDAP::Entry
|
118
|
+
# and subclasses for directory searches.
|
119
|
+
#
|
120
|
+
# You might need this to perform searches not supported by
|
121
|
+
# sub-classes of Entry.
|
122
|
+
#
|
123
|
+
# Note: callers should not cache the results of this call unless they
|
124
|
+
# are prepared to handle timed-out connections (which this method does).
|
125
|
+
#
|
126
|
+
def net_ldap
|
127
|
+
@net_ldap ||= new_net_ldap
|
128
|
+
end
|
129
|
+
|
130
|
+
def password #:nodoc:
|
131
|
+
@password
|
132
|
+
end
|
133
|
+
|
134
|
+
def username #:nodoc:
|
135
|
+
@username
|
136
|
+
end
|
137
|
+
|
138
|
+
##
|
139
|
+
# If you are using UCB::LDAP in a Rails application you can specify binds on a
|
140
|
+
# per-environment basis, just as you can with database credentials.
|
141
|
+
#
|
142
|
+
# # in ../config/ldap.yml
|
143
|
+
#
|
144
|
+
# development:
|
145
|
+
# username: user_dev
|
146
|
+
# password: pass_dev
|
147
|
+
#
|
148
|
+
# # etc.
|
149
|
+
#
|
150
|
+
#
|
151
|
+
# # in ../config/environment.rb
|
152
|
+
#
|
153
|
+
# require 'ucb_ldap'
|
154
|
+
# UCB::LDAP.bind_for_rails()
|
155
|
+
#
|
156
|
+
# Runtime error will be raised if bind_file not found or if environment key not
|
157
|
+
# found in bind_file.
|
158
|
+
#
|
159
|
+
def bind_for_rails(bind_file = "#{Rails.root}/config/ldap.yml", environment = Rails.env)
|
160
|
+
bind(bind_file, environment)
|
161
|
+
end
|
162
|
+
|
163
|
+
def bind(bind_file, environment)
|
164
|
+
raise "Can't find bind file: #{bind_file}" unless FileTest.exists?(bind_file)
|
165
|
+
binds = YAML.load(IO.read(bind_file))
|
166
|
+
bind = binds[environment] || raise("Can't find environment=#{environment} in bind file")
|
167
|
+
authenticate(bind['username'], bind['password'])
|
168
|
+
end
|
169
|
+
|
170
|
+
##
|
171
|
+
# Returns +arg+ as a Ruby +Date+ in local time zone. Returns +nil+ if +arg+ is +nil+.
|
172
|
+
#
|
173
|
+
def local_date_parse(arg)
|
174
|
+
arg.nil? ? nil : Date.parse(Time.parse(arg.to_s).localtime.to_s)
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# Returns +arg+ as a Ruby +DateTime+ in local time zone. Returns +nil+ if +arg+ is +nil+.
|
179
|
+
#
|
180
|
+
def local_datetime_parse(arg)
|
181
|
+
arg.nil? ? nil : DateTime.parse(Time.parse(arg.to_s).localtime.to_s)
|
182
|
+
end
|
183
|
+
|
184
|
+
## TODO: restore private
|
185
|
+
# private unless $TESTING
|
186
|
+
|
187
|
+
##
|
188
|
+
# The value of the :auth parameter for Net::LDAP.new.
|
189
|
+
#
|
190
|
+
def authentication_information
|
191
|
+
password.nil? ?
|
192
|
+
{ :method => :anonymous } :
|
193
|
+
{ :method => :simple, :username => username, :password => password }
|
194
|
+
end
|
195
|
+
|
196
|
+
##
|
197
|
+
# Returns +true+ if connection simple search works.
|
198
|
+
#
|
199
|
+
def ldap_ping
|
200
|
+
search_attrs = {
|
201
|
+
:base => "",
|
202
|
+
:scope => Net::LDAP::SearchScope_BaseObject,
|
203
|
+
:attributes => [1.1]
|
204
|
+
}
|
205
|
+
result = false
|
206
|
+
@net_ldap.search(search_attrs) { result = true }
|
207
|
+
result
|
208
|
+
end
|
209
|
+
|
210
|
+
##
|
211
|
+
# Returns new Net::LDAP instance.
|
212
|
+
#
|
213
|
+
def new_net_ldap
|
214
|
+
params = {
|
215
|
+
:host => host,
|
216
|
+
:auth => authentication_information,
|
217
|
+
:port => 636,
|
218
|
+
:encryption => { :method => :simple_tls }
|
219
|
+
}
|
220
|
+
@net_ldap = Net::LDAP.new(params)
|
221
|
+
@net_ldap.bind || raise(BindFailedException)
|
222
|
+
@net_ldap
|
223
|
+
rescue Net::LDAP::LdapError => e
|
224
|
+
raise(BindFailedException)
|
225
|
+
end
|
226
|
+
|
227
|
+
##
|
228
|
+
# Used for testing
|
229
|
+
#
|
230
|
+
def clear_instance_variables
|
231
|
+
@host = nil
|
232
|
+
@net_ldap = nil
|
233
|
+
@username = nil
|
234
|
+
@password = nil
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|