rom-ldap 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +251 -0
  3. data/CONTRIBUTING.md +18 -0
  4. data/README.md +172 -0
  5. data/TODO.md +33 -0
  6. data/config/responses.yml +328 -0
  7. data/lib/dry/monitor/ldap/colorizers/default.rb +17 -0
  8. data/lib/dry/monitor/ldap/colorizers/rouge.rb +31 -0
  9. data/lib/dry/monitor/ldap/logger.rb +58 -0
  10. data/lib/rom-ldap.rb +1 -0
  11. data/lib/rom/ldap.rb +22 -0
  12. data/lib/rom/ldap/alias.rb +30 -0
  13. data/lib/rom/ldap/associations.rb +6 -0
  14. data/lib/rom/ldap/associations/core.rb +23 -0
  15. data/lib/rom/ldap/associations/many_to_many.rb +18 -0
  16. data/lib/rom/ldap/associations/many_to_one.rb +22 -0
  17. data/lib/rom/ldap/associations/one_to_many.rb +32 -0
  18. data/lib/rom/ldap/associations/one_to_one.rb +19 -0
  19. data/lib/rom/ldap/associations/self_ref.rb +35 -0
  20. data/lib/rom/ldap/attribute.rb +327 -0
  21. data/lib/rom/ldap/client.rb +185 -0
  22. data/lib/rom/ldap/client/authentication.rb +118 -0
  23. data/lib/rom/ldap/client/operations.rb +233 -0
  24. data/lib/rom/ldap/commands.rb +6 -0
  25. data/lib/rom/ldap/commands/create.rb +41 -0
  26. data/lib/rom/ldap/commands/delete.rb +17 -0
  27. data/lib/rom/ldap/commands/update.rb +35 -0
  28. data/lib/rom/ldap/constants.rb +193 -0
  29. data/lib/rom/ldap/dataset.rb +286 -0
  30. data/lib/rom/ldap/dataset/conversion.rb +62 -0
  31. data/lib/rom/ldap/dataset/dsl.rb +299 -0
  32. data/lib/rom/ldap/dataset/persistence.rb +44 -0
  33. data/lib/rom/ldap/directory.rb +126 -0
  34. data/lib/rom/ldap/directory/capabilities.rb +71 -0
  35. data/lib/rom/ldap/directory/entry.rb +200 -0
  36. data/lib/rom/ldap/directory/env.rb +155 -0
  37. data/lib/rom/ldap/directory/operations.rb +282 -0
  38. data/lib/rom/ldap/directory/password.rb +122 -0
  39. data/lib/rom/ldap/directory/root.rb +187 -0
  40. data/lib/rom/ldap/directory/tokenization.rb +66 -0
  41. data/lib/rom/ldap/directory/transactions.rb +31 -0
  42. data/lib/rom/ldap/directory/vendors/active_directory.rb +129 -0
  43. data/lib/rom/ldap/directory/vendors/apache_ds.rb +27 -0
  44. data/lib/rom/ldap/directory/vendors/e_directory.rb +16 -0
  45. data/lib/rom/ldap/directory/vendors/open_directory.rb +12 -0
  46. data/lib/rom/ldap/directory/vendors/open_dj.rb +25 -0
  47. data/lib/rom/ldap/directory/vendors/open_ldap.rb +35 -0
  48. data/lib/rom/ldap/directory/vendors/three_eight_nine.rb +16 -0
  49. data/lib/rom/ldap/directory/vendors/unknown.rb +22 -0
  50. data/lib/rom/ldap/dsl.rb +76 -0
  51. data/lib/rom/ldap/errors.rb +47 -0
  52. data/lib/rom/ldap/expression.rb +77 -0
  53. data/lib/rom/ldap/expression_encoder.rb +174 -0
  54. data/lib/rom/ldap/extensions.rb +50 -0
  55. data/lib/rom/ldap/extensions/active_support_notifications.rb +26 -0
  56. data/lib/rom/ldap/extensions/compatibility.rb +11 -0
  57. data/lib/rom/ldap/extensions/dsml.rb +165 -0
  58. data/lib/rom/ldap/extensions/msgpack.rb +23 -0
  59. data/lib/rom/ldap/extensions/optimised_json.rb +25 -0
  60. data/lib/rom/ldap/extensions/rails_log_subscriber.rb +38 -0
  61. data/lib/rom/ldap/formatter.rb +26 -0
  62. data/lib/rom/ldap/functions.rb +207 -0
  63. data/lib/rom/ldap/gateway.rb +145 -0
  64. data/lib/rom/ldap/ldif.rb +74 -0
  65. data/lib/rom/ldap/ldif/exporter.rb +77 -0
  66. data/lib/rom/ldap/ldif/importer.rb +95 -0
  67. data/lib/rom/ldap/mapper_compiler.rb +19 -0
  68. data/lib/rom/ldap/matchers.rb +69 -0
  69. data/lib/rom/ldap/message_queue.rb +7 -0
  70. data/lib/rom/ldap/oid.rb +101 -0
  71. data/lib/rom/ldap/parsers/abstract_syntax.rb +91 -0
  72. data/lib/rom/ldap/parsers/attribute.rb +290 -0
  73. data/lib/rom/ldap/parsers/filter_syntax.rb +133 -0
  74. data/lib/rom/ldap/pdu.rb +285 -0
  75. data/lib/rom/ldap/plugin/pagination.rb +145 -0
  76. data/lib/rom/ldap/plugins.rb +7 -0
  77. data/lib/rom/ldap/projection_dsl.rb +38 -0
  78. data/lib/rom/ldap/relation.rb +135 -0
  79. data/lib/rom/ldap/relation/exporting.rb +72 -0
  80. data/lib/rom/ldap/relation/reading.rb +461 -0
  81. data/lib/rom/ldap/relation/writing.rb +64 -0
  82. data/lib/rom/ldap/responses.rb +17 -0
  83. data/lib/rom/ldap/restriction_dsl.rb +45 -0
  84. data/lib/rom/ldap/schema.rb +123 -0
  85. data/lib/rom/ldap/schema/attributes_inferrer.rb +59 -0
  86. data/lib/rom/ldap/schema/dsl.rb +13 -0
  87. data/lib/rom/ldap/schema/inferrer.rb +50 -0
  88. data/lib/rom/ldap/schema/type_builder.rb +133 -0
  89. data/lib/rom/ldap/scope.rb +19 -0
  90. data/lib/rom/ldap/search_request.rb +249 -0
  91. data/lib/rom/ldap/socket.rb +210 -0
  92. data/lib/rom/ldap/tasks/ldap.rake +103 -0
  93. data/lib/rom/ldap/tasks/ldif.rake +80 -0
  94. data/lib/rom/ldap/transaction.rb +29 -0
  95. data/lib/rom/ldap/type_map.rb +88 -0
  96. data/lib/rom/ldap/types.rb +158 -0
  97. data/lib/rom/ldap/version.rb +17 -0
  98. data/lib/rom/plugins/relation/ldap/active_directory.rb +182 -0
  99. data/lib/rom/plugins/relation/ldap/auto_restrictions.rb +69 -0
  100. data/lib/rom/plugins/relation/ldap/e_directory.rb +27 -0
  101. data/lib/rom/plugins/relation/ldap/instrumentation.rb +35 -0
  102. data/lib/rouge/lexers/ldap.rb +72 -0
  103. data/lib/rouge/themes/ldap.rb +49 -0
  104. metadata +231 -0
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ROM
4
+ module LDAP
5
+ MessageQueue = Hash.new { |hash, key| hash[key] = [] }
6
+ end
7
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Layout/HashAlignment
4
+
5
+ module ROM
6
+ module LDAP
7
+ # LDAP OID hash map
8
+ #
9
+ # @see http://oid-info.com/get/{{OID}}
10
+ # @see https://ldap.com/ldap-oid-reference-guide/
11
+ # @see http://ldapwiki.com/wiki/LDAP%20Extensions%20and%20Controls%20Listing
12
+ #
13
+ # @return [Hash]
14
+ #
15
+ # @api private
16
+ #
17
+ OID = {
18
+ matched_values: '1.2.826.0.1.3344810.2.3',
19
+ paged_results: '1.2.840.113556.1.4.319',
20
+ show_deleted: '1.2.840.113556.1.4.417',
21
+ sort_request: '1.2.840.113556.1.4.473',
22
+ sort_response: '1.2.840.113556.1.4.474',
23
+ crossdom_move_target: '1.2.840.113556.1.4.521',
24
+ search_notification: '1.2.840.113556.1.4.528',
25
+ lazy_commit: '1.2.840.113556.1.4.619',
26
+ sd_flags: '1.2.840.113556.1.4.801',
27
+ matching_rule_bit_and: '1.2.840.113556.1.4.803',
28
+ matching_rule_bit_or: '1.2.840.113556.1.4.804',
29
+ delete_tree: '1.2.840.113556.1.4.805',
30
+ directory_sync: '1.2.840.113556.1.4.841',
31
+ verify_name: '1.2.840.113556.1.4.1338',
32
+ domain_scope: '1.2.840.113556.1.4.1339',
33
+ search_options: '1.2.840.113556.1.4.1340',
34
+ permissive_modify: '1.2.840.113556.1.4.1413',
35
+ fast_concurrent_bind: '1.2.840.113556.1.4.1781',
36
+ matching_rule_in_chain: '1.2.840.113556.1.4.1941',
37
+ server_policy_hints: '1.2.840.113556.1.4.2239',
38
+ cancel_operation: '1.3.6.1.1.8',
39
+ assertion: '1.3.6.1.1.12',
40
+ pre_read: '1.3.6.1.1.13.1',
41
+ post_read: '1.3.6.1.1.13.2',
42
+ modify_increment: '1.3.6.1.1.14',
43
+ transaction_start_request: '1.3.6.1.1.21.1',
44
+ transaction_spec_request: '1.3.6.1.1.21.2',
45
+ transaction_end_request: '1.3.6.1.1.21.3',
46
+ dont_use_copy: '1.3.6.1.1.22',
47
+ password_policy_request: '1.3.6.1.4.1.42.2.27.8.5.1',
48
+ get_effective_rights_request: '1.3.6.1.4.1.42.2.27.9.5.2',
49
+ account_usable_request: '1.3.6.1.4.1.42.2.27.9.5.8',
50
+ apple_oid_prefix: '1.3.6.1.4.1.63',
51
+ notice_of_disconnection: '1.3.6.1.4.1.1466.20036',
52
+ start_tls: '1.3.6.1.4.1.1466.20037',
53
+ ns_transmitted: '1.3.6.1.4.1.1466.29539.12',
54
+ dynamic_refresh: '1.3.6.1.4.1.1466.101.119.1',
55
+ all_operational_attributes: '1.3.6.1.4.1.4203.1.5.1',
56
+ oc_ad_lists: '1.3.6.1.4.1.4203.1.5.2',
57
+ true_false_filters: '1.3.6.1.4.1.4203.1.5.3',
58
+ language_tag_options: '1.3.6.1.4.1.4203.1.5.4',
59
+ language_range_options: '1.3.6.1.4.1.4203.1.5.5',
60
+ sync_request: '1.3.6.1.4.1.4203.1.9.1.1',
61
+ sync_state: '1.3.6.1.4.1.4203.1.9.1.2',
62
+ sync_done: '1.3.6.1.4.1.4203.1.9.1.3',
63
+ sync_info_message: '1.3.6.1.4.1.4203.1.9.1.4',
64
+ subentries: '1.3.6.1.4.1.4203.1.10.1',
65
+ password_modify: '1.3.6.1.4.1.4203.1.11.1',
66
+ val_sort: '1.3.6.1.4.1.4203.666.5.14',
67
+ dereference: '1.3.6.1.4.1.4203.666.5.16',
68
+ cascade: '1.3.6.1.4.1.18060.0.0.1',
69
+ launch_diagnostic_ui_request: '1.3.6.1.4.1.18060.0.1.1',
70
+ launch_diagnostic_ui_response: '1.3.6.1.4.1.18060.0.1.2',
71
+ graceful_shutdown_request: '1.3.6.1.4.1.18060.0.1.3',
72
+ graceful_shutdown_response: '1.3.6.1.4.1.18060.0.1.4',
73
+ graceful_disconnect: '1.3.6.1.4.1.18060.0.1.5',
74
+ stored_procedure_request: '1.3.6.1.4.1.18060.0.1.6',
75
+ stored_procedure_response: '1.3.6.1.4.1.18060.0.1.7',
76
+ create_grouping_request: '2.16.840.1.113719.1.27.103.1',
77
+ create_grouping_response: '2.16.840.1.113719.1.27.103.1',
78
+ end_grouping_request: '2.16.840.1.113719.1.27.103.2',
79
+ end_grouping_response: '2.16.840.1.113719.1.27.103.2',
80
+ grouping: '2.16.840.1.113719.1.27.103.7',
81
+ transaction_grouping: '2.16.840.1.113719.1.27.103.8',
82
+ manage_dsa_it: '2.16.840.1.113730.3.4.2',
83
+ persistent_search: '2.16.840.1.113730.3.4.3',
84
+ netscape_password_expired: '2.16.840.1.113730.3.4.4',
85
+ netscape_password_expiring: '2.16.840.1.113730.3.4.5',
86
+ entry_change_notification: '2.16.840.1.113730.3.4.7',
87
+ virtual_list_view_request: '2.16.840.1.113730.3.4.9',
88
+ virtual_list_view_response: '2.16.840.1.113730.3.4.10',
89
+ proxied_authorization_v1: '2.16.840.1.113730.3.4.12',
90
+ replication_update_information: '2.16.840.1.113730.3.4.13',
91
+ search_on_specific_database: '2.16.840.1.113730.3.4.14',
92
+ authentication_response: '2.16.840.1.113730.3.4.15',
93
+ authentication_identity_request: '2.16.840.1.113730.3.4.16',
94
+ real_attribute_only_request: '2.16.840.1.113730.3.4.17',
95
+ proxied_authorization_v2: '2.16.840.1.113730.3.4.18',
96
+ virtual_attributes_only_request: '2.16.840.1.113730.3.4.19'
97
+ }.freeze
98
+ end
99
+ end
100
+
101
+ # rubocop:enable Layout/HashAlignment
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rom/ldap/expression'
4
+
5
+ module ROM
6
+ module LDAP
7
+ module Parsers
8
+ #
9
+ # Parses and AST into and Expression/RFC filter
10
+ #
11
+ # @api private
12
+ class AbstractSyntax
13
+
14
+ extend Initializer
15
+
16
+ param :ast, type: Types::Strict::Array
17
+
18
+ param :attributes, type: Types.Array(Types::Hash)
19
+
20
+ def call
21
+ case ast.size
22
+
23
+ # Join or negate expression
24
+ when 2
25
+ constructor, part = ast
26
+
27
+ expressions =
28
+ if constructor.eql?(:con_not)
29
+ [express(part)]
30
+ else
31
+ part.map(&method(:express))
32
+ end
33
+
34
+ Expression.new(op: constructor, exps: expressions)
35
+
36
+ # Create expression
37
+ when 3
38
+ operator, attribute, value = ast
39
+
40
+ Expression.new(
41
+ op: operator,
42
+ field: decode_attribute(attribute),
43
+ value: decode_value(value)
44
+ )
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ # Express a nested AST
51
+ #
52
+ # @api private
53
+ def express(ast_part)
54
+ self.class.new(ast_part, attributes).call
55
+ end
56
+
57
+ def decode_attribute(name)
58
+ attr = attributes.find { |a| a[:name].eql?(name) }
59
+ attr ? attr[:canonical] : name
60
+ end
61
+
62
+ # Check VALUES_MAP for encoded values otherwise return input.
63
+ #
64
+ # @param sym [Symbol,String] possible special value
65
+ #
66
+ # @return [String] "*", "TRUE", "FALSE"
67
+ #
68
+ def decode_value(sym)
69
+ VALUES_MAP.fetch(sym, sym)
70
+ end
71
+
72
+ # @param sym [Symbol] encoded version
73
+ #
74
+ # @return [Symbol,String]
75
+ #
76
+ def decode_constructor(sym)
77
+ CONSTRUCTORS.fetch(sym, :unknown_constructor)
78
+ end
79
+
80
+ # @param sym [Symbol] encoded version
81
+ #
82
+ # @return [Symbol,String]
83
+ #
84
+ def decode_operator(sym)
85
+ OPERATORS.fetch(sym, :'???')
86
+ end
87
+
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,290 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ROM
4
+ module LDAP
5
+ module Parsers
6
+ #
7
+ # RFC4512 - 4.1.2. Attribute Types
8
+ #
9
+ # @see https://tools.ietf.org/html/rfc4512#section-4.1.2
10
+ #
11
+ # Attribute Type definitions are written according to the ABNF:
12
+ #
13
+ # AttributeTypeDescription = LPAREN WSP
14
+ # numericoid ; object identifier
15
+ # [ SP "NAME" SP qdescrs ] ; short names (descriptors)
16
+ # [ SP "DESC" SP qdstring ] ; description
17
+ # [ SP "OBSOLETE" ] ; not active
18
+ # [ SP "SUP" SP oid ] ; supertype
19
+ # [ SP "EQUALITY" SP oid ] ; equality matching rule
20
+ # [ SP "ORDERING" SP oid ] ; ordering matching rule
21
+ # [ SP "SUBSTR" SP oid ] ; substrings matching rule
22
+ # [ SP "SYNTAX" SP noidlen ] ; value syntax
23
+ # [ SP "SINGLE-VALUE" ] ; single-value
24
+ # [ SP "COLLECTIVE" ] ; collective
25
+ # [ SP "NO-USER-MODIFICATION" ] ; not user modifiable
26
+ # [ SP "USAGE" SP usage ] ; usage
27
+ # extensions WSP RPAREN ; extensions
28
+ #
29
+ # usage = "userApplications" / ; user
30
+ # "directoryOperation" / ; directory operational
31
+ # "distributedOperation" / ; DSA-shared operational
32
+ # "dSAOperation" ; DSA-specific operational
33
+ #
34
+ # where:
35
+ # <numericoid> is object identifier assigned to this attribute type;
36
+ # NAME <qdescrs> are short names (descriptors) identifying this
37
+ # attribute type;
38
+ # DESC <qdstring> is a short descriptive string;
39
+ # OBSOLETE indicates this attribute type is not active;
40
+ # SUP oid specifies the direct supertype of this type;
41
+ # EQUALITY, ORDERING, and SUBSTR provide the oid of the equality,
42
+ # ordering, and substrings matching rules, respectively;
43
+ # SYNTAX identifies value syntax by object identifier and may suggest
44
+ # a minimum upper bound;
45
+ # SINGLE-VALUE indicates attributes of this type are restricted to a
46
+ # single value;
47
+ # COLLECTIVE indicates this attribute type is collective
48
+ # [X.501][RFC3671];
49
+ # NO-USER-MODIFICATION indicates this attribute type is not user
50
+ # modifiable;
51
+ # USAGE indicates the application of this attribute type; and
52
+ # <extensions> describe extensions.
53
+ #
54
+ #
55
+ # @param attribute [String]
56
+ # "( 0.9.2342.19200300.100.1.1 NAME ( 'uid' 'userid' )
57
+ # DESC 'RFC1274: user identifier' EQUALITY caseIgnoreMatch
58
+ # SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
59
+ # USAGE userApplications X-SCHEMA 'core' )"
60
+ #
61
+ # @return [Array<Hash>] Alternative names return multiple hashes
62
+ #
63
+ # @example
64
+ # Parsers::Attribute.new("( NAME cn....)").call
65
+ #
66
+ # @api private
67
+ class Attribute
68
+
69
+ extend Initializer
70
+
71
+ param :attribute, type: Types::Strict::String, reader: :private
72
+
73
+ def call
74
+ Array(canonical_names).map do |original_name|
75
+ {
76
+ name: LDAP.formatter[original_name],
77
+ definition: attribute,
78
+ canonical: original_name,
79
+ description: description,
80
+ oid: attribute_oid,
81
+ syntax: syntax_oid,
82
+ single: single_value?,
83
+ editable: editable?,
84
+ schema: schema,
85
+ draft: draft,
86
+
87
+ # super_type: [ SP "SUP" SP oid ]
88
+ # collective: [ SP "COLLECTIVE" ]
89
+
90
+ rules: {
91
+ approx: approx_matcher,
92
+ equality: equality_matcher,
93
+ substr: sub_string_rule,
94
+ ordering: ordering_rule,
95
+ min_value_count: min_value_count,
96
+ max_value_count: max_value_count,
97
+ min_value_length: min_value_length,
98
+ max_value_length: max_value_length,
99
+ min_int_value: min_int_value,
100
+ max_int_value: max_int_value,
101
+ allowed_value: allowed_value
102
+ }
103
+ }
104
+ end
105
+ end
106
+
107
+ private
108
+
109
+ # short names (descriptors)
110
+ #
111
+ # @return [Array<String>] => ['uid', 'userid']
112
+ #
113
+ def canonical_names
114
+ if attribute[/NAME '(\S+)'/]
115
+ Regexp.last_match(1)
116
+ elsif attribute[/NAME \( '(\S+)' '(\S+)' \)/]
117
+ [Regexp.last_match(1), Regexp.last_match(2)]
118
+ end
119
+ end
120
+
121
+ # numericoid
122
+ #
123
+ # @return [String]
124
+ #
125
+ def attribute_oid
126
+ attribute[/^\( ([\d\.]*)/, 1]
127
+ end
128
+
129
+ # @return [Boolean]
130
+ #
131
+ def editable?
132
+ modifiable? and public?
133
+ end
134
+
135
+ # not user modifiable
136
+ #
137
+ # @return [Boolean]
138
+ #
139
+ def modifiable?
140
+ attribute.scan(/NO-USER-MODIFICATION/).none?
141
+ end
142
+
143
+ # value syntax
144
+ #
145
+ # @return [String]
146
+ #
147
+ def syntax_oid
148
+ attribute[/SYNTAX (\S+)/, 1].to_s.tr("'", '')
149
+ end
150
+
151
+ # userApplications
152
+ #
153
+ # @return [Boolean]
154
+ #
155
+ def public?
156
+ attribute[/USAGE (\S+)/, 1] == 'userApplications'
157
+ end
158
+
159
+ # directoryOperation
160
+ # distributedOperation
161
+ # dSAOperation
162
+ #
163
+ # @return [Boolean]
164
+ #
165
+ def private?
166
+ attribute[/USAGE (\S+)/, 1] != 'userApplications'
167
+ end
168
+
169
+ # An optional human-readable description, which should be enclosed in single quotation marks.
170
+ #
171
+ # @return [String]
172
+ #
173
+ def description
174
+ attribute[/DESC '(.+)' [A-Z]+\s/, 1]
175
+ end
176
+
177
+ # ordering matching rule
178
+ #
179
+ # @return [String]
180
+ #
181
+ def ordering_rule
182
+ attribute[/ORDERING (\S+)/, 1]
183
+ end
184
+
185
+ # @return [String]
186
+ #
187
+ def sub_string_rule
188
+ attribute[/SUBSTR (\S+)/, 1]
189
+ end
190
+
191
+ # single-value
192
+ #
193
+ # @return [Boolean]
194
+ #
195
+ def single_value?
196
+ attribute.scan(/SINGLE-VALUE/).any?
197
+ end
198
+
199
+ # @return [String]
200
+ #
201
+ def equality_matcher
202
+ attribute[/EQUALITY (\S+)/, 1]
203
+ end
204
+
205
+ # ================================
206
+ #
207
+ # Extended Attribute Flags
208
+ #
209
+ # ================================
210
+
211
+ # Provides information about where the attribute type is defined,
212
+ # either by a particular RFC or Internet Draft or within the project.
213
+ #
214
+ def draft
215
+ attribute[/X-ORIGIN '(\S+)'/, 1]
216
+ end
217
+
218
+ # @return [String] Name of defining schema
219
+ #
220
+ def schema
221
+ attribute[/X-SCHEMA '(\S+)'/, 1]
222
+ end
223
+
224
+ # Indicates which approximate matching rule should be used for the attribute type. If this is specified, then its value should be the name or OID of a registered approximate matching rule.
225
+ # Specifies the name or OID of the approximate matching rule that should be
226
+ # used in conjunction with the specified attribute Type.
227
+ #
228
+ # @see https://ldapwiki.com/wiki/ApproxMatch
229
+ #
230
+ def approx_matcher
231
+ attribute[/X-APPROX (\S+)/, 1]
232
+ end
233
+
234
+ # Specifies the set of values that attributes of that type will be allowed to have.
235
+ #
236
+ def allowed_value
237
+ attribute[/X-ALLOWED-VALUE (\S+)/, 1]
238
+ end
239
+
240
+ # Provides one or more regular expressions that describe acceptable values for the associated attribute.
241
+ # Values will only be allowed if they match at least one of the regular expressions.
242
+ #
243
+ def value_regex
244
+ attribute[/X-VALUE-REGEX (\S+)/, 1]
245
+ end
246
+
247
+ # Specifies the minimum number of characters that values of the associated
248
+ # attribute are permitted to have.
249
+ #
250
+ def min_value_length
251
+ attribute[/X-MIN-VALUE-LENGTH (\d+)/, 1].to_i
252
+ end
253
+
254
+ # Specifies the maximum number of characters that values of the associated
255
+ # attribute are permitted to have.
256
+ #
257
+ def max_value_length
258
+ attribute[/X-MAX-VALUE-LENGTH (\d+)/, 1].to_i
259
+ end
260
+
261
+ # Specifies the minimum integer value that may be assigned to the associated attribute.
262
+ #
263
+ def min_int_value
264
+ attribute[/X-MIN-INT-VALUE (\d+)/, 1].to_i
265
+ end
266
+
267
+ # Specifies the maximum integer value that may be assigned to the associated attribute.
268
+ #
269
+ def max_int_value
270
+ attribute[/X-MAX-INT-VALUE (\d+)/, 1].to_i
271
+ end
272
+
273
+ # Specifies the minimum number of values that the attribute is allowed
274
+ # to have in any entry.
275
+ #
276
+ def min_value_count
277
+ attribute[/X-MIN-VALUE-COUNT (\d+)/, 1].to_i
278
+ end
279
+
280
+ # Specifies the maximum number of values that the attribute is allowed
281
+ # to have in any entry.
282
+ #
283
+ def max_value_count
284
+ attribute[/X-MAX-VALUE-COUNT (\d+)/, 1].to_i
285
+ end
286
+
287
+ end
288
+ end
289
+ end
290
+ end