diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..7cc5019d
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,31 @@
+# This workflow uses actions that are not certified by GitHub.
+# They are provided by a third-party and are governed by
+# separate terms of service, privacy policy, and support
+# documentation.
+# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
+# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
+
+name: Test
+
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ ruby:
+ - "3.0"
+ - "3.1"
+ - "3.2"
+ - "3.3"
+ - "jruby-9.4"
+ - "truffleruby"
+ steps:
+ - uses: actions/checkout@v2
+ - name: Run tests with Ruby ${{ matrix.ruby }}
+ run: docker compose run ci-${{ matrix.ruby }}
diff --git a/.gitignore b/.gitignore
index 9c2842d9..e7d58b8f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,5 @@ publish/
Gemfile.lock
.bundle
bin/
+.idea
+*.gem
diff --git a/.rubocop.yml b/.rubocop.yml
index 7bdfa631..b2f78bb0 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -4,7 +4,7 @@ AllCops:
Exclude:
- 'pkg/**/*'
-Style/ExtraSpacing:
+Layout/ExtraSpacing:
Enabled: false
Lint/AssignmentInCondition:
@@ -13,7 +13,7 @@ Lint/AssignmentInCondition:
Style/ParallelAssignment:
Enabled: false
-Style/TrailingCommaInLiteral:
+Style/TrailingCommaInArrayLiteral:
EnforcedStyleForMultiline: comma
Style/TrailingCommaInArguments:
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 50c86e74..426a2aed 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,19 +1,231 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
-# on 2016-08-17 14:58:12 -0700 using RuboCop version 0.42.0.
+# on 2023-03-29 17:13:45 UTC using RuboCop version 1.48.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: AlignWith, SupportedStyles, AutoCorrect.
-# SupportedStyles: keyword, variable, start_of_line
-Lint/EndAlignment:
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation, Include.
+# Include: **/*.gemspec
+Gemspec/OrderedDependencies:
+ Exclude:
+ - 'net-ldap.gemspec'
+
+# Offense count: 1
+# Configuration parameters: Severity, Include.
+# Include: **/*.gemspec
+Gemspec/RequiredRubyVersion:
+ Exclude:
+ - 'net-ldap.gemspec'
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, IndentationWidth.
+# SupportedStyles: with_first_element, with_fixed_indentation
+Layout/ArrayAlignment:
+ Exclude:
+ - 'lib/net/ldap.rb'
+ - 'lib/net/ldap/connection.rb'
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, IndentOneStep, IndentationWidth.
+# SupportedStyles: case, end
+Layout/CaseIndentation:
+ Exclude:
+ - 'lib/net/ldap/filter.rb'
+
+# Offense count: 24
+# This cop supports safe autocorrection (--autocorrect).
+Layout/EmptyLineAfterGuardClause:
+ Exclude:
+ - 'lib/net/ber.rb'
+ - 'lib/net/ber/core_ext/array.rb'
+ - 'lib/net/ldap.rb'
+ - 'lib/net/ldap/auth_adapter.rb'
+ - 'lib/net/ldap/connection.rb'
+ - 'lib/net/ldap/dataset.rb'
+ - 'lib/net/ldap/entry.rb'
+ - 'lib/net/ldap/filter.rb'
+ - 'lib/net/snmp.rb'
+ - 'test/integration/test_ber.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Layout/EmptyLineAfterMagicComment:
+ Exclude:
+ - 'net-ldap.gemspec'
+
+# Offense count: 6
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines.
+Layout/EmptyLineBetweenDefs:
+ Exclude:
+ - 'lib/net/ldap/dataset.rb'
+ - 'lib/net/ldap/error.rb'
+ - 'lib/net/snmp.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Layout/EmptyLines:
+ Exclude:
+ - 'lib/net/snmp.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowAliasSyntax, AllowedMethods.
+# AllowedMethods: alias_method, public, protected, private
+Layout/EmptyLinesAroundAttributeAccessor:
+ Exclude:
+ - 'lib/net/ber.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines, beginning_only, ending_only
+Layout/EmptyLinesAroundClassBody:
+ Exclude:
+ - 'lib/net/ldap.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Layout/EmptyLinesAroundExceptionHandlingKeywords:
+ Exclude:
+ - 'lib/net/ldap/connection.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyleAlignWith, Severity.
+# SupportedStylesAlignWith: keyword, variable, start_of_line
+Layout/EndAlignment:
Exclude:
- 'testserver/ldapserver.rb'
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: IndentationWidth.
+# SupportedStyles: special_inside_parentheses, consistent, align_brackets
+Layout/FirstArrayElementIndentation:
+ EnforcedStyle: consistent
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: IndentationWidth.
+# SupportedStyles: special_inside_parentheses, consistent, align_braces
+Layout/FirstHashElementIndentation:
+ EnforcedStyle: consistent
+
+# Offense count: 124
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
+# SupportedHashRocketStyles: key, separator, table
+# SupportedColonStyles: key, separator, table
+# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
+Layout/HashAlignment:
+ Exclude:
+ - 'lib/net/ber.rb'
+ - 'lib/net/ldap.rb'
+ - 'lib/net/ldap/auth_adapter/gss_spnego.rb'
+ - 'lib/net/ldap/connection.rb'
+ - 'lib/net/ldap/filter.rb'
+ - 'test/ber/test_ber.rb'
+ - 'test/integration/test_add.rb'
+ - 'test/integration/test_bind.rb'
+ - 'test/integration/test_delete.rb'
+ - 'test/integration/test_open.rb'
+ - 'test/test_helper.rb'
+ - 'test/test_ldap_connection.rb'
+
+# Offense count: 6
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Width, AllowedPatterns.
+Layout/IndentationWidth:
+ Exclude:
+ - 'lib/net/ber.rb'
+ - 'lib/net/ldap/password.rb'
+ - 'lib/net/snmp.rb'
+
+# Offense count: 15
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowDoxygenCommentStyle, AllowGemfileRubyComment.
+Layout/LeadingCommentSpace:
+ Exclude:
+ - 'lib/net/ber/core_ext/array.rb'
+ - 'lib/net/ldap.rb'
+ - 'lib/net/ldap/connection.rb'
+ - 'lib/net/ldap/entry.rb'
+ - 'lib/net/ldap/filter.rb'
+ - 'lib/net/ldap/pdu.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: symmetrical, new_line, same_line
+Layout/MultilineMethodCallBraceLayout:
+ Exclude:
+ - 'lib/net/ldap/filter.rb'
+
+# Offense count: 7
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: space, no_space
+Layout/SpaceAroundEqualsInParameterDefault:
+ Exclude:
+ - 'lib/net/ldap/connection.rb'
+ - 'lib/net/snmp.rb'
+
+# Offense count: 4
+# This cop supports safe autocorrection (--autocorrect).
+Layout/SpaceAroundKeyword:
+ Exclude:
+ - 'lib/net/ldap/entry.rb'
+ - 'lib/net/snmp.rb'
+
+# Offense count: 7
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator.
+# SupportedStylesForExponentOperator: space, no_space
+Layout/SpaceAroundOperators:
+ Exclude:
+ - 'lib/net/ber/ber_parser.rb'
+ - 'lib/net/ldap/connection.rb'
+ - 'lib/net/ldap/entry.rb'
+ - 'lib/net/ldap/filter.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
+# SupportedStyles: space, no_space
+# SupportedStylesForEmptyBraces: space, no_space
+Layout/SpaceInsideBlockBraces:
+ Exclude:
+ - 'lib/net/ldap/dataset.rb'
+
+# Offense count: 8
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: space, compact, no_space
+Layout/SpaceInsideParens:
+ Exclude:
+ - 'lib/net/ldap/entry.rb'
+ - 'lib/net/snmp.rb'
+
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: AllowComments.
+Lint/EmptyConditionalBody:
+ Exclude:
+ - 'lib/net/ldap/filter.rb'
+
+# Offense count: 1
+# Configuration parameters: AllowComments.
+Lint/EmptyWhen:
+ Exclude:
+ - 'lib/net/ldap/pdu.rb'
+
# Offense count: 30
Lint/ImplicitStringConcatenation:
Exclude:
@@ -29,23 +241,17 @@ Lint/RescueException:
Exclude:
- 'lib/net/ldap/pdu.rb'
-# Offense count: 1
-Lint/ShadowingOuterLocalVariable:
- Exclude:
- - 'lib/net/ldap/instrumentation.rb'
-
-# Offense count: 10
-# Cop supports --auto-correct.
+# Offense count: 9
+# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
Lint/UnusedBlockArgument:
Exclude:
- 'lib/net/ldap.rb'
- 'lib/net/snmp.rb'
- - 'test/support/vm/openldap/Vagrantfile'
# Offense count: 7
-# Cop supports --auto-correct.
-# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods.
Lint/UnusedMethodArgument:
Exclude:
- 'lib/net/ldap/entry.rb'
@@ -55,207 +261,224 @@ Lint/UnusedMethodArgument:
- 'test/test_search.rb'
# Offense count: 1
-# Configuration parameters: ContextCreatingMethods.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: ContextCreatingMethods, MethodCreatingMethods.
Lint/UselessAccessModifier:
Exclude:
- 'lib/net/ldap/connection.rb'
-# Offense count: 9
+# Offense count: 5
Lint/UselessAssignment:
Exclude:
- - 'lib/net/ldap/connection.rb'
- - 'lib/net/ldap/password.rb'
- 'test/integration/test_add.rb'
- 'test/test_ldap_connection.rb'
- 'test/test_search.rb'
- - 'test/test_snmp.rb'
-# Offense count: 47
+# Offense count: 38
+# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Metrics/AbcSize:
- Max: 114
+ Max: 124
+
+# Offense count: 3
+# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
+# AllowedMethods: refine
+Metrics/BlockLength:
+ Max: 119
# Offense count: 11
+# Configuration parameters: CountBlocks.
Metrics/BlockNesting:
Max: 4
-# Offense count: 10
-# Configuration parameters: CountComments.
+# Offense count: 11
+# Configuration parameters: CountComments, CountAsOne.
Metrics/ClassLength:
- Max: 431
+ Max: 451
-# Offense count: 22
+# Offense count: 20
+# Configuration parameters: AllowedMethods, AllowedPatterns.
Metrics/CyclomaticComplexity:
- Max: 41
+ Max: 45
-# Offense count: 225
-# Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
-# URISchemes: http, https
-Metrics/LineLength:
- Max: 360
-
-# Offense count: 70
-# Configuration parameters: CountComments.
+# Offense count: 74
+# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
Metrics/MethodLength:
Max: 130
# Offense count: 1
-# Configuration parameters: CountComments.
+# Configuration parameters: CountComments, CountAsOne.
Metrics/ModuleLength:
- Max: 104
+ Max: 103
-# Offense count: 14
+# Offense count: 12
+# Configuration parameters: AllowedMethods, AllowedPatterns.
Metrics/PerceivedComplexity:
- Max: 37
+ Max: 46
# Offense count: 1
-Style/AccessorMethodName:
+Naming/AccessorMethodName:
Exclude:
- 'lib/net/ldap.rb'
-# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: prefer_alias, prefer_alias_method
-Style/Alias:
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+Naming/BinaryOperatorParameterName:
+ Exclude:
+ - 'lib/net/ldap/filter.rb'
+
+# Offense count: 1
+# Configuration parameters: AllowedNames.
+# AllowedNames: module_parent
+Naming/ClassAndModuleCamelCase:
+ Exclude:
+ - 'lib/net/ldap/auth_adapter/gss_spnego.rb'
+
+# Offense count: 87
+Naming/ConstantName:
+ Exclude:
+ - 'lib/net/ldap.rb'
+ - 'lib/net/ldap/connection.rb'
+ - 'lib/net/ldap/filter.rb'
+ - 'lib/net/ldap/pdu.rb'
+ - 'lib/net/snmp.rb'
+ - 'test/test_ldif.rb'
+ - 'testserver/ldapserver.rb'
+
+# Offense count: 1
+# Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms.
+# CheckDefinitionPathHierarchyRoots: lib, spec, test, src
+# AllowedAcronyms: CLI, DSL, ACL, API, ASCII, CPU, CSS, DNS, EOF, GUID, HTML, HTTP, HTTPS, ID, IP, JSON, LHS, QPS, RAM, RHS, RPC, SLA, SMTP, SQL, SSH, TCP, TLS, TTL, UDP, UI, UID, UUID, URI, URL, UTF8, VM, XML, XMPP, XSRF, XSS
+Naming/FileName:
+ Exclude:
+ - 'lib/net-ldap.rb'
+
+# Offense count: 11
+# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
+# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
+Naming/MethodParameterName:
Exclude:
- - 'lib/net/ber/core_ext/array.rb'
- 'lib/net/ldap.rb'
- 'lib/net/ldap/entry.rb'
- 'lib/net/ldap/filter.rb'
+ - 'lib/net/snmp.rb'
+ - 'test/test_snmp.rb'
+ - 'testserver/ldapserver.rb'
+
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: PreferredName.
+Naming/RescuedExceptionsVariableName:
+ Exclude:
- 'lib/net/ldap/pdu.rb'
-# Offense count: 4
-# Cop supports --auto-correct.
-Style/AlignArray:
+# Offense count: 9
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: separated, grouped
+Style/AccessorGrouping:
Exclude:
- 'lib/net/ldap.rb'
- - 'lib/net/ldap/auth_adapter/sasl.rb'
- - 'lib/net/ldap/connection.rb'
+ - 'lib/net/ldap/pdu.rb'
# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
-# SupportedStyles: with_first_parameter, with_fixed_indentation
-Style/AlignParameters:
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: prefer_alias, prefer_alias_method
+Style/Alias:
Exclude:
- - 'test/ber/test_ber.rb'
- - 'test/integration/test_ber.rb'
- - 'test/integration/test_bind.rb'
- - 'test/integration/test_password_modify.rb'
+ - 'lib/net/ber/core_ext/array.rb'
+ - 'lib/net/ldap.rb'
+ - 'lib/net/ldap/entry.rb'
+ - 'lib/net/ldap/filter.rb'
+ - 'lib/net/ldap/pdu.rb'
-# Offense count: 37
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
+# Offense count: 12
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
# SupportedStyles: always, conditionals
Style/AndOr:
Exclude:
- - 'lib/net/ber/ber_parser.rb'
- 'lib/net/ldap.rb'
- 'lib/net/ldap/connection.rb'
- 'lib/net/ldap/dataset.rb'
- 'lib/net/ldap/filter.rb'
- 'lib/net/ldap/pdu.rb'
- - 'testserver/ldapserver.rb'
# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
# SupportedStyles: percent_q, bare_percent
Style/BarePercentLiterals:
Exclude:
- 'test/test_entry.rb'
# Offense count: 1
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
Style/BlockComments:
Exclude:
- 'test/test_rename.rb'
-# Offense count: 6
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: braces, no_braces, context_dependent
-Style/BracesAroundHashParameters:
- Exclude:
- - 'lib/net/ldap/auth_adapter/gss_spnego.rb'
- - 'lib/net/snmp.rb'
- - 'test/test_ldap.rb'
-
-# Offense count: 4
-# Cop supports --auto-correct.
-# Configuration parameters: IndentWhenRelativeTo, SupportedStyles, IndentOneStep, IndentationWidth.
-# SupportedStyles: case, end
-Style/CaseIndentation:
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: MinBranchesCount.
+Style/CaseLikeIf:
Exclude:
- - 'lib/net/ldap/filter.rb'
+ - 'lib/net/ber/ber_parser.rb'
# Offense count: 4
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
Style/CharacterLiteral:
Exclude:
- 'lib/net/ldap/dataset.rb'
- 'lib/net/ldap/entry.rb'
-# Offense count: 1
-Style/ClassAndModuleCamelCase:
- Exclude:
- - 'lib/net/ldap/auth_adapter/gss_spnego.rb'
-
# Offense count: 23
-# Configuration parameters: EnforcedStyle, SupportedStyles.
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
# SupportedStyles: nested, compact
Style/ClassAndModuleChildren:
Enabled: false
-# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
# SupportedStyles: is_a?, kind_of?
Style/ClassCheck:
Exclude:
- 'lib/net/ber/core_ext/array.rb'
- - 'lib/net/ldap/error.rb'
-
-# Offense count: 13
-# Cop supports --auto-correct.
-Style/ColonMethodCall:
- Exclude:
- - 'test/test_ldif.rb'
- - 'test/test_ssl_ber.rb'
# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: Keywords.
-# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Keywords, RequireColon.
+# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW, NOTE
Style/CommentAnnotation:
Exclude:
- 'lib/net/ber.rb'
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly.
-# SupportedStyles: assign_to_condition, assign_inside_condition
-Style/ConditionalAssignment:
- Exclude:
- - 'lib/net/ldap/dn.rb'
-
-# Offense count: 88
-Style/ConstantName:
+# Offense count: 8
+# This cop supports unsafe autocorrection (--autocorrect-all).
+Style/CommentedKeyword:
Exclude:
- 'lib/net/ldap.rb'
- 'lib/net/ldap/connection.rb'
+ - 'lib/net/ldap/entry.rb'
- 'lib/net/ldap/filter.rb'
- 'lib/net/ldap/pdu.rb'
- - 'lib/net/snmp.rb'
- - 'test/test_ldif.rb'
- - 'testserver/ldapserver.rb'
-# Offense count: 17
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
+# SupportedStyles: assign_to_condition, assign_inside_condition
+Style/ConditionalAssignment:
+ Exclude:
+ - 'lib/net/ldap/dn.rb'
+
+# Offense count: 12
+# Configuration parameters: AllowedConstants.
Style/Documentation:
Exclude:
- 'spec/**/*'
- 'test/**/*'
- - 'lib/net/ber/core_ext.rb'
- 'lib/net/ldap.rb'
- 'lib/net/ldap/auth_adapter.rb'
- 'lib/net/ldap/auth_adapter/sasl.rb'
@@ -268,65 +491,46 @@ Style/Documentation:
- 'lib/net/snmp.rb'
- 'testserver/ldapserver.rb'
-# Offense count: 19
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: leading, trailing
-Style/DotPosition:
- Exclude:
- - 'test/test_ldap_connection.rb'
- - 'test/test_ssl_ber.rb'
-
# Offense count: 1
-# Cop supports --auto-correct.
-Style/ElseAlignment:
- Exclude:
- - 'testserver/ldapserver.rb'
-
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: AllowAdjacentOneLineDefs.
-Style/EmptyLineBetweenDefs:
- Exclude:
- - 'lib/net/ldap.rb'
- - 'lib/net/ldap/dataset.rb'
- - 'lib/net/snmp.rb'
-
-# Offense count: 8
-# Cop supports --auto-correct.
-Style/EmptyLines:
- Exclude:
- - 'lib/net/snmp.rb'
- - 'testserver/ldapserver.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: empty_lines, no_empty_lines
-Style/EmptyLinesAroundClassBody:
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: compact, expanded
+Style/EmptyMethod:
Exclude:
- - 'lib/net/ldap.rb'
- - 'test/test_snmp.rb'
+ - 'test/test_auth_adapter.rb'
# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: empty_lines, no_empty_lines
-Style/EmptyLinesAroundModuleBody:
+# This cop supports safe autocorrection (--autocorrect).
+Style/Encoding:
Exclude:
- - 'testserver/ldapserver.rb'
+ - 'net-ldap.gemspec'
+ - 'test/test_filter_parser.rb'
# Offense count: 3
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
Style/EvenOdd:
Exclude:
- 'lib/net/ldap/dn.rb'
# Offense count: 1
-# Configuration parameters: ExpectMatchingDefinition, Regex, IgnoreExecutableScripts.
-Style/FileName:
+# This cop supports safe autocorrection (--autocorrect).
+Style/ExpandPathArguments:
Exclude:
- - 'lib/net-ldap.rb'
+ - 'net-ldap.gemspec'
+
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+Style/ExplicitBlockArgument:
+ Exclude:
+ - 'lib/net/ldap.rb'
+ - 'lib/net/ldap/dataset.rb'
+
+# Offense count: 54
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: always, always_true, never
+Style/FrozenStringLiteralComment:
+ Enabled: false
# Offense count: 9
# Configuration parameters: AllowedVariables.
@@ -334,10 +538,18 @@ Style/GlobalVars:
Exclude:
- 'testserver/ldapserver.rb'
-# Offense count: 161
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
-# SupportedStyles: ruby19, ruby19_no_mixed_keys, hash_rockets
+# Offense count: 5
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
+Style/GuardClause:
+ Exclude:
+ - 'lib/net/ldap/filter.rb'
+
+# Offense count: 159
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, EnforcedShorthandSyntax, UseHashRocketsWithSymbolValues, PreferHashRocketsForNonAlnumEndingSymbols.
+# SupportedStyles: ruby19, hash_rockets, no_mixed_keys, ruby19_no_mixed_keys
+# SupportedShorthandSyntax: always, never, either, consistent
Style/HashSyntax:
Exclude:
- 'lib/net/ber.rb'
@@ -347,7 +559,6 @@ Style/HashSyntax:
- 'lib/net/ldap/connection.rb'
- 'lib/net/ldap/pdu.rb'
- 'lib/net/snmp.rb'
- - 'test/integration/test_bind.rb'
- 'test/test_auth_adapter.rb'
- 'test/test_ldap.rb'
- 'test/test_ldap_connection.rb'
@@ -356,58 +567,31 @@ Style/HashSyntax:
- 'testserver/ldapserver.rb'
# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowIfModifier.
Style/IfInsideElse:
Exclude:
- 'lib/net/ldap/instrumentation.rb'
-# Offense count: 7
-# Cop supports --auto-correct.
-# Configuration parameters: MaxLineLength.
+# Offense count: 25
+# This cop supports safe autocorrection (--autocorrect).
Style/IfUnlessModifier:
Exclude:
- 'lib/net/ber.rb'
- 'lib/net/ber/core_ext/integer.rb'
- 'lib/net/ldap.rb'
+ - 'lib/net/ldap/auth_adapter.rb'
+ - 'lib/net/ldap/auth_adapter/sasl.rb'
+ - 'lib/net/ldap/auth_adapter/simple.rb'
+ - 'lib/net/ldap/connection.rb'
- 'lib/net/ldap/filter.rb'
- 'lib/net/snmp.rb'
- - 'test/test_ldap_connection.rb'
-
-# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: SupportedStyles, IndentationWidth.
-# SupportedStyles: special_inside_parentheses, consistent, align_brackets
-Style/IndentArray:
- EnforcedStyle: consistent
-
-# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: SupportedStyles, IndentationWidth.
-# SupportedStyles: special_inside_parentheses, consistent, align_braces
-Style/IndentHash:
- EnforcedStyle: consistent
-
-# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: Width.
-Style/IndentationWidth:
- Exclude:
- - 'lib/net/ber.rb'
- - 'lib/net/ldap/password.rb'
- - 'lib/net/snmp.rb'
- - 'test/test_snmp.rb'
- - 'testserver/ldapserver.rb'
-
-# Offense count: 3
-# Cop supports --auto-correct.
-Style/LeadingCommentSpace:
- Exclude:
- - 'lib/net/ber/core_ext/array.rb'
- - 'lib/net/ldap.rb'
- - 'lib/net/ldap/connection.rb'
+ - 'test/integration/test_delete.rb'
+ - 'test/integration/test_password_modify.rb'
# Offense count: 21
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
# SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline
Style/MethodDefParentheses:
Exclude:
@@ -417,43 +601,27 @@ Style/MethodDefParentheses:
- 'testserver/ldapserver.rb'
# Offense count: 2
-Style/MethodMissing:
+Style/MissingRespondToMissing:
Exclude:
- 'lib/net/ldap/dn.rb'
- 'lib/net/ldap/entry.rb'
-# Offense count: 1
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: snake_case, camelCase
-Style/MethodName:
- Exclude:
- - 'lib/net/ldap/filter.rb'
-
-# Offense count: 4
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: symmetrical, new_line, same_line
-Style/MultilineMethodCallBraceLayout:
- Exclude:
- - 'lib/net/ldap/filter.rb'
- - 'test/test_entry.rb'
- - 'test/test_ldap_connection.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
-# SupportedStyles: aligned, indented, indented_relative_to_receiver
-Style/MultilineMethodCallIndentation:
- Exclude:
- - 'test/test_ldap_connection.rb'
-
-# Offense count: 1
-Style/MultilineTernaryOperator:
+# Offense count: 2
+# This cop supports safe autocorrection (--autocorrect).
+Style/MultilineIfModifier:
Exclude:
- 'lib/net/ldap/connection.rb'
# Offense count: 26
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
+Style/MultilineWhenThen:
+ Exclude:
+ - 'lib/net/ldap/dn.rb'
+
+# Offense count: 25
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: literals, strict
Style/MutableConstant:
Exclude:
- 'lib/net/ber.rb'
@@ -463,25 +631,26 @@ Style/MutableConstant:
- 'lib/net/ldap/filter.rb'
- 'lib/net/ldap/version.rb'
- 'lib/net/snmp.rb'
- - 'test/support/vm/openldap/Vagrantfile'
- 'test/test_ldif.rb'
- 'testserver/ldapserver.rb'
# Offense count: 1
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: both, prefix, postfix
Style/NegatedIf:
Exclude:
- 'test/test_helper.rb'
# Offense count: 1
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
Style/NegatedWhile:
Exclude:
- 'lib/net/ldap/filter.rb'
# Offense count: 3
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, MinBodyLength.
# SupportedStyles: skip_modifier_ifs, always
Style/Next:
Exclude:
@@ -489,47 +658,55 @@ Style/Next:
- 'testserver/ldapserver.rb'
# Offense count: 1
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: predicate, comparison
Style/NilComparison:
Exclude:
- 'lib/net/ldap/connection.rb'
# Offense count: 1
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: IncludeSemanticChanges.
Style/NonNilCheck:
Exclude:
- 'lib/net/ber/ber_parser.rb'
# Offense count: 1
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
Style/Not:
Exclude:
- 'lib/net/ldap/filter.rb'
# Offense count: 11
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: Strict, AllowedNumbers, AllowedPatterns.
Style/NumericLiterals:
MinDigits: 8
-# Offense count: 4
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
+# Offense count: 14
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle, AllowedMethods, AllowedPatterns.
# SupportedStyles: predicate, comparison
Style/NumericPredicate:
Exclude:
+ - 'spec/**/*'
- 'lib/net/ber/core_ext/integer.rb'
+ - 'lib/net/ldap/connection.rb'
- 'lib/net/ldap/dn.rb'
+ - 'lib/net/ldap/filter.rb'
- 'testserver/ldapserver.rb'
-# Offense count: 3
-Style/OpMethod:
+# Offense count: 1
+# Configuration parameters: AllowedMethods.
+# AllowedMethods: respond_to_missing?
+Style/OptionalBooleanParameter:
Exclude:
- - 'lib/net/ldap/filter.rb'
+ - 'lib/net/ldap/entry.rb'
# Offense count: 6
-# Cop supports --auto-correct.
-# Configuration parameters: AllowSafeAssignment.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowSafeAssignment, AllowInMultilineConditions.
Style/ParenthesesAroundCondition:
Exclude:
- 'lib/net/ldap.rb'
@@ -537,25 +714,31 @@ Style/ParenthesesAroundCondition:
- 'lib/net/ldap/auth_adapter/sasl.rb'
- 'lib/net/ldap/auth_adapter/simple.rb'
-# Offense count: 3
-# Cop supports --auto-correct.
+# Offense count: 13
+# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: PreferredDelimiters.
Style/PercentLiteralDelimiters:
Exclude:
- 'net-ldap.gemspec'
+ - 'test/integration/test_add.rb'
+ - 'test/integration/test_delete.rb'
+ - 'test/integration/test_open.rb'
+ - 'test/integration/test_password_modify.rb'
- 'test/test_entry.rb'
+ - 'test/test_helper.rb'
-# Offense count: 11
-# Cop supports --auto-correct.
+# Offense count: 20
+# This cop supports safe autocorrection (--autocorrect).
Style/PerlBackrefs:
Exclude:
- 'lib/net/ldap/dataset.rb'
- 'lib/net/ldap/filter.rb'
+ - 'test/test_ldif.rb'
- 'testserver/ldapserver.rb'
# Offense count: 10
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, AllowedCompactTypes.
# SupportedStyles: compact, exploded
Style/RaiseArgs:
Exclude:
@@ -563,31 +746,55 @@ Style/RaiseArgs:
- 'lib/net/ldap/pdu.rb'
- 'lib/net/snmp.rb'
-# Offense count: 1
-# Cop supports --auto-correct.
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
Style/RedundantBegin:
Exclude:
+ - 'lib/net/ldap.rb'
+ - 'lib/net/ldap/connection.rb'
- 'lib/net/snmp.rb'
# Offense count: 4
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
Style/RedundantParentheses:
Exclude:
- 'lib/net/ldap/filter.rb'
- 'test/test_filter.rb'
-# Offense count: 4
-# Cop supports --auto-correct.
+# Offense count: 5
+# This cop supports safe autocorrection (--autocorrect).
+Style/RedundantPercentQ:
+ Exclude:
+ - 'net-ldap.gemspec'
+ - 'test/test_entry.rb'
+
+# Offense count: 11
+# This cop supports safe autocorrection (--autocorrect).
+Style/RedundantRegexpCharacterClass:
+ Exclude:
+ - 'lib/net/ber/core_ext/integer.rb'
+ - 'lib/net/ldap/dataset.rb'
+ - 'lib/net/ldap/filter.rb'
+ - 'testserver/ldapserver.rb'
+
+# Offense count: 5
+# This cop supports safe autocorrection (--autocorrect).
+Style/RedundantRegexpEscape:
+ Exclude:
+ - 'lib/net/ldap/dataset.rb'
+ - 'lib/net/ldap/filter.rb'
+
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowMultipleReturnValues.
Style/RedundantReturn:
Exclude:
- 'lib/net/ber/core_ext/string.rb'
- 'lib/net/ldap/auth_adapter.rb'
- 'lib/net/ldap/entry.rb'
- - 'lib/net/ldap/password.rb'
# Offense count: 8
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
Style/RedundantSelf:
Exclude:
- 'lib/net/ber/core_ext/array.rb'
@@ -596,8 +803,8 @@ Style/RedundantSelf:
- 'lib/net/ldap/filter.rb'
# Offense count: 2
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed
Style/RegexpLiteral:
Exclude:
@@ -605,149 +812,152 @@ Style/RegexpLiteral:
- 'net-ldap.gemspec'
# Offense count: 1
-# Cop supports --auto-correct.
+# This cop supports safe autocorrection (--autocorrect).
Style/RescueModifier:
Exclude:
- 'test/ber/core_ext/test_string.rb'
-# Offense count: 8
-# Cop supports --auto-correct.
-# Configuration parameters: AllowAsExpressionSeparator.
-Style/Semicolon:
- Exclude:
- - 'lib/net/ldap/dn.rb'
- - 'lib/net/ldap/error.rb'
- - 'testserver/ldapserver.rb'
-
# Offense count: 2
-# Configuration parameters: Methods.
-# Methods: {"reduce"=>["a", "e"]}, {"inject"=>["a", "e"]}
-Style/SingleLineBlockParams:
- Exclude:
- - 'lib/net/ldap/filter.rb'
-
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: space, no_space
-Style/SpaceAroundEqualsInParameterDefault:
- Exclude:
- - 'lib/net/ldap/connection.rb'
- - 'lib/net/snmp.rb'
-
-# Offense count: 4
-# Cop supports --auto-correct.
-Style/SpaceAroundKeyword:
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: implicit, explicit
+Style/RescueStandardError:
Exclude:
- - 'lib/net/ldap/entry.rb'
- 'lib/net/snmp.rb'
+ - 'testserver/ldapserver.rb'
-# Offense count: 9
-# Cop supports --auto-correct.
-# Configuration parameters: AllowForAlignment.
-Style/SpaceAroundOperators:
+# Offense count: 13
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
+# AllowedMethods: present?, blank?, presence, try, try!
+Style/SafeNavigation:
Exclude:
- - 'lib/net/ber/ber_parser.rb'
+ - 'lib/net/ldap.rb'
- 'lib/net/ldap/connection.rb'
- - 'lib/net/ldap/entry.rb'
- - 'lib/net/ldap/filter.rb'
- - 'test/test_entry.rb'
- - 'test/test_ldap_connection.rb'
+ - 'lib/net/ldap/dataset.rb'
+ - 'lib/net/ldap/pdu.rb'
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
-# SupportedStyles: space, no_space
-Style/SpaceInsideBlockBraces:
+# Offense count: 7
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowAsExpressionSeparator.
+Style/Semicolon:
Exclude:
- - 'lib/net/ldap/dataset.rb'
- - 'test/test_snmp.rb'
+ - 'lib/net/ldap/dn.rb'
- 'testserver/ldapserver.rb'
-# Offense count: 13
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles.
-# SupportedStyles: space, no_space, compact
-Style/SpaceInsideHashLiteralBraces:
+# Offense count: 3
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowModifier.
+Style/SoleNestedConditional:
Exclude:
- - 'lib/net/ldap/dataset.rb'
- - 'test/test_ldap.rb'
+ - 'lib/net/ldap.rb'
+ - 'lib/net/ldap/connection.rb'
-# Offense count: 20
-# Cop supports --auto-correct.
-Style/SpaceInsideParens:
+# Offense count: 4
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: RequireEnglish, EnforcedStyle.
+# SupportedStyles: use_perl_names, use_english_names, use_builtin_english_names
+Style/SpecialGlobalVars:
Exclude:
- - 'lib/net/ldap/entry.rb'
- 'lib/net/snmp.rb'
- - 'test/test_password.rb'
- 'testserver/ldapserver.rb'
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-# SupportedStyles: use_perl_names, use_english_names
-Style/SpecialGlobalVars:
+# Offense count: 15
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: Mode.
+Style/StringConcatenation:
Exclude:
- - 'lib/net/snmp.rb'
- - 'net-ldap.gemspec'
- - 'testserver/ldapserver.rb'
+ - 'lib/net/ldap/dn.rb'
+ - 'lib/net/ldap/filter.rb'
+ - 'lib/net/ldap/password.rb'
+ - 'test/ber/test_ber.rb'
+ - 'test/test_ldif.rb'
+ - 'test/test_snmp.rb'
-# Offense count: 679
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline.
+# Offense count: 683
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
# SupportedStyles: single_quotes, double_quotes
Style/StringLiterals:
Enabled: false
# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
Style/StructInheritance:
Exclude:
- 'test/test_ldap.rb'
+# Offense count: 11
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: MinSize.
+# SupportedStyles: percent, brackets
+Style/SymbolArray:
+ EnforcedStyle: brackets
+
# Offense count: 4
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles, AllowSafeAssignment.
-# SupportedStyles: require_parentheses, require_no_parentheses
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
+# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
Style/TernaryParentheses:
Exclude:
- 'lib/net/ber/core_ext/integer.rb'
- 'lib/net/ldap/connection.rb'
- 'lib/net/ldap/dataset.rb'
+# Offense count: 38
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: EnforcedStyleForMultiline.
+# SupportedStylesForMultiline: comma, consistent_comma, no_comma
+Style/TrailingCommaInHashLiteral:
+ Enabled: false
+
# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, Whitelist.
-# Whitelist: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, IgnoreClassMethods, AllowedMethods.
+# AllowedMethods: to_ary, to_a, to_c, to_enum, to_h, to_hash, to_i, to_int, to_io, to_open, to_path, to_proc, to_r, to_regexp, to_str, to_s, to_sym
Style/TrivialAccessors:
Exclude:
- 'lib/net/ldap/connection.rb'
-# Offense count: 5
-# Cop supports --auto-correct.
-Style/UnneededPercentQ:
+# Offense count: 1
+# This cop supports safe autocorrection (--autocorrect).
+Style/UnpackFirst:
Exclude:
- - 'net-ldap.gemspec'
- - 'test/test_entry.rb'
+ - 'lib/net/ber/ber_parser.rb'
# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: MaxLineLength.
+# This cop supports safe autocorrection (--autocorrect).
Style/WhileUntilModifier:
Exclude:
- 'lib/net/ldap/filter.rb'
# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: SupportedStyles, WordRegex.
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: WordRegex.
# SupportedStyles: percent, brackets
Style/WordArray:
EnforcedStyle: percent
MinSize: 3
+# Offense count: 1
+# This cop supports unsafe autocorrection (--autocorrect-all).
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: forbid_for_all_comparison_operators, forbid_for_equality_operators_only, require_for_all_comparison_operators, require_for_equality_operators_only
+Style/YodaCondition:
+ Exclude:
+ - 'lib/net/ber/ber_parser.rb'
+
# Offense count: 6
-# Cop supports --auto-correct.
+# This cop supports unsafe autocorrection (--autocorrect-all).
Style/ZeroLengthPredicate:
Exclude:
- 'lib/net/ldap/connection.rb'
- 'lib/net/ldap/filter.rb'
- 'testserver/ldapserver.rb'
+
+# Offense count: 24
+# This cop supports safe autocorrection (--autocorrect).
+# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
+# URISchemes: http, https
+Layout/LineLength:
+ Max: 360
diff --git a/.travis.yml b/.travis.yml
index fc764963..8956efb8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,20 +3,47 @@ rvm:
- 2.0.0
- 2.1
- 2.2
+ - 2.3
+ - 2.4
+ - 2.5
+ - 2.6
+ - 2.7
+ - jruby-9.2
# optional
- ruby-head
- jruby-19mode
+ - jruby-9.2
- jruby-head
- - rbx-2
+
+addons:
+ hosts:
+ - ldap.example.org # needed for TLS verification
+ - cert.mismatch.example.org
+
+services:
+ - docker
env:
- INTEGRATION=openldap
+cache: bundler
+
before_install:
- gem update bundler
install:
- - if [ "$INTEGRATION" = "openldap" ]; then sudo script/install-openldap; fi
+ - >
+ docker run \
+ --hostname ldap.example.org \
+ --env LDAP_TLS_VERIFY_CLIENT=try \
+ -p 389:389 \
+ -p 636:636 \
+ -v "$(pwd)"/test/fixtures/ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom \
+ --name openldap \
+ --detach \
+ osixia/openldap:1.3.0 \
+ --copy-service \
+ --loglevel debug \
- bundle install
script: bundle exec rake ci
@@ -25,8 +52,8 @@ matrix:
allow_failures:
- rvm: ruby-head
- rvm: jruby-19mode
+ - rvm: jruby-9.2
- rvm: jruby-head
- - rvm: rbx-2
fast_finish: true
notifications:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0247a3d4..ee5335b7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -49,6 +49,6 @@ MyClass.new \
baz: 'garply'
```
-[issues]: https://github.com/ruby-net-ldap/ruby-net-ldap/issues
+[issues]: https://github.com/ruby-ldap/ruby-net-ldap/issues
[pr]: https://help.github.com/articles/using-pull-requests
[travis]: https://travis-ci.org/ruby-ldap/ruby-net-ldap
diff --git a/History.rdoc b/History.rdoc
index 3fcc291b..3f6248ee 100644
--- a/History.rdoc
+++ b/History.rdoc
@@ -1,3 +1,69 @@
+=== Net::LDAP 0.19.0
+* Net::LDAP::DN - Retain trailing spaces in RDN values in DNs #412
+* Add in ability for users to specify LDAP controls when conducting searches #411
+* Document connect_timeout in Constructor Details #415
+* Fix openssl error when using multiple hosts #417
+
+=== Net::LDAP 0.18.0
+* Fix escaping of # and space in attrs #408
+* Add support to use SNI #406
+* Drop Ruby 2.5 and JRuby 9.2 from CI tests
+* Bump rubocop to 1.48.1
+* Update CI for TruffleRuby 22
+
+=== Net::LDAP 0.17.1
+* Fixed shebang of bash #385
+* Omit some tests for now until we update our CA cert #386
+* Add Ruby 3.0 support #388
+* Add TruffleRuby 21.0.0 to CI #389
+* Correct a typo in an error message #391
+* Enable bundler caching for travis #390
+* Fix circular require while loading lib/net/ldap/entry.rb and lib/net/ldap/dataset.rb #392
+* Handle nil value in GetbyteForSSLSocket::getbyte #306
+
+=== Net::LDAP 0.17.0
+* Added private recursive_delete as alternative to DELETE_TREE #268
+* Test suite updates #373 #376 #377
+* Use Base64.strict_encode64 and SSHA256 #303
+* Remove deprecated ConnectionRefusedError #366
+* Added method to get a duplicate of the internal Hash #286
+* remove a circular require #380
+* fix LdapServerAsnSyntax compile #379
+* Implement '==' operator for entries #381
+* fix for undefined method for write exception #383
+
+=== Net::LDAP 0.16.3
+
+* Add Net::LDAP::InvalidDNError #371
+* Use require_relative instead of require #360
+* Address some warnings and fix JRuby test omissions #365
+* Bump rake dev dependency to 12.3 #359
+* Enable rubocop in ci #251
+* Enhance rubocop configuration and test syntax #344
+* CI: Drop rbx-2, uninstallable #364
+* Fix RuboCop warnings #312
+* Fix wrong error class #305
+* CONTRIBUTING.md: Repair link to Issues #309
+* Make the generate() method more idiomatic... #326
+* Make encode_sort_controls() more idiomatic... #327
+* Make the instrument() method more idiomatic... #328
+* Fix uninitialised Net::LDAP::LdapPduError #338
+* README.rdoc: Use SVG build badge #310
+* Update TravisCI config to inclue Ruby 2.7 #346
+* add explicit ** to silence Ruby 2.7 warning #342
+* Support parsing filters with attribute tags #345
+* Bump rubocop development dependency version #336
+* Add link to generated and hosted documentation on rubydoc #319
+* Fix 'uninitialized constant Net::LDAP::PDU::LdapPduError' error #317
+* simplify encoding logic: no more chomping required #362
+
+=== Net::LDAP 0.16.2
+
+* Net::LDAP#open does not cache bind result {#334}[https://github.com/ruby-ldap/ruby-net-ldap/pull/334]
+* Fix CI build {#333}[https://github.com/ruby-ldap/ruby-net-ldap/pull/333]
+* Fix to "undefined method 'result_code'" {#308}[https://github.com/ruby-ldap/ruby-net-ldap/pull/308]
+* Fixed Exception: incompatible character encodings: ASCII-8BIT and UTF-8 in filter.rb {#285}[https://github.com/ruby-ldap/ruby-net-ldap/pull/285]
+
=== Net::LDAP 0.16.1
* Send DN and newPassword with password_modify request {#271}[https://github.com/ruby-ldap/ruby-net-ldap/pull/271]
diff --git a/README.rdoc b/README.rdoc
index f1b1ea36..88bdba61 100644
--- a/README.rdoc
+++ b/README.rdoc
@@ -1,4 +1,6 @@
-= Net::LDAP for Ruby {
}[https://travis-ci.org/ruby-ldap/ruby-net-ldap]
+= Net::LDAP for Ruby
+{
}[https://badge.fury.io/rb/net-ldap]
+{
}[https://travis-ci.org/ruby-ldap/ruby-net-ldap]
== Description
@@ -21,7 +23,7 @@ the most recent LDAP RFCs (4510–4519, plus portions of 4520–4532).
== Synopsis
-See Net::LDAP for documentation and usage samples.
+See {Net::LDAP on rubydoc.info}[https://www.rubydoc.info/github/ruby-ldap/ruby-net-ldap/Net/LDAP] for documentation and usage samples.
== Requirements
@@ -53,16 +55,26 @@ This task will run the test suite and the
rake rubotest
CI takes too long? If your local box supports
-{Vagrant}[https://www.vagrantup.com/], you can run most of the tests
-in a VM on your local box. For more details and setup instructions, see
-{test/support/vm/openldap/README.md}[https://github.com/ruby-ldap/ruby-net-ldap/tree/master/test/support/vm/openldap/README.md]
+{Docker}[https://www.docker.com/], you can also run integration tests locally.
+Simply run:
+
+ script/ldap-docker
+ INTEGRATION=openldap rake test
+
+Or, use {Docker Compose}[https://docs.docker.com/compose/]. See docker-compose.yml for available Ruby versions.
+
+ docker-compose run ci-2.7
+
+CAVEAT: you need to add the following line to /etc/hosts
+ 127.0.0.1 ldap.example.org
+ 127.0.0.1 cert.mismatch.example.org
== Release
This section is for gem maintainers to cut a new version of the gem.
* Check out a new branch `release-VERSION`
-* Update lib/net/ldap/version.rb to next version number X.X.X following {semver}(http://semver.org/).
+* Update lib/net/ldap/version.rb to next version number X.X.X following {semver}[http://semver.org/].
* Update `History.rdoc`. Get latest changes with `script/changelog`
* Open a pull request with these changes for review
* After merging, on the master branch, run `script/release`
diff --git a/Rakefile b/Rakefile
index 51ab55dc..da4cf8e7 100644
--- a/Rakefile
+++ b/Rakefile
@@ -15,7 +15,7 @@ Rake::TestTask.new do |t|
end
desc 'Run tests and RuboCop (RuboCop runs on mri only)'
-task ci: [:test]
+task ci: Bundler.current_ruby.mri? ? [:test, :rubocop] : [:test]
desc 'Run tests and RuboCop'
task rubotest: [:test, :rubocop]
diff --git a/ci-run.sh b/ci-run.sh
new file mode 100755
index 00000000..27024a77
--- /dev/null
+++ b/ci-run.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -e
+
+gem install bundler
+bundle check || bundle install
+bundle exec rake ci
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..11f93ba2
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,122 @@
+networks:
+ integration_test_network:
+
+services:
+ openldap:
+ image: osixia/openldap:1.4.0
+ networks:
+ integration_test_network:
+ aliases:
+ - ldap.example.org
+ - cert.mismatch.example.org
+ environment:
+ LDAP_TLS_VERIFY_CLIENT: "try"
+ LDAP_SEED_INTERNAL_LDIF_PATH: "/ldif"
+ healthcheck:
+ test: ["CMD", "ldapsearch", "-x", "-s", "base"]
+ interval: 60s
+ start_period: 30s
+ timeout: 5s
+ retries: 1
+ hostname: "ldap.example.org"
+ volumes:
+ - ./test/fixtures/ldif:/ldif:ro
+
+ ci-3.0:
+ image: ruby:3.0
+ entrypoint: /code/ci-run.sh
+ environment:
+ INTEGRATION: openldap
+ INTEGRATION_HOST: ldap.example.org
+ depends_on:
+ - openldap
+ networks:
+ integration_test_network:
+ volumes:
+ - .:/code
+ working_dir: /code
+
+ ci-3.1:
+ image: ruby:3.1
+ entrypoint: /code/ci-run.sh
+ environment:
+ INTEGRATION: openldap
+ INTEGRATION_HOST: ldap.example.org
+ depends_on:
+ - openldap
+ networks:
+ integration_test_network:
+ volumes:
+ - .:/code
+ working_dir: /code
+
+ ci-3.2:
+ image: ruby:3.2
+ entrypoint: /code/ci-run.sh
+ environment:
+ INTEGRATION: openldap
+ INTEGRATION_HOST: ldap.example.org
+ depends_on:
+ - openldap
+ networks:
+ integration_test_network:
+ volumes:
+ - .:/code
+ working_dir: /code
+
+ ci-3.3:
+ image: ruby:3.3
+ entrypoint: /code/ci-run.sh
+ environment:
+ INTEGRATION: openldap
+ INTEGRATION_HOST: ldap.example.org
+ depends_on:
+ - openldap
+ networks:
+ integration_test_network:
+ volumes:
+ - .:/code
+ working_dir: /code
+
+ # https://github.com/flavorjones/truffleruby/pkgs/container/truffleruby
+ ci-truffleruby:
+ image: ghcr.io/flavorjones/truffleruby:stable
+ entrypoint: /code/ci-run.sh
+ environment:
+ INTEGRATION: openldap
+ INTEGRATION_HOST: ldap.example.org
+ depends_on:
+ - openldap
+ networks:
+ integration_test_network:
+ volumes:
+ - .:/code
+ working_dir: /code
+
+ ci-jruby-9.3:
+ image: jruby:9.3
+ entrypoint: /code/ci-run.sh
+ environment:
+ INTEGRATION: openldap
+ INTEGRATION_HOST: ldap.example.org
+ depends_on:
+ - openldap
+ networks:
+ integration_test_network:
+ volumes:
+ - .:/code
+ working_dir: /code
+
+ ci-jruby-9.4:
+ image: jruby:9.4
+ entrypoint: /code/ci-run.sh
+ environment:
+ INTEGRATION: openldap
+ INTEGRATION_HOST: ldap.example.org
+ depends_on:
+ - openldap
+ networks:
+ integration_test_network:
+ volumes:
+ - .:/code
+ working_dir: /code
diff --git a/lib/net-ldap.rb b/lib/net-ldap.rb
index 879851eb..717878ca 100644
--- a/lib/net-ldap.rb
+++ b/lib/net-ldap.rb
@@ -1,2 +1,2 @@
# -*- ruby encoding: utf-8 -*-
-require 'net/ldap'
+require_relative 'net/ldap'
diff --git a/lib/net/ber.rb b/lib/net/ber.rb
index eb6f04b3..34696cc3 100644
--- a/lib/net/ber.rb
+++ b/lib/net/ber.rb
@@ -1,5 +1,5 @@
# -*- ruby encoding: utf-8 -*-
-require 'net/ldap/version'
+require_relative 'ldap/version'
module Net # :nodoc:
##
@@ -349,4 +349,4 @@ def to_ber
Null = Net::BER::BerIdentifiedNull.new
end
-require 'net/ber/core_ext'
+require_relative 'ber/core_ext'
diff --git a/lib/net/ber/core_ext.rb b/lib/net/ber/core_ext.rb
index b1939844..37e0993b 100644
--- a/lib/net/ber/core_ext.rb
+++ b/lib/net/ber/core_ext.rb
@@ -1,5 +1,5 @@
# -*- ruby encoding: utf-8 -*-
-require 'net/ber/ber_parser'
+require_relative 'ber_parser'
# :stopdoc:
class IO
include Net::BER::BERParser
@@ -19,35 +19,35 @@ class OpenSSL::SSL::SSLSocket
module Net::BER::Extensions # :nodoc:
end
-require 'net/ber/core_ext/string'
+require_relative 'core_ext/string'
# :stopdoc:
class String
include Net::BER::BERParser
include Net::BER::Extensions::String
end
-require 'net/ber/core_ext/array'
+require_relative 'core_ext/array'
# :stopdoc:
class Array
include Net::BER::Extensions::Array
end
# :startdoc:
-require 'net/ber/core_ext/integer'
+require_relative 'core_ext/integer'
# :stopdoc:
class Integer
include Net::BER::Extensions::Integer
end
# :startdoc:
-require 'net/ber/core_ext/true_class'
+require_relative 'core_ext/true_class'
# :stopdoc:
class TrueClass
include Net::BER::Extensions::TrueClass
end
# :startdoc:
-require 'net/ber/core_ext/false_class'
+require_relative 'core_ext/false_class'
# :stopdoc:
class FalseClass
include Net::BER::Extensions::FalseClass
diff --git a/lib/net/ldap.rb b/lib/net/ldap.rb
index f7a98ef5..8dca73c0 100644
--- a/lib/net/ldap.rb
+++ b/lib/net/ldap.rb
@@ -17,19 +17,19 @@ class LDAP
end
require 'socket'
-require 'net/ber'
-require 'net/ldap/pdu'
-require 'net/ldap/filter'
-require 'net/ldap/dataset'
-require 'net/ldap/password'
-require 'net/ldap/entry'
-require 'net/ldap/instrumentation'
-require 'net/ldap/connection'
-require 'net/ldap/version'
-require 'net/ldap/error'
-require 'net/ldap/auth_adapter'
-require 'net/ldap/auth_adapter/simple'
-require 'net/ldap/auth_adapter/sasl'
+require_relative 'ber'
+require_relative 'ldap/pdu'
+require_relative 'ldap/filter'
+require_relative 'ldap/dataset'
+require_relative 'ldap/password'
+require_relative 'ldap/entry'
+require_relative 'ldap/instrumentation'
+require_relative 'ldap/connection'
+require_relative 'ldap/version'
+require_relative 'ldap/error'
+require_relative 'ldap/auth_adapter'
+require_relative 'ldap/auth_adapter/simple'
+require_relative 'ldap/auth_adapter/sasl'
Net::LDAP::AuthAdapter.register([:simple, :anon, :anonymous], Net::LDAP::AuthAdapter::Simple)
Net::LDAP::AuthAdapter.register(:sasl, Net::LDAP::AuthAdapter::Sasl)
@@ -311,7 +311,7 @@ class Net::LDAP
0 => :array, # RFC-2251 Control and Filter-AND
1 => :array, # SearchFilter-OR
2 => :array, # SearchFilter-NOT
- 3 => :array, # Seach referral
+ 3 => :array, # Search referral
4 => :array, # unknown use in Microsoft Outlook
5 => :array, # SearchFilter-GE
6 => :array, # SearchFilter-LE
@@ -325,7 +325,7 @@ class Net::LDAP
universal = {
constructed: {
- 107 => :array, #ExtendedResponse (PasswdModifyResponseValue)
+ 107 => :string, # ExtendedResponse
},
}
@@ -341,6 +341,7 @@ class Net::LDAP
StartTlsOid = '1.3.6.1.4.1.1466.20037'
PasswdModifyOid = '1.3.6.1.4.1.4203.1.11.1'
+ WhoamiOid = '1.3.6.1.4.1.4203.1.11.3'
# https://tools.ietf.org/html/rfc4511#section-4.1.9
# https://tools.ietf.org/html/rfc4511#appendix-A
@@ -412,7 +413,7 @@ class Net::LDAP
ResultCodeStrongerAuthRequired => "Stronger Auth Needed",
ResultCodeReferral => "Referral",
ResultCodeAdminLimitExceeded => "Admin Limit Exceeded",
- ResultCodeUnavailableCriticalExtension => "Unavailable crtical extension",
+ ResultCodeUnavailableCriticalExtension => "Unavailable critical extension",
ResultCodeConfidentialityRequired => "Confidentiality Required",
ResultCodeSaslBindInProgress => "saslBindInProgress",
ResultCodeNoSuchAttribute => "No Such Attribute",
@@ -480,6 +481,8 @@ def self.result2string(code) #:nodoc:
# server says it supports them. This is a fix for MS Active Directory
# * :instrumentation_service => An object responsible for instrumenting
# operations, compatible with ActiveSupport::Notifications' public API.
+ # * :connect_timeout => The TCP socket timeout (in seconds) to use when
+ # connecting to the LDAP server (default 5 seconds).
# * :encryption => specifies the encryption to be used in communicating
# with the LDAP server. The value must be a Hash containing additional
# parameters, which consists of two keys:
@@ -712,7 +715,7 @@ def open
begin
@open_connection = new_connection
payload[:connection] = @open_connection
- payload[:bind] = @open_connection.bind(@auth)
+ payload[:bind] = @result = @open_connection.bind(@auth)
yield self
ensure
@open_connection.close if @open_connection
@@ -1182,14 +1185,39 @@ def delete(args)
# entries. This method sends an extra control code to tell the LDAP server
# to do a tree delete. ('1.2.840.113556.1.4.805')
#
+ # If the LDAP server does not support the DELETE_TREE control code, subordinate
+ # entries are deleted recursively instead.
+ #
# Returns True or False to indicate whether the delete succeeded. Extended
# status information is available by calling #get_operation_result.
#
# dn = "mail=deleteme@example.com, ou=people, dc=example, dc=com"
# ldap.delete_tree :dn => dn
def delete_tree(args)
- delete(args.merge(:control_codes => [[Net::LDAP::LDAPControls::DELETE_TREE, true]]))
+ if search_root_dse[:supportedcontrol].include? Net::LDAP::LDAPControls::DELETE_TREE
+ delete(args.merge(:control_codes => [[Net::LDAP::LDAPControls::DELETE_TREE, true]]))
+ else
+ recursive_delete(args)
+ end
+ end
+
+ # Return the authorization identity of the client that issues the
+ # ldapwhoami request. The method does not support any arguments.
+ #
+ # Returns True or False to indicate whether the request was successfull.
+ # The result is available in the extended status information when calling
+ # #get_operation_result.
+ #
+ # ldap.ldapwhoami
+ # puts ldap.get_operation_result.extended_response
+ def ldapwhoami(args = {})
+ instrument "ldapwhoami.net_ldap", args do |payload|
+ @result = use_connection(args, &:ldapwhoami)
+ @result.success? ? @result.extended_response : nil
+ end
end
+ alias_method :whoami, :ldapwhoami
+
# This method is experimental and subject to change. Return the rootDSE
# record from the LDAP server as a Net::LDAP::Entry, or an empty Entry if
# the server doesn't return the record.
@@ -1247,10 +1275,10 @@ def search_subschema_entry
rs = search(:ignore_server_caps => true, :base => "",
:scope => SearchScope_BaseObject,
:attributes => [:subschemaSubentry])
- return Net::LDAP::Entry.new unless (rs and rs.first)
+ return Net::LDAP::Entry.new unless rs and rs.first
subschema_name = rs.first.subschemasubentry
- return Net::LDAP::Entry.new unless (subschema_name and subschema_name.first)
+ return Net::LDAP::Entry.new unless subschema_name and subschema_name.first
rs = search(:ignore_server_caps => true, :base => subschema_name.first,
:scope => SearchScope_BaseObject,
@@ -1320,7 +1348,7 @@ def new_connection
# Force connect to see if there's a connection error
connection.socket
connection
- rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, Net::LDAP::ConnectionRefusedError => e
+ rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT => e
@result = {
:resultCode => 52,
:errorMessage => ResultStrings[ResultCodeUnavailable],
@@ -1340,4 +1368,19 @@ def normalize_encryption(args)
end
end
+ # Recursively delete a dn and it's subordinate children.
+ # This is useful when a server does not support the DELETE_TREE control code.
+ def recursive_delete(args)
+ raise EmptyDNError unless args.is_a?(Hash) && args.key?(:dn)
+ # Delete Children
+ search(base: args[:dn], scope: Net::LDAP::SearchScope_SingleLevel) do |entry|
+ recursive_delete(dn: entry.dn)
+ end
+ # Delete Self
+ unless delete(dn: args[:dn])
+ raise Net::LDAP::Error, get_operation_result[:error_message].to_s
+ end
+ true
+ end
+
end # class LDAP
diff --git a/lib/net/ldap/auth_adapter/gss_spnego.rb b/lib/net/ldap/auth_adapter/gss_spnego.rb
index 9f773454..b4c3e519 100644
--- a/lib/net/ldap/auth_adapter/gss_spnego.rb
+++ b/lib/net/ldap/auth_adapter/gss_spnego.rb
@@ -1,5 +1,5 @@
-require 'net/ldap/auth_adapter'
-require 'net/ldap/auth_adapter/sasl'
+require_relative '../auth_adapter'
+require_relative 'sasl'
module Net
class LDAP
@@ -20,7 +20,7 @@ def bind(auth)
require 'ntlm'
user, psw = [auth[:username] || auth[:dn], auth[:password]]
- raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
+ raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless user && psw
nego = proc do |challenge|
t2_msg = NTLM::Message.parse(challenge)
diff --git a/lib/net/ldap/auth_adapter/sasl.rb b/lib/net/ldap/auth_adapter/sasl.rb
index 139e8593..bfebfc94 100644
--- a/lib/net/ldap/auth_adapter/sasl.rb
+++ b/lib/net/ldap/auth_adapter/sasl.rb
@@ -1,4 +1,4 @@
-require 'net/ldap/auth_adapter'
+require_relative '../auth_adapter'
module Net
class LDAP
@@ -30,7 +30,7 @@ class Sasl < Net::LDAP::AuthAdapter
def bind(auth)
mech, cred, chall = auth[:mechanism], auth[:initial_credential],
auth[:challenge_response]
- raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (mech && cred && chall)
+ raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless mech && cred && chall
message_id = @connection.next_msgid
diff --git a/lib/net/ldap/auth_adapter/simple.rb b/lib/net/ldap/auth_adapter/simple.rb
index d01b57ae..8a753ea6 100644
--- a/lib/net/ldap/auth_adapter/simple.rb
+++ b/lib/net/ldap/auth_adapter/simple.rb
@@ -1,4 +1,4 @@
-require 'net/ldap/auth_adapter'
+require_relative '../auth_adapter'
module Net
class LDAP
@@ -11,7 +11,7 @@ def bind(auth)
["", ""]
end
- raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
+ raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless user && psw
message_id = @connection.next_msgid
request = [
diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb
index 61aacb53..f1a70b18 100644
--- a/lib/net/ldap/connection.rb
+++ b/lib/net/ldap/connection.rb
@@ -30,12 +30,12 @@ def socket_class=(socket_class)
@socket_class = socket_class
end
- def prepare_socket(server, timeout=nil)
+ def prepare_socket(server, timeout=nil, hostname='127.0.0.1')
socket = server[:socket]
encryption = server[:encryption]
@conn = socket
- setup_encryption(encryption, timeout) if encryption
+ setup_encryption(encryption, timeout, hostname) if encryption
end
def open_connection(server)
@@ -50,7 +50,7 @@ def open_connection(server)
errors = []
hosts.each do |host, port|
begin
- prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout)
+ prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout, host)
if encryption
if encryption[:tls_options] &&
encryption[:tls_options][:verify_mode] &&
@@ -74,7 +74,8 @@ def open_connection(server)
module GetbyteForSSLSocket
def getbyte
- getc.ord
+ c = getc
+ c && c.ord
end
end
@@ -85,7 +86,7 @@ def close
end
end
- def self.wrap_with_ssl(io, tls_options = {}, timeout=nil)
+ def self.wrap_with_ssl(io, tls_options = {}, timeout=nil, hostname=nil)
raise Net::LDAP::NoOpenSSLError, "OpenSSL is unavailable" unless Net::LDAP::HasOpenSSL
ctx = OpenSSL::SSL::SSLContext.new
@@ -95,6 +96,7 @@ def self.wrap_with_ssl(io, tls_options = {}, timeout=nil)
ctx.set_params(tls_options) unless tls_options.empty?
conn = OpenSSL::SSL::SSLSocket.new(io, ctx)
+ conn.hostname = hostname
begin
if timeout
@@ -147,11 +149,11 @@ def self.wrap_with_ssl(io, tls_options = {}, timeout=nil)
# communications, as with simple_tls. Thanks for Kouhei Sutou for
# generously contributing the :start_tls path.
#++
- def setup_encryption(args, timeout=nil)
+ def setup_encryption(args, timeout=nil, hostname=nil)
args[:tls_options] ||= {}
case args[:method]
when :simple_tls
- @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
+ @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout, hostname)
# additional branches requiring server validation and peer certs, etc.
# go here.
when :start_tls
@@ -169,7 +171,7 @@ def setup_encryption(args, timeout=nil)
raise Net::LDAP::StartTLSError,
"start_tls failed: #{pdu.result_code}" unless pdu.result_code.zero?
- @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
+ @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout, hostname)
else
raise Net::LDAP::EncMethodUnsupportedError, "unsupported encryption method #{args[:method]}"
end
@@ -181,7 +183,7 @@ def setup_encryption(args, timeout=nil)
# have to call it, but perhaps it will come in handy someday.
#++
def close
- return if @conn.nil?
+ return if !defined?(@conn) || @conn.nil?
@conn.close
@conn = nil
end
@@ -300,7 +302,7 @@ def encode_sort_controls(sort_definitions)
control[2] = (control[2] == true).to_ber
control.to_ber_sequence
end
- sort_control = [
+ [
Net::LDAP::LDAPControls::SORT_REQUEST.to_ber,
false.to_ber,
sort_control_values.to_ber_sequence.to_s.to_ber,
@@ -422,6 +424,7 @@ def search(args = nil)
# this breaks when calling to_ber. (Can't force binary data to UTF-8)
# we have to disable paging (even though server supports it) to get around this...
+ user_controls = args.fetch(:controls, [])
controls = []
controls <<
[
@@ -431,7 +434,12 @@ def search(args = nil)
rfc2696_cookie.map(&:to_ber).to_ber_sequence.to_s.to_ber,
].to_ber_sequence if paged
controls << ber_sort if ber_sort
- controls = controls.empty? ? nil : controls.to_ber_contextspecific(0)
+ if controls.empty? && user_controls.empty?
+ controls = nil
+ else
+ controls += user_controls
+ controls = controls.to_ber_contextspecific(0)
+ end
write(request, controls, message_id)
@@ -467,6 +475,10 @@ def search(args = nil)
end
end
+ if result_pdu.nil?
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing"
+ end
+
# count number of pages of results
payload[:page_count] ||= 0
payload[:page_count] += 1
@@ -557,7 +569,12 @@ def modify(args)
ops.to_ber_sequence,
].to_ber_appsequence(Net::LDAP::PDU::ModifyRequest)
- write(request, nil, message_id)
+ controls = args.fetch(:controls, nil)
+ unless controls.nil?
+ controls = controls.to_ber_contextspecific(0)
+ end
+
+ write(request, controls, message_id)
pdu = queued_read(message_id)
if !pdu || pdu.app_tag != Net::LDAP::PDU::ModifyResponse
@@ -606,7 +623,7 @@ def password_modify(args)
pdu = queued_read(message_id)
if !pdu || pdu.app_tag != Net::LDAP::PDU::ExtendedResponse
- raise Net::LDAP::ResponseMissingError, "response missing or invalid"
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
end
pdu
@@ -629,7 +646,12 @@ def add(args)
message_id = next_msgid
request = [add_dn.to_ber, add_attrs.to_ber_sequence].to_ber_appsequence(Net::LDAP::PDU::AddRequest)
- write(request, nil, message_id)
+ controls = args.fetch(:controls, nil)
+ unless controls.nil?
+ controls = controls.to_ber_contextspecific(0)
+ end
+
+ write(request, controls, message_id)
pdu = queued_read(message_id)
if !pdu || pdu.app_tag != Net::LDAP::PDU::AddResponse
@@ -681,12 +703,28 @@ def delete(args)
pdu
end
+ def ldapwhoami
+ ext_seq = [Net::LDAP::WhoamiOid.to_ber_contextspecific(0)]
+ request = ext_seq.to_ber_appsequence(Net::LDAP::PDU::ExtendedRequest)
+
+ message_id = next_msgid
+
+ write(request, nil, message_id)
+ pdu = queued_read(message_id)
+
+ if !pdu || pdu.app_tag != Net::LDAP::PDU::ExtendedResponse
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
+ end
+
+ pdu
+ end
+
# Internal: Returns a Socket like object used internally to communicate with
# LDAP server.
#
# Typically a TCPSocket, but can be a OpenSSL::SSL::SSLSocket
def socket
- return @conn if defined? @conn
+ return @conn if defined?(@conn) && !@conn.nil?
# First refactoring uses the existing methods open_connection and
# prepare_socket to set @conn. Next cleanup would centralize connection
@@ -706,7 +744,7 @@ def socket
# Wrap around Socket.tcp to normalize with other Socket initializers
class DefaultSocket
def self.new(host, port, socket_opts = {})
- Socket.tcp(host, port, socket_opts)
+ Socket.tcp(host, port, **socket_opts)
end
end
end # class Connection
diff --git a/lib/net/ldap/dataset.rb b/lib/net/ldap/dataset.rb
index 9027ed28..bc225e89 100644
--- a/lib/net/ldap/dataset.rb
+++ b/lib/net/ldap/dataset.rb
@@ -103,7 +103,7 @@ def gets
# with the conversion of
def from_entry(entry)
dataset = Net::LDAP::Dataset.new
- hash = { }
+ hash = {}
entry.each_attribute do |attribute, value|
next if attribute == :dn
hash[attribute] = value
@@ -164,5 +164,3 @@ def read_ldif(io)
end
end
end
-
-require 'net/ldap/entry' unless defined? Net::LDAP::Entry
diff --git a/lib/net/ldap/dn.rb b/lib/net/ldap/dn.rb
index e314b80e..9098cdb9 100644
--- a/lib/net/ldap/dn.rb
+++ b/lib/net/ldap/dn.rb
@@ -57,19 +57,19 @@ def each_pair
state = :key_oid
key << char
when ' ' then state = :key
- else raise "DN badly formed"
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
end
when :key_normal then
case char
when '=' then state = :value
when 'a'..'z', 'A'..'Z', '0'..'9', '-', ' ' then key << char
- else raise "DN badly formed"
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
end
when :key_oid then
case char
when '=' then state = :value
when '0'..'9', '.', ' ' then key << char
- else raise "DN badly formed"
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
end
when :value then
case char
@@ -81,7 +81,7 @@ def each_pair
value << char
when ',' then
state = :key
- yield key.string.strip, value.string.rstrip
+ yield key.string.strip, value.string
key = StringIO.new
value = StringIO.new;
else
@@ -93,7 +93,7 @@ def each_pair
when '\\' then state = :value_normal_escape
when ',' then
state = :key
- yield key.string.strip, value.string.rstrip
+ yield key.string.strip, value.string
key = StringIO.new
value = StringIO.new;
else value << char
@@ -110,7 +110,7 @@ def each_pair
when '0'..'9', 'a'..'f', 'A'..'F' then
state = :value_normal
value << "#{hex_buffer}#{char}".to_i(16).chr
- else raise "DN badly formed"
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
end
when :value_quoted then
case char
@@ -132,7 +132,7 @@ def each_pair
when '0'..'9', 'a'..'f', 'A'..'F' then
state = :value_quoted
value << "#{hex_buffer}#{char}".to_i(16).chr
- else raise "DN badly formed"
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
end
when :value_hexstring then
case char
@@ -142,37 +142,37 @@ def each_pair
when ' ' then state = :value_end
when ',' then
state = :key
- yield key.string.strip, value.string.rstrip
+ yield key.string.strip, value.string
key = StringIO.new
value = StringIO.new;
- else raise "DN badly formed"
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
end
when :value_hexstring_hex then
case char
when '0'..'9', 'a'..'f', 'A'..'F' then
state = :value_hexstring
value << char
- else raise "DN badly formed"
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
end
when :value_end then
case char
when ' ' then state = :value_end
when ',' then
state = :key
- yield key.string.strip, value.string.rstrip
+ yield key.string.strip, value.string
key = StringIO.new
value = StringIO.new;
- else raise "DN badly formed"
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
end
- else raise "Fell out of state machine"
+ else raise Net::LDAP::InvalidDNError, "Fell out of state machine"
end
end
# Last pair
- raise "DN badly formed" unless
+ raise Net::LDAP::InvalidDNError, "DN badly formed" unless
[:value, :value_normal, :value_hexstring, :value_end].include? state
- yield key.string.strip, value.string.rstrip
+ yield key.string.strip, value.string
end
##
@@ -192,27 +192,19 @@ def to_s
# http://tools.ietf.org/html/rfc2253 section 2.4 lists these exceptions
# for dn values. All of the following must be escaped in any normal string
# using a single backslash ('\') as escape.
- ESCAPES = {
- ',' => ',',
- '+' => '+',
- '"' => '"',
- '\\' => '\\',
- '<' => '<',
- '>' => '>',
- ';' => ';',
- }
+ ESCAPES = %w[, + " \\ < > ;]
- # Compiled character class regexp using the keys from the above hash, and
+ # Compiled character class regexp using the values from the above list, and
# checking for a space or # at the start, or space at the end, of the
# string.
ESCAPE_RE = Regexp.new("(^ |^#| $|[" +
- ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
+ ESCAPES.map { |e| Regexp.escape(e) }.join +
"])")
##
# Escape a string for use in a DN value
def self.escape(string)
- string.gsub(ESCAPE_RE) { |char| "\\" + ESCAPES[char] }
+ string.gsub(ESCAPE_RE) { |char| "\\" + char }
end
##
diff --git a/lib/net/ldap/entry.rb b/lib/net/ldap/entry.rb
index 10965c7c..18668892 100644
--- a/lib/net/ldap/entry.rb
+++ b/lib/net/ldap/entry.rb
@@ -133,6 +133,13 @@ def attribute_names
@myhash.keys
end
+ ##
+ # Creates a duplicate of the internal Hash containing the attributes
+ # of the entry.
+ def to_h
+ @myhash.dup
+ end
+
##
# Accesses each of the attributes present in the Entry.
#
@@ -187,6 +194,8 @@ def setter?(sym)
sym.to_s[-1] == ?=
end
private :setter?
-end # class Entry
-require 'net/ldap/dataset' unless defined? Net::LDAP::Dataset
+ def ==(other)
+ other.instance_of?(self.class) && @myhash == other.to_h
+ end
+end # class Entry
diff --git a/lib/net/ldap/error.rb b/lib/net/ldap/error.rb
index 50442d06..49a338d6 100644
--- a/lib/net/ldap/error.rb
+++ b/lib/net/ldap/error.rb
@@ -1,38 +1,13 @@
class Net::LDAP
- class LdapError < StandardError
- def message
- "Deprecation warning: Net::LDAP::LdapError is no longer used. Use Net::LDAP::Error or rescue one of it's subclasses. \n" + super
- end
- end
-
class Error < StandardError; end
class AlreadyOpenedError < Error; end
class SocketError < Error; end
- class ConnectionRefusedError < Error;
- def initialize(*args)
- warn_deprecation_message
- super
- end
-
- def message
- warn_deprecation_message
- super
- end
-
- private
-
- def warn_deprecation_message
- warn "Deprecation warning: Net::LDAP::ConnectionRefused will be deprecated. Use Errno::ECONNREFUSED instead."
- end
- end
class ConnectionError < Error
def self.new(errors)
error = errors.first.first
if errors.size == 1
- if error.kind_of? Errno::ECONNREFUSED
- return Net::LDAP::ConnectionRefusedError.new(error.message)
- end
+ return error if error.is_a? Errno::ECONNREFUSED
return Net::LDAP::Error.new(error.message)
end
@@ -60,6 +35,7 @@ class SearchScopeInvalidError < Error; end
class ResponseTypeInvalidError < Error; end
class ResponseMissingOrInvalidError < Error; end
class EmptyDNError < Error; end
+ class InvalidDNError < Error; end
class HashTypeUnsupportedError < Error; end
class OperatorError < Error; end
class SubstringFilterError < Error; end
diff --git a/lib/net/ldap/filter.rb b/lib/net/ldap/filter.rb
index 6f064488..dc0d0ab3 100644
--- a/lib/net/ldap/filter.rb
+++ b/lib/net/ldap/filter.rb
@@ -490,7 +490,7 @@ def to_ber
when :eq
if @right == "*" # presence test
@left.to_s.to_ber_contextspecific(7)
- elsif @right =~ /[*]/ # substring
+ elsif @right.to_s =~ /[*]/ # substring
# Parsing substrings is a little tricky. We use String#split to
# break a string into substrings delimited by the * (star)
# character. But we also need to know whether there is a star at the
@@ -646,7 +646,7 @@ def match(entry)
##
# Converts escaped characters (e.g., "\\28") to unescaped characters
# @note slawson20170317: Don't attempt to unescape 16 byte binary data which we assume are objectGUIDs
- # The binary form of 5936AE79-664F-44EA-BCCB-5C39399514C6 triggers a BINARY -> UTF-8 conversion error
+ # The binary form of 5936AE79-664F-44EA-BCCB-5C39399514C6 triggers a BINARY -> UTF-8 conversion error
def unescape(right)
right = right.to_s
if right.length == 16 && right.encoding == Encoding::BINARY
@@ -755,7 +755,7 @@ def parse_paren_expression(scanner)
# This parses a given expression inside of parentheses.
def parse_filter_branch(scanner)
scanner.scan(/\s*/)
- if token = scanner.scan(/[-\w:.]*[\w]/)
+ if token = scanner.scan(/[-\w:.;]*[\w]/)
scanner.scan(/\s*/)
if op = scanner.scan(/<=|>=|!=|:=|=/)
scanner.scan(/\s*/)
diff --git a/lib/net/ldap/instrumentation.rb b/lib/net/ldap/instrumentation.rb
index 143e03b3..d5cc6bf7 100644
--- a/lib/net/ldap/instrumentation.rb
+++ b/lib/net/ldap/instrumentation.rb
@@ -12,8 +12,8 @@ module Net::LDAP::Instrumentation
def instrument(event, payload = {})
payload = (payload || {}).dup
if instrumentation_service
- instrumentation_service.instrument(event, payload) do |payload|
- payload[:result] = yield(payload) if block_given?
+ instrumentation_service.instrument(event, payload) do |instr_payload|
+ instr_payload[:result] = yield(instr_payload) if block_given?
end
else
yield(payload) if block_given?
diff --git a/lib/net/ldap/password.rb b/lib/net/ldap/password.rb
index 28406f03..9a6658ed 100644
--- a/lib/net/ldap/password.rb
+++ b/lib/net/ldap/password.rb
@@ -1,5 +1,6 @@
# -*- ruby encoding: utf-8 -*-
require 'digest/sha1'
+require 'digest/sha2'
require 'digest/md5'
require 'base64'
require 'securerandom'
@@ -19,20 +20,21 @@ class << self
# * Should we provide sha1 as a synonym for sha1? I vote no because then
# should you also provide ssha1 for symmetry?
#
- attribute_value = ""
def generate(type, str)
case type
when :md5
- attribute_value = '{MD5}' + Base64.encode64(Digest::MD5.digest(str)).chomp!
+ '{MD5}' + Base64.strict_encode64(Digest::MD5.digest(str))
when :sha
- attribute_value = '{SHA}' + Base64.encode64(Digest::SHA1.digest(str)).chomp!
+ '{SHA}' + Base64.strict_encode64(Digest::SHA1.digest(str))
when :ssha
salt = SecureRandom.random_bytes(16)
- attribute_value = '{SSHA}' + Base64.encode64(Digest::SHA1.digest(str + salt) + salt).chomp!
+ '{SSHA}' + Base64.strict_encode64(Digest::SHA1.digest(str + salt) + salt)
+ when :ssha256
+ salt = SecureRandom.random_bytes(16)
+ '{SSHA256}' + Base64.strict_encode64(Digest::SHA256.digest(str + salt) + salt)
else
raise Net::LDAP::HashTypeUnsupportedError, "Unsupported password-hash type (#{type})"
end
- return attribute_value
end
end
end
diff --git a/lib/net/ldap/pdu.rb b/lib/net/ldap/pdu.rb
index 382c7acb..83a609b7 100644
--- a/lib/net/ldap/pdu.rb
+++ b/lib/net/ldap/pdu.rb
@@ -123,7 +123,7 @@ def initialize(ber_object)
when ExtendedResponse
parse_extended_response(ber_object[1])
else
- raise LdapPduError.new("unknown pdu-type: #{@app_tag}")
+ raise Error.new("unknown pdu-type: #{@app_tag}")
end
parse_controls(ber_object[2]) if ber_object[2]
@@ -194,13 +194,13 @@ def parse_ldap_result(sequence)
# requestValue [1] OCTET STRING OPTIONAL }
def parse_extended_response(sequence)
- sequence.length >= 3 or raise Net::LDAP::PDU::Error, "Invalid LDAP result length."
+ sequence.length.between?(3, 5) or raise Net::LDAP::PDU::Error, "Invalid LDAP result length."
@ldap_result = {
:resultCode => sequence[0],
:matchedDN => sequence[1],
:errorMessage => sequence[2],
}
- @extended_response = sequence[3]
+ @extended_response = sequence.length == 3 ? nil : sequence.last
end
private :parse_extended_response
diff --git a/lib/net/ldap/version.rb b/lib/net/ldap/version.rb
index 0a57d621..536b2f89 100644
--- a/lib/net/ldap/version.rb
+++ b/lib/net/ldap/version.rb
@@ -1,5 +1,5 @@
module Net
class LDAP
- VERSION = "0.16.1"
+ VERSION = "0.19.0"
end
end
diff --git a/lib/net/snmp.rb b/lib/net/snmp.rb
index 258e8060..f89fe267 100644
--- a/lib/net/snmp.rb
+++ b/lib/net/snmp.rb
@@ -1,5 +1,5 @@
# -*- ruby encoding: utf-8 -*-
-require 'net/ldap/version'
+require_relative 'ldap/version'
# :stopdoc:
module Net
diff --git a/net-ldap.gemspec b/net-ldap.gemspec
index 7516759b..3def4c20 100644
--- a/net-ldap.gemspec
+++ b/net-ldap.gemspec
@@ -1,7 +1,7 @@
# -*- encoding: utf-8 -*-
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
-require 'net/ldap/version'
+require_relative 'lib/net/ldap/version'
Gem::Specification.new do |s|
s.name = %q{net-ldap}
@@ -21,17 +21,18 @@ Our roadmap for Net::LDAP 1.0 is to gain full client compliance with
the most recent LDAP RFCs (4510-4519, plutions of 4520-4532).}
s.email = ["blackhedd@rubyforge.org", "gemiel@gmail.com", "rory.ocon@gmail.com", "kaspar.schiess@absurd.li", "austin@rubyforge.org"]
s.extra_rdoc_files = ["Contributors.rdoc", "Hacking.rdoc", "History.rdoc", "License.rdoc", "README.rdoc"]
- s.files = `git ls-files`.split $/
+ s.files = Dir["*.rdoc", "lib/**/*"]
s.test_files = s.files.grep(%r{^test})
s.homepage = %q{http://github.com/ruby-ldap/ruby-net-ldap}
s.rdoc_options = ["--main", "README.rdoc"]
s.require_paths = ["lib"]
- s.required_ruby_version = ">= 2.0.0"
+ s.required_ruby_version = ">= 3.0.0"
s.summary = %q{Net::LDAP for Ruby (also called net-ldap) implements client access for the Lightweight Directory Access Protocol (LDAP), an IETF standard protocol for accessing distributed directory services}
+ s.add_dependency("ostruct")
s.add_development_dependency("flexmock", "~> 1.3")
- s.add_development_dependency("rake", "~> 10.0")
- s.add_development_dependency("rubocop", "~> 0.42.0")
- s.add_development_dependency("test-unit")
- s.add_development_dependency("byebug")
+ s.add_development_dependency("rake", "~> 12.3.3")
+ s.add_development_dependency("rubocop", "~> 1.48")
+ s.add_development_dependency("test-unit", "~> 3.3")
+ s.add_development_dependency("byebug", "~> 9.0.6") unless RUBY_PLATFORM == "java"
end
diff --git a/script/changelog b/script/changelog
index cda2ad83..f42a0bd4 100755
--- a/script/changelog
+++ b/script/changelog
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
# Usage: script/changelog [-r ] [-b ] [-h ]
#
# repo: BASE string of GitHub REPOsitory url. e.g. "user_or_org/REPOsitory". Defaults to git remote url.
diff --git a/script/generate-fixture-ca b/script/generate-fixture-ca
deleted file mode 100755
index 89eb3d8d..00000000
--- a/script/generate-fixture-ca
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/bin/bash
-
-BASE_PATH=$( cd "`dirname $0`/../test/fixtures/ca" && pwd )
-cd "${BASE_PATH}" || exit 4
-
-USAGE=$( cat << EOS
-Usage:
- $0 --regenerate
-
-Generates a new self-signed CA, for integration testing. This should only need
-to be run if you are writing new TLS/SSL tests, and need to generate
-additional fixtuer CAs.
-
-This script uses the GnuTLS certtool CLI. If you are on macOS,
-'brew install gnutls', and it will be installed as 'gnutls-certtool'.
-Apple unfortunately ships with an incompatible /usr/bin/certtool that does
-different things.
-EOS
-)
-
-if [ "x$1" != 'x--regenerate' ]; then
- echo "${USAGE}"
- exit 1
-fi
-
-TOOL=`type -p certtool`
-if [ "$(uname)" = "Darwin" ]; then
- TOOL=`type -p gnutls-certtool`
- if [ ! -x "${TOOL}" ]; then
- echo "Sorry, Darwin requires gnutls-certtool; try `brew install gnutls`"
- exit 2
- fi
-fi
-
-if [ ! -x "${TOOL}" ]; then
- echo "Sorry, no certtool found!"
- exit 3
-fi
-export TOOL
-
-
-${TOOL} --generate-privkey > ./cakey.pem
-${TOOL} --generate-self-signed \
- --load-privkey ./cakey.pem \
- --template ./ca.info \
- --outfile ./cacert.pem
-
-echo "cert and private key generated! Don't forget to check them in"
diff --git a/script/install-openldap b/script/install-openldap
deleted file mode 100755
index 3e391d87..00000000
--- a/script/install-openldap
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env sh
-set -e
-set -x
-
-BASE_PATH=$( cd "`dirname $0`/../test/fixtures/openldap" && pwd )
-SEED_PATH=$( cd "`dirname $0`/../test/fixtures" && pwd )
-
-dpkg -s slapd time ldap-utils gnutls-bin ssl-cert > /dev/null ||\
- DEBIAN_FRONTEND=noninteractive apt-get update -y --force-yes && \
- DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes slapd time ldap-utils gnutls-bin ssl-cert
-
-/etc/init.d/slapd stop
-
-TMPDIR=$(mktemp -d)
-cd $TMPDIR
-
-# Delete data and reconfigure.
-cp -v /var/lib/ldap/DB_CONFIG ./DB_CONFIG
-rm -rf /etc/ldap/slapd.d/*
-rm -rf /var/lib/ldap/*
-cp -v ./DB_CONFIG /var/lib/ldap/DB_CONFIG
-slapadd -F /etc/ldap/slapd.d -b "cn=config" -l $BASE_PATH/slapd.conf.ldif
-# Load memberof and ref-int overlays and configure them.
-slapadd -F /etc/ldap/slapd.d -b "cn=config" -l $BASE_PATH/memberof.ldif
-# Load retcode overlay and configure
-slapadd -F /etc/ldap/slapd.d -b "cn=config" -l $BASE_PATH/retcode.ldif
-
-# Add base domain.
-slapadd -F /etc/ldap/slapd.d < /etc/ssl/ldap01.info <> /etc/ssl/ldap01.info
-done
-
-# Create the server certificate
-certtool --generate-certificate \
- --load-privkey /etc/ssl/private/ldap01_slapd_key.pem \
- --load-ca-certificate "${CA_CERT}" \
- --load-ca-privkey "${CA_KEY}" \
- --template /etc/ssl/ldap01.info \
- --outfile /etc/ssl/certs/ldap01_slapd_cert.pem
-
-ldapmodify -Y EXTERNAL -H ldapi:/// <> /etc/hosts
-grep ldap02 /etc/hosts || echo "127.0.0.1 ldap02.example.com" >> /etc/hosts
-grep bogus /etc/hosts || echo "127.0.0.1 bogus.example.com" >> /etc/hosts
-
-service slapd restart
diff --git a/script/ldap-docker b/script/ldap-docker
new file mode 100755
index 00000000..c677eec8
--- /dev/null
+++ b/script/ldap-docker
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+# Usage: script/ldap-docker
+#
+# Starts a openldap docker container ready for integration tests
+
+docker run --rm -ti \
+ --hostname ldap.example.org \
+ --env LDAP_TLS_VERIFY_CLIENT=try \
+ -p 389:389 -p 636:636 \
+ -v "$(pwd)"/test/fixtures/ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom \
+ --name my-openldap-container \
+ osixia/openldap:1.3.0 --copy-service --loglevel debug
\ No newline at end of file
diff --git a/script/release b/script/release
index 6dcd8cb3..595a00dc 100755
--- a/script/release
+++ b/script/release
@@ -9,8 +9,7 @@ version="$(script/package | grep Version: | awk '{print $2}')"
[ -n "$version" ] || exit 1
echo $version
-git commit --allow-empty -a -m "Release $version"
-git tag "v$version"
+git tag "v$version" -m "Release $version"
git push origin
git push origin "v$version"
gem push pkg/*-${version}.gem
diff --git a/test/ber/test_ber.rb b/test/ber/test_ber.rb
index 5d5c1266..b700972e 100644
--- a/test/ber/test_ber.rb
+++ b/test/ber/test_ber.rb
@@ -95,7 +95,7 @@ def test_utf8_encodable_strings
def test_encode_binary_data
# This is used for searching for GUIDs in Active Directory
assert_equal "\x04\x10" + "j1\xB4\xA1*\xA2zA\xAC\xA9`?'\xDDQ\x16".b,
- ["6a31b4a12aa27a41aca9603f27dd5116"].pack("H*").to_ber_bin
+ ["6a31b4a12aa27a41aca9603f27dd5116"].pack("H*").to_ber_bin
end
def test_non_utf8_encodable_strings
diff --git a/test/fixtures/ca/ca.info b/test/fixtures/ca/ca.info
deleted file mode 100644
index c0fd3629..00000000
--- a/test/fixtures/ca/ca.info
+++ /dev/null
@@ -1,4 +0,0 @@
-cn = rubyldap
-ca
-cert_signing_key
-expiration_days = 7200
diff --git a/test/fixtures/ca/cacert.pem b/test/fixtures/ca/cacert.pem
deleted file mode 100644
index 0218dd8a..00000000
--- a/test/fixtures/ca/cacert.pem
+++ /dev/null
@@ -1,24 +0,0 @@
------BEGIN CERTIFICATE-----
-MIID7zCCAlegAwIBAgIMV7zWei6SNfABx6jMMA0GCSqGSIb3DQEBCwUAMBMxETAP
-BgNVBAMTCHJ1YnlsZGFwMB4XDTE2MDgyMzIzMDQyNloXDTM2MDUxMDIzMDQyNlow
-EzERMA8GA1UEAxMIcnVieWxkYXAwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGK
-AoIBgQDGe9wziGHZJhIf+IEKSk1tpT9Mu7YgsUwjrlutvkoO1Q6K+amTAVDXizPf
-1DVSDpZP5+CfBOznhgLMsPvrQ02w4qx5/6X9L+zJcMk8jTNYSKj5uIKpK52E7Uok
-aygMXeaqroPONGkoJIZiVGgdbWfTvcffTm8FOhztXUbMrMXJNinFsocGHEoMNN8b
-vqgAyG4+DFHoK4L0c6eQjE4nZBChieZdShUhaBpV7r2qSNbPw67cvAKuEzml58mV
-1ZF1F73Ua8gPWXHEfUe2GEfG0NnRq6sGbsDYe/DIKxC7AZ89udZF3WZXNrPhvXKj
-ZT7njwcMQemns4dNPQ0k2V4vAQ8pD8r8Qvb65FiSopUhVaGQswAnIMS1DnFq88AQ
-KJTKIXbBuMwuaNNSs6R/qTS2RDk1w+CGpRXAg7+1SX5NKdrEsu1IaABA/tQ/zKKk
-OLLJaD0giX1weBVmNeFcKxIoT34VS59eEt5APmPcguJnx+aBrA9TLzSO788apBN0
-4lGAmR0CAwEAAaNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwQA
-MB0GA1UdDgQWBBRTvXSkge03oqLu7UUjFI+oLYwnujANBgkqhkiG9w0BAQsFAAOC
-AYEATSZQWH+uSN5GvOUvJ8LHWkeVovn0UhboK0K7GzmMeGz+dp/Xrj6eQ4ONK0zI
-RCJyoo/nCR7CfQ5ujVXr03XD2SUgyD565ulXuhw336DasL5//fucmQYDeqhwbKML
-FTzsF9H9dO4J5TjxJs7e5dRJ0wrP/XEY+WFhXXdSHTl8vGCI6QqWc7TvDpmbS4iX
-uTzjJswu9Murt9JUJNMN2DlDi/vBBeruaj4c2cMMnKMvkfj14kd8wMocmzj+gVQl
-r+fRQbKAJNec65lA4/Zeb6sD9SAi0ZIVgxA4a7g8/sdNWHIAxPicpJkIJf30TsyY
-F+8+Hd5mBtCbvFfAVkT6bHBP1OiAgNke+Rh/j/sQbyWbKCKw0+jpFJgO9KUNGfC0
-O/CqX+J4G7HqL8VJqrLnBvOdhfetAvNQtf1gcw5ZwpeEFM+Kvx/lsILaIYdAUSjX
-ePOc5gI2Bi9WXq+T9AuhSf+TWUR874m/rdTWe5fM8mXCNl7C4I5zCqLltEDkSoMP
-jDj/
------END CERTIFICATE-----
diff --git a/test/fixtures/ca/cakey.pem b/test/fixtures/ca/cakey.pem
deleted file mode 100644
index d75ab299..00000000
--- a/test/fixtures/ca/cakey.pem
+++ /dev/null
@@ -1,190 +0,0 @@
-Public Key Info:
- Public Key Algorithm: RSA
- Key Security Level: High (3072 bits)
-
-modulus:
- 00:c6:7b:dc:33:88:61:d9:26:12:1f:f8:81:0a:4a:4d
- 6d:a5:3f:4c:bb:b6:20:b1:4c:23:ae:5b:ad:be:4a:0e
- d5:0e:8a:f9:a9:93:01:50:d7:8b:33:df:d4:35:52:0e
- 96:4f:e7:e0:9f:04:ec:e7:86:02:cc:b0:fb:eb:43:4d
- b0:e2:ac:79:ff:a5:fd:2f:ec:c9:70:c9:3c:8d:33:58
- 48:a8:f9:b8:82:a9:2b:9d:84:ed:4a:24:6b:28:0c:5d
- e6:aa:ae:83:ce:34:69:28:24:86:62:54:68:1d:6d:67
- d3:bd:c7:df:4e:6f:05:3a:1c:ed:5d:46:cc:ac:c5:c9
- 36:29:c5:b2:87:06:1c:4a:0c:34:df:1b:be:a8:00:c8
- 6e:3e:0c:51:e8:2b:82:f4:73:a7:90:8c:4e:27:64:10
- a1:89:e6:5d:4a:15:21:68:1a:55:ee:bd:aa:48:d6:cf
- c3:ae:dc:bc:02:ae:13:39:a5:e7:c9:95:d5:91:75:17
- bd:d4:6b:c8:0f:59:71:c4:7d:47:b6:18:47:c6:d0:d9
- d1:ab:ab:06:6e:c0:d8:7b:f0:c8:2b:10:bb:01:9f:3d
- b9:d6:45:dd:66:57:36:b3:e1:bd:72:a3:65:3e:e7:8f
- 07:0c:41:e9:a7:b3:87:4d:3d:0d:24:d9:5e:2f:01:0f
- 29:0f:ca:fc:42:f6:fa:e4:58:92:a2:95:21:55:a1:90
- b3:00:27:20:c4:b5:0e:71:6a:f3:c0:10:28:94:ca:21
- 76:c1:b8:cc:2e:68:d3:52:b3:a4:7f:a9:34:b6:44:39
- 35:c3:e0:86:a5:15:c0:83:bf:b5:49:7e:4d:29:da:c4
- b2:ed:48:68:00:40:fe:d4:3f:cc:a2:a4:38:b2:c9:68
- 3d:20:89:7d:70:78:15:66:35:e1:5c:2b:12:28:4f:7e
- 15:4b:9f:5e:12:de:40:3e:63:dc:82:e2:67:c7:e6:81
- ac:0f:53:2f:34:8e:ef:cf:1a:a4:13:74:e2:51:80:99
- 1d:
-
-public exponent:
- 01:00:01:
-
-private exponent:
- 1d:0d:9a:50:ec:c0:ad:e1:75:bb:ba:4b:61:2f:39:20
- 38:95:08:6d:5d:9e:71:75:5c:af:b3:f9:bd:a5:e7:7f
- e6:4e:0f:77:73:ee:38:60:24:9f:26:3f:50:c2:bf:21
- df:76:68:99:be:45:d3:29:f9:94:ee:bf:21:53:cb:b6
- 7d:a7:93:80:09:53:03:45:dc:c2:a6:a2:37:64:f1:a2
- 49:21:ac:91:6b:a3:d7:bd:d2:62:0c:ec:a6:83:10:e7
- a7:ca:3d:be:dc:4b:1c:36:24:79:96:33:5b:43:5d:74
- 50:0e:46:b0:9b:6d:9f:71:06:89:a5:c8:65:ed:d9:a3
- 15:00:3c:3e:a9:75:50:9d:72:cb:c9:aa:e1:ba:a3:9c
- 07:77:14:32:30:d4:4d:65:f4:7c:23:1d:79:84:9b:2e
- 9a:19:df:43:ed:cd:e3:08:1f:d5:ff:6b:42:98:36:f7
- 44:cc:48:b4:f7:b8:16:b3:23:37:8d:b8:22:3f:8a:86
- db:71:b3:85:2d:6d:42:44:b7:dc:c1:36:e0:c4:0f:fe
- cb:76:84:81:e2:83:f5:82:76:a9:7b:35:d5:44:00:d1
- 1a:fc:ef:b9:a4:2b:62:aa:f8:56:eb:60:e5:16:33:f1
- 28:e1:da:91:50:e3:a4:c7:d6:30:21:cf:04:07:cd:8c
- b6:9e:b0:a7:6c:96:57:2e:09:5b:39:26:d0:60:be:e3
- 90:59:a3:8e:e7:6e:3f:62:7e:b4:2a:e1:8f:00:37:7a
- 83:9e:7a:9c:d2:ae:ba:50:84:73:65:3a:64:95:d8:48
- f9:fd:0e:c3:5b:6e:08:3b:c5:c9:1c:29:55:bb:67:e8
- fa:50:40:30:2a:d1:b7:cf:54:a8:f0:f0:76:89:ad:19
- e7:a0:3a:56:6c:75:c5:bc:d8:46:ce:1e:66:f2:61:96
- 11:e4:57:cc:52:ff:e4:ed:6b:2c:ce:78:15:ba:b7:ed
- 31:f2:68:88:79:bf:7c:29:3c:2f:66:71:0b:09:b7:41
-
-
-prime1:
- 00:fd:c2:37:b9:6f:77:88:51:a2:f7:4f:c2:3c:a4:57
- bf:ba:71:14:f3:61:f4:39:78:22:3d:bc:d8:d2:4e:c0
- 4b:9e:c2:6d:38:a8:21:e2:70:1a:96:48:95:18:85:01
- 46:fb:62:a4:81:09:f8:2a:3a:87:78:07:5d:93:54:ce
- 2a:51:b3:51:6f:61:0a:2e:9d:b0:51:37:e3:13:bd:81
- 23:2b:61:53:fa:ac:08:dc:a0:e6:63:a3:b0:cc:cf:73
- 1d:65:b7:11:bc:29:70:fb:72:ea:63:9d:67:02:d6:35
- 24:13:1d:bc:72:fb:9e:3d:ab:0b:57:6e:bd:a1:51:56
- f9:bc:96:15:74:a3:31:16:c6:b8:98:1b:0a:a2:59:7c
- c8:b7:14:b8:5b:f3:2e:26:b4:f0:46:c4:3d:27:dd:41
- 31:52:a7:15:a8:af:6a:98:a5:9c:20:17:f9:1d:54:54
- ff:10:91:a3:a5:ca:ac:63:e7:16:2b:71:3c:3a:cd:4f
- ed:
-
-prime2:
- 00:c8:3c:a8:9f:8a:db:42:b5:8d:cf:2a:a1:2f:e5:73
- 05:de:30:d8:17:b9:5c:9d:08:60:02:c9:66:9d:88:50
- ac:cd:0f:b5:47:b4:a8:73:3b:7d:65:79:bf:4c:6f:d0
- e2:03:ed:d4:28:4e:00:07:23:00:01:4f:05:de:9b:44
- 1a:84:ae:09:4a:d6:ed:61:5d:77:e2:fa:13:99:4c:b7
- 76:72:3d:f8:53:93:69:78:e8:bd:26:cb:b0:f9:01:f4
- 1d:20:4f:60:f5:ab:3c:19:85:73:34:f3:ec:d2:67:ef
- 56:b8:5d:93:73:8e:d9:3e:28:ff:87:f5:4a:26:fa:b1
- ae:c6:d3:9d:03:e3:fd:c2:24:48:af:85:2a:8e:3b:5b
- 93:07:38:91:21:ae:49:cb:6d:e3:30:81:15:ed:65:eb
- dc:01:df:3b:9d:43:fd:a6:e1:df:ef:ad:22:42:34:f1
- 3f:81:5e:57:0a:e0:56:94:f2:2a:00:d0:cc:c5:50:67
- f1:
-
-coefficient:
- 00:bd:23:8c:2e:a7:7b:6b:1e:85:77:db:7d:77:f6:e5
- b0:15:c6:e1:9e:35:57:72:df:35:6d:93:89:7f:83:9f
- 63:7f:08:0a:b3:d4:ba:63:9b:10:7f:0f:d3:55:e9:38
- cf:90:37:3d:85:3d:a7:97:8c:33:f2:c2:b1:38:2b:db
- 39:ca:a8:d0:23:d7:89:cc:8d:02:7d:61:9b:b6:04:69
- 14:e8:c9:84:34:36:6c:fb:84:58:cc:9a:53:74:a4:42
- bd:1d:25:1b:ba:82:c0:fb:23:2c:90:bb:35:4b:5b:b0
- 98:d0:ab:9d:61:6e:ea:e8:84:e7:a7:6c:ae:1b:2c:00
- cb:0f:1a:f8:e2:7c:fd:42:1a:e2:13:52:c7:50:fa:65
- c9:5f:ed:40:a8:7f:46:0e:ce:f6:56:83:6f:0e:8e:39
- f8:33:5f:83:de:be:be:ef:8c:66:ad:16:c8:ec:98:d4
- b2:b2:55:66:a2:9e:27:6a:84:f1:31:07:e8:bf:a7:a7
- bd:
-
-exp1:
- 00:b6:50:0c:53:19:07:8b:14:03:fe:a4:fa:0b:31:93
- ad:b7:18:b9:91:a6:c5:9d:68:77:49:5d:dd:75:33:89
- 2a:8b:54:6a:be:32:e5:ad:57:17:72:f3:90:d2:fd:f4
- 0d:f8:5c:45:8e:44:08:5c:e6:92:1f:a5:43:10:af:f4
- 33:29:61:a8:d7:59:a3:c4:1c:1c:ea:2d:39:e3:1b:da
- a4:d6:ec:e5:36:0a:d5:8f:15:b6:90:cd:b1:1f:64:c7
- f2:cd:fa:3a:2e:b2:a3:6e:b4:80:3b:b3:81:a7:e3:18
- 68:e3:a7:10:96:97:ba:77:d9:e4:9b:1b:7f:f8:5f:85
- 1a:85:e8:5a:5f:e3:43:48:76:db:76:c4:ae:de:37:66
- d4:99:dc:b4:1b:b3:da:6b:8a:c1:ba:46:11:1e:0b:f3
- 63:a9:5b:4b:cf:56:c0:42:0d:71:df:08:fa:3c:9d:33
- 37:d1:c2:a1:0d:63:50:79:b2:34:16:60:13:82:b7:b1
- 7d:
-
-exp2:
- 00:98:38:2c:c4:24:4e:2c:b7:52:17:a4:43:a6:e2:99
- ff:62:fa:e4:bb:9c:49:40:83:66:61:97:f3:af:5c:3a
- 60:32:ff:77:03:0c:de:65:c3:5a:bf:72:bf:2f:7f:6d
- 5e:f4:37:af:69:f8:69:e3:03:03:74:fb:3a:ee:10:40
- c4:9c:0a:a5:bb:c4:09:ef:53:9b:d8:eb:dd:4c:53:da
- c0:6b:76:9a:ba:06:3d:4f:12:37:01:30:25:d8:16:59
- 1a:6f:3e:88:ea:19:83:75:af:52:76:75:dc:99:d3:33
- 4a:4c:9b:ae:85:51:99:ea:bc:46:0d:78:36:27:cd:ba
- 97:b0:44:9c:7f:a1:a9:7e:16:11:3f:85:4f:65:92:d0
- 39:c4:6a:87:42:00:79:ce:f1:39:9d:dc:f3:eb:65:e8
- d8:76:7f:da:94:e2:64:08:a2:7b:97:7b:99:a8:95:10
- b5:03:46:d1:8a:ce:22:63:d6:78:81:e8:39:52:e2:9e
- 31:
-
-
-Public Key ID: 53:BD:74:A4:81:ED:37:A2:A2:EE:ED:45:23:14:8F:A8:2D:8C:27:BA
-Public key's random art:
-+--[ RSA 3072]----+
-| . o. . |
-| . +...+ |
-| . o o.+ . |
-| o o . . .ooo |
-| o = . S o..o . |
-| . o . .+.. |
-|. . .. |
-| . .. . |
-|E oo.o |
-+-----------------+
-
------BEGIN RSA PRIVATE KEY-----
-MIIG5QIBAAKCAYEAxnvcM4hh2SYSH/iBCkpNbaU/TLu2ILFMI65brb5KDtUOivmp
-kwFQ14sz39Q1Ug6WT+fgnwTs54YCzLD760NNsOKsef+l/S/syXDJPI0zWEio+biC
-qSudhO1KJGsoDF3mqq6DzjRpKCSGYlRoHW1n073H305vBToc7V1GzKzFyTYpxbKH
-BhxKDDTfG76oAMhuPgxR6CuC9HOnkIxOJ2QQoYnmXUoVIWgaVe69qkjWz8Ou3LwC
-rhM5pefJldWRdRe91GvID1lxxH1HthhHxtDZ0aurBm7A2HvwyCsQuwGfPbnWRd1m
-Vzaz4b1yo2U+548HDEHpp7OHTT0NJNleLwEPKQ/K/EL2+uRYkqKVIVWhkLMAJyDE
-tQ5xavPAECiUyiF2wbjMLmjTUrOkf6k0tkQ5NcPghqUVwIO/tUl+TSnaxLLtSGgA
-QP7UP8yipDiyyWg9IIl9cHgVZjXhXCsSKE9+FUufXhLeQD5j3ILiZ8fmgawPUy80
-ju/PGqQTdOJRgJkdAgMBAAECggGAHQ2aUOzAreF1u7pLYS85IDiVCG1dnnF1XK+z
-+b2l53/mTg93c+44YCSfJj9Qwr8h33Zomb5F0yn5lO6/IVPLtn2nk4AJUwNF3MKm
-ojdk8aJJIayRa6PXvdJiDOymgxDnp8o9vtxLHDYkeZYzW0NddFAORrCbbZ9xBoml
-yGXt2aMVADw+qXVQnXLLyarhuqOcB3cUMjDUTWX0fCMdeYSbLpoZ30PtzeMIH9X/
-a0KYNvdEzEi097gWsyM3jbgiP4qG23GzhS1tQkS33ME24MQP/st2hIHig/WCdql7
-NdVEANEa/O+5pCtiqvhW62DlFjPxKOHakVDjpMfWMCHPBAfNjLaesKdsllcuCVs5
-JtBgvuOQWaOO524/Yn60KuGPADd6g556nNKuulCEc2U6ZJXYSPn9DsNbbgg7xckc
-KVW7Z+j6UEAwKtG3z1So8PB2ia0Z56A6Vmx1xbzYRs4eZvJhlhHkV8xS/+TtayzO
-eBW6t+0x8miIeb98KTwvZnELCbdBAoHBAP3CN7lvd4hRovdPwjykV7+6cRTzYfQ5
-eCI9vNjSTsBLnsJtOKgh4nAalkiVGIUBRvtipIEJ+Co6h3gHXZNUzipRs1FvYQou
-nbBRN+MTvYEjK2FT+qwI3KDmY6OwzM9zHWW3EbwpcPty6mOdZwLWNSQTHbxy+549
-qwtXbr2hUVb5vJYVdKMxFsa4mBsKoll8yLcUuFvzLia08EbEPSfdQTFSpxWor2qY
-pZwgF/kdVFT/EJGjpcqsY+cWK3E8Os1P7QKBwQDIPKifittCtY3PKqEv5XMF3jDY
-F7lcnQhgAslmnYhQrM0PtUe0qHM7fWV5v0xv0OID7dQoTgAHIwABTwXem0QahK4J
-StbtYV134voTmUy3dnI9+FOTaXjovSbLsPkB9B0gT2D1qzwZhXM08+zSZ+9WuF2T
-c47ZPij/h/VKJvqxrsbTnQPj/cIkSK+FKo47W5MHOJEhrknLbeMwgRXtZevcAd87
-nUP9puHf760iQjTxP4FeVwrgVpTyKgDQzMVQZ/ECgcEAtlAMUxkHixQD/qT6CzGT
-rbcYuZGmxZ1od0ld3XUziSqLVGq+MuWtVxdy85DS/fQN+FxFjkQIXOaSH6VDEK/0
-MylhqNdZo8QcHOotOeMb2qTW7OU2CtWPFbaQzbEfZMfyzfo6LrKjbrSAO7OBp+MY
-aOOnEJaXunfZ5Jsbf/hfhRqF6Fpf40NIdtt2xK7eN2bUmdy0G7Paa4rBukYRHgvz
-Y6lbS89WwEINcd8I+jydMzfRwqENY1B5sjQWYBOCt7F9AoHBAJg4LMQkTiy3Uhek
-Q6bimf9i+uS7nElAg2Zhl/OvXDpgMv93AwzeZcNav3K/L39tXvQ3r2n4aeMDA3T7
-Ou4QQMScCqW7xAnvU5vY691MU9rAa3aaugY9TxI3ATAl2BZZGm8+iOoZg3WvUnZ1
-3JnTM0pMm66FUZnqvEYNeDYnzbqXsEScf6GpfhYRP4VPZZLQOcRqh0IAec7xOZ3c
-8+tl6Nh2f9qU4mQIonuXe5molRC1A0bRis4iY9Z4geg5UuKeMQKBwQC9I4wup3tr
-HoV323139uWwFcbhnjVXct81bZOJf4OfY38ICrPUumObEH8P01XpOM+QNz2FPaeX
-jDPywrE4K9s5yqjQI9eJzI0CfWGbtgRpFOjJhDQ2bPuEWMyaU3SkQr0dJRu6gsD7
-IyyQuzVLW7CY0KudYW7q6ITnp2yuGywAyw8a+OJ8/UIa4hNSx1D6Zclf7UCof0YO
-zvZWg28Ojjn4M1+D3r6+74xmrRbI7JjUsrJVZqKeJ2qE8TEH6L+np70=
------END RSA PRIVATE KEY-----
diff --git a/test/fixtures/ca/docker-ca.pem b/test/fixtures/ca/docker-ca.pem
new file mode 100644
index 00000000..ab543a31
--- /dev/null
+++ b/test/fixtures/ca/docker-ca.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC0zCCAlmgAwIBAgIUCfQ+m0pgZ/BjYAJvxrn/bdGNZokwCgYIKoZIzj0EAwMw
+gZYxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxBMUEgQ2FyIFdhc2gxJDAiBgNVBAsT
+G0luZm9ybWF0aW9uIFRlY2hub2xvZ3kgRGVwLjEUMBIGA1UEBxMLQWxidXF1ZXJx
+dWUxEzARBgNVBAgTCk5ldyBNZXhpY28xHzAdBgNVBAMTFmRvY2tlci1saWdodC1i
+YXNlaW1hZ2UwHhcNMTUxMjIzMTM1MzAwWhcNMjAxMjIxMTM1MzAwWjCBljELMAkG
+A1UEBhMCVVMxFTATBgNVBAoTDEExQSBDYXIgV2FzaDEkMCIGA1UECxMbSW5mb3Jt
+YXRpb24gVGVjaG5vbG9neSBEZXAuMRQwEgYDVQQHEwtBbGJ1cXVlcnF1ZTETMBEG
+A1UECBMKTmV3IE1leGljbzEfMB0GA1UEAxMWZG9ja2VyLWxpZ2h0LWJhc2VpbWFn
+ZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMZf/12pupAgl8Sm+j8GmjNeNbSFAZWW
+oTmIvf2Mu4LWPHy4bTldkQgHUbBpT3xWz8f0lB/ru7596CHsGoL2A28hxuclq5hb
+Ux1yrIt3bJIY3TuiX25HGTe6kGCJPB1aLaNmMGQwDgYDVR0PAQH/BAQDAgEGMBIG
+A1UdEwEB/wQIMAYBAf8CAQIwHQYDVR0OBBYEFE+l6XolXDAYnGLTl4W6ULKHrm74
+MB8GA1UdIwQYMBaAFE+l6XolXDAYnGLTl4W6ULKHrm74MAoGCCqGSM49BAMDA2gA
+MGUCMQCXLZj8okyxW6UTL7hribUUbu63PbjuwIXnwi420DdNsvA9A7fcQEXScWFL
+XAGC8rkCMGcqwXZPSRfwuI9r+R11gTrP92hnaVxs9sjRikctpkQpOyNlIXFPopFK
+8FdfWPypvA==
+-----END CERTIFICATE-----
diff --git a/test/fixtures/openldap/retcode.ldif b/test/fixtures/ldif/06-retcode.ldif
similarity index 92%
rename from test/fixtures/openldap/retcode.ldif
rename to test/fixtures/ldif/06-retcode.ldif
index 9faffe1d..dfd12d06 100644
--- a/test/fixtures/openldap/retcode.ldif
+++ b/test/fixtures/ldif/06-retcode.ldif
@@ -1,19 +1,18 @@
-dn: cn=module,cn=config
-cn: module
-objectClass: olcModuleList
-objectClass: top
-olcModulePath: /usr/lib/ldap
-olcModuleLoad: retcode.la
+dn: cn=module{0},cn=config
+changetype: modify
+add: olcModuleLoad
+olcModuleLoad: retcode
# source: http://www.opensource.apple.com/source/OpenLDAP/OpenLDAP-186/OpenLDAP/tests/data/retcode.conf?txt
-dn: olcOverlay={2}retcode,olcDatabase={1}hdb,cn=config
+dn: olcOverlay={2}retcode,olcDatabase={1}{{ LDAP_BACKEND }},cn=config
+changetype: add
objectClass: olcConfig
objectClass: olcRetcodeConfig
objectClass: olcOverlayConfig
objectClass: top
olcOverlay: retcode
-olcRetcodeParent: ou=Retcodes,dc=rubyldap,dc=com
+olcRetcodeParent: ou=Retcodes,dc=example,dc=org
olcRetcodeInDir: TRUE
olcRetcodeSleep: 0
olcRetcodeItem: "cn=success" 0x00
diff --git a/test/fixtures/ldif/50-seed.ldif b/test/fixtures/ldif/50-seed.ldif
new file mode 100644
index 00000000..addedf5a
--- /dev/null
+++ b/test/fixtures/ldif/50-seed.ldif
@@ -0,0 +1,374 @@
+dn: ou=People,dc=example,dc=org
+objectClass: top
+objectClass: organizationalUnit
+ou: People
+
+dn: ou=Groups,dc=example,dc=org
+objectClass: top
+objectClass: organizationalUnit
+ou: Groups
+
+# Directory Superuser
+dn: uid=admin,dc=example,dc=org
+uid: admin
+cn: system administrator
+sn: administrator
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+displayName: Directory Superuser
+userPassword: passworD1
+
+# Users 1-10
+
+dn: uid=user1,ou=People,dc=example,dc=org
+uid: user1
+cn: user1
+sn: user1
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user1@rubyldap.com
+
+dn: uid=user2,ou=People,dc=example,dc=org
+uid: user2
+cn: user2
+sn: user2
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user2@rubyldap.com
+
+dn: uid=user3,ou=People,dc=example,dc=org
+uid: user3
+cn: user3
+sn: user3
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user3@rubyldap.com
+
+dn: uid=user4,ou=People,dc=example,dc=org
+uid: user4
+cn: user4
+sn: user4
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user4@rubyldap.com
+
+dn: uid=user5,ou=People,dc=example,dc=org
+uid: user5
+cn: user5
+sn: user5
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user5@rubyldap.com
+
+dn: uid=user6,ou=People,dc=example,dc=org
+uid: user6
+cn: user6
+sn: user6
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user6@rubyldap.com
+
+dn: uid=user7,ou=People,dc=example,dc=org
+uid: user7
+cn: user7
+sn: user7
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user7@rubyldap.com
+
+dn: uid=user8,ou=People,dc=example,dc=org
+uid: user8
+cn: user8
+sn: user8
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user8@rubyldap.com
+
+dn: uid=user9,ou=People,dc=example,dc=org
+uid: user9
+cn: user9
+sn: user9
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user9@rubyldap.com
+
+dn: uid=user10,ou=People,dc=example,dc=org
+uid: user10
+cn: user10
+sn: user10
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: user10@rubyldap.com
+
+# Emailless User
+
+dn: uid=emailless-user1,ou=People,dc=example,dc=org
+uid: emailless-user1
+cn: emailless-user1
+sn: emailless-user1
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+
+# Groupless User
+
+dn: uid=groupless-user1,ou=People,dc=example,dc=org
+uid: groupless-user1
+cn: groupless-user1
+sn: groupless-user1
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+
+# Admin User
+
+dn: uid=admin1,ou=People,dc=example,dc=org
+uid: admin1
+cn: admin1
+sn: admin1
+objectClass: top
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+userPassword: passworD1
+mail: admin1@rubyldap.com
+
+# Groups
+
+dn: cn=ghe-users,ou=Groups,dc=example,dc=org
+cn: ghe-users
+objectClass: groupOfNames
+member: uid=user1,ou=People,dc=example,dc=org
+member: uid=emailless-user1,ou=People,dc=example,dc=org
+
+dn: cn=all-users,ou=Groups,dc=example,dc=org
+cn: all-users
+objectClass: groupOfNames
+member: cn=ghe-users,ou=Groups,dc=example,dc=org
+member: uid=user1,ou=People,dc=example,dc=org
+member: uid=user2,ou=People,dc=example,dc=org
+member: uid=user3,ou=People,dc=example,dc=org
+member: uid=user4,ou=People,dc=example,dc=org
+member: uid=user5,ou=People,dc=example,dc=org
+member: uid=user6,ou=People,dc=example,dc=org
+member: uid=user7,ou=People,dc=example,dc=org
+member: uid=user8,ou=People,dc=example,dc=org
+member: uid=user9,ou=People,dc=example,dc=org
+member: uid=user10,ou=People,dc=example,dc=org
+member: uid=emailless-user1,ou=People,dc=example,dc=org
+
+dn: cn=ghe-admins,ou=Groups,dc=example,dc=org
+cn: ghe-admins
+objectClass: groupOfNames
+member: uid=admin1,ou=People,dc=example,dc=org
+
+dn: cn=all-admins,ou=Groups,dc=example,dc=org
+cn: all-admins
+objectClass: groupOfNames
+member: cn=ghe-admins,ou=Groups,dc=example,dc=org
+member: uid=admin1,ou=People,dc=example,dc=org
+
+dn: cn=n-member-group10,ou=Groups,dc=example,dc=org
+cn: n-member-group10
+objectClass: groupOfNames
+member: uid=user1,ou=People,dc=example,dc=org
+member: uid=user2,ou=People,dc=example,dc=org
+member: uid=user3,ou=People,dc=example,dc=org
+member: uid=user4,ou=People,dc=example,dc=org
+member: uid=user5,ou=People,dc=example,dc=org
+member: uid=user6,ou=People,dc=example,dc=org
+member: uid=user7,ou=People,dc=example,dc=org
+member: uid=user8,ou=People,dc=example,dc=org
+member: uid=user9,ou=People,dc=example,dc=org
+member: uid=user10,ou=People,dc=example,dc=org
+
+dn: cn=nested-group1,ou=Groups,dc=example,dc=org
+cn: nested-group1
+objectClass: groupOfNames
+member: uid=user1,ou=People,dc=example,dc=org
+member: uid=user2,ou=People,dc=example,dc=org
+member: uid=user3,ou=People,dc=example,dc=org
+member: uid=user4,ou=People,dc=example,dc=org
+member: uid=user5,ou=People,dc=example,dc=org
+
+dn: cn=nested-group2,ou=Groups,dc=example,dc=org
+cn: nested-group2
+objectClass: groupOfNames
+member: uid=user6,ou=People,dc=example,dc=org
+member: uid=user7,ou=People,dc=example,dc=org
+member: uid=user8,ou=People,dc=example,dc=org
+member: uid=user9,ou=People,dc=example,dc=org
+member: uid=user10,ou=People,dc=example,dc=org
+
+dn: cn=nested-groups,ou=Groups,dc=example,dc=org
+cn: nested-groups
+objectClass: groupOfNames
+member: cn=nested-group1,ou=Groups,dc=example,dc=org
+member: cn=nested-group2,ou=Groups,dc=example,dc=org
+
+dn: cn=n-member-nested-group1,ou=Groups,dc=example,dc=org
+cn: n-member-nested-group1
+objectClass: groupOfNames
+member: cn=nested-group1,ou=Groups,dc=example,dc=org
+
+dn: cn=deeply-nested-group0.0.0,ou=Groups,dc=example,dc=org
+cn: deeply-nested-group0.0.0
+objectClass: groupOfNames
+member: uid=user1,ou=People,dc=example,dc=org
+member: uid=user2,ou=People,dc=example,dc=org
+member: uid=user3,ou=People,dc=example,dc=org
+member: uid=user4,ou=People,dc=example,dc=org
+member: uid=user5,ou=People,dc=example,dc=org
+
+dn: cn=deeply-nested-group0.0.1,ou=Groups,dc=example,dc=org
+cn: deeply-nested-group0.0.1
+objectClass: groupOfNames
+member: uid=user6,ou=People,dc=example,dc=org
+member: uid=user7,ou=People,dc=example,dc=org
+member: uid=user8,ou=People,dc=example,dc=org
+member: uid=user9,ou=People,dc=example,dc=org
+member: uid=user10,ou=People,dc=example,dc=org
+
+dn: cn=deeply-nested-group0.0,ou=Groups,dc=example,dc=org
+cn: deeply-nested-group0.0
+objectClass: groupOfNames
+member: cn=deeply-nested-group0.0.0,ou=Groups,dc=example,dc=org
+member: cn=deeply-nested-group0.0.1,ou=Groups,dc=example,dc=org
+
+dn: cn=deeply-nested-group0,ou=Groups,dc=example,dc=org
+cn: deeply-nested-group0
+objectClass: groupOfNames
+member: cn=deeply-nested-group0.0,ou=Groups,dc=example,dc=org
+
+dn: cn=deeply-nested-groups,ou=Groups,dc=example,dc=org
+cn: deeply-nested-groups
+objectClass: groupOfNames
+member: cn=deeply-nested-group0,ou=Groups,dc=example,dc=org
+
+dn: cn=n-depth-nested-group1,ou=Groups,dc=example,dc=org
+cn: n-depth-nested-group1
+objectClass: groupOfNames
+member: cn=nested-group1,ou=Groups,dc=example,dc=org
+
+dn: cn=n-depth-nested-group2,ou=Groups,dc=example,dc=org
+cn: n-depth-nested-group2
+objectClass: groupOfNames
+member: cn=n-depth-nested-group1,ou=Groups,dc=example,dc=org
+
+dn: cn=n-depth-nested-group3,ou=Groups,dc=example,dc=org
+cn: n-depth-nested-group3
+objectClass: groupOfNames
+member: cn=n-depth-nested-group2,ou=Groups,dc=example,dc=org
+
+dn: cn=n-depth-nested-group4,ou=Groups,dc=example,dc=org
+cn: n-depth-nested-group4
+objectClass: groupOfNames
+member: cn=n-depth-nested-group3,ou=Groups,dc=example,dc=org
+
+dn: cn=n-depth-nested-group5,ou=Groups,dc=example,dc=org
+cn: n-depth-nested-group5
+objectClass: groupOfNames
+member: cn=n-depth-nested-group4,ou=Groups,dc=example,dc=org
+
+dn: cn=n-depth-nested-group6,ou=Groups,dc=example,dc=org
+cn: n-depth-nested-group6
+objectClass: groupOfNames
+member: cn=n-depth-nested-group5,ou=Groups,dc=example,dc=org
+
+dn: cn=n-depth-nested-group7,ou=Groups,dc=example,dc=org
+cn: n-depth-nested-group7
+objectClass: groupOfNames
+member: cn=n-depth-nested-group6,ou=Groups,dc=example,dc=org
+
+dn: cn=n-depth-nested-group8,ou=Groups,dc=example,dc=org
+cn: n-depth-nested-group8
+objectClass: groupOfNames
+member: cn=n-depth-nested-group7,ou=Groups,dc=example,dc=org
+
+dn: cn=n-depth-nested-group9,ou=Groups,dc=example,dc=org
+cn: n-depth-nested-group9
+objectClass: groupOfNames
+member: cn=n-depth-nested-group8,ou=Groups,dc=example,dc=org
+
+dn: cn=head-group,ou=Groups,dc=example,dc=org
+cn: head-group
+objectClass: groupOfNames
+member: cn=tail-group,ou=Groups,dc=example,dc=org
+member: uid=user1,ou=People,dc=example,dc=org
+member: uid=user2,ou=People,dc=example,dc=org
+member: uid=user3,ou=People,dc=example,dc=org
+member: uid=user4,ou=People,dc=example,dc=org
+member: uid=user5,ou=People,dc=example,dc=org
+
+dn: cn=tail-group,ou=Groups,dc=example,dc=org
+cn: tail-group
+objectClass: groupOfNames
+member: cn=head-group,ou=Groups,dc=example,dc=org
+member: uid=user6,ou=People,dc=example,dc=org
+member: uid=user7,ou=People,dc=example,dc=org
+member: uid=user8,ou=People,dc=example,dc=org
+member: uid=user9,ou=People,dc=example,dc=org
+member: uid=user10,ou=People,dc=example,dc=org
+
+dn: cn=recursively-nested-groups,ou=Groups,dc=example,dc=org
+cn: recursively-nested-groups
+objectClass: groupOfNames
+member: cn=head-group,ou=Groups,dc=example,dc=org
+member: cn=tail-group,ou=Groups,dc=example,dc=org
+
+# posixGroup
+
+dn: cn=posix-group1,ou=Groups,dc=example,dc=org
+cn: posix-group1
+objectClass: posixGroup
+gidNumber: 1001
+memberUid: user1
+memberUid: user2
+memberUid: user3
+memberUid: user4
+memberUid: user5
+
+# missing members
+
+dn: cn=missing-users,ou=Groups,dc=example,dc=org
+cn: missing-users
+objectClass: groupOfNames
+member: uid=user1,ou=People,dc=example,dc=org
+member: uid=user2,ou=People,dc=example,dc=org
+member: uid=nonexistent-user,ou=People,dc=example,dc=org
diff --git a/test/fixtures/openldap/memberof.ldif b/test/fixtures/openldap/memberof.ldif
deleted file mode 100644
index dac7c6b5..00000000
--- a/test/fixtures/openldap/memberof.ldif
+++ /dev/null
@@ -1,33 +0,0 @@
-dn: cn=module,cn=config
-cn: module
-objectClass: olcModuleList
-objectClass: top
-olcModulePath: /usr/lib/ldap
-olcModuleLoad: memberof.la
-
-dn: olcOverlay={0}memberof,olcDatabase={1}hdb,cn=config
-objectClass: olcConfig
-objectClass: olcMemberOf
-objectClass: olcOverlayConfig
-objectClass: top
-olcOverlay: memberof
-olcMemberOfDangling: ignore
-olcMemberOfRefInt: TRUE
-olcMemberOfGroupOC: groupOfNames
-olcMemberOfMemberAD: member
-olcMemberOfMemberOfAD: memberOf
-
-dn: cn=module,cn=config
-cn: module
-objectclass: olcModuleList
-objectclass: top
-olcmoduleload: refint.la
-olcmodulepath: /usr/lib/ldap
-
-dn: olcOverlay={1}refint,olcDatabase={1}hdb,cn=config
-objectClass: olcConfig
-objectClass: olcOverlayConfig
-objectClass: olcRefintConfig
-objectClass: top
-olcOverlay: {1}refint
-olcRefintAttribute: memberof member manager owner
diff --git a/test/fixtures/openldap/slapd.conf.ldif b/test/fixtures/openldap/slapd.conf.ldif
deleted file mode 100644
index 77a6af09..00000000
--- a/test/fixtures/openldap/slapd.conf.ldif
+++ /dev/null
@@ -1,67 +0,0 @@
-dn: cn=config
-objectClass: olcGlobal
-cn: config
-olcPidFile: /var/run/slapd/slapd.pid
-olcArgsFile: /var/run/slapd/slapd.args
-olcLogLevel: -1
-olcToolThreads: 1
-
-dn: olcDatabase={-1}frontend,cn=config
-objectClass: olcDatabaseConfig
-objectClass: olcFrontendConfig
-olcDatabase: {-1}frontend
-olcSizeLimit: 500
-olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
-olcAccess: {1}to dn.exact="" by * read
-olcAccess: {2}to dn.base="cn=Subschema" by * read
-
-dn: olcDatabase=config,cn=config
-objectClass: olcDatabaseConfig
-olcDatabase: config
-olcAccess: to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
-
-dn: cn=schema,cn=config
-objectClass: olcSchemaConfig
-cn: schema
-
-include: file:///etc/ldap/schema/core.ldif
-include: file:///etc/ldap/schema/cosine.ldif
-include: file:///etc/ldap/schema/nis.ldif
-include: file:///etc/ldap/schema/inetorgperson.ldif
-
-dn: cn=module{0},cn=config
-objectClass: olcModuleList
-cn: module{0}
-olcModulePath: /usr/lib/ldap
-olcModuleLoad: back_hdb
-
-dn: olcBackend=hdb,cn=config
-objectClass: olcBackendConfig
-olcBackend: hdb
-
-dn: olcDatabase=hdb,cn=config
-objectClass: olcDatabaseConfig
-objectClass: olcHdbConfig
-olcDatabase: hdb
-olcDbCheckpoint: 512 30
-olcDbConfig: set_cachesize 1 0 0
-olcDbConfig: set_lk_max_objects 1500
-olcDbConfig: set_lk_max_locks 1500
-olcDbConfig: set_lk_max_lockers 1500
-olcLastMod: TRUE
-olcSuffix: dc=rubyldap,dc=com
-olcDbDirectory: /var/lib/ldap
-olcRootDN: cn=admin,dc=rubyldap,dc=com
-# admin's password: "passworD1"
-olcRootPW: {SHA}LFSkM9eegU6j3PeGG7UuHrT/KZM=
-olcDbIndex: objectClass eq
-olcAccess: to attrs=userPassword,shadowLastChange
- by self write
- by anonymous auth
- by dn="cn=admin,dc=rubyldap,dc=com" write
- by * none
-olcAccess: to dn.base="" by * read
-olcAccess: to *
- by self write
- by dn="cn=admin,dc=rubyldap,dc=com" write
- by * read
diff --git a/test/fixtures/seed.ldif b/test/fixtures/seed.ldif
deleted file mode 100644
index 3ad3e293..00000000
--- a/test/fixtures/seed.ldif
+++ /dev/null
@@ -1,374 +0,0 @@
-dn: ou=People,dc=rubyldap,dc=com
-objectClass: top
-objectClass: organizationalUnit
-ou: People
-
-dn: ou=Groups,dc=rubyldap,dc=com
-objectClass: top
-objectClass: organizationalUnit
-ou: Groups
-
-# Directory Superuser
-dn: uid=admin,dc=rubyldap,dc=com
-uid: admin
-cn: system administrator
-sn: administrator
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-displayName: Directory Superuser
-userPassword: passworD1
-
-# Users 1-10
-
-dn: uid=user1,ou=People,dc=rubyldap,dc=com
-uid: user1
-cn: user1
-sn: user1
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user1@rubyldap.com
-
-dn: uid=user2,ou=People,dc=rubyldap,dc=com
-uid: user2
-cn: user2
-sn: user2
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user2@rubyldap.com
-
-dn: uid=user3,ou=People,dc=rubyldap,dc=com
-uid: user3
-cn: user3
-sn: user3
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user3@rubyldap.com
-
-dn: uid=user4,ou=People,dc=rubyldap,dc=com
-uid: user4
-cn: user4
-sn: user4
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user4@rubyldap.com
-
-dn: uid=user5,ou=People,dc=rubyldap,dc=com
-uid: user5
-cn: user5
-sn: user5
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user5@rubyldap.com
-
-dn: uid=user6,ou=People,dc=rubyldap,dc=com
-uid: user6
-cn: user6
-sn: user6
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user6@rubyldap.com
-
-dn: uid=user7,ou=People,dc=rubyldap,dc=com
-uid: user7
-cn: user7
-sn: user7
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user7@rubyldap.com
-
-dn: uid=user8,ou=People,dc=rubyldap,dc=com
-uid: user8
-cn: user8
-sn: user8
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user8@rubyldap.com
-
-dn: uid=user9,ou=People,dc=rubyldap,dc=com
-uid: user9
-cn: user9
-sn: user9
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user9@rubyldap.com
-
-dn: uid=user10,ou=People,dc=rubyldap,dc=com
-uid: user10
-cn: user10
-sn: user10
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: user10@rubyldap.com
-
-# Emailless User
-
-dn: uid=emailless-user1,ou=People,dc=rubyldap,dc=com
-uid: emailless-user1
-cn: emailless-user1
-sn: emailless-user1
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-
-# Groupless User
-
-dn: uid=groupless-user1,ou=People,dc=rubyldap,dc=com
-uid: groupless-user1
-cn: groupless-user1
-sn: groupless-user1
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-
-# Admin User
-
-dn: uid=admin1,ou=People,dc=rubyldap,dc=com
-uid: admin1
-cn: admin1
-sn: admin1
-objectClass: top
-objectClass: person
-objectClass: organizationalPerson
-objectClass: inetOrgPerson
-userPassword: passworD1
-mail: admin1@rubyldap.com
-
-# Groups
-
-dn: cn=ghe-users,ou=Groups,dc=rubyldap,dc=com
-cn: ghe-users
-objectClass: groupOfNames
-member: uid=user1,ou=People,dc=rubyldap,dc=com
-member: uid=emailless-user1,ou=People,dc=rubyldap,dc=com
-
-dn: cn=all-users,ou=Groups,dc=rubyldap,dc=com
-cn: all-users
-objectClass: groupOfNames
-member: cn=ghe-users,ou=Groups,dc=rubyldap,dc=com
-member: uid=user1,ou=People,dc=rubyldap,dc=com
-member: uid=user2,ou=People,dc=rubyldap,dc=com
-member: uid=user3,ou=People,dc=rubyldap,dc=com
-member: uid=user4,ou=People,dc=rubyldap,dc=com
-member: uid=user5,ou=People,dc=rubyldap,dc=com
-member: uid=user6,ou=People,dc=rubyldap,dc=com
-member: uid=user7,ou=People,dc=rubyldap,dc=com
-member: uid=user8,ou=People,dc=rubyldap,dc=com
-member: uid=user9,ou=People,dc=rubyldap,dc=com
-member: uid=user10,ou=People,dc=rubyldap,dc=com
-member: uid=emailless-user1,ou=People,dc=rubyldap,dc=com
-
-dn: cn=ghe-admins,ou=Groups,dc=rubyldap,dc=com
-cn: ghe-admins
-objectClass: groupOfNames
-member: uid=admin1,ou=People,dc=rubyldap,dc=com
-
-dn: cn=all-admins,ou=Groups,dc=rubyldap,dc=com
-cn: all-admins
-objectClass: groupOfNames
-member: cn=ghe-admins,ou=Groups,dc=rubyldap,dc=com
-member: uid=admin1,ou=People,dc=rubyldap,dc=com
-
-dn: cn=n-member-group10,ou=Groups,dc=rubyldap,dc=com
-cn: n-member-group10
-objectClass: groupOfNames
-member: uid=user1,ou=People,dc=rubyldap,dc=com
-member: uid=user2,ou=People,dc=rubyldap,dc=com
-member: uid=user3,ou=People,dc=rubyldap,dc=com
-member: uid=user4,ou=People,dc=rubyldap,dc=com
-member: uid=user5,ou=People,dc=rubyldap,dc=com
-member: uid=user6,ou=People,dc=rubyldap,dc=com
-member: uid=user7,ou=People,dc=rubyldap,dc=com
-member: uid=user8,ou=People,dc=rubyldap,dc=com
-member: uid=user9,ou=People,dc=rubyldap,dc=com
-member: uid=user10,ou=People,dc=rubyldap,dc=com
-
-dn: cn=nested-group1,ou=Groups,dc=rubyldap,dc=com
-cn: nested-group1
-objectClass: groupOfNames
-member: uid=user1,ou=People,dc=rubyldap,dc=com
-member: uid=user2,ou=People,dc=rubyldap,dc=com
-member: uid=user3,ou=People,dc=rubyldap,dc=com
-member: uid=user4,ou=People,dc=rubyldap,dc=com
-member: uid=user5,ou=People,dc=rubyldap,dc=com
-
-dn: cn=nested-group2,ou=Groups,dc=rubyldap,dc=com
-cn: nested-group2
-objectClass: groupOfNames
-member: uid=user6,ou=People,dc=rubyldap,dc=com
-member: uid=user7,ou=People,dc=rubyldap,dc=com
-member: uid=user8,ou=People,dc=rubyldap,dc=com
-member: uid=user9,ou=People,dc=rubyldap,dc=com
-member: uid=user10,ou=People,dc=rubyldap,dc=com
-
-dn: cn=nested-groups,ou=Groups,dc=rubyldap,dc=com
-cn: nested-groups
-objectClass: groupOfNames
-member: cn=nested-group1,ou=Groups,dc=rubyldap,dc=com
-member: cn=nested-group2,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-member-nested-group1,ou=Groups,dc=rubyldap,dc=com
-cn: n-member-nested-group1
-objectClass: groupOfNames
-member: cn=nested-group1,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=deeply-nested-group0.0.0,ou=Groups,dc=rubyldap,dc=com
-cn: deeply-nested-group0.0.0
-objectClass: groupOfNames
-member: uid=user1,ou=People,dc=rubyldap,dc=com
-member: uid=user2,ou=People,dc=rubyldap,dc=com
-member: uid=user3,ou=People,dc=rubyldap,dc=com
-member: uid=user4,ou=People,dc=rubyldap,dc=com
-member: uid=user5,ou=People,dc=rubyldap,dc=com
-
-dn: cn=deeply-nested-group0.0.1,ou=Groups,dc=rubyldap,dc=com
-cn: deeply-nested-group0.0.1
-objectClass: groupOfNames
-member: uid=user6,ou=People,dc=rubyldap,dc=com
-member: uid=user7,ou=People,dc=rubyldap,dc=com
-member: uid=user8,ou=People,dc=rubyldap,dc=com
-member: uid=user9,ou=People,dc=rubyldap,dc=com
-member: uid=user10,ou=People,dc=rubyldap,dc=com
-
-dn: cn=deeply-nested-group0.0,ou=Groups,dc=rubyldap,dc=com
-cn: deeply-nested-group0.0
-objectClass: groupOfNames
-member: cn=deeply-nested-group0.0.0,ou=Groups,dc=rubyldap,dc=com
-member: cn=deeply-nested-group0.0.1,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=deeply-nested-group0,ou=Groups,dc=rubyldap,dc=com
-cn: deeply-nested-group0
-objectClass: groupOfNames
-member: cn=deeply-nested-group0.0,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=deeply-nested-groups,ou=Groups,dc=rubyldap,dc=com
-cn: deeply-nested-groups
-objectClass: groupOfNames
-member: cn=deeply-nested-group0,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-depth-nested-group1,ou=Groups,dc=rubyldap,dc=com
-cn: n-depth-nested-group1
-objectClass: groupOfNames
-member: cn=nested-group1,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-depth-nested-group2,ou=Groups,dc=rubyldap,dc=com
-cn: n-depth-nested-group2
-objectClass: groupOfNames
-member: cn=n-depth-nested-group1,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-depth-nested-group3,ou=Groups,dc=rubyldap,dc=com
-cn: n-depth-nested-group3
-objectClass: groupOfNames
-member: cn=n-depth-nested-group2,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-depth-nested-group4,ou=Groups,dc=rubyldap,dc=com
-cn: n-depth-nested-group4
-objectClass: groupOfNames
-member: cn=n-depth-nested-group3,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-depth-nested-group5,ou=Groups,dc=rubyldap,dc=com
-cn: n-depth-nested-group5
-objectClass: groupOfNames
-member: cn=n-depth-nested-group4,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-depth-nested-group6,ou=Groups,dc=rubyldap,dc=com
-cn: n-depth-nested-group6
-objectClass: groupOfNames
-member: cn=n-depth-nested-group5,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-depth-nested-group7,ou=Groups,dc=rubyldap,dc=com
-cn: n-depth-nested-group7
-objectClass: groupOfNames
-member: cn=n-depth-nested-group6,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-depth-nested-group8,ou=Groups,dc=rubyldap,dc=com
-cn: n-depth-nested-group8
-objectClass: groupOfNames
-member: cn=n-depth-nested-group7,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=n-depth-nested-group9,ou=Groups,dc=rubyldap,dc=com
-cn: n-depth-nested-group9
-objectClass: groupOfNames
-member: cn=n-depth-nested-group8,ou=Groups,dc=rubyldap,dc=com
-
-dn: cn=head-group,ou=Groups,dc=rubyldap,dc=com
-cn: head-group
-objectClass: groupOfNames
-member: cn=tail-group,ou=Groups,dc=rubyldap,dc=com
-member: uid=user1,ou=People,dc=rubyldap,dc=com
-member: uid=user2,ou=People,dc=rubyldap,dc=com
-member: uid=user3,ou=People,dc=rubyldap,dc=com
-member: uid=user4,ou=People,dc=rubyldap,dc=com
-member: uid=user5,ou=People,dc=rubyldap,dc=com
-
-dn: cn=tail-group,ou=Groups,dc=rubyldap,dc=com
-cn: tail-group
-objectClass: groupOfNames
-member: cn=head-group,ou=Groups,dc=rubyldap,dc=com
-member: uid=user6,ou=People,dc=rubyldap,dc=com
-member: uid=user7,ou=People,dc=rubyldap,dc=com
-member: uid=user8,ou=People,dc=rubyldap,dc=com
-member: uid=user9,ou=People,dc=rubyldap,dc=com
-member: uid=user10,ou=People,dc=rubyldap,dc=com
-
-dn: cn=recursively-nested-groups,ou=Groups,dc=rubyldap,dc=com
-cn: recursively-nested-groups
-objectClass: groupOfNames
-member: cn=head-group,ou=Groups,dc=rubyldap,dc=com
-member: cn=tail-group,ou=Groups,dc=rubyldap,dc=com
-
-# posixGroup
-
-dn: cn=posix-group1,ou=Groups,dc=rubyldap,dc=com
-cn: posix-group1
-objectClass: posixGroup
-gidNumber: 1001
-memberUid: user1
-memberUid: user2
-memberUid: user3
-memberUid: user4
-memberUid: user5
-
-# missing members
-
-dn: cn=missing-users,ou=Groups,dc=rubyldap,dc=com
-cn: missing-users
-objectClass: groupOfNames
-member: uid=user1,ou=People,dc=rubyldap,dc=com
-member: uid=user2,ou=People,dc=rubyldap,dc=com
-member: uid=nonexistent-user,ou=People,dc=rubyldap,dc=com
diff --git a/test/integration/test_add.rb b/test/integration/test_add.rb
index dcac6149..108fd93b 100644
--- a/test/integration/test_add.rb
+++ b/test/integration/test_add.rb
@@ -3,9 +3,7 @@
class TestAddIntegration < LDAPIntegrationTestCase
def setup
super
- @ldap.authenticate "cn=admin,dc=rubyldap,dc=com", "passworD1"
-
- @dn = "uid=added-user1,ou=People,dc=rubyldap,dc=com"
+ @dn = "uid=added-user1,ou=People,dc=example,dc=org"
end
def test_add
diff --git a/test/integration/test_ber.rb b/test/integration/test_ber.rb
index 51e93334..4464bf78 100644
--- a/test/integration/test_ber.rb
+++ b/test/integration/test_ber.rb
@@ -8,7 +8,7 @@ def test_true_ber_encoding
attrs = [:dn, :uid, :cn, :mail]
assert types_entry = @ldap.search(
- base: "dc=rubyldap,dc=com",
+ base: "dc=example,dc=org",
filter: "(uid=user1)",
size: 1,
attributes: attrs,
@@ -25,6 +25,6 @@ def test_true_ber_encoding
end
assert_includes Net::LDAP::ResultCodesSearchSuccess,
- @ldap.get_operation_result.code, "should be a successful search operation"
+ @ldap.get_operation_result.code, "should be a successful search operation"
end
end
diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb
index bd1281e2..4a1a0194 100644
--- a/test/integration/test_bind.rb
+++ b/test/integration/test_bind.rb
@@ -1,13 +1,16 @@
require_relative '../test_helper'
class TestBindIntegration < LDAPIntegrationTestCase
+ INTEGRATION_HOSTNAME = 'ldap.example.org'.freeze
+
def test_bind_success
assert @ldap.bind(BIND_CREDS),
@ldap.get_operation_result.inspect
end
def test_bind_timeout
- @ldap.port = 8389
+ @ldap.host = "10.255.255.1" # non-routable IP
+
error = assert_raise Net::LDAP::Error do
@ldap.bind BIND_CREDS
end
@@ -24,7 +27,7 @@ def test_bind_anonymous_fail
assert_equal Net::LDAP::ResultCodeUnwillingToPerform, result.code
assert_equal Net::LDAP::ResultStrings[Net::LDAP::ResultCodeUnwillingToPerform], result.message
assert_equal "unauthenticated bind (DN with no password) disallowed",
- result.error_message
+ result.error_message
assert_equal "", result.matched_dn
end
@@ -34,6 +37,8 @@ def test_bind_fail
end
def test_bind_tls_with_cafile
+ omit "We need to update our CA cert"
+ @ldap.host = INTEGRATION_HOSTNAME
@ldap.encryption(
method: :start_tls,
tls_options: TLS_OPTS.merge(ca_file: CA_FILE),
@@ -43,7 +48,7 @@ def test_bind_tls_with_cafile
end
def test_bind_tls_with_bad_hostname_verify_none_no_ca_passes
- @ldap.host = '127.0.0.1'
+ @ldap.host = INTEGRATION_HOSTNAME
@ldap.encryption(
method: :start_tls,
tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE },
@@ -53,7 +58,7 @@ def test_bind_tls_with_bad_hostname_verify_none_no_ca_passes
end
def test_bind_tls_with_bad_hostname_verify_none_no_ca_opt_merge_passes
- @ldap.host = '127.0.0.1'
+ @ldap.host = 'cert.mismatch.example.org'
@ldap.encryption(
method: :start_tls,
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_NONE),
@@ -63,14 +68,15 @@ def test_bind_tls_with_bad_hostname_verify_none_no_ca_opt_merge_passes
end
def test_bind_tls_with_bad_hostname_verify_peer_ca_fails
- @ldap.host = '127.0.0.1'
+ omit "We need to update our CA cert"
+ @ldap.host = 'cert.mismatch.example.org'
@ldap.encryption(
method: :start_tls,
tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER,
ca_file: CA_FILE },
)
error = assert_raise Net::LDAP::Error,
- Net::LDAP::ConnectionRefusedError do
+ Errno::ECONNREFUSED do
@ldap.bind BIND_CREDS
end
assert_equal(
@@ -80,13 +86,14 @@ def test_bind_tls_with_bad_hostname_verify_peer_ca_fails
end
def test_bind_tls_with_bad_hostname_ca_default_opt_merge_fails
- @ldap.host = '127.0.0.1'
+ omit "We need to update our CA cert"
+ @ldap.host = 'cert.mismatch.example.org'
@ldap.encryption(
method: :start_tls,
tls_options: TLS_OPTS.merge(ca_file: CA_FILE),
)
error = assert_raise Net::LDAP::Error,
- Net::LDAP::ConnectionRefusedError do
+ Errno::ECONNREFUSED do
@ldap.bind BIND_CREDS
end
assert_equal(
@@ -96,13 +103,14 @@ def test_bind_tls_with_bad_hostname_ca_default_opt_merge_fails
end
def test_bind_tls_with_bad_hostname_ca_no_opt_merge_fails
- @ldap.host = '127.0.0.1'
+ omit "We need to update our CA cert"
+ @ldap.host = 'cert.mismatch.example.org'
@ldap.encryption(
method: :start_tls,
tls_options: { ca_file: CA_FILE },
)
error = assert_raise Net::LDAP::Error,
- Net::LDAP::ConnectionRefusedError do
+ Errno::ECONNREFUSED do
@ldap.bind BIND_CREDS
end
assert_equal(
@@ -112,7 +120,8 @@ def test_bind_tls_with_bad_hostname_ca_no_opt_merge_fails
end
def test_bind_tls_with_valid_hostname_default_opts_passes
- @ldap.host = 'localhost'
+ omit "We need to update our CA cert"
+ @ldap.host = INTEGRATION_HOSTNAME
@ldap.encryption(
method: :start_tls,
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER,
@@ -123,7 +132,8 @@ def test_bind_tls_with_valid_hostname_default_opts_passes
end
def test_bind_tls_with_valid_hostname_just_verify_peer_ca_passes
- @ldap.host = 'localhost'
+ omit "We need to update our CA cert"
+ @ldap.host = INTEGRATION_HOSTNAME
@ldap.encryption(
method: :start_tls,
tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER,
@@ -134,10 +144,10 @@ def test_bind_tls_with_valid_hostname_just_verify_peer_ca_passes
end
def test_bind_tls_with_bogus_hostname_system_ca_fails
- @ldap.host = '127.0.0.1'
+ @ldap.host = 'cert.mismatch.example.org'
@ldap.encryption(method: :start_tls, tls_options: {})
error = assert_raise Net::LDAP::Error,
- Net::LDAP::ConnectionRefusedError do
+ Errno::ECONNREFUSED do
@ldap.bind BIND_CREDS
end
assert_equal(
@@ -146,13 +156,10 @@ def test_bind_tls_with_bogus_hostname_system_ca_fails
)
end
- # The following depend on /etc/hosts hacking.
- # We can do that on CI, but it's less than cool on people's dev boxes
def test_bind_tls_with_multiple_hosts
- omit_unless ENV['TRAVIS'] == 'true'
-
+ omit "We need to update our CA cert"
@ldap.host = nil
- @ldap.hosts = [['ldap01.example.com', 389], ['ldap02.example.com', 389]]
+ @ldap.hosts = [[INTEGRATION_HOSTNAME, 389], [INTEGRATION_HOSTNAME, 389]]
@ldap.encryption(
method: :start_tls,
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER,
@@ -163,10 +170,9 @@ def test_bind_tls_with_multiple_hosts
end
def test_bind_tls_with_multiple_bogus_hosts
- omit_unless ENV['TRAVIS'] == 'true'
-
+ # omit "We need to update our CA cert"
@ldap.host = nil
- @ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]]
+ @ldap.hosts = [['cert.mismatch.example.org', 389], ['bogus.example.com', 389]]
@ldap.encryption(
method: :start_tls,
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER,
@@ -181,10 +187,9 @@ def test_bind_tls_with_multiple_bogus_hosts
end
def test_bind_tls_with_multiple_bogus_hosts_no_verification
- omit_unless ENV['TRAVIS'] == 'true'
-
+ omit "We need to update our CA cert"
@ldap.host = nil
- @ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]]
+ @ldap.hosts = [['cert.mismatch.example.org', 389], ['bogus.example.com', 389]]
@ldap.encryption(
method: :start_tls,
tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_NONE),
@@ -194,10 +199,8 @@ def test_bind_tls_with_multiple_bogus_hosts_no_verification
end
def test_bind_tls_with_multiple_bogus_hosts_ca_check_only_fails
- omit_unless ENV['TRAVIS'] == 'true'
-
@ldap.host = nil
- @ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]]
+ @ldap.hosts = [['cert.mismatch.example.org', 389], ['bogus.example.com', 389]]
@ldap.encryption(
method: :start_tls,
tls_options: { ca_file: CA_FILE },
@@ -213,8 +216,10 @@ def test_bind_tls_with_multiple_bogus_hosts_ca_check_only_fails
# This test is CI-only because we can't add the fixture CA
# to the system CA store on people's dev boxes.
def test_bind_tls_valid_hostname_system_ca_on_travis_passes
+ omit "not sure how to install custom CA cert in travis"
omit_unless ENV['TRAVIS'] == 'true'
+ @ldap.host = INTEGRATION_HOSTNAME
@ldap.encryption(
method: :start_tls,
tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER },
@@ -222,23 +227,4 @@ def test_bind_tls_valid_hostname_system_ca_on_travis_passes
assert @ldap.bind(BIND_CREDS),
@ldap.get_operation_result.inspect
end
-
- # Inverse of the above! Don't run this on Travis, only on Vagrant.
- # Since Vagrant's hypervisor *won't* have the CA in the system
- # x509 store, we can assume validation will fail
- def test_bind_tls_valid_hostname_system_on_vagrant_fails
- omit_if ENV['TRAVIS'] == 'true'
-
- @ldap.encryption(
- method: :start_tls,
- tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER },
- )
- error = assert_raise Net::LDAP::Error do
- @ldap.bind BIND_CREDS
- end
- assert_equal(
- "SSL_connect returned=1 errno=0 state=error: certificate verify failed",
- error.message,
- )
- end
end
diff --git a/test/integration/test_delete.rb b/test/integration/test_delete.rb
index 0cca32a9..20e3414c 100644
--- a/test/integration/test_delete.rb
+++ b/test/integration/test_delete.rb
@@ -3,9 +3,7 @@
class TestDeleteIntegration < LDAPIntegrationTestCase
def setup
super
- @ldap.authenticate "cn=admin,dc=rubyldap,dc=com", "passworD1"
-
- @dn = "uid=delete-user1,ou=People,dc=rubyldap,dc=com"
+ @dn = "uid=delete-user1,ou=People,dc=example,dc=org"
attrs = {
objectclass: %w(top inetOrgPerson organizationalPerson person),
@@ -18,6 +16,29 @@ def setup
assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
end
assert @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
+
+ @parent_dn = "uid=parent,ou=People,dc=example,dc=org"
+ parent_attrs = {
+ objectclass: %w(top inetOrgPerson organizationalPerson person),
+ uid: "parent",
+ cn: "parent",
+ sn: "parent",
+ mail: "parent@rubyldap.com",
+ }
+ @child_dn = "uid=child,uid=parent,ou=People,dc=example,dc=org"
+ child_attrs = {
+ objectclass: %w(top inetOrgPerson organizationalPerson person),
+ uid: "child",
+ cn: "child",
+ sn: "child",
+ mail: "child@rubyldap.com",
+ }
+ unless @ldap.search(base: @parent_dn, scope: Net::LDAP::SearchScope_BaseObject)
+ assert @ldap.add(dn: @parent_dn, attributes: parent_attrs), @ldap.get_operation_result.inspect
+ assert @ldap.add(dn: @child_dn, attributes: child_attrs), @ldap.get_operation_result.inspect
+ end
+ assert @ldap.search(base: @parent_dn, scope: Net::LDAP::SearchScope_BaseObject)
+ assert @ldap.search(base: @child_dn, scope: Net::LDAP::SearchScope_BaseObject)
end
def test_delete
@@ -28,4 +49,14 @@ def test_delete
assert_equal Net::LDAP::ResultCodeNoSuchObject, result.code
assert_equal Net::LDAP::ResultStrings[Net::LDAP::ResultCodeNoSuchObject], result.message
end
+
+ def test_delete_tree
+ assert @ldap.delete_tree(dn: @parent_dn), @ldap.get_operation_result.inspect
+ refute @ldap.search(base: @parent_dn, scope: Net::LDAP::SearchScope_BaseObject)
+ refute @ldap.search(base: @child_dn, scope: Net::LDAP::SearchScope_BaseObject)
+
+ result = @ldap.get_operation_result
+ assert_equal Net::LDAP::ResultCodeNoSuchObject, result.code
+ assert_equal Net::LDAP::ResultStrings[Net::LDAP::ResultCodeNoSuchObject], result.message
+ end
end
diff --git a/test/integration/test_open.rb b/test/integration/test_open.rb
index a7ac09da..9ce36d72 100644
--- a/test/integration/test_open.rb
+++ b/test/integration/test_open.rb
@@ -4,8 +4,8 @@ class TestBindIntegration < LDAPIntegrationTestCase
def test_binds_without_open
events = @service.subscribe "bind.net_ldap_connection"
- @ldap.search(filter: "uid=user1", base: "ou=People,dc=rubyldap,dc=com", ignore_server_caps: true)
- @ldap.search(filter: "uid=user1", base: "ou=People,dc=rubyldap,dc=com", ignore_server_caps: true)
+ @ldap.search(filter: "uid=user1", base: "ou=People,dc=example,dc=org", ignore_server_caps: true)
+ @ldap.search(filter: "uid=user1", base: "ou=People,dc=example,dc=org", ignore_server_caps: true)
assert_equal 2, events.size
end
@@ -14,8 +14,8 @@ def test_binds_with_open
events = @service.subscribe "bind.net_ldap_connection"
@ldap.open do
- @ldap.search(filter: "uid=user1", base: "ou=People,dc=rubyldap,dc=com", ignore_server_caps: true)
- @ldap.search(filter: "uid=user1", base: "ou=People,dc=rubyldap,dc=com", ignore_server_caps: true)
+ @ldap.search(filter: "uid=user1", base: "ou=People,dc=example,dc=org", ignore_server_caps: true)
+ @ldap.search(filter: "uid=user1", base: "ou=People,dc=example,dc=org", ignore_server_caps: true)
end
assert_equal 1, events.size
@@ -29,9 +29,9 @@ def test_nested_search_without_open
entries = []
nested_entry = nil
- @ldap.search(filter: "(|(uid=user1)(uid=user2))", base: "ou=People,dc=rubyldap,dc=com") do |entry|
+ @ldap.search(filter: "(|(uid=user1)(uid=user2))", base: "ou=People,dc=example,dc=org") do |entry|
entries << entry.uid.first
- nested_entry ||= @ldap.search(filter: "uid=user3", base: "ou=People,dc=rubyldap,dc=com").first
+ nested_entry ||= @ldap.search(filter: "uid=user3", base: "ou=People,dc=example,dc=org").first
end
assert_equal "user3", nested_entry.uid.first
@@ -43,9 +43,9 @@ def test_nested_search_with_open
nested_entry = nil
@ldap.open do
- @ldap.search(filter: "(|(uid=user1)(uid=user2))", base: "ou=People,dc=rubyldap,dc=com") do |entry|
+ @ldap.search(filter: "(|(uid=user1)(uid=user2))", base: "ou=People,dc=example,dc=org") do |entry|
entries << entry.uid.first
- nested_entry ||= @ldap.search(filter: "uid=user3", base: "ou=People,dc=rubyldap,dc=com").first
+ nested_entry ||= @ldap.search(filter: "uid=user3", base: "ou=People,dc=example,dc=org").first
end
end
@@ -57,7 +57,7 @@ def test_nested_add_with_open
entries = []
nested_entry = nil
- dn = "uid=nested-open-added-user1,ou=People,dc=rubyldap,dc=com"
+ dn = "uid=nested-open-added-user1,ou=People,dc=example,dc=org"
attrs = {
objectclass: %w(top inetOrgPerson organizationalPerson person),
uid: "nested-open-added-user1",
@@ -66,11 +66,10 @@ def test_nested_add_with_open
mail: "nested-open-added-user1@rubyldap.com",
}
- @ldap.authenticate "cn=admin,dc=rubyldap,dc=com", "passworD1"
@ldap.delete dn: dn
@ldap.open do
- @ldap.search(filter: "(|(uid=user1)(uid=user2))", base: "ou=People,dc=rubyldap,dc=com") do |entry|
+ @ldap.search(filter: "(|(uid=user1)(uid=user2))", base: "ou=People,dc=example,dc=org") do |entry|
entries << entry.uid.first
nested_entry ||= begin
diff --git a/test/integration/test_password_modify.rb b/test/integration/test_password_modify.rb
index ed8d4f5b..e7d8d670 100644
--- a/test/integration/test_password_modify.rb
+++ b/test/integration/test_password_modify.rb
@@ -1,12 +1,19 @@
require_relative '../test_helper'
class TestPasswordModifyIntegration < LDAPIntegrationTestCase
+ # see: https://www.rfc-editor.org/rfc/rfc3062#section-2
+ PASSWORD_MODIFY_SYNTAX = Net::BER.compile_syntax(
+ application: {},
+ universal: {},
+ context_specific: { primitive: { 0 => :string } },
+ )
+
def setup
super
- @admin_account = {dn: 'cn=admin,dc=rubyldap,dc=com', password: 'passworD1', method: :simple}
+ @admin_account = { dn: 'cn=admin,dc=example,dc=org', password: 'admin', method: :simple }
@ldap.authenticate @admin_account[:dn], @admin_account[:password]
- @dn = 'uid=modify-password-user1,ou=People,dc=rubyldap,dc=com'
+ @dn = 'uid=modify-password-user1,ou=People,dc=example,dc=org'
attrs = {
objectclass: %w(top inetOrgPerson organizationalPerson person),
@@ -14,7 +21,7 @@ def setup
cn: 'modify-password-user1',
sn: 'modify-password-user1',
mail: 'modify-password-user1@rubyldap.com',
- userPassword: 'passworD1',
+ userPassword: 'admin',
}
unless @ldap.search(base: @dn, scope: Net::LDAP::SearchScope_BaseObject)
assert @ldap.add(dn: @dn, attributes: attrs), @ldap.get_operation_result.inspect
@@ -24,55 +31,66 @@ def setup
@auth = {
method: :simple,
username: @dn,
- password: 'passworD1',
+ password: 'admin',
}
end
def test_password_modify
assert @ldap.password_modify(dn: @dn,
auth: @auth,
- old_password: 'passworD1',
+ old_password: 'admin',
new_password: 'passworD2')
assert @ldap.get_operation_result.extended_response.nil?,
- 'Should not have generated a new password'
+ 'Should not have generated a new password'
- refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
- 'Old password should no longer be valid'
+ refute @ldap.bind(username: @dn, password: 'admin', method: :simple),
+ 'Old password should no longer be valid'
assert @ldap.bind(username: @dn, password: 'passworD2', method: :simple),
- 'New password should be valid'
+ 'New password should be valid'
end
def test_password_modify_generate
assert @ldap.password_modify(dn: @dn,
auth: @auth,
- old_password: 'passworD1')
+ old_password: 'admin')
- generated_password = @ldap.get_operation_result.extended_response[0][0]
+ passwd_modify_response_value = @ldap.get_operation_result.extended_response
+ seq = Net::BER::BerIdentifiedArray.new
+ sio = StringIO.new(passwd_modify_response_value)
+ until (e = sio.read_ber(PASSWORD_MODIFY_SYNTAX)).nil?
+ seq << e
+ end
+ generated_password = seq[0][0]
assert generated_password, 'Should have generated a password'
- refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
- 'Old password should no longer be valid'
+ refute @ldap.bind(username: @dn, password: 'admin', method: :simple),
+ 'Old password should no longer be valid'
assert @ldap.bind(username: @dn, password: generated_password, method: :simple),
- 'New password should be valid'
+ 'New password should be valid'
end
def test_password_modify_generate_no_old_password
assert @ldap.password_modify(dn: @dn,
auth: @auth)
- generated_password = @ldap.get_operation_result.extended_response[0][0]
-
+ passwd_modify_response_value = @ldap.get_operation_result.extended_response
+ seq = Net::BER::BerIdentifiedArray.new
+ sio = StringIO.new(passwd_modify_response_value)
+ until (e = sio.read_ber(PASSWORD_MODIFY_SYNTAX)).nil?
+ seq << e
+ end
+ generated_password = seq[0][0]
assert generated_password, 'Should have generated a password'
- refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
- 'Old password should no longer be valid'
+ refute @ldap.bind(username: @dn, password: 'admin', method: :simple),
+ 'Old password should no longer be valid'
assert @ldap.bind(username: @dn, password: generated_password, method: :simple),
- 'New password should be valid'
+ 'New password should be valid'
end
def test_password_modify_overwrite_old_password
@@ -80,11 +98,11 @@ def test_password_modify_overwrite_old_password
auth: @admin_account,
new_password: 'passworD3')
- refute @ldap.bind(username: @dn, password: 'passworD1', method: :simple),
- 'Old password should no longer be valid'
+ refute @ldap.bind(username: @dn, password: 'admin', method: :simple),
+ 'Old password should no longer be valid'
assert @ldap.bind(username: @dn, password: 'passworD3', method: :simple),
- 'New password should be valid'
+ 'New password should be valid'
end
def teardown
diff --git a/test/integration/test_return_codes.rb b/test/integration/test_return_codes.rb
index 0e381a0a..30057a2a 100644
--- a/test/integration/test_return_codes.rb
+++ b/test/integration/test_return_codes.rb
@@ -4,8 +4,16 @@
# See: section 12.12 http://www.openldap.org/doc/admin24/overlays.html
class TestReturnCodeIntegration < LDAPIntegrationTestCase
+ def test_open_error
+ @ldap.authenticate "cn=fake", "creds"
+ @ldap.open do
+ result = @ldap.get_operation_result
+ assert_equal Net::LDAP::ResultCodeInvalidCredentials, result.code
+ end
+ end
+
def test_operations_error
- refute @ldap.search(filter: "cn=operationsError", base: "ou=Retcodes,dc=rubyldap,dc=com")
+ refute @ldap.search(filter: "cn=operationsError", base: "ou=Retcodes,dc=example,dc=org")
assert result = @ldap.get_operation_result
assert_equal Net::LDAP::ResultCodeOperationsError, result.code
@@ -13,7 +21,7 @@ def test_operations_error
end
def test_protocol_error
- refute @ldap.search(filter: "cn=protocolError", base: "ou=Retcodes,dc=rubyldap,dc=com")
+ refute @ldap.search(filter: "cn=protocolError", base: "ou=Retcodes,dc=example,dc=org")
assert result = @ldap.get_operation_result
assert_equal Net::LDAP::ResultCodeProtocolError, result.code
@@ -21,7 +29,7 @@ def test_protocol_error
end
def test_time_limit_exceeded
- assert @ldap.search(filter: "cn=timeLimitExceeded", base: "ou=Retcodes,dc=rubyldap,dc=com")
+ assert @ldap.search(filter: "cn=timeLimitExceeded", base: "ou=Retcodes,dc=example,dc=org")
assert result = @ldap.get_operation_result
assert_equal Net::LDAP::ResultCodeTimeLimitExceeded, result.code
@@ -29,7 +37,7 @@ def test_time_limit_exceeded
end
def test_size_limit_exceeded
- assert @ldap.search(filter: "cn=sizeLimitExceeded", base: "ou=Retcodes,dc=rubyldap,dc=com")
+ assert @ldap.search(filter: "cn=sizeLimitExceeded", base: "ou=Retcodes,dc=example,dc=org")
assert result = @ldap.get_operation_result
assert_equal Net::LDAP::ResultCodeSizeLimitExceeded, result.code
diff --git a/test/integration/test_search.rb b/test/integration/test_search.rb
index 96f9ff42..1f562c22 100644
--- a/test/integration/test_search.rb
+++ b/test/integration/test_search.rb
@@ -4,7 +4,7 @@ class TestSearchIntegration < LDAPIntegrationTestCase
def test_search
entries = []
- result = @ldap.search(base: "dc=rubyldap,dc=com") do |entry|
+ result = @ldap.search(base: "dc=example,dc=org") do |entry|
assert_kind_of Net::LDAP::Entry, entry
entries << entry
end
@@ -16,7 +16,7 @@ def test_search
def test_search_without_result
entries = []
- result = @ldap.search(base: "dc=rubyldap,dc=com", return_result: false) do |entry|
+ result = @ldap.search(base: "dc=example,dc=org", return_result: false) do |entry|
assert_kind_of Net::LDAP::Entry, entry
entries << entry
end
@@ -26,24 +26,24 @@ def test_search_without_result
end
def test_search_filter_string
- entries = @ldap.search(base: "dc=rubyldap,dc=com", filter: "(uid=user1)")
+ entries = @ldap.search(base: "dc=example,dc=org", filter: "(uid=user1)")
assert_equal 1, entries.size
end
def test_search_filter_object
filter = Net::LDAP::Filter.eq("uid", "user1") | Net::LDAP::Filter.eq("uid", "user2")
- entries = @ldap.search(base: "dc=rubyldap,dc=com", filter: filter)
+ entries = @ldap.search(base: "dc=example,dc=org", filter: filter)
assert_equal 2, entries.size
end
def test_search_constrained_attributes
- entry = @ldap.search(base: "uid=user1,ou=People,dc=rubyldap,dc=com", attributes: ["cn", "sn"]).first
+ entry = @ldap.search(base: "uid=user1,ou=People,dc=example,dc=org", attributes: ["cn", "sn"]).first
assert_equal [:cn, :dn, :sn], entry.attribute_names.sort # :dn is always included
assert_empty entry[:mail]
end
def test_search_attributes_only
- entry = @ldap.search(base: "uid=user1,ou=People,dc=rubyldap,dc=com", attributes_only: true).first
+ entry = @ldap.search(base: "uid=user1,ou=People,dc=example,dc=org", attributes_only: true).first
assert_empty entry[:cn], "unexpected attribute value: #{entry[:cn]}"
end
@@ -52,7 +52,7 @@ def test_search_timeout
entries = []
events = @service.subscribe "search.net_ldap_connection"
- result = @ldap.search(base: "dc=rubyldap,dc=com", time: 5) do |entry|
+ result = @ldap.search(base: "dc=example,dc=org", time: 5) do |entry|
assert_kind_of Net::LDAP::Entry, entry
entries << entry
end
@@ -66,7 +66,7 @@ def test_search_timeout
def test_search_with_size
entries = []
- result = @ldap.search(base: "dc=rubyldap,dc=com", size: 1) do |entry|
+ result = @ldap.search(base: "dc=example,dc=org", size: 1) do |entry|
assert_kind_of Net::LDAP::Entry, entry
entries << entry
end
diff --git a/test/support/vm/openldap/README.md b/test/support/vm/openldap/README.md
deleted file mode 100644
index f79f4dc6..00000000
--- a/test/support/vm/openldap/README.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# Local OpenLDAP Integration Testing
-
-Set up a [Vagrant](http://www.vagrantup.com/) VM to run integration
-tests against OpenLDAP locally. *NOTE*: To support some of the SSL tests,
-Vagrant forwards localhost port 9389 to VM host port 9389. The port mapping
-goes away when you run `vagrant destroy`.
-
-## Install Vagrant
-
-*NOTE*: The Vagrant gem (`gem install vagrant`) is
-[no longer supported](https://www.vagrantup.com/docs/installation/). If you've
-previously installed it, run `gem uninstall vagrant`. If you're an rbenv
-user, you probably want to follow that up with `rbenv rehash; hash -r`.
-
-If you use Homebrew on macOS:
-``` bash
-$ brew update
-$ brew cask install virtualbox
-$ brew cask install vagrant
-$ brew cask install vagrant-manager
-$ vagrant plugin install vagrant-vbguest
-```
-
-Installing Vagrant and virtualbox on other operating systems is left
-as an exercise to the reader. Note the `vagrant-vbguest` plugin is required
-to update the VirtualBox guest extensions in the guest VM image.
-
-## Run the tests
-
-``` bash
-# start VM (from the correct directory)
-$ cd test/support/vm/openldap/
-$ vagrant up
-
-# get the IP address of the VM
-$ ip=$(vagrant ssh -- "ifconfig eth1 | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -n1")
-
-# change back to root project directory
-$ cd ../../../..
-
-# set the TCP port for testing
-$ export INTEGRATION_PORT=9389
-
-# run all tests, including integration tests
-$ time INTEGRATION=openldap INTEGRATION_HOST=$ip bundle exec rake
-
-# run a specific integration test file
-$ time INTEGRATION=openldap INTEGRATION_HOST=$ip bundle exec ruby test/integration/test_search.rb
-
-# run integration tests by default
-$ export INTEGRATION=openldap
-$ export INTEGRATION_HOST=$ip
-
-# now run tests without having to set ENV variables
-$ time bundle exec rake
-
-# Once you're all done
-$ cd test/support/vm/openldap
-$ vagrant destroy
-```
-
-If at any point your VM appears to have broken itself, `vagrant destroy`
-from the `test/support/vm/openldap` directory will blow it away. You can
-then do `vagrant up` and start over.
diff --git a/test/support/vm/openldap/Vagrantfile b/test/support/vm/openldap/Vagrantfile
deleted file mode 100644
index 1f375e76..00000000
--- a/test/support/vm/openldap/Vagrantfile
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- mode: ruby -*-
-# vi: set ft=ruby :
-
-# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
-VAGRANTFILE_API_VERSION = "2"
-
-Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
- config.vm.hostname = "rubyldap.com"
-
- config.vm.box = "hashicorp/precise64"
-
- config.vm.network "private_network", type: :dhcp
- config.vm.network "forwarded_port", guest: 389, host: 9389
-
- config.ssh.forward_agent = true
-
- config.vm.provision "shell", inline: "apt-get update; exec env /vagrant_data/script/install-openldap"
-
- config.vm.synced_folder "../../../..", "/vagrant_data"
-
- config.vm.provider "vmware_fusion" do |vb, override|
- override.vm.box = "hashicorp/precise64"
- vb.memory = 4596
- vb.vmx["displayname"] = "integration tests vm"
- vb.vmx["numvcpus"] = "2"
- end
-
- config.vm.provider "virtualbox" do |vb, override|
- vb.memory = 4096
- vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
- vb.customize ["modifyvm", :id, "--chipset", "ich9"]
- vb.customize ["modifyvm", :id, "--vram", "16"]
- end
-end
diff --git a/test/test_dn.rb b/test/test_dn.rb
index 5fff6ae8..52e87bd7 100644
--- a/test/test_dn.rb
+++ b/test/test_dn.rb
@@ -1,11 +1,25 @@
require_relative 'test_helper'
-require 'net/ldap/dn'
+require_relative '../lib/net/ldap/dn'
class TestDN < Test::Unit::TestCase
def test_escape
assert_equal '\\,\\+\\"\\\\\\<\\>\\;', Net::LDAP::DN.escape(',+"\\<>;')
end
+ def test_escape_pound_sign
+ assert_equal '\\#test', Net::LDAP::DN.escape('#test')
+ end
+
+ def test_escape_space
+ assert_equal '\\ before_after\\ ', Net::LDAP::DN.escape(' before_after ')
+ end
+
+ def test_retain_spaces
+ dn = Net::LDAP::DN.new('CN=Foo.bar.baz, OU=Foo \ ,OU=\ Bar, O=Baz')
+ assert_equal "CN=Foo.bar.baz, OU=Foo \\ ,OU=\\ Bar, O=Baz", dn.to_s
+ assert_equal ["CN", "Foo.bar.baz", "OU", "Foo ", "OU", " Bar", "O", "Baz"], dn.to_a
+ end
+
def test_escape_on_initialize
dn = Net::LDAP::DN.new('cn', ',+"\\<>;', 'ou=company')
assert_equal 'cn=\\,\\+\\"\\\\\\<\\>\\;,ou=company', dn.to_s
@@ -18,7 +32,7 @@ def test_to_a
def test_to_a_parenthesis
dn = Net::LDAP::DN.new('cn = \ James , ou = "Comp\28ny" ')
- assert_equal ['cn', ' James', 'ou', 'Comp(ny'], dn.to_a
+ assert_equal ['cn', ' James ', 'ou', 'Comp(ny'], dn.to_a
end
def test_to_a_hash_symbol
@@ -26,7 +40,6 @@ def test_to_a_hash_symbol
assert_equal ['1.23.4', '#A3B4D5', 'ou', 'Company'], dn.to_a
end
- # TODO: raise a more specific exception than RuntimeError
def test_bad_input_raises_error
[
'cn=James,',
@@ -38,7 +51,7 @@ def test_bad_input_raises_error
'd1.2=Value',
].each do |input|
dn = Net::LDAP::DN.new(input)
- assert_raises(RuntimeError) { dn.to_a }
+ assert_raises(Net::LDAP::InvalidDNError) { dn.to_a }
end
end
end
diff --git a/test/test_entry.rb b/test/test_entry.rb
index e2184747..60c89ba6 100644
--- a/test/test_entry.rb
+++ b/test/test_entry.rb
@@ -39,6 +39,32 @@ def test_case_insensitive_attribute_names
assert_equal ['Jensen'], @entry['Sn']
assert_equal ['Jensen'], @entry['SN']
end
+
+ def test_to_h
+ @entry['sn'] = 'Jensen'
+ expected = {
+ dn: ['cn=Barbara,o=corp'],
+ sn: ['Jensen'],
+ }
+ duplicate = @entry.to_h
+ assert_equal expected, duplicate
+
+ # check that changing the duplicate
+ # does not affect the internal state
+ duplicate.delete(:sn)
+ assert_not_equal duplicate, @entry.to_h
+ end
+
+ def test_equal_operator
+ entry_two = Net::LDAP::Entry.new 'cn=Barbara,o=corp'
+ assert_equal @entry, entry_two
+
+ @entry['sn'] = 'Jensen'
+ assert_not_equal @entry, entry_two
+
+ entry_two['sn'] = 'Jensen'
+ assert_equal @entry, entry_two
+ end
end
class TestEntryLDIF < Test::Unit::TestCase
@@ -47,7 +73,8 @@ def setup
%Q{dn: something
foo: foo
barAttribute: bar
- })
+ },
+ )
end
def test_attribute
@@ -59,7 +86,7 @@ def test_modify_attribute
@entry.foo = 'bar'
assert_equal ['bar'], @entry.foo
- @entry.fOo= 'baz'
+ @entry.fOo = 'baz'
assert_equal ['baz'], @entry.foo
end
end
diff --git a/test/test_filter_parser.rb b/test/test_filter_parser.rb
index 6f1ca48b..960ff1ad 100644
--- a/test/test_filter_parser.rb
+++ b/test/test_filter_parser.rb
@@ -1,4 +1,5 @@
# encoding: utf-8
+
require_relative 'test_helper'
class TestFilterParser < Test::Unit::TestCase
@@ -21,4 +22,8 @@ def test_slash
def test_colons
assert_kind_of Net::LDAP::Filter, Net::LDAP::Filter::FilterParser.parse("(ismemberof=cn=edu:berkeley:app:calmessages:deans,ou=campus groups,dc=berkeley,dc=edu)")
end
+
+ def test_attr_tag
+ assert_kind_of Net::LDAP::Filter, Net::LDAP::Filter::FilterParser.parse("(mail;primary=jane@example.org)")
+ end
end
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 0a976be4..4a7600bd 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -1,6 +1,6 @@
# Add 'lib' to load path.
require 'test/unit'
-require 'net/ldap'
+require_relative '../lib/net/ldap'
require 'flexmock/test_unit'
# Whether integration tests should be run.
@@ -14,14 +14,14 @@
if File.exist?("/etc/ssl/certs/cacert.pem")
"/etc/ssl/certs/cacert.pem"
else
- File.expand_path("fixtures/ca/cacert.pem", File.dirname(__FILE__))
+ File.expand_path("fixtures/ca/docker-ca.pem", File.dirname(__FILE__))
end
end
BIND_CREDS = {
method: :simple,
- username: "uid=user1,ou=People,dc=rubyldap,dc=com",
- password: "passworD1",
+ username: "cn=admin,dc=example,dc=org",
+ password: "admin",
}.freeze
TLS_OPTS = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge({}).freeze
@@ -65,10 +65,9 @@ def setup
@ldap = Net::LDAP.new \
host: ENV.fetch('https://github.com/INTEGRATION_HOST', 'localhost'),
port: ENV.fetch('https://github.com/INTEGRATION_PORT', 389),
- admin_user: 'uid=admin,dc=rubyldap,dc=com',
- admin_password: 'passworD1',
- search_domains: %w(dc=rubyldap,dc=com),
+ search_domains: %w(dc=example,dc=org),
uid: 'uid',
instrumentation_service: @service
+ @ldap.authenticate "cn=admin,dc=example,dc=org", "admin"
end
end
diff --git a/test/test_ldap.rb b/test/test_ldap.rb
index 8d6a9a72..6c061475 100644
--- a/test/test_ldap.rb
+++ b/test/test_ldap.rb
@@ -1,4 +1,4 @@
-require 'test_helper'
+require_relative 'test_helper'
class TestLDAPInstrumentation < Test::Unit::TestCase
# Fake Net::LDAP::Connection for testing
@@ -94,7 +94,7 @@ def test_encryption
def test_normalize_encryption_symbol
enc = @subject.send(:normalize_encryption, :start_tls)
- assert_equal enc, {:method => :start_tls, :tls_options => {}}
+ assert_equal enc, :method => :start_tls, :tls_options => {}
end
def test_normalize_encryption_nil
@@ -104,11 +104,11 @@ def test_normalize_encryption_nil
def test_normalize_encryption_string
enc = @subject.send(:normalize_encryption, 'start_tls')
- assert_equal enc, {:method => :start_tls, :tls_options => {}}
+ assert_equal enc, :method => :start_tls, :tls_options => {}
end
def test_normalize_encryption_hash
- enc = @subject.send(:normalize_encryption, {:method => :start_tls, :tls_options => {:foo => :bar}})
- assert_equal enc, {:method => :start_tls, :tls_options => {:foo => :bar}}
+ enc = @subject.send(:normalize_encryption, :method => :start_tls, :tls_options => { :foo => :bar })
+ assert_equal enc, :method => :start_tls, :tls_options => { :foo => :bar }
end
end
diff --git a/test/test_ldap_connection.rb b/test/test_ldap_connection.rb
index 8489c377..fdfa418c 100644
--- a/test/test_ldap_connection.rb
+++ b/test/test_ldap_connection.rb
@@ -61,7 +61,7 @@ def test_result_for_connection_failed_is_set
ldap_client = Net::LDAP.new(host: '127.0.0.1', port: 12345)
- assert_raise Net::LDAP::ConnectionRefusedError do
+ assert_raise Errno::ECONNREFUSED do
ldap_client.bind(method: :simple, username: 'asdf', password: 'asdf')
end
@@ -86,16 +86,15 @@ def test_blocked_port
def test_connection_refused
connection = Net::LDAP::Connection.new(:host => "fail.Errno::ECONNREFUSED", :port => 636, :socket_class => FakeTCPSocket)
stderr = capture_stderr do
- assert_raise Net::LDAP::ConnectionRefusedError do
+ assert_raise Errno::ECONNREFUSED do
connection.socket
end
end
- assert_equal("Deprecation warning: Net::LDAP::ConnectionRefused will be deprecated. Use Errno::ECONNREFUSED instead.\n", stderr)
end
def test_connection_timeout
connection = Net::LDAP::Connection.new(:host => "fail.Errno::ETIMEDOUT", :port => 636, :socket_class => FakeTCPSocket)
- stderr = capture_stderr do
+ capture_stderr do
assert_raise Net::LDAP::Error do
connection.socket
end
@@ -124,7 +123,7 @@ def test_modify_ops_add
end
def test_modify_ops_replace
- args = { :operations =>[[:replace, "mail", "testuser@example.com"]] }
+ args = { :operations => [[:replace, "mail", "testuser@example.com"]] }
result = Net::LDAP::Connection.modify_ops(args[:operations])
expected = ["0#\n\x01\x020\x1E\x04\x04mail1\x16\x04\x14testuser@example.com"]
assert_equal(expected, result)
@@ -191,9 +190,9 @@ def test_queued_read_reads_until_message_id_match
result2 = make_message(2)
mock = flexmock("socket")
- mock.should_receive(:read_ber).
- and_return(result1).
- and_return(result2)
+ mock.should_receive(:read_ber)
+ .and_return(result1)
+ .and_return(result2)
conn = Net::LDAP::Connection.new(:socket => mock)
assert result = conn.queued_read(2)
@@ -206,9 +205,9 @@ def test_queued_read_modify
result2 = make_message(2, app_tag: Net::LDAP::PDU::ModifyResponse)
mock = flexmock("socket")
- mock.should_receive(:read_ber).
- and_return(result1).
- and_return(result2)
+ mock.should_receive(:read_ber)
+ .and_return(result1)
+ .and_return(result2)
mock.should_receive(:write)
conn = Net::LDAP::Connection.new(:socket => mock)
@@ -227,9 +226,9 @@ def test_queued_read_add
result2 = make_message(2, app_tag: Net::LDAP::PDU::AddResponse)
mock = flexmock("socket")
- mock.should_receive(:read_ber).
- and_return(result1).
- and_return(result2)
+ mock.should_receive(:read_ber)
+ .and_return(result1)
+ .and_return(result2)
mock.should_receive(:write)
conn = Net::LDAP::Connection.new(:socket => mock)
@@ -245,9 +244,9 @@ def test_queued_read_rename
result2 = make_message(2, app_tag: Net::LDAP::PDU::ModifyRDNResponse)
mock = flexmock("socket")
- mock.should_receive(:read_ber).
- and_return(result1).
- and_return(result2)
+ mock.should_receive(:read_ber)
+ .and_return(result1)
+ .and_return(result2)
mock.should_receive(:write)
conn = Net::LDAP::Connection.new(:socket => mock)
@@ -266,9 +265,9 @@ def test_queued_read_delete
result2 = make_message(2, app_tag: Net::LDAP::PDU::DeleteResponse)
mock = flexmock("socket")
- mock.should_receive(:read_ber).
- and_return(result1).
- and_return(result2)
+ mock.should_receive(:read_ber)
+ .and_return(result1)
+ .and_return(result2)
mock.should_receive(:write)
conn = Net::LDAP::Connection.new(:socket => mock)
@@ -284,13 +283,13 @@ def test_queued_read_setup_encryption_with_start_tls
result2 = make_message(2, app_tag: Net::LDAP::PDU::ExtendedResponse)
mock = flexmock("socket")
- mock.should_receive(:read_ber).
- and_return(result1).
- and_return(result2)
+ mock.should_receive(:read_ber)
+ .and_return(result1)
+ .and_return(result2)
mock.should_receive(:write)
conn = Net::LDAP::Connection.new(:socket => mock)
- flexmock(Net::LDAP::Connection).should_receive(:wrap_with_ssl).with(mock, {}, nil).
- and_return(mock)
+ flexmock(Net::LDAP::Connection).should_receive(:wrap_with_ssl).with(mock, {}, nil, nil)
+ .and_return(mock)
conn.next_msgid # simulates ongoing query
@@ -303,9 +302,9 @@ def test_queued_read_bind_simple
result2 = make_message(2, app_tag: Net::LDAP::PDU::BindResult)
mock = flexmock("socket")
- mock.should_receive(:read_ber).
- and_return(result1).
- and_return(result2)
+ mock.should_receive(:read_ber)
+ .and_return(result1)
+ .and_return(result2)
mock.should_receive(:write)
conn = Net::LDAP::Connection.new(:socket => mock)
@@ -314,7 +313,8 @@ def test_queued_read_bind_simple
assert result = conn.bind(
method: :simple,
username: "uid=user1,ou=People,dc=rubyldap,dc=com",
- password: "passworD1")
+ password: "passworD1",
+ )
assert result.success?
assert_equal 2, result.message_id
end
@@ -324,9 +324,9 @@ def test_queued_read_bind_sasl
result2 = make_message(2, app_tag: Net::LDAP::PDU::BindResult)
mock = flexmock("socket")
- mock.should_receive(:read_ber).
- and_return(result1).
- and_return(result2)
+ mock.should_receive(:read_ber)
+ .and_return(result1)
+ .and_return(result2)
mock.should_receive(:write)
conn = Net::LDAP::Connection.new(:socket => mock)
@@ -336,10 +336,23 @@ def test_queued_read_bind_sasl
method: :sasl,
mechanism: "fake",
initial_credential: "passworD1",
- challenge_response: flexmock("challenge proc"))
+ challenge_response: flexmock("challenge proc"),
+ )
assert result.success?
assert_equal 2, result.message_id
end
+
+ def test_invalid_pdu_type
+ options = {
+ code: Net::LDAP::ResultCodeSuccess,
+ matched_dn: "",
+ error_message: "",
+ }
+ ber = Net::BER::BerIdentifiedArray.new([options[:code], options[:matched_dn], options[:error_message]])
+ assert_raise Net::LDAP::PDU::Error do
+ Net::LDAP::PDU.new([0, ber])
+ end
+ end
end
class TestLDAPConnectionErrors < Test::Unit::TestCase
@@ -469,8 +482,8 @@ def test_search_net_ldap_connection_event
search_result_ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, "", ""])
search_result_ber.ber_identifier = Net::LDAP::PDU::SearchResult
search_result = [1, search_result_ber]
- @tcp_socket.should_receive(:read_ber).and_return(search_data).
- and_return(search_result)
+ @tcp_socket.should_receive(:read_ber).and_return(search_data)
+ .and_return(search_result)
events = @service.subscribe "search.net_ldap_connection"
unread = @service.subscribe "search_messages_unread.net_ldap_connection"
@@ -488,4 +501,88 @@ def test_search_net_ldap_connection_event
# ensure no unread
assert unread.empty?, "should not have any leftover unread messages"
end
+
+ def test_add_with_controls
+ dacl_flag = 0x4 # DACL_SECURITY_INFORMATION
+ control_values = [dacl_flag].map(&:to_ber).to_ber_sequence.to_s.to_ber
+ controls = []
+ # LDAP_SERVER_SD_FLAGS constant definition, taken from https://ldapwiki.com/wiki/LDAP_SERVER_SD_FLAGS_OID
+ ldap_server_sd_flags = '1.2.840.113556.1.4.801'.freeze
+ controls << [ldap_server_sd_flags.to_ber, true.to_ber, control_values].to_ber_sequence
+
+ ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, "", ""])
+ ber.ber_identifier = Net::LDAP::PDU::AddResponse
+ @tcp_socket.should_receive(:read_ber).and_return([1, ber])
+
+ result = @connection.add(:dn => "uid=added-user1,ou=People,dc=rubyldap,dc=com", :controls => controls)
+ assert result.success?, "should be success"
+ assert_equal "", result.error_message
+ end
+
+ def test_modify_with_controls
+ dacl_flag = 0x4 # DACL_SECURITY_INFORMATION
+ control_values = [dacl_flag].map(&:to_ber).to_ber_sequence.to_s.to_ber
+ controls = []
+ # LDAP_SERVER_SD_FLAGS constant definition, taken from https://ldapwiki.com/wiki/LDAP_SERVER_SD_FLAGS_OID
+ ldap_server_sd_flags = '1.2.840.113556.1.4.801'.freeze
+ controls << [ldap_server_sd_flags.to_ber, true.to_ber, control_values].to_ber_sequence
+
+ ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, "", ""])
+ ber.ber_identifier = Net::LDAP::PDU::ModifyResponse
+ @tcp_socket.should_receive(:read_ber).and_return([1, ber])
+
+ result = @connection.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]], :controls => controls)
+ assert result.success?, "should be success"
+ assert_equal "", result.error_message
+ end
+
+ def test_search_with_controls
+ # search data
+ search_data_ber = Net::BER::BerIdentifiedArray.new([1, [
+ "uid=user1,ou=People,dc=rubyldap,dc=com",
+ [["uid", ["user1"]]],
+ ]])
+ search_data_ber.ber_identifier = Net::LDAP::PDU::SearchReturnedData
+ search_data = [1, search_data_ber]
+ # search result (end of results)
+ search_result_ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, "", ""])
+ search_result_ber.ber_identifier = Net::LDAP::PDU::SearchResult
+ search_result = [1, search_result_ber]
+ @tcp_socket.should_receive(:read_ber).and_return(search_data)
+ .and_return(search_result)
+
+ events = @service.subscribe "search.net_ldap_connection"
+ unread = @service.subscribe "search_messages_unread.net_ldap_connection"
+
+ all_but_sacl_flag = 0x1 | 0x2 | 0x4 # OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
+ control_values = [all_but_sacl_flag].map(&:to_ber).to_ber_sequence.to_s.to_ber
+ controls = []
+ # LDAP_SERVER_SD_FLAGS constant definition, taken from https://ldapwiki.com/wiki/LDAP_SERVER_SD_FLAGS_OID
+ ldap_server_sd_flags = '1.2.840.113556.1.4.801'.freeze
+ controls << [ldap_server_sd_flags.to_ber, true.to_ber, control_values].to_ber_sequence
+
+ result = @connection.search(filter: "(uid=user1)", base: "ou=People,dc=rubyldap,dc=com", controls: controls)
+ assert result.success?, "should be success"
+
+ # a search event
+ payload, result = events.pop
+ assert payload.key?(:result)
+ assert payload.key?(:filter)
+ assert_equal "(uid=user1)", payload[:filter].to_s
+ assert result
+
+ # ensure no unread
+ assert unread.empty?, "should not have any leftover unread messages"
+ end
+
+ def test_ldapwhoami
+ ber = Net::BER::BerIdentifiedArray.new([Net::LDAP::ResultCodeSuccess, '', '', 0, 'dn:uid=zerosteiner,ou=users,dc=example,dc=org'])
+ ber.ber_identifier = Net::LDAP::PDU::ExtendedResponse
+ response = [1, ber]
+
+ @tcp_socket.should_receive(:read_ber).and_return(response)
+
+ result = @connection.ldapwhoami
+ assert result.extended_response == 'dn:uid=zerosteiner,ou=users,dc=example,dc=org'
+ end
end
diff --git a/test/test_ldif.rb b/test/test_ldif.rb
index cc1ee2bf..c74ea6e7 100644
--- a/test/test_ldif.rb
+++ b/test/test_ldif.rb
@@ -22,46 +22,46 @@ def test_ldif_with_version
def test_ldif_with_comments
str = ["# Hello from LDIF-land", "# This is an unterminated comment"]
io = StringIO.new(str[0] + "\r\n" + str[1])
- ds = Net::LDAP::Dataset::read_ldif(io)
+ ds = Net::LDAP::Dataset.read_ldif(io)
assert_equal(str, ds.comments)
end
def test_ldif_with_password
psw = "goldbricks"
- hashed_psw = "{SHA}" + Base64::encode64(Digest::SHA1.digest(psw)).chomp
+ hashed_psw = "{SHA}" + Base64.encode64(Digest::SHA1.digest(psw)).chomp
- ldif_encoded = Base64::encode64(hashed_psw).chomp
- ds = Net::LDAP::Dataset::read_ldif(StringIO.new("dn: Goldbrick\r\nuserPassword:: #{ldif_encoded}\r\n\r\n"))
+ ldif_encoded = Base64.encode64(hashed_psw).chomp
+ ds = Net::LDAP::Dataset.read_ldif(StringIO.new("dn: Goldbrick\r\nuserPassword:: #{ldif_encoded}\r\n\r\n"))
recovered_psw = ds["Goldbrick"][:userpassword].shift
assert_equal(hashed_psw, recovered_psw)
end
def test_ldif_with_continuation_lines
- ds = Net::LDAP::Dataset::read_ldif(StringIO.new("dn: abcdefg\r\n hijklmn\r\n\r\n"))
+ ds = Net::LDAP::Dataset.read_ldif(StringIO.new("dn: abcdefg\r\n hijklmn\r\n\r\n"))
assert_equal(true, ds.key?("abcdefghijklmn"))
end
def test_ldif_with_continuation_lines_and_extra_whitespace
- ds1 = Net::LDAP::Dataset::read_ldif(StringIO.new("dn: abcdefg\r\n hijklmn\r\n\r\n"))
+ ds1 = Net::LDAP::Dataset.read_ldif(StringIO.new("dn: abcdefg\r\n hijklmn\r\n\r\n"))
assert_equal(true, ds1.key?("abcdefg hijklmn"))
- ds2 = Net::LDAP::Dataset::read_ldif(StringIO.new("dn: abcdefg\r\n hij klmn\r\n\r\n"))
+ ds2 = Net::LDAP::Dataset.read_ldif(StringIO.new("dn: abcdefg\r\n hij klmn\r\n\r\n"))
assert_equal(true, ds2.key?("abcdefghij klmn"))
end
def test_ldif_tab_is_not_continuation
- ds = Net::LDAP::Dataset::read_ldif(StringIO.new("dn: key\r\n\tnotcontinued\r\n\r\n"))
+ ds = Net::LDAP::Dataset.read_ldif(StringIO.new("dn: key\r\n\tnotcontinued\r\n\r\n"))
assert_equal(true, ds.key?("key"))
end
def test_ldif_with_base64_dn
str = "dn:: Q049QmFzZTY0IGRuIHRlc3QsT1U9VGVzdCxPVT1Vbml0cyxEQz1leGFtcGxlLERDPWNvbQ==\r\n\r\n"
- ds = Net::LDAP::Dataset::read_ldif(StringIO.new(str))
+ ds = Net::LDAP::Dataset.read_ldif(StringIO.new(str))
assert_equal(true, ds.key?("CN=Base64 dn test,OU=Test,OU=Units,DC=example,DC=com"))
end
def test_ldif_with_base64_dn_and_continuation_lines
str = "dn:: Q049QmFzZTY0IGRuIHRlc3Qgd2l0aCBjb250aW51YXRpb24gbGluZSxPVT1UZXN0LE9VPVVua\r\n XRzLERDPWV4YW1wbGUsREM9Y29t\r\n\r\n"
- ds = Net::LDAP::Dataset::read_ldif(StringIO.new(str))
+ ds = Net::LDAP::Dataset.read_ldif(StringIO.new(str))
assert_equal(true, ds.key?("CN=Base64 dn test with continuation line,OU=Test,OU=Units,DC=example,DC=com"))
end
@@ -69,7 +69,7 @@ def test_ldif_with_base64_dn_and_continuation_lines
# to verify the content.
def test_ldif
File.open(TestLdifFilename, "r") do |f|
- ds = Net::LDAP::Dataset::read_ldif(f)
+ ds = Net::LDAP::Dataset.read_ldif(f)
assert_equal(13, ds.length)
end
end
@@ -84,7 +84,7 @@ def test_to_ldif
entries = data.lines.grep(/^dn:\s*/) { $'.chomp }
dn_entries = entries.dup
- ds = Net::LDAP::Dataset::read_ldif(io) do |type, value|
+ ds = Net::LDAP::Dataset.read_ldif(io) do |type, value|
case type
when :dn
assert_equal(dn_entries.first, value)
diff --git a/test/test_password.rb b/test/test_password.rb
index 87b47d91..cc1878da 100644
--- a/test/test_password.rb
+++ b/test/test_password.rb
@@ -4,7 +4,12 @@
class TestPassword < Test::Unit::TestCase
def test_psw
- assert_equal("{MD5}xq8jwrcfibi0sZdZYNkSng==", Net::LDAP::Password.generate( :md5, "cashflow" ))
- assert_equal("{SHA}YE4eGkN4BvwNN1f5R7CZz0kFn14=", Net::LDAP::Password.generate( :sha, "cashflow" ))
+ assert_equal("{MD5}xq8jwrcfibi0sZdZYNkSng==", Net::LDAP::Password.generate(:md5, "cashflow"))
+ assert_equal("{SHA}YE4eGkN4BvwNN1f5R7CZz0kFn14=", Net::LDAP::Password.generate(:sha, "cashflow"))
+ end
+
+ def test_psw_with_ssha256_should_not_contain_linefeed
+ flexmock(SecureRandom).should_receive(:random_bytes).and_return('\xE5\x8A\x99\xF8\xCB\x15GW\xE8\xEA\xAD\x0F\xBF\x95\xB0\xDC')
+ assert_equal("{SSHA256}Cc7MXboTyUP5PnPAeJeCrgMy8+7Gus0sw7kBJuTrmf1ceEU1XHg4QVx4OTlceEY4XHhDQlx4MTVHV1x4RThceEVBXHhBRFx4MEZceEJGXHg5NVx4QjBceERD", Net::LDAP::Password.generate(:ssha256, "cashflow"))
end
end
diff --git a/test/test_snmp.rb b/test/test_snmp.rb
index 6a809a80..fa064d41 100644
--- a/test/test_snmp.rb
+++ b/test/test_snmp.rb
@@ -1,7 +1,7 @@
# $Id: testsnmp.rb 231 2006-12-21 15:09:29Z blackhedd $
require_relative 'test_helper'
-require 'net/snmp'
+require_relative '../lib/net/snmp'
class TestSnmp < Test::Unit::TestCase
def self.raw_string(s)
@@ -17,7 +17,7 @@ def self.raw_string(s)
def test_invalid_packet
data = "xxxx"
assert_raise(Net::BER::BerError) do
-ary = data.read_ber(Net::SNMP::AsnSyntax)
+ data.read_ber(Net::SNMP::AsnSyntax)
end
end
@@ -41,7 +41,7 @@ def _test_consume_string
def test_weird_packet
assert_raise(Net::SnmpPdu::Error) do
-Net::SnmpPdu.parse("aaaaaaaaaaaaaa")
+ Net::SnmpPdu.parse("aaaaaaaaaaaaaa")
end
end
@@ -93,7 +93,7 @@ def test_make_response
def test_make_bad_response
pdu = Net::SnmpPdu.new
- assert_raise(Net::SnmpPdu::Error) {pdu.to_ber_string}
+ assert_raise(Net::SnmpPdu::Error) { pdu.to_ber_string }
pdu.pdu_type = :get_response
pdu.request_id = 999
pdu.to_ber_string
@@ -115,5 +115,4 @@ def test_community
pdu = Net::SnmpPdu.parse(ary)
assert_equal("xxxxxx", pdu.community)
end
-
end
diff --git a/test/test_ssl_ber.rb b/test/test_ssl_ber.rb
index 7711558b..766c8b84 100644
--- a/test/test_ssl_ber.rb
+++ b/test/test_ssl_ber.rb
@@ -5,7 +5,7 @@ class TestSSLBER < Test::Unit::TestCase
# Transmits str to @to and reads it back from @from.
#
def transmit(str)
- Timeout::timeout(1) do
+ Timeout.timeout(1) do
@to.write(str)
@to.close
@@ -22,18 +22,24 @@ def setup
#
# TODO: Replace test with real socket
# https://github.com/ruby-ldap/ruby-net-ldap/pull/121#discussion_r18746386
- flexmock(OpenSSL::SSL::SSLSocket).
- new_instances.should_receive(:connect => nil)
+ flexmock(OpenSSL::SSL::SSLSocket)
+ .new_instances.should_receive(:connect => nil)
@to = Net::LDAP::Connection.wrap_with_ssl(@to)
@from = Net::LDAP::Connection.wrap_with_ssl(@from)
end
def test_transmit_strings
+ omit_if RUBY_PLATFORM == "java", "JRuby throws an error without a real socket"
+ omit_if (RUBY_VERSION >= "3.1" || RUBY_ENGINE == "truffleruby"), "Ruby complains about connection not being open"
+
assert_equal "foo", transmit("foo")
end
def test_transmit_ber_encoded_numbers
+ omit_if RUBY_PLATFORM == "java", "JRuby throws an error without a real socket"
+ omit_if (RUBY_VERSION >= "3.1" || RUBY_ENGINE == "truffleruby"), "Ruby complains about connection not being open"
+
@to.write 1234.to_ber
assert_equal 1234, @from.read_ber
end
diff --git a/testserver/ldapserver.rb b/testserver/ldapserver.rb
index 809f9e7e..9adeacb0 100644
--- a/testserver/ldapserver.rb
+++ b/testserver/ldapserver.rb
@@ -15,8 +15,7 @@
#------------------------------------------------
module LdapServer
-
- LdapServerAsnSyntax = {
+ LdapServerAsnSyntaxTemplate = {
:application => {
:constructed => {
0 => :array, # LDAP BindRequest
@@ -46,7 +45,7 @@ def receive_data data
@data ||= ""; @data << data
while pdu = @data.read_ber!(LdapServerAsnSyntax)
begin
- handle_ldap_pdu pdu
+ handle_ldap_pdu pdu
rescue
$logger.error "closing connection due to error #{$!}"
close_connection
@@ -87,9 +86,7 @@ def handle_bind_request pdu
end
end
-
-
- #--
+ # --
# Search Response ::=
# CHOICE {
# entry [APPLICATION 4] SEQUENCE {
@@ -119,9 +116,9 @@ def handle_search_request pdu
# pdu[1][7] is the list of requested attributes.
# If it's an empty array, that means that *all* attributes were requested.
requested_attrs = if pdu[1][7].length > 0
- pdu[1][7].map(&:downcase)
- else
- :all
+ pdu[1][7].map(&:downcase)
+ else
+ :all
end
filters = pdu[1][6]
@@ -131,13 +128,13 @@ def handle_search_request pdu
end
# TODO, what if this returns nil?
- filter = Net::LDAP::Filter.parse_ldap_filter( filters )
+ filter = Net::LDAP::Filter.parse_ldap_filter(filters)
$ldif.each do |dn, entry|
- if filter.match( entry )
+ if filter.match(entry)
attrs = []
entry.each do |k, v|
- if requested_attrs == :all or requested_attrs.include?(k.downcase)
+ if requested_attrs == :all || requested_attrs.include?(k.downcase)
attrvals = v.map(&:to_ber).to_ber_set
attrs << [k.to_ber, attrvals].to_ber_sequence
end
@@ -149,32 +146,27 @@ def handle_search_request pdu
end
end
-
send_ldap_response 5, pdu[0].to_i, 0, "", "Was that what you wanted?"
end
-
-
def send_ldap_response pkt_tag, msgid, code, dn, text
- send_data( [msgid.to_ber, [code.to_ber, dn.to_ber, text.to_ber].to_ber_appsequence(pkt_tag)].to_ber )
+ send_data([msgid.to_ber, [code.to_ber, dn.to_ber, text.to_ber].to_ber_appsequence(pkt_tag)].to_ber)
end
-
end
-
#------------------------------------------------
# Rather bogus, a global method, which reads a HARDCODED filename
# parses out LDIF data. It will be used to serve LDAP queries out of this server.
#
def load_test_data
- ary = File.readlines( "./testdata.ldif" )
+ ary = File.readlines("./testdata.ldif")
hash = {}
- while line = ary.shift and line.chomp!
+ while (line = ary.shift) && line.chomp!
if line =~ /^dn:[\s]*/i
dn = $'
hash[dn] = {}
- while attr = ary.shift and attr.chomp! and attr =~ /^([\w]+)[\s]*:[\s]*/
+ while (attr = ary.shift) && attr.chomp! && attr =~ /^([\w]+)[\s]*:[\s]*/
hash[dn][$1.downcase] ||= []
hash[dn][$1.downcase] << $'
end
@@ -183,7 +175,6 @@ def load_test_data
hash
end
-
#------------------------------------------------
if __FILE__ == $0
@@ -200,10 +191,10 @@ def load_test_data
$ldif = load_test_data
require 'net/ldap'
-
+ LdapServerAsnSyntax = Net::BER.compile_syntax(LdapServerAsnSyntaxTemplate)
EventMachine.run do
$logger.info "starting LDAP server on 127.0.0.1 port 3890"
EventMachine.start_server "127.0.0.1", 3890, LdapServer
- EventMachine.add_periodic_timer 60, proc {$logger.info "heartbeat"}
+ EventMachine.add_periodic_timer 60, proc { $logger.info "heartbeat" }
end
end