rom-ldap 0.2.2
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +251 -0
- data/CONTRIBUTING.md +18 -0
- data/README.md +172 -0
- data/TODO.md +33 -0
- data/config/responses.yml +328 -0
- data/lib/dry/monitor/ldap/colorizers/default.rb +17 -0
- data/lib/dry/monitor/ldap/colorizers/rouge.rb +31 -0
- data/lib/dry/monitor/ldap/logger.rb +58 -0
- data/lib/rom-ldap.rb +1 -0
- data/lib/rom/ldap.rb +22 -0
- data/lib/rom/ldap/alias.rb +30 -0
- data/lib/rom/ldap/associations.rb +6 -0
- data/lib/rom/ldap/associations/core.rb +23 -0
- data/lib/rom/ldap/associations/many_to_many.rb +18 -0
- data/lib/rom/ldap/associations/many_to_one.rb +22 -0
- data/lib/rom/ldap/associations/one_to_many.rb +32 -0
- data/lib/rom/ldap/associations/one_to_one.rb +19 -0
- data/lib/rom/ldap/associations/self_ref.rb +35 -0
- data/lib/rom/ldap/attribute.rb +327 -0
- data/lib/rom/ldap/client.rb +185 -0
- data/lib/rom/ldap/client/authentication.rb +118 -0
- data/lib/rom/ldap/client/operations.rb +233 -0
- data/lib/rom/ldap/commands.rb +6 -0
- data/lib/rom/ldap/commands/create.rb +41 -0
- data/lib/rom/ldap/commands/delete.rb +17 -0
- data/lib/rom/ldap/commands/update.rb +35 -0
- data/lib/rom/ldap/constants.rb +193 -0
- data/lib/rom/ldap/dataset.rb +286 -0
- data/lib/rom/ldap/dataset/conversion.rb +62 -0
- data/lib/rom/ldap/dataset/dsl.rb +299 -0
- data/lib/rom/ldap/dataset/persistence.rb +44 -0
- data/lib/rom/ldap/directory.rb +126 -0
- data/lib/rom/ldap/directory/capabilities.rb +71 -0
- data/lib/rom/ldap/directory/entry.rb +200 -0
- data/lib/rom/ldap/directory/env.rb +155 -0
- data/lib/rom/ldap/directory/operations.rb +282 -0
- data/lib/rom/ldap/directory/password.rb +122 -0
- data/lib/rom/ldap/directory/root.rb +187 -0
- data/lib/rom/ldap/directory/tokenization.rb +66 -0
- data/lib/rom/ldap/directory/transactions.rb +31 -0
- data/lib/rom/ldap/directory/vendors/active_directory.rb +129 -0
- data/lib/rom/ldap/directory/vendors/apache_ds.rb +27 -0
- data/lib/rom/ldap/directory/vendors/e_directory.rb +16 -0
- data/lib/rom/ldap/directory/vendors/open_directory.rb +12 -0
- data/lib/rom/ldap/directory/vendors/open_dj.rb +25 -0
- data/lib/rom/ldap/directory/vendors/open_ldap.rb +35 -0
- data/lib/rom/ldap/directory/vendors/three_eight_nine.rb +16 -0
- data/lib/rom/ldap/directory/vendors/unknown.rb +22 -0
- data/lib/rom/ldap/dsl.rb +76 -0
- data/lib/rom/ldap/errors.rb +47 -0
- data/lib/rom/ldap/expression.rb +77 -0
- data/lib/rom/ldap/expression_encoder.rb +174 -0
- data/lib/rom/ldap/extensions.rb +50 -0
- data/lib/rom/ldap/extensions/active_support_notifications.rb +26 -0
- data/lib/rom/ldap/extensions/compatibility.rb +11 -0
- data/lib/rom/ldap/extensions/dsml.rb +165 -0
- data/lib/rom/ldap/extensions/msgpack.rb +23 -0
- data/lib/rom/ldap/extensions/optimised_json.rb +25 -0
- data/lib/rom/ldap/extensions/rails_log_subscriber.rb +38 -0
- data/lib/rom/ldap/formatter.rb +26 -0
- data/lib/rom/ldap/functions.rb +207 -0
- data/lib/rom/ldap/gateway.rb +145 -0
- data/lib/rom/ldap/ldif.rb +74 -0
- data/lib/rom/ldap/ldif/exporter.rb +77 -0
- data/lib/rom/ldap/ldif/importer.rb +95 -0
- data/lib/rom/ldap/mapper_compiler.rb +19 -0
- data/lib/rom/ldap/matchers.rb +69 -0
- data/lib/rom/ldap/message_queue.rb +7 -0
- data/lib/rom/ldap/oid.rb +101 -0
- data/lib/rom/ldap/parsers/abstract_syntax.rb +91 -0
- data/lib/rom/ldap/parsers/attribute.rb +290 -0
- data/lib/rom/ldap/parsers/filter_syntax.rb +133 -0
- data/lib/rom/ldap/pdu.rb +285 -0
- data/lib/rom/ldap/plugin/pagination.rb +145 -0
- data/lib/rom/ldap/plugins.rb +7 -0
- data/lib/rom/ldap/projection_dsl.rb +38 -0
- data/lib/rom/ldap/relation.rb +135 -0
- data/lib/rom/ldap/relation/exporting.rb +72 -0
- data/lib/rom/ldap/relation/reading.rb +461 -0
- data/lib/rom/ldap/relation/writing.rb +64 -0
- data/lib/rom/ldap/responses.rb +17 -0
- data/lib/rom/ldap/restriction_dsl.rb +45 -0
- data/lib/rom/ldap/schema.rb +123 -0
- data/lib/rom/ldap/schema/attributes_inferrer.rb +59 -0
- data/lib/rom/ldap/schema/dsl.rb +13 -0
- data/lib/rom/ldap/schema/inferrer.rb +50 -0
- data/lib/rom/ldap/schema/type_builder.rb +133 -0
- data/lib/rom/ldap/scope.rb +19 -0
- data/lib/rom/ldap/search_request.rb +249 -0
- data/lib/rom/ldap/socket.rb +210 -0
- data/lib/rom/ldap/tasks/ldap.rake +103 -0
- data/lib/rom/ldap/tasks/ldif.rake +80 -0
- data/lib/rom/ldap/transaction.rb +29 -0
- data/lib/rom/ldap/type_map.rb +88 -0
- data/lib/rom/ldap/types.rb +158 -0
- data/lib/rom/ldap/version.rb +17 -0
- data/lib/rom/plugins/relation/ldap/active_directory.rb +182 -0
- data/lib/rom/plugins/relation/ldap/auto_restrictions.rb +69 -0
- data/lib/rom/plugins/relation/ldap/e_directory.rb +27 -0
- data/lib/rom/plugins/relation/ldap/instrumentation.rb +35 -0
- data/lib/rouge/lexers/ldap.rb +72 -0
- data/lib/rouge/themes/ldap.rb +49 -0
- metadata +231 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ROM
|
|
4
|
+
module LDAP
|
|
5
|
+
#
|
|
6
|
+
# Apache Directory Extension
|
|
7
|
+
#
|
|
8
|
+
# @api private
|
|
9
|
+
module ApacheDs
|
|
10
|
+
# IGNORE_ATTRS_REGEX = /^[m-|ads|entry].*$/.freeze
|
|
11
|
+
|
|
12
|
+
# @return [Array]
|
|
13
|
+
#
|
|
14
|
+
# @api public
|
|
15
|
+
def schema_attributes
|
|
16
|
+
query(base: 'ou=schema', filter: '(objectClass=metaAttributeType)')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @return [Array]
|
|
20
|
+
#
|
|
21
|
+
# @api public
|
|
22
|
+
def schemas_classes
|
|
23
|
+
query(base: 'ou=schema', filter: '(objectClass=metaObjectClass)')
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ROM
|
|
4
|
+
module LDAP
|
|
5
|
+
#
|
|
6
|
+
# OpenDJ Server Extension
|
|
7
|
+
#
|
|
8
|
+
# @api private
|
|
9
|
+
module OpenDj
|
|
10
|
+
# @return [String]
|
|
11
|
+
#
|
|
12
|
+
# @api public
|
|
13
|
+
def full_vendor_version
|
|
14
|
+
root.first('fullVendorVersion')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @return [String]
|
|
18
|
+
#
|
|
19
|
+
# @api public
|
|
20
|
+
def etag
|
|
21
|
+
root.first('etag')
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ROM
|
|
4
|
+
module LDAP
|
|
5
|
+
#
|
|
6
|
+
# OpenLDAP Extension
|
|
7
|
+
#
|
|
8
|
+
# @api private
|
|
9
|
+
module OpenLdap
|
|
10
|
+
#
|
|
11
|
+
# @return [String]
|
|
12
|
+
#
|
|
13
|
+
# @api public
|
|
14
|
+
def vendor_name
|
|
15
|
+
'OpenLDAP'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# @return [String]
|
|
20
|
+
#
|
|
21
|
+
# @api public
|
|
22
|
+
def vendor_version
|
|
23
|
+
'0.0'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# @return [String]
|
|
28
|
+
#
|
|
29
|
+
# @api public
|
|
30
|
+
def organization
|
|
31
|
+
query(base: contexts[0]).first.first('o')
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ROM
|
|
4
|
+
module LDAP
|
|
5
|
+
# @api private
|
|
6
|
+
module Unknown
|
|
7
|
+
# @return [String]
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
def vendor_name
|
|
11
|
+
'Unknown'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# @return [String]
|
|
15
|
+
#
|
|
16
|
+
# @api public
|
|
17
|
+
def vendor_version
|
|
18
|
+
'Unknown'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/lib/rom/ldap/dsl.rb
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'concurrent/map'
|
|
4
|
+
require 'rom/support/inflector'
|
|
5
|
+
require 'rom/constants'
|
|
6
|
+
require 'rom/ldap/types'
|
|
7
|
+
|
|
8
|
+
module ROM
|
|
9
|
+
module LDAP
|
|
10
|
+
# @api private
|
|
11
|
+
class DSL < BasicObject
|
|
12
|
+
|
|
13
|
+
# @!attribute [r] schema
|
|
14
|
+
# @return [LDAP::Schema]
|
|
15
|
+
attr_reader :schema
|
|
16
|
+
|
|
17
|
+
# @!attribute [r] relations
|
|
18
|
+
# @return [Hash, RelationRegistry]
|
|
19
|
+
attr_reader :relations
|
|
20
|
+
|
|
21
|
+
# @!attribute [r] picked_relations
|
|
22
|
+
# @return [Concurrent::Map]
|
|
23
|
+
attr_reader :picked_relations
|
|
24
|
+
|
|
25
|
+
# @api private
|
|
26
|
+
def initialize(schema)
|
|
27
|
+
@schema = schema
|
|
28
|
+
@relations = schema.respond_to?(:relations) ? schema.relations : EMPTY_HASH
|
|
29
|
+
@picked_relations = ::Concurrent::Map.new
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @api private
|
|
33
|
+
def call(&block)
|
|
34
|
+
result = instance_exec(select_relations(block.parameters), &block)
|
|
35
|
+
|
|
36
|
+
if result.is_a?(::Array)
|
|
37
|
+
result
|
|
38
|
+
else
|
|
39
|
+
[result]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @api private
|
|
44
|
+
def respond_to_missing?(name, include_private = false)
|
|
45
|
+
super || schema.key?(name)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
# @api private
|
|
51
|
+
def type(identifier)
|
|
52
|
+
type_name = Inflector.classify(identifier)
|
|
53
|
+
types.const_get(type_name) if types.const_defined?(type_name)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @api private
|
|
57
|
+
def types
|
|
58
|
+
::ROM::LDAP::Types
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @api private
|
|
62
|
+
def select_relations(parameters)
|
|
63
|
+
@picked_relations.fetch_or_store(parameters.hash) do
|
|
64
|
+
keys = parameters.select { |type, _| type == :keyreq }
|
|
65
|
+
|
|
66
|
+
if keys.empty?
|
|
67
|
+
relations
|
|
68
|
+
else
|
|
69
|
+
keys.each_with_object({}) { |(_, k), rs| rs[k] = relations[k] }
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ROM
|
|
4
|
+
module LDAP
|
|
5
|
+
# @see ROM::LDAP::Gateway
|
|
6
|
+
#
|
|
7
|
+
# @see ROM::LDAP::Schema::Inferrer
|
|
8
|
+
#
|
|
9
|
+
CONNECTION_FAILURES = [
|
|
10
|
+
EOFError,
|
|
11
|
+
Errno::ECONNABORTED,
|
|
12
|
+
Errno::ECONNREFUSED,
|
|
13
|
+
Errno::ECONNRESET,
|
|
14
|
+
Errno::EHOSTUNREACH,
|
|
15
|
+
Errno::EIO,
|
|
16
|
+
Errno::ENETDOWN,
|
|
17
|
+
Errno::ENETRESET,
|
|
18
|
+
Errno::EPIPE,
|
|
19
|
+
Errno::ETIMEDOUT,
|
|
20
|
+
IOError
|
|
21
|
+
].freeze
|
|
22
|
+
|
|
23
|
+
# @see Client::Authentication#bind
|
|
24
|
+
#
|
|
25
|
+
BindError = Class.new(StandardError)
|
|
26
|
+
|
|
27
|
+
# @see Client::Authentication#sasl_bind
|
|
28
|
+
#
|
|
29
|
+
SecureBindError = Class.new(StandardError)
|
|
30
|
+
|
|
31
|
+
# @see Client#submit
|
|
32
|
+
#
|
|
33
|
+
ResponseError = Class.new(StandardError)
|
|
34
|
+
|
|
35
|
+
# @see Directory::Operations#find, #by_dn, #add
|
|
36
|
+
#
|
|
37
|
+
DistinguishedNameError = Class.new(StandardError)
|
|
38
|
+
|
|
39
|
+
# @see Socket#connect
|
|
40
|
+
#
|
|
41
|
+
ConnectionError = Class.new(StandardError)
|
|
42
|
+
|
|
43
|
+
# @see Directory::Password#generate
|
|
44
|
+
#
|
|
45
|
+
PasswordError = Class.new(StandardError)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ROM
|
|
4
|
+
module LDAP
|
|
5
|
+
# @api private
|
|
6
|
+
class Expression
|
|
7
|
+
|
|
8
|
+
extend Initializer
|
|
9
|
+
|
|
10
|
+
option :op, type: Types::Abstract
|
|
11
|
+
|
|
12
|
+
option :field, optional: true, type: Types::Field
|
|
13
|
+
|
|
14
|
+
option :value, optional: true, type: Types::Value
|
|
15
|
+
|
|
16
|
+
option :exps, optional: true, type: Types::Array.of(Types.Instance(Expression))
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
#
|
|
20
|
+
# @return [String]
|
|
21
|
+
#
|
|
22
|
+
# @api public
|
|
23
|
+
def to_ber
|
|
24
|
+
require 'rom/ldap/expression_encoder'
|
|
25
|
+
ExpressionEncoder.new(options).call
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Unbracketed filter string
|
|
29
|
+
#
|
|
30
|
+
# @return [String]
|
|
31
|
+
#
|
|
32
|
+
def to_raw_filter
|
|
33
|
+
case op
|
|
34
|
+
when :op_eql, :op_bineq then "#{field}=#{value}"
|
|
35
|
+
when :op_ext then "#{field}:=#{value}"
|
|
36
|
+
when :op_gte then "#{field}>=#{value}"
|
|
37
|
+
when :op_lte then "#{field}<=#{value}"
|
|
38
|
+
when :op_prx then "#{field}~=#{value}"
|
|
39
|
+
when :con_and then "&#{exps.map(&:to_filter).join}"
|
|
40
|
+
when :con_or then "|#{exps.map(&:to_filter).join}"
|
|
41
|
+
when :con_not then "!#{exps[0].to_filter}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Bracketed filter string
|
|
46
|
+
#
|
|
47
|
+
# @return [String]
|
|
48
|
+
#
|
|
49
|
+
def to_filter
|
|
50
|
+
"(#{to_raw_filter})"
|
|
51
|
+
end
|
|
52
|
+
alias_method :to_s, :to_filter
|
|
53
|
+
|
|
54
|
+
# AST with original atrributes and values
|
|
55
|
+
#
|
|
56
|
+
# @return [Array]
|
|
57
|
+
#
|
|
58
|
+
def to_ast
|
|
59
|
+
case op
|
|
60
|
+
when :con_and then [op, exps.map(&:to_ast)]
|
|
61
|
+
when :con_or then [op, exps.map(&:to_ast)]
|
|
62
|
+
when :con_not then [op, exps[0].to_ast]
|
|
63
|
+
else
|
|
64
|
+
[op, field, value]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
alias_method :to_a, :to_ast
|
|
68
|
+
|
|
69
|
+
# @return [String]
|
|
70
|
+
#
|
|
71
|
+
def inspect
|
|
72
|
+
%(#<#{self.class} #{to_raw_filter} />)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ROM
|
|
4
|
+
module LDAP
|
|
5
|
+
# Used in ROM::LDAP::Expression#to_ber.
|
|
6
|
+
#
|
|
7
|
+
# Filter ::=
|
|
8
|
+
# CHOICE {
|
|
9
|
+
# and [0] SET OF Filter,
|
|
10
|
+
# or [1] SET OF Filter,
|
|
11
|
+
# not [2] Filter,
|
|
12
|
+
# equalityMatch [3] AttributeValueAssertion,
|
|
13
|
+
# substrings [4] SubstringFilter,
|
|
14
|
+
# greaterOrEqual [5] AttributeValueAssertion,
|
|
15
|
+
# lessOrEqual [6] AttributeValueAssertion,
|
|
16
|
+
# present [7] AttributeType,
|
|
17
|
+
# approxMatch [8] AttributeValueAssertion,
|
|
18
|
+
# extensibleMatch [9] MatchingRuleAssertion
|
|
19
|
+
# }
|
|
20
|
+
#
|
|
21
|
+
# SubstringFilter ::=
|
|
22
|
+
# SEQUENCE {
|
|
23
|
+
# type AttributeType,
|
|
24
|
+
# SEQUENCE OF CHOICE {
|
|
25
|
+
# initial [0] LDAPString,
|
|
26
|
+
# any [1] LDAPString,
|
|
27
|
+
# final [2] LDAPString
|
|
28
|
+
# }
|
|
29
|
+
# }
|
|
30
|
+
#
|
|
31
|
+
# MatchingRuleAssertion ::=
|
|
32
|
+
# SEQUENCE {
|
|
33
|
+
# matchingRule [1] MatchingRuleId OPTIONAL,
|
|
34
|
+
# type [2] AttributeDescription OPTIONAL,
|
|
35
|
+
# matchValue [3] AssertionValue,
|
|
36
|
+
# dnAttributes [4] BOOLEAN DEFAULT FALSE
|
|
37
|
+
# }
|
|
38
|
+
#
|
|
39
|
+
# Matching Rule Suffixes
|
|
40
|
+
# Less than [.1] or .[lt]
|
|
41
|
+
# Less than or equal to [.2] or [.lte]
|
|
42
|
+
# Equality [.3] or [.eq] (default)
|
|
43
|
+
# Greater than or equal to [.4] or [.gte]
|
|
44
|
+
# Greater than [.5] or [.gt]
|
|
45
|
+
# Substring [.6] or [.sub]
|
|
46
|
+
#
|
|
47
|
+
#
|
|
48
|
+
# @api private
|
|
49
|
+
class ExpressionEncoder
|
|
50
|
+
|
|
51
|
+
using ::BER
|
|
52
|
+
|
|
53
|
+
extend Initializer
|
|
54
|
+
|
|
55
|
+
option :op, type: Types::Abstract
|
|
56
|
+
|
|
57
|
+
option :field, optional: true, type: Types::Field
|
|
58
|
+
option :value, optional: true, type: Types::Value
|
|
59
|
+
option :exps, optional: true, type: Types::Array.of(Types.Instance(LDAP::Expression))
|
|
60
|
+
|
|
61
|
+
# @return [BER]
|
|
62
|
+
#
|
|
63
|
+
def call
|
|
64
|
+
case op
|
|
65
|
+
when :op_eql
|
|
66
|
+
if value == WILDCARD
|
|
67
|
+
field.to_s.to_ber_contextspecific(7)
|
|
68
|
+
elsif /[*]/.match?(value.to_s) # substring
|
|
69
|
+
substring
|
|
70
|
+
else
|
|
71
|
+
to_context(3)
|
|
72
|
+
end
|
|
73
|
+
when :op_bineq
|
|
74
|
+
[
|
|
75
|
+
field.to_s.to_ber,
|
|
76
|
+
unescape(value).to_ber_bin
|
|
77
|
+
].to_ber_contextspecific(3)
|
|
78
|
+
when :op_ext
|
|
79
|
+
extensible
|
|
80
|
+
when :op_gte
|
|
81
|
+
to_context(5)
|
|
82
|
+
when :op_lte
|
|
83
|
+
to_context(6)
|
|
84
|
+
when :op_prx
|
|
85
|
+
to_context(8)
|
|
86
|
+
when :con_and
|
|
87
|
+
exps.map(&:to_ber).to_ber_contextspecific(0)
|
|
88
|
+
when :con_or
|
|
89
|
+
exps.map(&:to_ber).to_ber_contextspecific(1)
|
|
90
|
+
when :con_not
|
|
91
|
+
exps.map(&:to_ber).to_ber_contextspecific(2)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
def substring
|
|
98
|
+
ary = value.split(/[*]+/, -1)
|
|
99
|
+
|
|
100
|
+
if ary.first.empty?
|
|
101
|
+
first = nil
|
|
102
|
+
ary.shift
|
|
103
|
+
else
|
|
104
|
+
first = unescape(ary.shift).to_ber_contextspecific(0)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
if ary.last.empty?
|
|
108
|
+
last = nil
|
|
109
|
+
ary.pop
|
|
110
|
+
else
|
|
111
|
+
last = unescape(ary.pop).to_ber_contextspecific(2)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
seq = ary.map { |e| unescape(e).to_ber_contextspecific(1) }
|
|
115
|
+
seq.unshift(first) if first
|
|
116
|
+
seq.push(last) if last
|
|
117
|
+
|
|
118
|
+
[
|
|
119
|
+
field.to_s.to_ber,
|
|
120
|
+
seq.to_ber
|
|
121
|
+
].to_ber_contextspecific(4)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def extensible
|
|
125
|
+
raise(Error, "Bad attribute #{field}") unless field =~ EXTENSIBLE_REGEX
|
|
126
|
+
|
|
127
|
+
type = Regexp.last_match(1)
|
|
128
|
+
dn = Regexp.last_match(2)
|
|
129
|
+
rule = Regexp.last_match(4)
|
|
130
|
+
|
|
131
|
+
seq = []
|
|
132
|
+
seq << rule.to_ber_contextspecific(1) unless rule.to_s.empty? # matchingRule
|
|
133
|
+
seq << type.to_ber_contextspecific(2) unless type.to_s.empty? # type
|
|
134
|
+
seq << unescape(value).to_ber_contextspecific(3) # matchingValue
|
|
135
|
+
seq << '1'.to_ber_contextspecific(4) unless dn.to_s.empty? # dnAttributes
|
|
136
|
+
|
|
137
|
+
seq.to_ber_contextspecific(9)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Common BER encoding
|
|
141
|
+
#
|
|
142
|
+
# @return [String]
|
|
143
|
+
#
|
|
144
|
+
def to_context(int)
|
|
145
|
+
[
|
|
146
|
+
field.to_s.to_ber,
|
|
147
|
+
unescape(value).to_ber
|
|
148
|
+
].to_ber_contextspecific(int)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# @note
|
|
152
|
+
# Don't attempt to unescape 16 byte binary data assumed to be objectGUIDs.
|
|
153
|
+
# The binary form of 5936AE79-664F-44EA-BCCB-5C39399514C6
|
|
154
|
+
# triggers a BINARY -> UTF-8 conversion error.
|
|
155
|
+
#
|
|
156
|
+
# Converts escaped characters to unescaped characters
|
|
157
|
+
#
|
|
158
|
+
# @example
|
|
159
|
+
# => "\\28"
|
|
160
|
+
#
|
|
161
|
+
# @return [String]
|
|
162
|
+
#
|
|
163
|
+
# @api private
|
|
164
|
+
def unescape(str)
|
|
165
|
+
if str.to_s.length.eql?(16) && str.to_s.encoding.eql?(Encoding::BINARY)
|
|
166
|
+
str
|
|
167
|
+
else
|
|
168
|
+
str.to_s.gsub(UNESCAPE_REGEX) { [Regexp.last_match(1).hex].pack('U') }
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|