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.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/CHANGELOG +137 -135
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/{README → README.md} +82 -80
  7. data/Rakefile +38 -20
  8. data/lib/ucb_ldap.rb +238 -204
  9. data/lib/{ucb_ldap_address.rb → ucb_ldap/address.rb} +106 -106
  10. data/lib/{ucb_ldap_affiliation.rb → ucb_ldap/affiliation.rb} +16 -16
  11. data/lib/{ucb_ldap_entry.rb → ucb_ldap/entry.rb} +455 -448
  12. data/lib/{ucb_ldap_person_job_appointment.rb → ucb_ldap/job_appointment.rb} +77 -79
  13. data/lib/{ucb_ldap_namespace.rb → ucb_ldap/namespace.rb} +40 -50
  14. data/lib/{ucb_ldap_org.rb → ucb_ldap/org.rb} +427 -429
  15. data/lib/{ucb_ldap_person.rb → ucb_ldap/person.rb} +157 -148
  16. data/lib/{person → ucb_ldap/person}/affiliation_methods.rb +23 -22
  17. data/lib/ucb_ldap/person/common_attributes.rb +63 -0
  18. data/lib/{ucb_ldap_schema.rb → ucb_ldap/schema.rb} +28 -28
  19. data/lib/{ucb_ldap_schema_attribute.rb → ucb_ldap/schema_attribute.rb} +152 -153
  20. data/lib/{ucb_ldap_service.rb → ucb_ldap/service.rb} +17 -19
  21. data/lib/{ucb_ldap_student_term.rb → ucb_ldap/student_term.rb} +29 -31
  22. data/lib/ucb_ldap/version.rb +3 -0
  23. data/spec/rails_binds.yml +9 -0
  24. data/spec/spec_helper.rb +43 -0
  25. data/spec/ucb_ldap/address_spec.rb +54 -0
  26. data/spec/ucb_ldap/affiliation_spec.rb +85 -0
  27. data/spec/ucb_ldap/entry_spec.rb +241 -0
  28. data/spec/ucb_ldap/job_appointment_spec.rb +65 -0
  29. data/spec/ucb_ldap/namespace_spec.rb +72 -0
  30. data/spec/ucb_ldap/org_spec.rb +217 -0
  31. data/spec/ucb_ldap/person_spec.rb +225 -0
  32. data/spec/ucb_ldap/schema_attribute_spec.rb +122 -0
  33. data/spec/ucb_ldap/schema_spec.rb +104 -0
  34. data/spec/ucb_ldap/service_spec.rb +127 -0
  35. data/spec/ucb_ldap/student_term_spec.rb +121 -0
  36. data/spec/ucb_ldap_spec.rb +182 -0
  37. data/ucb_ldap.gemspec +20 -27
  38. metadata +113 -64
  39. data/Manifest +0 -23
  40. data/TODO +0 -2
  41. data/lib/person/adv_con_person.rb +0 -0
  42. data/lib/person/generic_attributes.rb +0 -68
  43. data/lib/ucb_ldap_exceptions.rb +0 -27
  44. data/version.yml +0 -1
