Class: UCB::LDAP::Entry
- Inherits:
-
Object
- Object
- UCB::LDAP::Entry
- Defined in:
- lib/ucb_ldap/entry.rb
Overview
UCB::LDAP::Entry
Abstract class representing an entry in the UCB LDAP directory. You won’t ever deal with Entry instances, but instead instances of Entry sub-classes.
Accessing LDAP Attributes
You will not see the attributes documented in the instance method section of the documentation for Entry sub-classes, even though you can access them as if they were instance methods.
person = Person.find_by_uid("123") #=> #<UCB::LDAP::Person ..>
people.givenname #=> ["John"]
Entry sub-classes may have convenience methods that allow for accessing attributes by friendly names:
person = Person.person_by_uid("123") #=> #<UCB::LDAP::Person ..>
person.firstname #=> "John"
See the sub-class documentation for specifics.
Single- / Multi-Value Attributes
Attribute values are returned as arrays or scalars based on how they are defined in the LDAP schema.
Entry subclasses may have convenience methods that return scalars even though the schema defines the underlying attribute as multi-valued becuase in practice the are single-valued.
Attribute Types
Attribute values are stored as arrays of strings in LDAP, but when accessed through Entry sub-class methods are returned cast to their Ruby type as defined in the schema. Types are one of:
-
string
-
integer
-
boolean
-
datetime
Missing Attribute Values
If an attribute value is not present, the value returned depends on type and multi/single value field:
-
empty multi-valued attributes return an empty array ([])
-
empty booleans return
false
-
everything else returns
nil
if empty
Attempting to get an attribute value for an invalid attribute name will raise a BadAttributeNameException.
Direct Known Subclasses
Address, Affiliation, JobAppointment, Namespace, Org, Person, Service, StudentTerm
Constant Summary collapse
- TESTING =
false
Class Method Summary collapse
-
.canonical(string_or_symbol) ⇒ Object
Returns the canonical representation of a symbol or string so we can look up attributes in a number of ways.
-
.combine_filters(filters, operator = '&') ⇒ Object
Returns a new Net::LDAP::Filter that is the result of combining filters using operator (filters is an
Array
of Net::LDAP::Filter). -
.create(args) ⇒ Object
Creates and returns new entry.
-
.create!(args) ⇒ Object
Same as #create(), but raises DirectoryNotUpdated on failure.
-
.entity_name ⇒ Object
Schema entity name.
- .filter_in(attribute_name, array_of_values) ⇒ Object
-
.find_by_dn(dn) ⇒ Object
Returns entry whose distinguised name is dn.
-
.make_search_filter(filter) ⇒ Object
Returns Net::LDAP::Filter.
-
.net_ldap ⇒ Object
Returns underlying Net::LDAP instance.
-
.object_classes ⇒ Object
Returns
Array
of object classes making up this type of LDAP entity. -
.required_attributes ⇒ Object
returns an Array of symbols where each symbol is the name of a required attribute for the Entry.
-
.required_schema_attributes ⇒ Object
returns Hash of SchemaAttribute objects that are required for the Entry.
- .schema_attribute(attribute_name) ⇒ Object
-
.schema_attributes_array ⇒ Object
Returns an
Array
of Schema::Attribute for the entity. -
.schema_attributes_hash ⇒ Object
Returns as
Hash
whose keys are the canonical attribute names and whose values are the corresponding Schema::Attributes. -
.search(args = {}) ⇒ Object
Returns Array of UCB::LDAP::Entry for entries matching args.
-
.set_schema_attributes ⇒ Object
Want an array of Schema::Attributes as well as a hash of all possible variations on a name pointing to correct array element.
-
.tree_base ⇒ Object
Returns tree base for LDAP searches.
- .tree_base=(tree_base) ⇒ Object
- .unique_object_class ⇒ Object
Instance Method Summary collapse
- #assigned_attributes ⇒ Object
-
#attributes ⇒ Object
Hash
of attributes returned from underlying NET::LDAP::Entry instance. -
#canonical(string_or_symbol) ⇒ Object
:nodoc:.
-
#dn ⇒ Object
Returns the value of the Distinguished Name attribute.
-
#initialize(net_ldap_entry) ⇒ Entry
constructor
Returns new instance of UCB::LDAP::Entry.
-
#method_missing(method, *args) ⇒ Object
Used to get attribute values.
- #net_ldap ⇒ Object
Constructor Details
#initialize(net_ldap_entry) ⇒ Entry
Returns new instance of UCB::LDAP::Entry. The argument net_ldap_entry is an instance of Net::LDAP::Entry.
You should not need to create any UCB::LDAP::Entry instances; they are created by calls to UCB::LDAP.search and friends.
70 71 72 73 74 75 76 77 78 |
# File 'lib/ucb_ldap/entry.rb', line 70 def initialize(net_ldap_entry) #:nodoc: # Don't store Net::LDAP entry in object since it uses the block # initialization method of Hash which can't be marshalled ... this # means it can't be stored in a Rails session. @attributes = {} net_ldap_entry.each do |attr, value| @attributes[canonical(attr)] = value.map { |v| v.dup } end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
Used to get attribute values.
If we can’t make an attribute name out of method, let regular method_missing() handle it.
117 118 119 120 121 122 123 |
# File 'lib/ucb_ldap/entry.rb', line 117 def method_missing(method, *args) #:nodoc: schema_attribute = self.class.schema_attribute(method) raw_value = attributes[canonical(schema_attribute.name)] schema_attribute.get_value(raw_value) rescue BadAttributeNameException return super end |
Class Method Details
.canonical(string_or_symbol) ⇒ Object
Returns the canonical representation of a symbol or string so we can look up attributes in a number of ways.
304 305 306 |
# File 'lib/ucb_ldap/entry.rb', line 304 def canonical(string_or_symbol) string_or_symbol.to_s.downcase.to_sym end |
.combine_filters(filters, operator = '&') ⇒ Object
Returns a new Net::LDAP::Filter that is the result of combining filters using operator (filters is an Array
of Net::LDAP::Filter).
See Net::LDAP#& and Net::LDAP#| for details.
f1 = Net::LDAP::Filter.eq("lastname", "hansen")
f2 = Net::LDAP::Filter.eq("firstname", "steven")
combine_filters([f1, f2]) # same as: f1 & f2
combine_filters([f1, f2], '|') # same as: f1 | f2
190 191 192 |
# File 'lib/ucb_ldap/entry.rb', line 190 def combine_filters(filters, operator = '&') filters.inject { |accum, filter| accum.send(operator, filter) } end |
.create(args) ⇒ Object
Creates and returns new entry. Returns false
if unsuccessful. Sets :objectclass key of args[:attributes] to object_classes read from schema.
dn = "uid=999999,ou=people,dc=example,dc=com"
attr = {
:uid => "999999",
:mail => "[email protected]"
}
EntrySubClass.create(:dn => dn, :attributes => attr) #=> #<UCB::LDAP::EntrySubClass ..>
Caller is responsible for setting :dn and :attributes correctly, as well as any other validation.
154 155 156 157 158 159 |
# File 'lib/ucb_ldap/entry.rb', line 154 def create(args) args[:attributes][:objectclass] = object_classes result = net_ldap.add(args) result or return false find_by_dn(args[:dn]) end |
.create!(args) ⇒ Object
Same as #create(), but raises DirectoryNotUpdated on failure.
173 174 175 |
# File 'lib/ucb_ldap/entry.rb', line 173 def create!(args) create(args) || raise(DirectoryNotUpdatedException) end |
.entity_name ⇒ Object
Schema entity name. Set in each subclass.
321 322 323 |
# File 'lib/ucb_ldap/entry.rb', line 321 def entity_name @entity_name end |
.filter_in(attribute_name, array_of_values) ⇒ Object
134 135 136 137 |
# File 'lib/ucb_ldap/entry.rb', line 134 def filter_in(attribute_name, array_of_values) filters = array_of_values.map { |value| Net::LDAP::Filter.eq(attribute_name, value) } UCB::LDAP::Entry.combine_filters(filters, '|') end |
.find_by_dn(dn) ⇒ Object
Returns entry whose distinguised name is dn.
163 164 165 166 167 168 169 |
# File 'lib/ucb_ldap/entry.rb', line 163 def find_by_dn(dn) search( :base => dn, :scope => Net::LDAP::SearchScope_BaseObject, :filter => "objectClass=*" ).first end |
.make_search_filter(filter) ⇒ Object
201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/ucb_ldap/entry.rb', line 201 def make_search_filter(filter) return filter if filter.instance_of? Net::LDAP::Filter return filter if filter.instance_of? String filters = [] # sort so result is predictable for unit test filter.keys.sort_by { |symbol| "#{symbol}" }.each do |attr| filters << Net::LDAP::Filter.eq("#{attr}", "#{filter[attr]}") end combine_filters(filters, "&") end |
.net_ldap ⇒ Object
Returns underlying Net::LDAP instance.
311 312 313 |
# File 'lib/ucb_ldap/entry.rb', line 311 def net_ldap #:nodoc: UCB::LDAP.net_ldap end |
.object_classes ⇒ Object
Returns Array
of object classes making up this type of LDAP entity.
215 216 217 |
# File 'lib/ucb_ldap/entry.rb', line 215 def object_classes @object_classes ||= UCB::LDAP::Schema.schema_hash[entity_name]["objectClasses"] end |
.required_attributes ⇒ Object
returns an Array of symbols where each symbol is the name of a required attribute for the Entry
226 227 228 |
# File 'lib/ucb_ldap/entry.rb', line 226 def required_attributes required_schema_attributes.keys end |
.required_schema_attributes ⇒ Object
returns Hash of SchemaAttribute objects that are required for the Entry. Each SchemaAttribute object is keyed to the attribute’s name.
Note: required_schema_attributes will not return aliases, it only returns the original attributes
Example:
Person.required_schema_attribues[:cn]
=> <UCB::LDAP::Schema::Attribute:0x11c6b68>
242 243 244 245 246 247 248 |
# File 'lib/ucb_ldap/entry.rb', line 242 def required_schema_attributes required_atts = schema_attributes_hash.reject { |key, value| !value.required? } required_atts.reject do |key, value| aliases = value.aliases.map { |a| canonical(a) } aliases.include?(key) end end |
.schema_attribute(attribute_name) ⇒ Object
267 268 269 270 |
# File 'lib/ucb_ldap/entry.rb', line 267 def schema_attribute(attribute_name) schema_attributes_hash[canonical(attribute_name)] || raise(BadAttributeNameException, "'#{attribute_name}' is not a recognized attribute name") end |
.schema_attributes_array ⇒ Object
Returns an Array
of Schema::Attribute for the entity.
253 254 255 256 |
# File 'lib/ucb_ldap/entry.rb', line 253 def schema_attributes_array @schema_attributes_array || set_schema_attributes @schema_attributes_array end |
.schema_attributes_hash ⇒ Object
Returns as Hash
whose keys are the canonical attribute names and whose values are the corresponding Schema::Attributes.
262 263 264 265 |
# File 'lib/ucb_ldap/entry.rb', line 262 def schema_attributes_hash @schema_attributes_hash || set_schema_attributes @schema_attributes_hash end |
.search(args = {}) ⇒ Object
Returns Array of UCB::LDAP::Entry for entries matching args. When called from a subclass, returns Array of subclass instances.
See Net::LDAP::search for more information on args.
Most common arguments are :base
and :filter
. Search methods of subclasses have default :base
that can be overriden.
See make_search_filter for :filter
options.
base = "ou=people,dc=berkeley,dc=edu"
entries = UCB::LDAP::Entry.search(:base => base, :filter => {:uid => '123'})
entries = UCB::LDAP::Entry.search(:base => base, :filter => {:sn => 'Doe', :givenname => 'John'}
288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/ucb_ldap/entry.rb', line 288 def search(args={}) args = args.dup args[:base] ||= tree_base args[:filter] = make_search_filter args[:filter] if args[:filter] results = [] net_ldap.search(args) do |entry| results << new(entry) end results end |
.set_schema_attributes ⇒ Object
Want an array of Schema::Attributes as well as a hash of all possible variations on a name pointing to correct array element.
329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/ucb_ldap/entry.rb', line 329 def set_schema_attributes @schema_attributes_array = [] @schema_attributes_hash = {} UCB::LDAP::Schema.schema_hash[entity_name]["attributes"].each do |k, v| sa = UCB::LDAP::Schema::Attribute.new(v.merge("name" => k)) @schema_attributes_array << sa [sa.name, sa.aliases].flatten.each do |name| @schema_attributes_hash[canonical(name)] = sa end end rescue raise "Error loading schema attributes for entity_name '#{entity_name}'" end |
.tree_base ⇒ Object
Returns tree base for LDAP searches. Subclasses each have their own value.
Can be overridden in #search by passing in a :base
parm.
349 350 351 |
# File 'lib/ucb_ldap/entry.rb', line 349 def tree_base @tree_base end |
.tree_base=(tree_base) ⇒ Object
353 354 355 |
# File 'lib/ucb_ldap/entry.rb', line 353 def tree_base=(tree_base) @tree_base = tree_base end |
.unique_object_class ⇒ Object
219 220 221 |
# File 'lib/ucb_ldap/entry.rb', line 219 def unique_object_class @unique_object_class ||= UCB::LDAP::Schema.schema_hash[entity_name]["uniqueObjectClass"] end |
Instance Method Details
#assigned_attributes ⇒ Object
125 126 127 |
# File 'lib/ucb_ldap/entry.rb', line 125 def assigned_attributes @assigned_attributes ||= {} end |
#attributes ⇒ Object
Hash
of attributes returned from underlying NET::LDAP::Entry instance. Hash keys are #canonical attribute names, hash values are attribute values as returned from LDAP, i.e. arrays.
You should most likely be referencing attributes as if they were instance methods rather than directly through this method. See top of this document.
89 90 91 |
# File 'lib/ucb_ldap/entry.rb', line 89 def attributes @attributes end |
#canonical(string_or_symbol) ⇒ Object
:nodoc:
100 101 102 |
# File 'lib/ucb_ldap/entry.rb', line 100 def canonical(string_or_symbol) #:nodoc: self.class.canonical(string_or_symbol) end |
#dn ⇒ Object
Returns the value of the Distinguished Name attribute.
96 97 98 |
# File 'lib/ucb_ldap/entry.rb', line 96 def dn attributes[canonical(:dn)] end |
#net_ldap ⇒ Object
104 105 106 |
# File 'lib/ucb_ldap/entry.rb', line 104 def net_ldap self.class.net_ldap end |