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.
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,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ROM
4
+ module LDAP
5
+ # The major version of ROM-LDAP. Only bumped for major changes.
6
+ MAJOR = 0
7
+
8
+ # The minor version of ROM-LDAP. Bumped for every non-patch level release.
9
+ MINOR = 2
10
+
11
+ # The tiny version of ROM-LDAP. Only bumped for bugfix releases.
12
+ TINY = 2
13
+
14
+ # The version of ROM-LDAP, as a string (e.g. "2.11.0")
15
+ VERSION = [MAJOR, MINOR, TINY].join('.').freeze
16
+ end
17
+ end
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ROM
4
+ module Plugins
5
+ module Relation
6
+ module LDAP
7
+ # Microsoft Active Directory specific extension.
8
+ #
9
+ # @api public
10
+ module ActiveDirectory
11
+ ACCOUNT_DISABLED = 2
12
+ ACCOUNT_TEMP_DUPLICATE = 256
13
+ ACCOUNT_NORMAL = 512
14
+
15
+ DOMAIN_CONTROLLER = 532_480
16
+ PREAUTH_NOT_REQUIRED = 4_194_304 # Kerberos Preauthentication Disabled
17
+ ENCRYPTED_TEXT_PWD_ALLOWED = 128
18
+
19
+ GROUP_GLOBAL = 2
20
+ GROUP_LOCAL = 4
21
+ GROUP_UNIVERSAL = 8
22
+ GROUP_SECURITY_ENABLED = 2_147_483_648
23
+
24
+ HOMEDIR_REQUIRED = 8
25
+ INTERDOMAIN_TRUST_ACCOUNT = 2048
26
+ LOCKOUT = 16
27
+ MNS_LOGON_ACCOUNT = 131_072
28
+ NOT_DELEGATED = 1_048_576
29
+ PARTIAL_SECRETS_ACCOUNT = 67_108_864
30
+
31
+ PASSWORD_NOT_REQUIRED = 32
32
+ PASSWORD_CANT_CHANGE = 64
33
+ PASSWORD_DONT_EXPIRE = 65_536
34
+ SMARTCARD_REQUIRED = 262_144 # Smart Card Login Enforced
35
+ PASSWORD_EXPIRED = 8_388_608
36
+
37
+ SCRIPT = 1
38
+ SERVER_TRUST_ACCOUNT = 8192
39
+ TRUSTED_FOR_DELEGATION = 524_288
40
+ TRUSTED_TO_AUTH_FOR_DELEGATION = 16_777_216
41
+ USE_DES_KEY_ONLY = 2_097_152
42
+ WORKSTATION_TRUST_ACCOUNT = 4096
43
+
44
+ RULE_BIT = ROM::LDAP::OID[:matching_rule_bit_and]
45
+ RULE_CHAIN = ROM::LDAP::OID[:matching_rule_in_chain]
46
+
47
+ FLAG = "systemFlags:#{RULE_BIT}:"
48
+ GROUP = "groupType:#{RULE_BIT}:"
49
+ MEMBER = "memberOf:#{RULE_CHAIN}:"
50
+ OPTS = "options:#{RULE_BIT}:"
51
+ UAC = "userAccountControl:#{RULE_BIT}:"
52
+
53
+ #
54
+ # Ambiguous Name Resolution (ANR)
55
+ #
56
+ # @return [Relation]
57
+ #
58
+ # @api public
59
+ def ambiguous(value)
60
+ equal('anr' => value)
61
+ end
62
+
63
+ # All DC's and their versions
64
+ # '(&(&(&(&(samAccountType=805306369)(primaryGroupId=516))(objectCategory=computer)(operatingSystem=*))))'
65
+
66
+ #
67
+ # Accounts
68
+ #
69
+
70
+ # @return [Relation]
71
+ #
72
+ # @api public
73
+ def ad_accounts_all
74
+ equal('sAMAccountType' => 805_306_368)
75
+ end
76
+
77
+ # AD_USER_DISABLED = Filter::Builder.ex("userAccountControl:1.2.840.113556.1.4.803", "2")
78
+ #
79
+ # @return [Relation]
80
+ #
81
+ # @api public
82
+ def ad_accounts_disabled
83
+ ad_accounts_all.equal(UAC => ACCOUNT_DISABLED)
84
+ end
85
+
86
+ def ad_accounts_enabled
87
+ ad_accounts_all.unequal(UAC => ACCOUNT_DISABLED)
88
+ end
89
+
90
+ def ad_accounts_insecure
91
+ ad_accounts_all.equal(UAC => PASSWORD_NOT_REQUIRED)
92
+ end
93
+
94
+ def ad_accounts_expired_password
95
+ ad_accounts_all.equal(UAC => PASSWORD_EXPIRED)
96
+ end
97
+
98
+ def ad_accounts_permanent_password
99
+ ad_accounts_all.equal(UAC => PASSWORD_DONT_EXPIRE)
100
+ end
101
+
102
+ def ad_accounts_control(oid)
103
+ ad_accounts_all.equal(UAC => oid)
104
+ end
105
+
106
+ def ad_accounts_membership(groupdn)
107
+ ad_accounts_all.equal(MEMBER => groupdn)
108
+ end
109
+
110
+ def ad_accounts_with_email
111
+ ad_accounts_all.present(:mailnickname)
112
+ end
113
+
114
+ # FIXME: the attribute names should be original format?
115
+ # see for example ad_accounts_all
116
+ #
117
+ def ad_accounts_with_fax
118
+ ad_accounts_all.equal(proxyaddresses: 'FAX:*')
119
+ end
120
+
121
+ def ad_accounts_hidden_email
122
+ unequal(objectclass: 'publicFolder').equal(msexchhidefromaddresslists: 'TRUE')
123
+ end
124
+
125
+ #
126
+ # Groups and Objects
127
+ #
128
+
129
+ # @return [Relation]
130
+ #
131
+ # @api public
132
+ def ad_groups_security
133
+ equal(GROUP => GROUP_SECURITY_ENABLED)
134
+ # equal(grouptype: GROUP_SECURITY_ENABLED)
135
+ end
136
+
137
+ def ad_groups_universal
138
+ equal(GROUP => GROUP_UNIVERSAL)
139
+ end
140
+
141
+ def ad_groups_empty
142
+ equal(objectclass: 'group').missing(:member)
143
+ end
144
+
145
+ def ad_catalog_global
146
+ equal(objectcategory: 'nTDSDSA', OPTS => SCRIPT)
147
+ end
148
+
149
+ def ad_computers
150
+ equal(objectcategory: 'computer')
151
+ end
152
+
153
+ def ad_controllers
154
+ ad_computers.equal(UAC => SERVER_TRUST_ACCOUNT)
155
+ end
156
+
157
+ def ad_exchanges
158
+ equal(objectclass: 'msExchExchangeServer').unequal(objectclass: 'msExchExchangeServerPolicy')
159
+ end
160
+
161
+ def ad_contacts
162
+ equal(objectcategory: 'contact')
163
+ end
164
+
165
+ def ad_unrenamable_object
166
+ equal(FLAG => 134_217_728)
167
+ end
168
+
169
+ def ad_undeletable_object
170
+ equal(FLAG => -GROUP_SECURITY_ENABLED)
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ ROM.plugins do
179
+ adapter :ldap do
180
+ register :active_directory, ROM::Plugins::Relation::LDAP::ActiveDirectory, type: :relation
181
+ end
182
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rom/support/notifications'
4
+
5
+ module ROM
6
+ module Plugins
7
+ module Relation
8
+ module LDAP
9
+ # Generates methods for restricting relations by their indexed attributes
10
+ #
11
+ # @example
12
+ # rom = ROM.container(:ldap, {}) do |config|
13
+ #
14
+ # config.plugin(:ldap, relations: :auto_restrictions)
15
+ #
16
+ # config.relation(:users) do
17
+ # schema('(cn=*)', infer: true) do
18
+ # attribute :cn, ROM::LDAP::Types::Strings.meta(index: true)
19
+ # end
20
+ # end
21
+ # end
22
+ #
23
+ # rom.relations[:users].by_cn('Directory Administrator')
24
+ #
25
+ # @api public
26
+ module AutoRestrictions
27
+ extend Notifications::Listener
28
+
29
+ subscribe('configuration.relations.schema.set', adapter: :ldap) do |event|
30
+ schema = event[:schema]
31
+ relation = event[:relation]
32
+
33
+ methods, mod = AutoRestrictions.restriction_methods(schema)
34
+ relation.include(mod)
35
+
36
+ methods.each { |meth| relation.auto_curry(meth) }
37
+ end
38
+
39
+ # @api private
40
+ def self.restriction_methods(schema)
41
+ mod = Module.new
42
+ methods = schema.attributes.each_with_object([]) do |attribute, generated|
43
+ next unless attribute.indexed?
44
+
45
+ meth_name = :"by_#{attribute.name}"
46
+ next if generated.include?(meth_name)
47
+
48
+ mod.module_eval do
49
+ define_method(meth_name) do |value|
50
+ where(attribute.name => value)
51
+ end
52
+ end
53
+
54
+ generated << meth_name
55
+ end
56
+
57
+ [methods, mod]
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ ROM.plugins do
66
+ adapter :ldap do
67
+ register :auto_restrictions, ROM::Plugins::Relation::LDAP::AutoRestrictions, type: :relation
68
+ end
69
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ROM
4
+ module Plugins
5
+ module Relation
6
+ module LDAP
7
+ # Novell eDirectory specific extension.
8
+ #
9
+ # @api public
10
+ module EDirectory
11
+ NETWARE_SERVERS = '(objectClass=ncpServer)'
12
+ NETWARE_VOLUMES = '(objectClass=volume)'
13
+ ZEN_APPLICATION = '(objectClass=appApplication)'
14
+
15
+ # @see https://confluence.atlassian.com/kb/how-to-write-ldap-search-filters-792496933.html
16
+ # dn_part_match = '(|(ou:dn:=Chicago)(ou:dn:=Miami)))'.freeze
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ ROM.plugins do
24
+ adapter :ldap do
25
+ register :e_directory, ROM::Plugins::Relation::LDAP::EDirectory, type: :relation
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rom/plugins/relation/instrumentation'
4
+
5
+ module ROM
6
+ module Plugins
7
+ module Relation
8
+ module LDAP
9
+ # @api private
10
+ module Instrumentation
11
+ def self.included(klass)
12
+ super
13
+
14
+ klass.class_eval do
15
+ include ROM::Plugins::Relation::Instrumentation
16
+
17
+ # @overload [Hash]
18
+ #
19
+ # @api private
20
+ def notification_payload(relation)
21
+ super.merge(query: relation.to_filter)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ ROM.plugins do
32
+ adapter :ldap do
33
+ register :instrumentation, ROM::Plugins::Relation::LDAP::Instrumentation, type: :relation
34
+ end
35
+ end
@@ -0,0 +1,72 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ class LDAP < RegexLexer
7
+
8
+ title 'LDAP'
9
+ desc 'the LDAP query filter format'
10
+ tag 'ldap'
11
+
12
+
13
+ EXTENSIBLE = /^([-;\w]*)(:dn)?(:(\w+|[.\w]+))?$/
14
+
15
+ OPERATORS = '[~><:]?='
16
+
17
+ CONSTRUCTORS = '&|\!|\|'
18
+
19
+
20
+ state :root do
21
+
22
+
23
+
24
+ # parentheses
25
+ # rule /\s*[()]\s*/, Punctuation, :root
26
+ rule %r{[()]}, Comment
27
+
28
+ # constructors &, !, |
29
+ # rule %r"&|\!|\|", Str::Symbol
30
+ rule %r{[&\!\|]}, Str::Symbol
31
+
32
+
33
+
34
+
35
+ # attribute name
36
+ # rule /\w/, Keyword
37
+ # rule %r"(\w)[~><:]?=", Name::Attribute
38
+
39
+ # operators
40
+ # rule /\s*[~><:]?=\s*/, Name::Function
41
+ rule %r{([~><:]?=)}, Operator
42
+
43
+ rule %r{[~><:]?=(\w+)}, Keyword
44
+
45
+ # rule /\s*[~><:]?=\s*/ do
46
+ # groups Name::Function
47
+ # push :root
48
+ # end
49
+
50
+ # numeric values
51
+ # rule /\s*\d\s*/, Num::Integer
52
+
53
+
54
+ # wild and boolean values
55
+ rule %r{\*|TRUE|FALSE}, Name::Tag
56
+
57
+
58
+
59
+ # string values
60
+ # rule /\w/, Name::Variable
61
+ # rule %r"=(\*)\)", Name::Variable
62
+ # rule %r"=(\*)\)", Name::Tag
63
+
64
+
65
+ end
66
+
67
+ start do
68
+ # this is run whenever a fresh lex is started
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,49 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Themes
6
+ class LDAP < CSSTheme
7
+ name 'ldap'
8
+
9
+ style Text, :fg => :fg0, :bg => :bg0
10
+ style Error, :fg => :red, :bg => :bg0, :bold => true
11
+ style Comment, :fg => :gray, :italic => true
12
+
13
+ style Comment::Preproc, :fg => :aqua
14
+
15
+ style Name::Tag, :fg => :red
16
+
17
+ style Operator,
18
+ Punctuation, :fg => :fg0
19
+
20
+ style Generic::Inserted, :fg => :green, :bg => :bg0
21
+ style Generic::Deleted, :fg => :red, :bg => :bg0
22
+ style Generic::Heading, :fg => :green, :bold => true
23
+
24
+ style Keyword, :fg => :red
25
+ style Keyword::Constant, :fg => :purple
26
+ style Keyword::Type, :fg => :yellow
27
+
28
+ style Keyword::Declaration, :fg => :orange
29
+
30
+ style Literal::String,
31
+ Literal::String::Interpol,
32
+ Literal::String::Regex, :fg => :green, :italic => true
33
+
34
+ style Literal::String::Escape, :fg => :orange
35
+
36
+ style Name::Namespace,
37
+ Name::Class, :fg => :aqua
38
+
39
+ style Name::Constant, :fg => :purple
40
+
41
+ style Name::Attribute, :fg => :green
42
+
43
+ style Literal::Number, :fg => :purple
44
+
45
+ style Literal::String::Symbol, :fg => :blue
46
+
47
+ end
48
+ end
49
+ end