data/Rakefile CHANGED
@@ -1,20 +1,38 @@
1
- require 'rubygems'
2
- require 'rake'
3
- require 'echoe'
4
-
5
- Echoe.new('ucb_ldap', '2.0.0.pre1') do |p|
6
- p.description = "Convenience classes for interacing with UCB's LDAP directory"
7
- p.url = "http://ucbrb.rubyforge.org/ucb_ldap"
8
- p.author = "Steven Hansen, Steve Downey, Lucas Rockwell"
9
- p.email = "runner@berkeley.edu"
10
- p.ignore_pattern = ["svn_user.yml", "tasks/ucb_ldap.rake", "spec/**/**", "test/**/**"]
11
- p.project = "ucbrb"
12
- p.runtime_dependencies = ["net-ldap =0.2.2"]
13
- p.rdoc_pattern = ["README", "lib/**/**"]
14
- end
15
-
16
- Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
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
- require 'ucb_ldap_exceptions'
5
- require 'ucb_ldap_schema'
6
- require 'ucb_ldap_schema_attribute'
7
- require 'ucb_ldap_entry'
8
-
9
- require 'person/affiliation_methods.rb'
10
- require 'person/generic_attributes.rb'
11
- require 'ucb_ldap_person.rb'
12
-
13
- require 'ucb_ldap_person_job_appointment'
14
- require 'ucb_ldap_org'
15
- require 'ucb_ldap_namespace'
16
- require 'ucb_ldap_address'
17
- require 'ucb_ldap_student_term'
18
- require 'ucb_ldap_affiliation'
19
- require 'ucb_ldap_service'
20
-
21
- module UCB #:nodoc:
22
- ##
23
- # =UCB::LDAP
24
- #
25
- # <b>If you are doing searches that don't require a privileged bind
26
- # and are accessing the default (production) server
27
- # you probably don't need to call any of the methods in this module.</b>
28
- #
29
- # Methods in this module are about making <em>connections</em>
30
- # to the LDAP directory.
31
- #
32
- # Interaction with the directory (searches and updates) is usually through the search()
33
- # and other methods of UCB::LDAP::Entry and its sub-classes.
34
- #
35
- module LDAP
36
-
37
- HOST_PRODUCTION = 'ldap.berkeley.edu'
38
- HOST_TEST = 'ldap-test.berkeley.edu'
39
-
40
- class << self
41
- ##
42
- # Give (new) bind credentials to LDAP. An attempt will be made
43
- # to bind and will raise BindFailedException if bind fails.
44
- #
45
- # Call clear_authentication() to remove privileged bind.
46
- #
47
- def authenticate(username, password)
48
- @username, @password = username, password
49
- new_net_ldap() # to force bind()
50
- end
51
-
52
- ##
53
- # Removes current bind (username, password).
54
- #
55
- def clear_authentication()
56
- authenticate(nil, nil)
57
- end
58
-
59
- ##
60
- # Returns LDAP host used for lookups. Default is HOST_PRODUCTION.
61
- #
62
- def host()
63
- @host || HOST_PRODUCTION
64
- end
65
-
66
- ##
67
- # Setter for #host.
68
- #
69
- # Note: validation of host is deferred until a search is performed
70
- # or #authenticate() is called at which time a bad host will
71
- # raise ConnectionFailedException.
72
- #---
73
- # Don't want to reconnect unless host really changed.
74
- #
75
- def host=(host)
76
- if host != @host
77
- @host = host
78
- @net_ldap = nil
79
- end
80
- end
81
-
82
- ##
83
- # Returns Net::LDAP instance that is used by UCB::LDAP::Entry
84
- # and subclasses for directory searches.
85
- #
86
- # You might need this to perform searches not supported by
87
- # sub-classes of Entry.
88
- #
89
- # Note: callers should not cache the results of this call unless they
90
- # are prepared to handle timed-out connections (which this method does).
91
- #
92
- def net_ldap()
93
- @net_ldap ||= new_net_ldap
94
- end
95
-
96
- def password() #:nodoc:
97
- @password
98
- end
99
-
100
- def username() #:nodoc:
101
- @username
102
- end
103
-
104
- ##
105
- # If you are using UCB::LDAP in a Rails application you can specify binds on a
106
- # per-environment basis, just as you can with database credentials.
107
- #
108
- # # in ../config/ldap.yml
109
- #
110
- # development:
111
- # username: user_dev
112
- # password: pass_dev
113
- #
114
- # # etc.
115
- #
116
- #
117
- # # in ../config/environment.rb
118
- #
119
- # require 'ucb_ldap'
120
- # UCB::LDAP.bind_for_rails()
121
- #
122
- # Runtime error will be raised if bind_file not found or if environment key not
123
- # found in bind_file.
124
- #
125
- def bind_for_rails(bind_file = "#{RAILS_ROOT}/config/ldap.yml", environment = RAILS_ENV)
126
- bind(bind_file, environment)
127
- end
128
-
129
- def bind(bind_file, environment)
130
- raise "Can't find bind file: #{bind_file}" unless FileTest.exists?(bind_file)
131
- binds = YAML.load(IO.read(bind_file))
132
- bind = binds[environment] || raise("Can't find environment=#{environment} in bind file")
133
- authenticate(bind['username'], bind['password'])
134
- end
135
-
136
- ##
137
- # Returns +arg+ as a Ruby +Date+ in local time zone. Returns +nil+ if +arg+ is +nil+.
138
- #
139
- def local_date_parse(arg)
140
- arg.nil? ? nil : Date.parse(Time.parse(arg.to_s).localtime.to_s)
141
- end
142
-
143
- ##
144
- # Returns +arg+ as a Ruby +DateTime+ in local time zone. Returns +nil+ if +arg+ is +nil+.
145
- #
146
- def local_datetime_parse(arg)
147
- arg.nil? ? nil : DateTime.parse(Time.parse(arg.to_s).localtime.to_s)
148
- end
149
-
150
- private unless $TESTING
151
-
152
- ##
153
- # The value of the :auth parameter for Net::LDAP.new().
154
- #
155
- def authentication_information()
156
- password.nil? ?
157
- {:method => :anonymous} :
158
- {:method => :simple, :username => username, :password => password}
159
- end
160
-
161
- ##
162
- # Returns +true+ if connection simple search works.
163
- #
164
- def ldap_ping()
165
- search_attrs = {
166
- :base => "",
167
- :scope => Net::LDAP::SearchScope_BaseObject,
168
- :attributes => [1.1]
169
- }
170
- result = false
171
- @net_ldap.search(search_attrs) { result = true }
172
- result
173
- end
174
-
175
- ##
176
- # Returns new Net::LDAP instance.
177
- #
178
- def new_net_ldap()
179
- params = {
180
- :host => host,
181
- :auth => authentication_information,
182
- :port => 636,
183
- :encryption => {:method =>:simple_tls}
184
- }
185
- @net_ldap = Net::LDAP.new(params)
186
- @net_ldap.bind || raise(BindFailedException)
187
- @net_ldap
188
- rescue Net::LDAP::LdapError => e
189
- raise(BindFailedException)
190
- end
191
-
192
- ##
193
- # Used for testing
194
- #
195
- def clear_instance_variables()
196
- @host = nil
197
- @net_ldap = nil
198
- @username = nil
199
- @password = nil
200
- end
201
- end
202
- end
203
- end
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