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,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/core/extensions'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module LDAP
|
7
|
+
extend Dry::Core::Extensions
|
8
|
+
|
9
|
+
# Make entry attributes suitable method names.
|
10
|
+
#
|
11
|
+
register_extension(:compatibility) do
|
12
|
+
require 'rom/ldap/extensions/compatibility'
|
13
|
+
end
|
14
|
+
|
15
|
+
#=======================================
|
16
|
+
# Exporters
|
17
|
+
#=======================================
|
18
|
+
|
19
|
+
# Add #to_dsml method to relation instance.
|
20
|
+
#
|
21
|
+
register_extension(:dsml_export) do
|
22
|
+
require 'rom/ldap/extensions/dsml'
|
23
|
+
end
|
24
|
+
|
25
|
+
# Add #to_msgpack method to relation instance.
|
26
|
+
#
|
27
|
+
register_extension(:msgpack_export) do
|
28
|
+
require 'rom/ldap/extensions/msgpack'
|
29
|
+
end
|
30
|
+
|
31
|
+
# Patch #to_json method in relation instance.
|
32
|
+
#
|
33
|
+
register_extension(:oj_export) do
|
34
|
+
require 'rom/ldap/extensions/optimised_json'
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
#=======================================
|
39
|
+
# Autoloaded for Rails
|
40
|
+
#=======================================
|
41
|
+
|
42
|
+
register_extension(:active_support_notifications) do
|
43
|
+
require 'rom/ldap/extensions/active_support_notifications'
|
44
|
+
end
|
45
|
+
|
46
|
+
register_extension(:rails_log_subscriber) do
|
47
|
+
require 'rom/ldap/extensions/rails_log_subscriber'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/notifications'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module LDAP
|
7
|
+
module ActiveSupportInstrumentation
|
8
|
+
def call(filter)
|
9
|
+
ActiveSupport::Notifications.instrument(
|
10
|
+
'ldap.rom',
|
11
|
+
ldap: 'foobar',
|
12
|
+
name: instrumentation_name,
|
13
|
+
binds: filter
|
14
|
+
) { super }
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def instrumentation_name
|
20
|
+
"ROM[#{directory.type}]"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Dataset.prepend ActiveSupportInstrumentation
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rom/initializer'
|
4
|
+
require 'libxml'
|
5
|
+
|
6
|
+
module ROM
|
7
|
+
module LDAP
|
8
|
+
#
|
9
|
+
# Directory Service Markup Language (DSML)
|
10
|
+
#
|
11
|
+
# Refines Array and Hash with #to_dsml method.
|
12
|
+
#
|
13
|
+
# @see https://publib.boulder.ibm.com/tividd/td/ITIM/SC32-1149-01/en_US/HTML/Policy_Org_Admin395.htm
|
14
|
+
# @see Directory::Entry
|
15
|
+
# @see Relation::Exporting
|
16
|
+
#
|
17
|
+
module DSML
|
18
|
+
# Export Entry objects as DSML files.
|
19
|
+
#
|
20
|
+
# @param tuple [Entry]
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
class Exporter
|
24
|
+
|
25
|
+
extend Initializer
|
26
|
+
|
27
|
+
include LibXML
|
28
|
+
|
29
|
+
# Dataset
|
30
|
+
#
|
31
|
+
param :tuples, type: Types::Strict::Array.of(Types::Strict::Hash)
|
32
|
+
|
33
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
34
|
+
# <dsml>
|
35
|
+
# <directory-entries>
|
36
|
+
# <entry dn="dn">
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
def to_dsml
|
42
|
+
doc = XML::Document.new
|
43
|
+
doc.encoding = XML::Encoding::UTF_8
|
44
|
+
doc.root = root = create_node('dsml')
|
45
|
+
root << (entries = create_node('directory-entries'))
|
46
|
+
map_tuples { |entry| entries << entry }
|
47
|
+
doc.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# <entry dn="dn">
|
53
|
+
#
|
54
|
+
# @yield [LibXML::XML::Node]
|
55
|
+
#
|
56
|
+
def map_tuples
|
57
|
+
tuples.each do |tuple|
|
58
|
+
next if tuple.empty?
|
59
|
+
|
60
|
+
dn = tuple.delete('dn')
|
61
|
+
objc = tuple.delete('objectClass')
|
62
|
+
|
63
|
+
entry_node = create_node('entry', dn: dn&.first)
|
64
|
+
|
65
|
+
classes(objc) { |c| entry_node << c }
|
66
|
+
|
67
|
+
attributes(tuple) { |a| entry_node << a }
|
68
|
+
|
69
|
+
yield(entry_node)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns "<objectclass/>" if param is nil
|
74
|
+
#
|
75
|
+
# <oc-value>inetOrgPerson</oc-value>
|
76
|
+
#
|
77
|
+
# @param [Array, Nil] values
|
78
|
+
#
|
79
|
+
# @yield [LibXML::XML::Node]
|
80
|
+
#
|
81
|
+
def classes(values)
|
82
|
+
class_node = create_node('objectclass')
|
83
|
+
values.to_a.each do |value|
|
84
|
+
value_node = create_node('oc-value')
|
85
|
+
value_node.content = value
|
86
|
+
class_node << value_node
|
87
|
+
end
|
88
|
+
yield(class_node)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @example
|
92
|
+
#
|
93
|
+
# {'cn'=>['Peter']}
|
94
|
+
# => <attr name="cn"><value>Peter</value></attr>
|
95
|
+
#
|
96
|
+
# @yield [LibXML::XML::Node]
|
97
|
+
#
|
98
|
+
def attributes(attrs)
|
99
|
+
attrs.each do |attr_name, attr_values|
|
100
|
+
attr_node = create_node('attr', name: attr_name)
|
101
|
+
attr_values.each do |value|
|
102
|
+
value_node = create_node('value')
|
103
|
+
value_node.content = value
|
104
|
+
attr_node << value_node
|
105
|
+
end
|
106
|
+
yield(attr_node)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# @return [LibXML::XML::Node]
|
112
|
+
#
|
113
|
+
def create_node(type, params = EMPTY_OPTS)
|
114
|
+
node = XML::Node.new(type)
|
115
|
+
unless params.empty?
|
116
|
+
params.each do |key, value|
|
117
|
+
XML::Attr.new(node, key.to_s, value.to_s)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
node
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
# Extend functionality of Hash class.
|
126
|
+
#
|
127
|
+
refine ::Hash do
|
128
|
+
# Convert hash to DSML format
|
129
|
+
#
|
130
|
+
# @return [String]
|
131
|
+
#
|
132
|
+
# @api public
|
133
|
+
def to_dsml
|
134
|
+
Exporter.new([self]).to_dsml
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Extend functionality of Array class.
|
139
|
+
#
|
140
|
+
refine ::Array do
|
141
|
+
# Convert array to DSML format
|
142
|
+
#
|
143
|
+
# @return [String]
|
144
|
+
#
|
145
|
+
# @api public
|
146
|
+
def to_dsml
|
147
|
+
Exporter.new(self).to_dsml
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
module DSMLExport
|
153
|
+
using DSML
|
154
|
+
#
|
155
|
+
# @return [String]
|
156
|
+
#
|
157
|
+
# @api public
|
158
|
+
def to_dsml
|
159
|
+
export.to_dsml
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
Relation.include DSMLExport
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'msgpack'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module LDAP
|
7
|
+
module MsgPackExport
|
8
|
+
# Export the relation as MessagePack Binary
|
9
|
+
#
|
10
|
+
# @return [String]
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# relation.to_msgpack
|
14
|
+
#
|
15
|
+
# @api public
|
16
|
+
def to_msgpack
|
17
|
+
export.to_msgpack
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Relation.include MsgPackExport
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'oj'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module LDAP
|
7
|
+
module OptimisedJSON
|
8
|
+
# Replace #to_json
|
9
|
+
#
|
10
|
+
# @param _opts [Mixed] compatibility with JSON.generate
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# relation.to_json
|
16
|
+
#
|
17
|
+
# @api public
|
18
|
+
def to_json(_opts = nil)
|
19
|
+
Oj.generate(export)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Relation.include OptimisedJSON
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/log_subscriber'
|
4
|
+
|
5
|
+
module ROM
|
6
|
+
module LDAP
|
7
|
+
class RailsLogSubscriber < ActiveSupport::LogSubscriber
|
8
|
+
|
9
|
+
def ldap(event)
|
10
|
+
return unless logger.debug?
|
11
|
+
|
12
|
+
payload = event.payload
|
13
|
+
|
14
|
+
name = format('%s (%.1fms)', payload[:name], event.duration)
|
15
|
+
ldap = payload[:ldap].squeeze(' ')
|
16
|
+
binds = payload[:binds].to_a.inspect if payload[:binds]
|
17
|
+
|
18
|
+
if odd?
|
19
|
+
name = color(name, :cyan, true)
|
20
|
+
ldap = color(ldap, nil, true)
|
21
|
+
else
|
22
|
+
name = color(name, :magenta, true)
|
23
|
+
end
|
24
|
+
|
25
|
+
debug " #{name} #{ldap} #{binds}"
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :odd_or_even
|
29
|
+
private :odd_or_even
|
30
|
+
def odd?
|
31
|
+
@odd_or_even = !odd_or_even
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
RailsLogSubscriber.attach_to(:rom)
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ROM
|
4
|
+
module LDAP
|
5
|
+
# Proc that returns input value.
|
6
|
+
#
|
7
|
+
DEFAULT_FORMATTER = ->(v) { v }
|
8
|
+
|
9
|
+
# Set/Reset the formatting proc
|
10
|
+
#
|
11
|
+
# @param func [Proc] Callable object
|
12
|
+
#
|
13
|
+
def self.use_formatter(func = nil)
|
14
|
+
@formatter = func
|
15
|
+
end
|
16
|
+
|
17
|
+
# @see 'rom/ldap/extensions/compatibility'
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# ROM::LDAP.load_extensions :compatibility
|
21
|
+
#
|
22
|
+
def self.formatter
|
23
|
+
@formatter || DEFAULT_FORMATTER
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/transformer/all'
|
4
|
+
require 'base64'
|
5
|
+
require 'rom/support/inflector'
|
6
|
+
|
7
|
+
module ROM
|
8
|
+
module LDAP
|
9
|
+
# @api private
|
10
|
+
module Functions
|
11
|
+
extend Dry::Transformer::Registry
|
12
|
+
|
13
|
+
import Dry::Transformer::Coercions
|
14
|
+
import Dry::Transformer::ArrayTransformations
|
15
|
+
import Dry::Transformer::HashTransformations
|
16
|
+
|
17
|
+
# Build tuple from arguments.
|
18
|
+
# Translates keys into original schema names and stringify values.
|
19
|
+
#
|
20
|
+
# @param tuple [Hash] input arguments for directory #add and #modify
|
21
|
+
#
|
22
|
+
# @return [Hash]
|
23
|
+
#
|
24
|
+
# @note Directory#add will receive a hash with key :dn
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
def self.tuplify(tuple, matrix)
|
28
|
+
fn = t(:rename_keys, matrix) >>
|
29
|
+
t(:map_values, t(:identify_value)) >>
|
30
|
+
t(:map_values, t(:stringify)) >> t(:reject_blank)
|
31
|
+
|
32
|
+
fn.call(tuple)
|
33
|
+
end
|
34
|
+
|
35
|
+
# remove keys with blank values
|
36
|
+
# nil values allow attribute to be deleted
|
37
|
+
#
|
38
|
+
def self.reject_blank(tuple)
|
39
|
+
tuple.reject { |_k, v| v&.empty? }
|
40
|
+
end
|
41
|
+
|
42
|
+
# Map from
|
43
|
+
#
|
44
|
+
# @todo Finish documentation
|
45
|
+
#
|
46
|
+
# @param val [Symbol,String]
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# id_value(true) => 'TRUE'
|
50
|
+
# id_value('TRUE') => true
|
51
|
+
# id_value('peter hamilton') => 'peter hamilton'
|
52
|
+
#
|
53
|
+
# @return [Mixed]
|
54
|
+
#
|
55
|
+
# @api private
|
56
|
+
def self.identify_value(val)
|
57
|
+
case val
|
58
|
+
when ::Symbol, ::TrueClass, ::FalseClass, ::NilClass
|
59
|
+
VALUES_MAP.fetch(val, val)
|
60
|
+
else
|
61
|
+
VALUES_MAP.invert.fetch(val, val)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Ensure tuple values are strings or nil
|
66
|
+
#
|
67
|
+
# @param value [Mixed]
|
68
|
+
#
|
69
|
+
# @return [String, NilClass]
|
70
|
+
#
|
71
|
+
# @api private
|
72
|
+
def self.stringify(value)
|
73
|
+
case value
|
74
|
+
when ::Numeric then value.to_s
|
75
|
+
when ::Enumerable then value.map(&:to_s)
|
76
|
+
when ::Hash then value.to_json
|
77
|
+
when ::String then value
|
78
|
+
else
|
79
|
+
value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Compare Magic Bytes
|
84
|
+
#
|
85
|
+
# @see https://en.wikipedia.org/wiki/List_of_file_signatures
|
86
|
+
# @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types
|
87
|
+
# @see https://github.com/sdsykes/fastimage/blob/master/lib/fastimage.rb
|
88
|
+
#
|
89
|
+
# @param value [String] UTF-8 encoded
|
90
|
+
#
|
91
|
+
def self.mime_type(value)
|
92
|
+
mime =
|
93
|
+
case value[0, 2]
|
94
|
+
when "\xFF\xD8".b
|
95
|
+
'image/jpeg'
|
96
|
+
when "\x89P".b
|
97
|
+
'image/png'
|
98
|
+
when 'BM'
|
99
|
+
'image/bitmap'
|
100
|
+
when 'II', 'MM'
|
101
|
+
'image/tiff'
|
102
|
+
when "\xFF\xFBID".b
|
103
|
+
'audio/mpeg'
|
104
|
+
when 'WA'
|
105
|
+
'audio/x-wav'
|
106
|
+
else
|
107
|
+
'application/octet-stream'
|
108
|
+
end
|
109
|
+
to_base64(value).prepend("data:#{mime};base64,")
|
110
|
+
end
|
111
|
+
|
112
|
+
# Base64 encoded string, with optional new line characters.
|
113
|
+
#
|
114
|
+
# @return [String]
|
115
|
+
#
|
116
|
+
def self.to_base64(value, strict: true)
|
117
|
+
if strict
|
118
|
+
Base64.strict_encode64(value).chomp
|
119
|
+
else
|
120
|
+
# [value].pack('m').chomp
|
121
|
+
Base64.encode64(value).chomp
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
#
|
127
|
+
# @return [Boolean]
|
128
|
+
#
|
129
|
+
def self.to_boolean(value)
|
130
|
+
Dry::Transformer::Coercions::BOOLEAN_MAP.fetch(value.to_s.downcase)
|
131
|
+
end
|
132
|
+
|
133
|
+
# The 18-digit Active Directory timestamps, also named
|
134
|
+
# 'Windows NT time format','Win32 FILETIME or SYSTEMTIME' or 'NTFS file time'.
|
135
|
+
#
|
136
|
+
# These are used in Microsoft Active Directory for
|
137
|
+
# pwdLastSet, accountExpires, LastLogon, LastLogonTimestamp and LastPwdSet.
|
138
|
+
#
|
139
|
+
# The number of 100-nanoseconds intervals since 12:00 A.M. January 1st, 1601 (UTC).
|
140
|
+
# NB:
|
141
|
+
# 1 nanosecond = a billionth of a second
|
142
|
+
# Accurate to the nearest millisecond (7 digits)
|
143
|
+
#
|
144
|
+
# @see ROM::LDAP::Types::Time
|
145
|
+
# @see https://ldapwiki.com/wiki/Microsoft%20TIME
|
146
|
+
#
|
147
|
+
# @param value [String] time or integer
|
148
|
+
#
|
149
|
+
# @return [Time] UTC formatted
|
150
|
+
#
|
151
|
+
def self.to_time(value)
|
152
|
+
unix_epoch_time = (Integer(value) / TEN_MILLION) - SINCE_1601
|
153
|
+
::Time.at(unix_epoch_time).utc
|
154
|
+
rescue ArgumentError
|
155
|
+
::Time.parse(value).utc
|
156
|
+
end
|
157
|
+
|
158
|
+
# @return [Array<String>]
|
159
|
+
#
|
160
|
+
def self.map_to_base64(values)
|
161
|
+
t(:map_array, t(:to_base64)).call(values)
|
162
|
+
end
|
163
|
+
|
164
|
+
# @return [Array<Integer>]
|
165
|
+
#
|
166
|
+
def self.map_to_integers(tuples)
|
167
|
+
t(:map_array, t(:to_integer)).call(tuples)
|
168
|
+
end
|
169
|
+
|
170
|
+
# @return [Array<Symbol>]
|
171
|
+
#
|
172
|
+
def self.map_to_symbols(tuples)
|
173
|
+
t(:map_array, t(:to_symbol)).call(tuples)
|
174
|
+
end
|
175
|
+
|
176
|
+
# @return [Array<TrueClass, FalseClass>]
|
177
|
+
#
|
178
|
+
def self.map_to_booleans(values)
|
179
|
+
t(:map_array, t(:to_boolean)).call(values)
|
180
|
+
end
|
181
|
+
|
182
|
+
# @return [Array<Time>]
|
183
|
+
#
|
184
|
+
def self.map_to_times(values)
|
185
|
+
t(:map_array, t(:to_time)).call(values)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Convert string to snake case.
|
189
|
+
#
|
190
|
+
# @param value [String]
|
191
|
+
#
|
192
|
+
# @return [String]
|
193
|
+
#
|
194
|
+
def self.to_underscore(value)
|
195
|
+
Inflector.underscore(value.delete('= '))
|
196
|
+
end
|
197
|
+
|
198
|
+
# Function applied to Directory::Entry to format incoming attribute names.
|
199
|
+
#
|
200
|
+
# @api public
|
201
|
+
def self.to_method_name(value)
|
202
|
+
fn = t(:to_string) >> t(:to_underscore) >> t(:to_symbol)
|
203
|
+
fn.call(value)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|