class Treequel::Schema
This is an object that is used to parse and query a directory's schema
Authors¶ ↑
-
Michael Granger <ged@FaerieMUD.org>
-
Mahlon E. Smith <mahlon@martini.nu>
Copyright © 2008-2016, Michael Granger and Mahlon E. Smith All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
Neither the name of the author/s, nor the names of the project's contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This is a collection of classes for representing objectClasses in a Treequel::Schema
.
Authors¶ ↑
-
Michael Granger <ged@FaerieMUD.org>
-
Mahlon E. Smith <mahlon@martini.nu>
Copyright © 2008-2016, Michael Granger and Mahlon E. Smith All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
Neither the name of the author/s, nor the names of the project's contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Constants
- OBJECTCLASS_TYPES
The types of objectClass as specified in the schema, along with which Ruby class corresponds to it. Each class registers itself as it's defined.
Attributes
The hash of Treequel::Schema::AttributeType
objects, keyed by OID and any associated NAME attributes (as Symbols), that describe the attributeTypes in the directory's schema.
The hash of Treequel::Schema::LDAPSyntax
objects, keyed by OID, that describe the syntaxes in the directory's schema.
The hash of Treequel::Schema::MatchingRuleUse
objects, keyed by OID and any associated NAME attributes (as Symbols), that describe the attributes to which a matchingRule can be applied.
The hash of Treequel::Schema::MatchingRuleUse
objects, keyed by OID and any associated NAME attributes (as Symbols), that describe the attributes to which a matchingRule can be applied.
The hash of Treequel::Schema::MatchingRule
objects, keyed by OID and any associated NAME attributes (as Symbols), that describe the matchingRules int he directory's schema.
The table of Treequel::Schema::ObjectClass
objects, keyed by OID and any associated NAME attributes (as Symbols), that describes the objectClasses in the directory's schema.
Public Class Methods
Create a new Treequel::Schema
from the specified hash
. The hash
should be of the same form as the one returned by LDAP::Conn.schema, i.e., a Hash of Arrays associated with the keys “objectClasses”, “ldapSyntaxes”, “matchingRuleUse”, “attributeTypes”, and “matchingRules”.
# File lib/treequel/schema.rb, line 177 def initialize( hash ) @object_classes = self.parse_objectclasses( hash['objectClasses'] || [] ) @attribute_types = self.parse_attribute_types( hash['attributeTypes'] || [] ) @ldap_syntaxes = self.parse_ldap_syntaxes( hash['ldapSyntaxes'] || [] ) @matching_rules = self.parse_matching_rules( hash['matchingRules'] || [] ) @matching_rule_uses = self.parse_matching_rule_uses( hash['matchingRuleUse'] || [] ) end
Return a description of the given oids
suitable for inclusion in an RFC4512-style schema description entry.
# File lib/treequel/schema.rb, line 158 def self::oids( *oids ) oids.flatten! if oids.length > 1 return "( %s )" % [ oids.join(" $ ") ] else return oids.first end end
Parse the given short names
string (a 'qdescrs' in the BNF) into an Array of zero or more Strings.
# File lib/treequel/schema.rb, line 97 def self::parse_names( names ) # Treequel.logger.debug " parsing NAME attribute from: %p" % [ names ] # Unspecified if names.nil? # Treequel.logger.debug " no NAME attribute" return [] # Multi-value elsif names =~ /#{LPAREN} #{WSP} (#{QDESCRLIST}) #{WSP} #{RPAREN}/x # Treequel.logger.debug " parsing a NAME list from %p" % [ $1 ] return $1.scan( QDESCR ).collect {|qd| qd[1..-2].untaint.to_sym } # Single-value else # Return the name without the quotes # Treequel.logger.debug " dequoting a single NAME" return [ names[1..-2].untaint.to_sym ] end end
Parse a single OID into either a numeric OID string or a Symbol.
# File lib/treequel/schema.rb, line 86 def self::parse_oid( oidstring ) if oidstring =~ NUMERICOID return oidstring.untaint else return oidstring.untaint.to_sym end end
Parse the given oidstring
into an Array of OIDs, with Strings for numeric OIDs and Symbols for aliases.
# File lib/treequel/schema.rb, line 61 def self::parse_oids( oidstring ) return [] unless oidstring unless /^ #{OIDS} $/x.match( oidstring.strip ) raise Treequel::ParseError, "couldn't find an OIDLIST in %p" % [ oidstring ] end oids = $MATCH # Treequel.logger.debug " found OIDs: %p" % [ oids ] # If it's an OIDLIST, strip off leading and trailing parens and whitespace, then split # on ' $ ' and parse each OID if oids.include?( '$' ) parse_oid = self.method( :parse_oid ) return $MATCH[1..-2].strip.split( /#{WSP} #{DOLLAR} #{WSP}/x ).collect( &parse_oid ) else return [ self.parse_oid(oids) ] end end
Return a description of the given descriptors
suitable for inclusion in an RFC4512-style schema description entry.
# File lib/treequel/schema.rb, line 129 def self::qdescrs( *descriptors ) descriptors.flatten! if descriptors.length > 1 return "( %s )" % [ descriptors.collect {|str| self.qdstring(str) }.join(" ") ] else return self.qdstring( descriptors.first ) end end
Escape and quote the specified string
according to the rules in RFC4512/2252.
# File lib/treequel/schema.rb, line 151 def self::qdstring( string ) return "'%s'" % [ string.to_s.gsub(/\\/, '\\\\5c').gsub(/'/, '\\\\27') ] end
Set the strict-parsing flag
. Setting this to a true
value causes schema-parsing errors to be propagated to the caller instead of handled by the constructor, which is the default behavior.
# File lib/treequel/schema.rb, line 48 def self::strict_parse_mode=( newval ) @strict_parse_mode = newval ? true : false end
Test whether or not strict-parsing mode is in effect.
# File lib/treequel/schema.rb, line 54 def self::strict_parse_mode? return @strict_parse_mode ? true : false end
Return a new string which is desc
with quotes stripped and any escaped characters un-escaped.
# File lib/treequel/schema.rb, line 121 def self::unquote_desc( desc ) return nil if desc.nil? return desc.gsub( QQ, "'" ).gsub( QS, '\\' )[ 1..-2 ] end
Public Instance Methods
Return a human-readable representation of the object suitable for debugging.
# File lib/treequel/schema.rb, line 228 def inspect return %{#<%s:0x%0x %s>} % [ self.class.name, self.object_id / 2, self.ivar_descriptions.join( ', ' ), ] end
Return the Treequel::Schema::AttributeType
objects that correspond to the operational attributes that are supported by the directory.
# File lib/treequel/schema.rb, line 214 def operational_attribute_types return self.attribute_types.values.find_all {|attrtype| attrtype.operational? }.uniq end
Return the schema as a human-readable english string.
# File lib/treequel/schema.rb, line 220 def to_s parts = [ "Schema:" ] parts << self.ivar_descriptions.collect {|desc| ' ' + desc } return parts.join( $/ ) end
Protected Instance Methods
Return descriptions of the schema's artifacts, and how many of each it has.
# File lib/treequel/schema.rb, line 353 def ivar_descriptions self.instance_variables.sort.collect do |ivar| next unless ivar.respond_to?( :length ) len = self.instance_variable_get( ivar ).length "%d %s" % [ len, ivar.to_s.gsub(/_/, ' ')[1..-1] ] end end
Parse the given attributeType descriptions
into Treequel::Schema::AttributeType
objects and return them as a Hash keyed both by numeric OID and by each of its NAME attributes (if it has any).
# File lib/treequel/schema.rb, line 266 def parse_attribute_types( descriptions ) return descriptions.inject( Treequel::Schema::Table.new ) do |table, desc| begin attrtype = Treequel::Schema::AttributeType.parse( self, desc ) table[ attrtype.oid ] = attrtype attrtype.names.inject( table ) {|h, name| h[name] = attrtype; h } rescue Treequel::ParseError => err if self.class.strict_parse_mode? raise else self.log.warn( err.message ) end end table end end
Parse the given LDAP
syntax descriptions
into Treequel::Schema::LDAPSyntax
objects and return them as a Hash keyed by numeric OID.
# File lib/treequel/schema.rb, line 287 def parse_ldap_syntaxes( descriptions ) descriptions ||= [] return descriptions.inject( Treequel::Schema::Table.new ) do |table, desc| begin syntax = Treequel::Schema::LDAPSyntax.parse( self, desc ) table[ syntax.oid ] = syntax rescue Treequel::ParseError => err if self.class.strict_parse_mode? raise else self.log.warn( err.message ) end end table end end
Parse the given matchingRuleUse descriptions
into Treequel::Schema::MatchingRuleUse
objects and return them as a Hash keyed both by numeric OID and by each of its NAME attributes (if it has any).
# File lib/treequel/schema.rb, line 332 def parse_matching_rule_uses( descriptions ) descriptions ||= [] return descriptions.inject( Treequel::Schema::Table.new ) do |table, desc| begin ruleuse = Treequel::Schema::MatchingRuleUse.parse( self, desc ) table[ ruleuse.oid ] = ruleuse ruleuse.names.inject( table ) {|h, name| h[name] = ruleuse; h } rescue Treequel::ParseError => err if self.class.strict_parse_mode? raise else self.log.warn( err.message ) end end table end end
Parse the given matchingRule descriptions
into Treequel::Schema::MatchingRule
objects and return them as a Hash keyed both by numeric OID and by each of its NAME attributes (if it has any).
# File lib/treequel/schema.rb, line 309 def parse_matching_rules( descriptions ) descriptions ||= [] return descriptions.inject( Treequel::Schema::Table.new ) do |table, desc| begin rule = Treequel::Schema::MatchingRule.parse( self, desc ) table[ rule.oid ] = rule rule.names.inject( table ) {|h, name| h[name] = rule; h } rescue Treequel::ParseError => err if self.class.strict_parse_mode? raise else self.log.warn( err.message ) end end table end end
Parse the given objectClass descriptions
into Treequel::Schema::ObjectClass
objects, and return them as a Hash keyed both by numeric OID and by each of its NAME attributes (if it has any).
# File lib/treequel/schema.rb, line 244 def parse_objectclasses( descriptions ) return descriptions.inject( Treequel::Schema::Table.new ) do |table, desc| begin oc = Treequel::Schema::ObjectClass.parse( self, desc ) table[ oc.oid ] = oc oc.names.inject( table ) {|h, name| h[name] = oc; h } rescue Treequel::ParseError => err if self.class.strict_parse_mode? raise else self.log.warn( err.message ) end end table end end