Class: UCB::LDAP::Org
Overview
UCB::LDAP::Org
Class for accessing the Org Unit tree of the UCB LDAP directory.
You can search by specifying your own filter:
e = Org.search(:filter => 'ou=jkasd')
But most of the time you’ll use the find_by_ou() method:
e = Org.find_by_ou('jkasd')
Get attribute values as if the attribute names were instance methods. Values returned reflect the cardinality and type as specified in the LDAP schema.
e = Org.find_by_ou('jkasd')
e.ou #=> ['JKASD']
e.description #=> ['Application Services']
e.berkeleyEduOrgUnitProcessUnitFlag #=> true
Convenience methods are provided that have friendlier names and return scalars for attributes the schema says are mulit-valued, but in practice are single-valued:
e = Org.find_by_ou('jkasd')
e.deptid #=> 'JKASD'
e.name #=> 'Application Services'
e.processing_unit? #=> true
Other methods encapsulate common processing:
e.level #=> 4
e.parent_node #=> #<UCB::LDAP::Org: ...>
e.parent_node.deptid #=> 'VRIST'
e.child_nodes #=> [#<UCB::LDAP::Org: ..>, ...]
You can retrieve people in a department. This will be an Array
of UCB::LDAP::Person.
asd = Org.find_by_ou('jkasd')
asd_staff = asd.persons #=> [#<UCB::LDAP::Person: ...>, ...]
Getting a Node’s Level “n” Code or Name
There are methods that will return the org code and org name at a particular level. They are implemented by method_missing and so are not documented in the instance method section.
o = Org.find_by_ou('jkasd')
o.code #=> 'JKASD'
o.level #=> 4
o.level_4_code #=> 'JKASD'
o.level_3_name #=> 'Info Services & Technology'
o.level_2_code #=> 'AVCIS'
o.level_5_code #=> nil
Dealing With the Entire Org Tree
There are several class methods that simplify most operations involving the entire org tree.
Org.all_nodes()
Returns a Hash
of all org nodes whose keys are deptids and whose values are corresponding Org instances.
# List all nodes alphabetically by department name
nodes_by_name = Org.all_nodes.values.sort_by{|n| n.name.upcase}
nodes_by_name.each do |n|
puts "#{n.deptid} - #{n.name}"
end
Org.flattened_tree()
Returns an Array
of all nodes in hierarchy order.
UCB::LDAP::Org.flattened_tree.each do |node|
puts "#{node.level} #{node.deptid} - #{node.name}"
end
Produces:
1 UCBKL - UC Berkeley Campus
2 AVCIS - Information Sys & Technology
3 VRIST - Info Systems & Technology
4 JFAVC - Office of the CIO
5 JFADM - Assoc VC Off General Ops
4 JGMIP - Museum Informatics Project
4 JHSSC - Social Sci Computing Lab
etc.
Org.root_node()
Returns the root node in the Org Tree.
By recursing down child_nodes you can access the entire org tree:
# display deptid, name and children recursively
def display_node(node)
indent = " " * (node.level - 1)
puts "#{indent} #{node.deptid} - #{node.name}"
node.child_nodes.each{|child| display_node(child)}
end
# start at root node
display_node(Org.root_node)
Caching of Search Results
Calls to any of the following class methods automatically cache the entire Org tree:
-
all_nodes()
-
flattened_tree()
-
root_node()
Subsequent calls to any of these methods return the results from cache and don’t require another LDAP query.
Subsequent calls to find_by_ou() are done against the local cache. Searches done via the #search() method do not use the local cache.
Force loading of the cache by calling load_all_nodes().
Class Method Summary collapse
-
.add_to_flattened_tree(node) ⇒ Object
Adds a node and its children to @flattened_tree.
-
.all_nodes ⇒ Object
Returns a
Hash
of all org nodes whose keys are deptids and whose values are corresponding Org instances. -
.all_nodes_i ⇒ Object
Direct access to instance variables for unit testing.
-
.bind_for_whole_tree ⇒ Object
Use bind that allows for retreiving entire org tree in one search.
-
.build_flattened_tree ⇒ Object
Builds flattened tree.
-
.build_test_node_cache ⇒ Object
Build cache of all nodes.
-
.calculate_all_child_nodes ⇒ Object
Will calculate child_nodes for every node.
- .clear_all_nodes ⇒ Object
-
.find_by_ou(ou) ⇒ Object
(also: org_by_ou)
Returns an instance of Org for the matching ou.
-
.find_by_ou_from_cache(ou) ⇒ Object
Returns an instance of Org from the local if cache exists, else
nil
. -
.flattened_tree(options = {}) ⇒ Object
Returns an
Array
of all nodes in hierarchy order. -
.load_all_nodes ⇒ Object
Loads all org nodes and stores then in Hash returned by all_nodes().
-
.nodes_from_test_cache ⇒ Object
Returns cached nodes if we are testing and have already fetched all the nodes.
-
.root_node ⇒ Object
Returns the root node in the Org Tree.
Instance Method Summary collapse
-
#child_nodes ⇒ Object
Returns
Array
of child nodes, each an instance of Org, sorted by department id. -
#child_nodes_i ⇒ Object
Access to instance variables for testing.
-
#code_or_name_at_level(level, code_or_name) ⇒ Object
Return the level “n” code or name.
-
#deptid ⇒ Object
(also: #code)
Returns the department id.
-
#init_child_nodes ⇒ Object
— Must be public for load_all_nodes().
-
#level ⇒ Object
Returns the entry’s level in the Org Tree.
-
#load_child_nodes ⇒ Object
Loads child nodes for individual node.
-
#method_missing(method, *args) ⇒ Object
Support for method names like level_2_code, level_2_name.
-
#name ⇒ Object
Returns the department name.
-
#parent_deptid ⇒ Object
Returns parent node’s deptid.
-
#parent_deptids ⇒ Object
Returns Array of parent deptids.
-
#parent_node ⇒ Object
Return parent node which is an instance of Org.
-
#parent_nodes ⇒ Object
Returns
Array
of parent nodes which are instances of Org. -
#persons ⇒ Object
Returns
Array
of UCB::LDAP::Person instances for each person in the org node. -
#processing_unit? ⇒ Boolean
Returns
true
if org is a processing unit. -
#push_child_node(child_node) ⇒ Object
— Add node to child node array.
Methods inherited from Entry
#attributes, #canonical, canonical, combine_filters, create, create!, #delete, #delete!, #dn, entity_name, find_by_dn, hydrate, #initialize, make_search_filter, #modify, #modify_operations, #net_ldap, net_ldap, #new_record?, object_classes, required_attributes, schema_attribute, schema_attributes_array, schema_attributes_hash, search, set_schema_attributes, #setter_method?, #tainted_attributes, tree_base, tree_base=, unique_object_class, #update_attributes, #update_attributes!, #value_getter, #value_setter
Constructor Details
This class inherits a constructor from UCB::LDAP::Entry
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
Support for method names like level_2_code, level_2_name
196 197 198 199 |
# File 'lib/ucb_ldap_org.rb', line 196 def method_missing(method, *args) #:nodoc: return code_or_name_at_level($1, $2) if method.to_s =~ /^level_([1-6])_(code|name)$/ super end |
Class Method Details
.add_to_flattened_tree(node) ⇒ Object
Adds a node and its children to @flattened_tree.
350 351 352 353 |
# File 'lib/ucb_ldap_org.rb', line 350 def add_to_flattened_tree(node) @flattened_tree.push node node.child_nodes.each{|child| add_to_flattened_tree child} end |
.all_nodes ⇒ Object
Returns a Hash
of all org nodes whose keys are deptids and whose values are corresponding Org instances.
250 251 252 |
# File 'lib/ucb_ldap_org.rb', line 250 def all_nodes @all_nodes ||= load_all_nodes end |
.all_nodes_i ⇒ Object
Direct access to instance variables for unit testing
357 358 359 |
# File 'lib/ucb_ldap_org.rb', line 357 def all_nodes_i @all_nodes end |
.bind_for_whole_tree ⇒ Object
Use bind that allows for retreiving entire org tree in one search.
302 303 304 305 306 |
# File 'lib/ucb_ldap_org.rb', line 302 def bind_for_whole_tree username = "uid=istaswa-ruby,ou=applications,dc=berkeley,dc=edu" password = "t00lBox12" UCB::LDAP.authenticate(username, password) end |
.build_flattened_tree ⇒ Object
Builds flattened tree. See RDoc for flattened_tree() for details.
342 343 344 345 346 347 |
# File 'lib/ucb_ldap_org.rb', line 342 def build_flattened_tree load_all_nodes @flattened_tree = [] add_to_flattened_tree UCB::LDAP::Org.root_node @flattened_tree end |
.build_test_node_cache ⇒ Object
Build cache of all nodes. Only used during testing.
325 326 327 328 |
# File 'lib/ucb_ldap_org.rb', line 325 def build_test_node_cache() @test_node_cache = {} @all_nodes.each{|k, v| @test_node_cache[k] = v.clone} end |
.calculate_all_child_nodes ⇒ Object
Will calculate child_nodes for every node.
331 332 333 334 335 336 337 338 339 |
# File 'lib/ucb_ldap_org.rb', line 331 def calculate_all_child_nodes @all_nodes.values.each{|node| node.init_child_nodes} @all_nodes.values.each do |node| next if node.deptid == 'UCBKL' || node.deptid == "Org Units" parent_node = find_by_ou_from_cache node.parent_deptids.last parent_node.push_child_node node end end |
.clear_all_nodes ⇒ Object
361 362 363 |
# File 'lib/ucb_ldap_org.rb', line 361 def clear_all_nodes @all_nodes = nil end |
.find_by_ou(ou) ⇒ Object Also known as: org_by_ou
Returns an instance of Org for the matching ou.
255 256 257 |
# File 'lib/ucb_ldap_org.rb', line 255 def find_by_ou(ou) find_by_ou_from_cache(ou) || search(:filter => {:ou => ou}).first end |
.find_by_ou_from_cache(ou) ⇒ Object
Returns an instance of Org from the local if cache exists, else nil
.
309 310 311 312 313 |
# File 'lib/ucb_ldap_org.rb', line 309 def find_by_ou_from_cache(ou) #:nodoc: return nil if ou.nil? return nil unless @all_nodes @all_nodes[ou.upcase] end |
.flattened_tree(options = {}) ⇒ Object
268 269 270 271 272 |
# File 'lib/ucb_ldap_org.rb', line 268 def flattened_tree(={}) @flattened_tree ||= build_flattened_tree return @flattened_tree unless [:level] @flattened_tree.reject{|o| o.level > [:level]} end |
.load_all_nodes ⇒ Object
Loads all org nodes and stores then in Hash returned by all_nodes(). Subsequent calls to find_by_ou() will be from cache and not require a trip to the LDAP server.
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/ucb_ldap_org.rb', line 277 def load_all_nodes return @all_nodes if @all_nodes return nodes_from_test_cache if $TESTING && @test_node_cache @all_nodes = {} bind_for_whole_tree search(:filter => 'ou=*', :base => @tree_base).each do |org| @all_nodes[org.deptid] = org unless org.deptid == "Org Units" end build_test_node_cache if $TESTING calculate_all_child_nodes UCB::LDAP.clear_authentication @all_nodes end |
.nodes_from_test_cache ⇒ Object
Returns cached nodes if we are testing and have already fetched all the nodes.
317 318 319 320 321 322 |
# File 'lib/ucb_ldap_org.rb', line 317 def nodes_from_test_cache @all_nodes = {} @test_node_cache.each{|k, v| @all_nodes[k] = v.clone} calculate_all_child_nodes @all_nodes end |
.root_node ⇒ Object
Returns the root node in the Org Tree.
294 295 296 297 |
# File 'lib/ucb_ldap_org.rb', line 294 def root_node load_all_nodes find_by_ou 'UCBKL' end |
Instance Method Details
#child_nodes ⇒ Object
Returns Array
of child nodes, each an instance of Org, sorted by department id.
144 145 146 |
# File 'lib/ucb_ldap_org.rb', line 144 def child_nodes @sorted_child_nodes ||= load_child_nodes.sort_by{|node| node.deptid} end |
#child_nodes_i ⇒ Object
Access to instance variables for testing
240 241 242 |
# File 'lib/ucb_ldap_org.rb', line 240 def child_nodes_i @child_nodes end |
#code_or_name_at_level(level, code_or_name) ⇒ Object
Return the level “n” code or name. Returns nil if level > self.level. Called from method_messing().
203 204 205 206 207 208 |
# File 'lib/ucb_ldap_org.rb', line 203 def code_or_name_at_level(level, code_or_name) #:nodoc: return (code_or_name == 'code' ? code : name) if level.to_i == self.level element = level.to_i - 1 return parent_deptids[element] if code_or_name == 'code' parent_nodes[element] && parent_nodes[element].name end |
#deptid ⇒ Object Also known as: code
Returns the department id.
149 150 151 |
# File 'lib/ucb_ldap_org.rb', line 149 def deptid ou.first end |
#init_child_nodes ⇒ Object
Must be public for load_all_nodes()
218 219 220 |
# File 'lib/ucb_ldap_org.rb', line 218 def init_child_nodes #:nodoc: @child_nodes = [] end |
#level ⇒ Object
Returns the entry’s level in the Org Tree.
155 156 157 |
# File 'lib/ucb_ldap_org.rb', line 155 def level @level ||= parent_deptids.size + 1 end |
#load_child_nodes ⇒ Object
Loads child nodes for individual node. If all_nodes_nodes() has been called, child nodes are all loaded/calculated.
234 235 236 |
# File 'lib/ucb_ldap_org.rb', line 234 def load_child_nodes @child_nodes ||= UCB::LDAP::Org.search(:scope => 1, :base => dn, :filter => {:ou => '*'}) end |
#name ⇒ Object
Returns the department name.
160 161 162 |
# File 'lib/ucb_ldap_org.rb', line 160 def name description.first end |
#parent_deptid ⇒ Object
Returns parent node’s deptid
165 166 167 |
# File 'lib/ucb_ldap_org.rb', line 165 def parent_deptid @parent_deptid ||= parent_deptids.last end |
#parent_deptids ⇒ Object
Returns Array of parent deptids.
Highest level is first element; immediate parent is last element.
172 173 174 175 176 177 |
# File 'lib/ucb_ldap_org.rb', line 172 def parent_deptids return @parent_deptids if @parent_deptids hierarchy_array = berkeleyEduOrgUnitHierarchyString.split("-") hierarchy_array.pop # last element is deptid ... toss it @parent_deptids = hierarchy_array end |
#parent_node ⇒ Object
Return parent node which is an instance of Org.
185 186 187 188 |
# File 'lib/ucb_ldap_org.rb', line 185 def parent_node return nil if parent_deptids.size == 0 @parent_node ||= UCB::LDAP::Org.find_by_ou parent_deptid end |
#parent_nodes ⇒ Object
Returns Array
of parent nodes which are instances of Org.
191 192 193 |
# File 'lib/ucb_ldap_org.rb', line 191 def parent_nodes @parent_nodes ||= parent_deptids.map{|deptid| UCB::LDAP::Org.find_by_ou deptid} end |
#persons ⇒ Object
Returns Array
of UCB::LDAP::Person instances for each person in the org node.
212 213 214 |
# File 'lib/ucb_ldap_org.rb', line 212 def persons @persons ||= UCB::LDAP::Person.search(:filter => {:departmentnumber => ou}) end |
#processing_unit? ⇒ Boolean
Returns true
if org is a processing unit.
180 181 182 |
# File 'lib/ucb_ldap_org.rb', line 180 def processing_unit? berkeleyEduOrgUnitProcessUnitFlag end |
#push_child_node(child_node) ⇒ Object
Add node to child node array.
224 225 226 227 228 |
# File 'lib/ucb_ldap_org.rb', line 224 def push_child_node(child_node)#:nodoc: @child_nodes ||= [] @child_nodes.push(child_node) unless # it already exists @child_nodes.find{|n| n.ou == child_node.ou} end |