ucb_ldap 2.0.0.pre1 → 2.0.0.pre3

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.
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
@@ -1,8 +1,7 @@
1
-
2
1
  module UCB
3
2
  module LDAP
4
3
  # = UCB::LDAP::StudentTerm
5
- #
4
+ #
6
5
  # This class models a student's term entries in the UCB LDAP directory.
7
6
  #
8
7
  # terms = StudentTerm.find_by_uid("1234") #=> [#<UCB::LDAP::StudentTerm: ...>, ...]
@@ -13,7 +12,7 @@ module UCB
13
12
  # terms = p.student_terms #=> [#<UCB::LDAP::StudentTerm: ...>, ...]
14
13
  #
15
14
  # == Note on Binds
16
- #
15
+ #
17
16
  # You must have a privileged bind and pass your credentials to UCB::LDAP.authenticate()
18
17
  # before performing your StudentTerm search.
19
18
  #
@@ -23,79 +22,78 @@ module UCB
23
22
  def change_datetime
24
23
  UCB::LDAP.local_datetime_parse(berkeleyEduStuChangeDate)
25
24
  end
26
-
25
+
27
26
  def college_code
28
27
  berkeleyEduStuCollegeCode
29
28
  end
30
-
29
+
31
30
  def college_name
32
31
  berkeleyEduStuCollegeName
33
32
  end
34
-
33
+
35
34
  def level_code
36
35
  berkeleyEduStuEduLevelCode
37
36
  end
38
-
37
+
39
38
  def level_name
40
39
  berkeleyEduStuEduLevelName
41
40
  end
42
-
41
+
43
42
  def role_code
44
43
  berkeleyEduStuEduRoleCode
45
44
  end
46
-
45
+
47
46
  def role_name
48
47
  berkeleyEduStuEduRoleName
49
48
  end
50
-
49
+
51
50
  def major_code
52
51
  berkeleyEduStuMajorCode
53
52
  end
54
-
53
+
55
54
  def major_name
56
55
  berkeleyEduStuMajorName
57
56
  end
58
-
57
+
59
58
  def registration_status_code
60
59
  berkeleyEduStuRegStatCode
61
60
  end
62
-
61
+
63
62
  def registration_status_name
64
63
  berkeleyEduStuRegStatName
65
64
  end
66
-
65
+
67
66
  def term_code
68
67
  berkeleyEduStuTermCode
69
68
  end
70
-
69
+
71
70
  def term_name
72
71
  berkeleyEduStuTermName
73
72
  end
74
-
73
+
75
74
  def term_status
76
75
  berkeleyEduStuTermStatus
77
76
  end
78
-
77
+
79
78
  def term_year
80
79
  berkeleyEduStuTermYear
81
80
  end
82
-
81
+
83
82
  def under_graduate_code
84
83
  berkeleyEduStuUGCode
85
84
  end
86
-
87
- class << self
88
- # Returns an Array of JobAppointment for <tt>uid</tt>, sorted by
89
- # record_number().
90
- # Returns an empty Array ([]) if nothing is found.
91
- #
92
- def find_by_uid(uid)
93
- base = "uid=#{uid},ou=people,dc=berkeley,dc=edu"
94
- filter = Net::LDAP::Filter.eq("objectclass", 'berkeleyEduPersonTerm')
95
- search(:base => base, :filter => filter)
96
- end
97
-
85
+
86
+ ##
87
+ # Returns an Array of JobAppointment for <tt>uid</tt>, sorted by
88
+ # record_number().
89
+ # Returns an empty Array ([]) if nothing is found.
90
+ #
91
+ def self.find_by_uid(uid)
92
+ base = "uid=#{uid},ou=people,dc=berkeley,dc=edu"
93
+ filter = Net::LDAP::Filter.eq("objectclass", 'berkeleyEduPersonTerm')
94
+ search(:base => base, :filter => filter)
98
95
  end
96
+
99
97
  end
100
98
  end
