Add LdapTemplate to LdapClient Adapter

Closes gh-774
This commit is contained in:
Josh Cummings
2025-02-11 17:56:11 -07:00
parent cb083d690f
commit 30efe4ecd8
6 changed files with 75 additions and 6 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -70,6 +70,8 @@ class DefaultLdapClient implements LdapClient {
private static final boolean RETURN_OBJ_FLAG = true;
private final Builder builder;
private final ContextSource contextSource;
private final Supplier<SearchControls> searchControlsSupplier;
@@ -80,9 +82,11 @@ class DefaultLdapClient implements LdapClient {
private boolean ignoreSizeLimitExceededException = true;
DefaultLdapClient(ContextSource contextSource, Supplier<SearchControls> searchControlsSupplier) {
DefaultLdapClient(ContextSource contextSource, Supplier<SearchControls> searchControlsSupplier,
LdapClient.Builder builder) {
this.contextSource = contextSource;
this.searchControlsSupplier = searchControlsSupplier;
this.builder = builder;
}
@Override
@@ -153,7 +157,7 @@ class DefaultLdapClient implements LdapClient {
*/
@Override
public Builder mutate() {
return new DefaultLdapClientBuilder(this.contextSource, this.searchControlsSupplier);
return this.builder;
}
/**

View File

@@ -47,6 +47,20 @@ class DefaultLdapClientBuilder implements LdapClient.Builder {
this.searchControlsSupplier = searchControlsSupplier;
}
DefaultLdapClientBuilder(LdapTemplate ldap) {
this.contextSource = ldap.getContextSource();
this.searchControlsSupplier = () -> {
SearchControls controls = new SearchControls();
controls.setSearchScope(ldap.getDefaultSearchScope());
controls.setCountLimit(ldap.getDefaultCountLimit());
controls.setTimeLimit(ldap.getDefaultTimeLimit());
return controls;
};
this.ignoreNameNotFoundException = ldap.isIgnoreNameNotFoundException();
this.ignoreSizeLimitExceededException = ldap.isIgnoreSizeLimitExceededException();
this.ignorePartialResultException = ldap.isIgnorePartialResultException();
}
@Override
public DefaultLdapClientBuilder contextSource(ContextSource contextSource) {
this.contextSource = contextSource;
@@ -99,7 +113,7 @@ class DefaultLdapClientBuilder implements LdapClient.Builder {
@Override
public LdapClient build() {
DefaultLdapClient client = new DefaultLdapClient(this.contextSource, this.searchControlsSupplier);
DefaultLdapClient client = new DefaultLdapClient(this.contextSource, this.searchControlsSupplier, this);
client.setIgnorePartialResultException(this.ignorePartialResultException);
client.setIgnoreSizeLimitExceededException(this.ignoreSizeLimitExceededException);
client.setIgnoreNameNotFoundException(this.ignoreNameNotFoundException);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2005-2023 the original author or authors.
* Copyright 2005-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -167,6 +167,16 @@ public interface LdapClient {
return new DefaultLdapClientBuilder().contextSource(contextSource).build();
}
/**
* Create an instance of {@link LdapClient}
* @param ldap the {@link LdapTemplate} to base this client off of
* @since 3.3
* @see #builder()
*/
static LdapClient create(LdapTemplate ldap) {
return new DefaultLdapClientBuilder(ldap).build();
}
/**
* Obtain a {@code LdapClient} builder.
*/

View File

@@ -166,6 +166,10 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
this.ignoreNameNotFoundException = ignore;
}
boolean isIgnoreNameNotFoundException() {
return this.ignoreNameNotFoundException;
}
/**
* Specify whether <code>PartialResultException</code> should be ignored in searches.
* AD servers typically have a problem with referrals. Normally a referral should be
@@ -182,6 +186,10 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
this.ignorePartialResultException = ignore;
}
boolean isIgnorePartialResultException() {
return this.ignorePartialResultException;
}
/**
* Specify whether <code>SizeLimitExceededException</code> should be ignored in
* searches. This is typically what you want if you specify count limit in your search
@@ -194,6 +202,10 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
this.ignoreSizeLimitExceededException = ignore;
}
boolean isIgnoreSizeLimitExceededException() {
return this.ignoreSizeLimitExceededException;
}
/**
* Set the default scope to be used in searches if not explicitly specified. Default
* is {@link javax.naming.directory.SearchControls#SUBTREE_SCOPE}.
@@ -206,6 +218,10 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
this.defaultSearchScope = defaultSearchScope;
}
int getDefaultSearchScope() {
return this.defaultSearchScope;
}
/**
* Set the default time limit be used in searches if not explicitly specified. Default
* is 0, indicating no time limit.
@@ -216,6 +232,10 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
this.defaultTimeLimit = defaultTimeLimit;
}
int getDefaultTimeLimit() {
return this.defaultTimeLimit;
}
/**
* Set the default count limit be used in searches if not explicitly specified.
* Default is 0, indicating no count limit.
@@ -226,6 +246,10 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
this.defaultCountLimit = defaultCountLimit;
}
int getDefaultCountLimit() {
return this.defaultCountLimit;
}
/**
* {@inheritDoc}
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2005-2023 the original author or authors.
* Copyright 2005-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -645,6 +645,21 @@ public class DefaultLdapClientTests {
verify(this.dirContextMock).close();
}
@Test
public void createWhenLdapTemplateThenUses() {
LdapTemplate ldap = mock(LdapTemplate.class);
given(ldap.getContextSource()).willReturn(this.contextSourceMock);
given(this.contextSourceMock.getReadOnlyContext()).willReturn(this.dirContextMock);
LdapClient.create(ldap).search().name("dc=name").toEntryStream();
verify(ldap).getContextSource();
verify(ldap).isIgnoreNameNotFoundException();
verify(ldap).isIgnorePartialResultException();
verify(ldap).isIgnoreSizeLimitExceededException();
verify(ldap).getDefaultCountLimit();
verify(ldap).getDefaultSearchScope();
verify(ldap).getDefaultTimeLimit();
}
private void noSearchResults(SearchControls controls) throws Exception {
given(this.dirContextMock.search(eq(this.nameMock), eq("(ou=somevalue)"),
argThat(new SearchControlsMatcher(controls))))

View File

@@ -214,6 +214,8 @@ The following list briefly describes the most important changes in Spring LDAP 2
* The https://github.com/spring-projects/spring-ldap/tree/main/samples[samples] have been polished and updated to make use of the features in 2.0.
Quite a bit of effort has been put into providing a useful example of an https://github.com/spring-projects/spring-ldap/tree/main/samples/user-admin[LDAP user management application].
* Added `LdapClient.create(LdapTemplate)` to simplify constructing an `LdapClient` from an `LdapTemplate`
[[spring-ldap-packaging-overview]]
== Packaging Overview