rom-ldap 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|