101
- end
99
+ end
@@ -0,0 +1,3 @@
1
+ module UcbLdap
2
+ VERSION = "2.0.0.pre3"
3
+ end
@@ -0,0 +1,9 @@
1
+ # Used for testing Rails binds -- these aren't real credentials
2
+ development:
3
+ username: username_development
4
+ password: password_development
5
+
6
+ production:
7
+ username: username_production
8
+ password: password_production
9
+
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require_relative "../lib/ucb_ldap"
4
+
5
+ RSpec.configure do |config|
6
+ # config block
7
+ end
8
+
9
+ $TESTING = true
10
+
11
+ include UCB::LDAP
12
+ UCB::LDAP.host = "ldap-test.berkeley.edu"
13
+
14
+ $binds ||= YAML.load(IO.read("#{File.dirname(__FILE__)}/binds.yml"))
15
+
16
+ def bind_for(bind_key)
17
+ bind = $binds[bind_key] or raise("No bind found for '#{bind_key}'")
18
+ UCB::LDAP.authenticate(bind["username"], bind["password"])
19
+ end
20
+
21
+ def address_bind
22
+ bind_for("address")
23
+ end
24
+
25
+ def job_appointment_bind
26
+ bind_for("job_appointment")
27
+ end
28
+
29
+ def namespace_bind
30
+ bind_for("namespace")
31
+ end
32
+
33
+ def org_bind
34
+ bind_for("org")
35
+ end
36
+
37
+ def affiliation_bind
38
+ bind_for("affiliation")
39
+ end
40
+
41
+ def service_bind
42
+ bind_for("affiliation")
43
+ end
@@ -0,0 +1,54 @@
1
+ require_relative "../spec_helper"
2
+
3
+
4
+ describe "UCB::LDAP::Address" do
5
+ before(:all) do
6
+ address_bind
7
+ end
8
+
9
+ before(:each) do
10
+ # assumes 'sh' has 1 address, 'ba' has 1
11
+ @sh_addresses = Address.find_by_uid('61065')
12
+ @ba_addresses = Address.find_by_uid('230455')
13
+ end
14
+
15
+ after(:all) do
16
+ UCB::LDAP.clear_authentication
17
+ end
18
+
19
+ it "should find addresses by uid" do
20
+ @sh_addresses.should be_instance_of(Array)
21
+ @sh_addresses.first.should be_instance_of(Address)
22
+ @sh_addresses.size.should == 1
23
+
24
+ @ba_addresses.size.should == 1
25
+ end
26
+
27
+ it "should know primary work address" do
28
+ @sh_addresses.first.should be_primary_work_address
29
+
30
+ @ba_addresses.each do |addr|
31
+ addr.should(be_primary_work_address) if addr.berkeleyEduPersonAddressPrimaryFlag
32
+ addr.should_not(be_primary_work_address) if !addr.berkeleyEduPersonAddressPrimaryFlag
33
+ end
34
+ end
35
+
36
+ it "should return addresses in sort order" do
37
+ [@sh_addresses, @ba_addresses].each do |addresses|
38
+ addresses.each_with_index do |addr, i|
39
+ addr.sort_order.should == (i + 1)
40
+ end
41
+ end
42
+ end
43
+
44
+ # it "should print itself" do
45
+ # [@sh_addresses, @ba_addresses].flatten.each do |a|
46
+ # puts "----"
47
+ # a.attributes.keys.sort_by{|k|k.to_s}.each do |k|
48
+ # puts "#{k}: #{a.attributes[k].inspect}"#, a.send(k).inspect
49
+ # end
50
+ # end
51
+ # end
52
+
53
+ end
54
+
@@ -0,0 +1,85 @@
1
+ require_relative "../spec_helper"
2
+
3
+
4
+ describe "UCB::LDAP::Affiliation" do
5
+ before(:all) do
6
+ affiliation_bind
7
+ @uid = "61065"
8
+ @student = Person.find_by_uid(@uid)
9
+ @datetime_string = '20010203040506Z'
10
+ @datetime_expected = '2001-02-02T20:05:06-08:00'
11
+ @date_expected = '2001-02-02'
12
+ end
13
+
14
+ after(:all) do
15
+ UCB::LDAP.clear_authentication
16
+ end
17
+
18
+ it "should find affiliations by uid" do
19
+ Affiliation.find_by_uid(@uid).class.should == Array
20
+ end
21
+
22
+ it "should find affiliations from Person" do
23
+ @student.affiliations.class.should == Array
24
+ end
25
+
26
+ it "should return create_datetime" do
27
+ Affiliation.new({}).create_datetime.should be_nil
28
+ Affiliation.new(:berkeleyEduAffCreateDate => [@datetime_string]).create_datetime.to_s.should == @datetime_expected
29
+ end
30
+
31
+ it "should return expired_by" do
32
+ Affiliation.new({}).expired_by.should be_nil
33
+ Affiliation.new(:berkeleyEduAffExpBy => ['foo']).expired_by.to_s.should == 'foo'
34
+ end
35
+
36
+ it "should return expiration_date" do
37
+ Affiliation.new({}).expiration_date.should be_nil
38
+ Affiliation.new(:berkeleyEduAffExpDate => [@datetime_string]).expiration_date.to_s.should == @date_expected
39
+ end
40
+
41
+ it "should return affiliate_id" do
42
+ Affiliation.new({}).affiliate_id.should be_nil
43
+ Affiliation.new(:berkeleyEduAffID => ['foo']).affiliate_id.to_s.should == 'foo'
44
+ end
45
+
46
+ it "should return affiliate_type" do
47
+ Affiliation.new({}).affiliate_type.should be_nil
48
+ Affiliation.new(:berkeleyEduAffType => ['foo']).affiliate_type.to_s.should == 'foo'
49
+ end
50
+
51
+ it "should return first_name" do
52
+ Affiliation.new({}).first_name.should be_nil
53
+ Affiliation.new(:givenName => ['foo']).first_name.to_s.should == 'foo'
54
+ end
55
+
56
+ it "should return middle_name" do
57
+ Affiliation.new({}).middle_name.should be_nil
58
+ Affiliation.new(:berkeleyEduMiddleName => ['foo']).middle_name.to_s.should == 'foo'
59
+ end
60
+
61
+ it "should return last_name" do
62
+ Affiliation.new({}).last_name.should be_nil
63
+ Affiliation.new(:sn => ['foo']).last_name.to_s.should == 'foo'
64
+ end
65
+
66
+ it "should return modified_by" do
67
+ Affiliation.new({}).modified_by.should be_nil
68
+ Affiliation.new(:berkeleyEduModifiedBy => ['foo']).modified_by.to_s.should == 'foo'
69
+ end
70
+
71
+ it "should return source" do
72
+ Affiliation.new({}).source.should be_nil
73
+ Affiliation.new(:berkeleyEduPersonAffiliateSource => ['foo']).source.to_s.should == 'foo'
74
+ end
75
+
76
+ it "should return dept_code" do
77
+ Affiliation.new({}).dept_code.should be_nil
78
+ Affiliation.new(:departmentNumber => ['foo']).dept_code.to_s.should == 'foo'
79
+ end
80
+
81
+ it "should return dept_name" do
82
+ Affiliation.new({}).dept_name.should be_nil
83
+ Affiliation.new(:berkeleyEduUnitCalNetDeptName => ['foo']).dept_name.to_s.should == 'foo'
84
+ end
85
+ end
@@ -0,0 +1,241 @@
1
+ require_relative '../spec_helper'
2
+
3
+
4
+ describe UCB::LDAP::Entry do
5
+ before(:each) do
6
+ Entry.stub!(:entity_name).and_return("org")
7
+ Entry.schema_attributes_array # force load
8
+ end
9
+
10
+ it "should make canonical attribute names" do
11
+ Entry.canonical("firstLast").should == :firstlast
12
+ Entry.canonical("FIRSTLAST").should == :firstlast
13
+ Entry.canonical(:FIRSTLAST).should == :firstlast
14
+ end
15
+
16
+ it "should return an Array of object_classes" do
17
+ Entry.object_classes.should == %w{top organizationalunit berkeleyEduOrgUnit}
18
+ end
19
+
20
+ it "should return unique object class" do
21
+ Entry.unique_object_class.should == 'berkeleyEduOrgUnit'
22
+ end
23
+
24
+ it "should return an Array of Schema::Attribute" do
25
+ Entry.schema_attributes_array.should be_instance_of(Array)
26
+ Entry.schema_attributes_array[0].should be_instance_of(Schema::Attribute)
27
+ end
28
+
29
+ it "schema_attribute works by name, alias, symbol, any-case version of same" do
30
+ fax_attr = Entry.schema_attributes_array.find { |attr| attr.name == "facsimileTelephoneNumber" }
31
+ fax_attr.aliases.should == ["fax"]
32
+ ["facsimileTelephoneNumber", "facsimiletelephonenumber",
33
+ "fax", "FAX", :fax].each do |version|
34
+ Entry.schema_attribute(version).should equal(fax_attr)
35
+ end
36
+ end
37
+
38
+ it "should raise exception trying to access bad attribute name" do
39
+ lambda { Entry.schema_attribute("bogus") }.should raise_error(BadAttributeNameException)
40
+ end
41
+
42
+ it "should know which of its attributes are required" do
43
+ # commonname is an alias for cn
44
+ # userid is an alias for uid
45
+ # surname is an alias for sn
46
+ # aliases should not show up in the required attributes
47
+ required_person_attributes = [:cn, :objectclass, :sn, :uid]
48
+
49
+ TestPerson = Class.new(Entry)
50
+ TestPerson.stub!(:entity_name).and_return("person")
51
+ TestPerson.required_attributes.length.should == required_person_attributes.length
52
+ TestPerson.required_attributes.each do |attr|
53
+ required_person_attributes.should include(attr)
54
+ end
55
+ end
56
+ end
57
+
58
+
59
+ describe "UCB::LDAP::Entry instance" do
60
+ before(:each) do
61
+ Entry.stub!(:entity_name).and_return("org")
62
+ Entry.schema_attributes_array # force load
63
+ @e = Entry.new("facsimileTelephoneNumber" => ["1", "2"], :dn => ["dn"])
64
+ end
65
+
66
+ it "should make canonical attribute names" do
67
+ @e.canonical("firstLast").should == :firstlast
68
+ @e.canonical("FIRSTLAST").should == :firstlast
69
+ @e.canonical(:FIRSTLAST).should == :firstlast
70
+ end
71
+
72
+ it "should return dn (Distinguished Name)" do
73
+ @e.dn.should == ["dn"]
74
+ end
75
+
76
+ it "should raise NoMethodError if bad attribute name treated like method" do
77
+ lambda { @e.bogus }.should raise_error(NoMethodError)
78
+ end
79
+
80
+ it "should retrieve values by 'official' attribute name as instance method" do
81
+ @e.facsimileTelephoneNumber.should == ["1", "2"]
82
+ end
83
+
84
+ it "should retrieve values by any-cased name as instance method" do
85
+ @e.facsimiletelephonenumber.should == ["1", "2"]
86
+ end
87
+
88
+ it "should retrieve values by alias" do
89
+ @e.fax.should == ["1", "2"]
90
+ end
91
+
92
+ it "should return scalar result for scalars" do
93
+ @e = Entry.new("berkeleyEduOrgUnitProcessUnitFlag" => ["true"])
94
+ @sa = Entry.schema_attribute("berkeleyEduOrgUnitProcessUnitFlag")
95
+ @e.berkeleyEduOrgUnitProcessUnitFlag.should be_true
96
+ end
97
+
98
+ it "should return array result for multi-valued attributes" do
99
+ @e.facsimileTelephoneNumber.should == ["1", "2"]
100
+ end
101
+
102
+ it "setter methods end in '='" do
103
+ @e.send(:setter_method?, :foo=).should be_true
104
+ @e.send(:setter_method?, "foo=").should be_true
105
+ @e.send(:setter_method?, :foo).should be_false
106
+ @e.send(:setter_method?, "foo").should be_false
107
+ end
108
+ end
109
+
110
+
111
+ describe "Setting UCB::LDAP::Namespace attributes" do
112
+ before(:all) do
113
+ namespace_bind # _setup_specs.rb
114
+ end
115
+
116
+ before(:each) do
117
+ @namespace = Namespace.find_by_uid("61065").first
118
+ end
119
+
120
+ after(:all) do
121
+ UCB::LDAP.clear_authentication
122
+ end
123
+
124
+ it "should set assigned attributes when set w/scalar" do
125
+ @namespace.cn = "a_name"
126
+ @namespace.assigned_attributes[:cn].should == ["a_name"]
127
+ end
128
+
129
+ it "should set assigned attributes when set w/array" do
130
+ @namespace.cn = ["a", "b"]
131
+ @namespace.assigned_attributes[:cn].should == ["a", "b"]
132
+ end
133
+
134
+ it "should set assigned attributes when set w/nil" do
135
+ @namespace.cn = nil
136
+ @namespace.assigned_attributes[:cn].should be_nil
137
+ end
138
+
139
+ it "should trim leading/trailing spaces and imbedded newlines" do
140
+ @namespace.cn = " foo\nbar "
141
+ @namespace.assigned_attributes[:cn].should == ['foobar']
142
+ end
143
+
144
+ it "should set modify operations correctly" do
145
+ @namespace.cn = ["CN"]
146
+ @namespace.uid = nil
147
+ @namespace.berkeleyEduServices = ["s1", "s2"]
148
+ @namespace.modify_operations.should == [
149
+ [:replace, :berkeleyeduservices, ["s1", "s2"]],
150
+ [:replace, :cn, ["CN"]],
151
+ [:delete, :uid, nil]
152
+ ]
153
+ end
154
+ end
155
+
156
+
157
+ describe "Updating UCB::LDAP::Namespace entries" do
158
+ before(:all) do
159
+ UCB::LDAP.host == HOST_TEST
160
+ namespace_bind
161
+ end
162
+
163
+ before(:each) do
164
+ @uid = '61065'
165
+ @cn = 'test_add'
166
+ @dn_base = 'ou=names,ou=namespace,dc=berkeley,dc=edu'
167
+ delete_by_cn(@cn)
168
+ end
169
+
170
+ after(:all) do
171
+ UCB::LDAP.clear_authentication
172
+ end
173
+
174
+ def delete_by_cn(cn)
175
+ Namespace.find_by_cn(cn).delete rescue nil
176
+ end
177
+
178
+ def add_entry(cn, services="calnet", method="create")
179
+ dn = "cn=#{cn},#{@dn_base}"
180
+ attrs = { :cn => @cn, :berkeleyEduServices => services, :uid => @uid }
181
+ Namespace.send(method, :dn => dn, :attributes => attrs)
182
+ end
183
+
184
+ it "create should return new entry on success, false on failure" do
185
+ pending "Need to Fix Ldap Permissions"
186
+
187
+ Namespace.find_by_cn(@cn).should be_nil
188
+ ns = add_entry(@cn)
189
+ ns.class.should == Namespace
190
+ ns.cn.should == [@cn]
191
+ ns.services.should == ['calnet']
192
+ add_entry(@cn).should be_false
193
+ end
194
+
195
+ it "create! should return new entry on success, raise error on failure" do
196
+ pending "Need to Fix Ldap Permissions"
197
+
198
+ Namespace.find_by_cn(@cn).should be_nil
199
+ ns = add_entry(@cn, 'calmail', "create!")
200
+ ns.should be_instance_of(Namespace)
201
+ ns.cn.should == [@cn]
202
+ lambda { add_entry(@cn, 'calnet', "create!") }.should raise_error(DirectoryNotUpdatedException)
203
+ end
204
+
205
+ it "update_attributes should return true on success, false on failure" do
206
+ pending "Need to Fix Ldap Permissions"
207
+
208
+ ns = add_entry(@cn)
209
+ ns.services.should == ['calnet']
210
+ ns.update_attributes(:berkeleyEduServices => ['calmail', 'calnet']).should be_true
211
+ ns.services.should == ['calmail', 'calnet']
212
+ ns.update_attributes(:berkeleyEduServices => ["calmail", "calmail"]).should be_false
213
+ end
214
+
215
+ it "update_attributes! should raise error on failure" do
216
+ pending "Need to Fix Ldap Permissions"
217
+
218
+ ns = add_entry(@cn)
219
+ ns.services.should == ['calnet']
220
+ ns.update_attributes!(:berkeleyEduServices => "calmail").should be_true
221
+ ns.services.should == ['calmail']
222
+ lambda { ns.update_attributes!(:berkeleyEduServices => ["calmail", "calmail"]) }.should raise_error(DirectoryNotUpdatedException)
223
+ end
224
+
225
+ it "delete should return true on success and false on failure" do
226
+ pending "Need to Fix Ldap Permissions"
227
+
228
+ ns = add_entry(@cn)
229
+ ns.delete.should be_true
230
+ ns.delete.should be_false
231
+ end
232
+
233
+ it "delete! should return true on success, raise DirectoryNotUpdated on failure" do
234
+ pending "Need to Fix Ldap Permissions"
235
+
236
+ ns = add_entry(@cn)
237
+ ns.delete!.should be_true
238
+ lambda { ns.delete! }.should raise_error(DirectoryNotUpdatedException)
239
+ end
240
+ end
241
+