Merge branch '5.8.x' into 6.0.x

Closes gh-13882
This commit is contained in:
Marcus Da Coregio
2023-09-29 11:46:00 -03:00
1152 changed files with 10637 additions and 8548 deletions

View File

@@ -52,7 +52,7 @@ public class LdapUtilsTests {
final DirContext mockCtx = mock(DirContext.class);
given(mockCtx.getNameInNamespace()).willReturn("");
assertThat(LdapUtils.getRelativeName("cn=jane,dc=springframework,dc=org", mockCtx))
.isEqualTo("cn=jane,dc=springframework,dc=org");
.isEqualTo("cn=jane,dc=springframework,dc=org");
}
@Test
@@ -60,7 +60,7 @@ public class LdapUtilsTests {
final DirContext mockCtx = mock(DirContext.class);
given(mockCtx.getNameInNamespace()).willReturn("dc=springsecurity,dc = org");
assertThat(LdapUtils.getRelativeName("cn=jane smith, dc = springsecurity , dc=org", mockCtx))
.isEqualTo("cn=jane smith");
.isEqualTo("cn=jane smith");
}
@Test
@@ -70,15 +70,15 @@ public class LdapUtilsTests {
assertThat(LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/")).isEqualTo("");
assertThat(LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/")).isEqualTo("");
assertThat(LdapUtils.parseRootDnFromUrl("ldaps://monkeymachine.co.uk/dc=springframework,dc=org"))
.isEqualTo("dc=springframework,dc=org");
.isEqualTo("dc=springframework,dc=org");
assertThat(LdapUtils.parseRootDnFromUrl("ldap:///dc=springframework,dc=org"))
.isEqualTo("dc=springframework,dc=org");
.isEqualTo("dc=springframework,dc=org");
assertThat(LdapUtils.parseRootDnFromUrl("ldap://monkeymachine/dc=springframework,dc=org"))
.isEqualTo("dc=springframework,dc=org");
.isEqualTo("dc=springframework,dc=org");
assertThat(LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk/dc=springframework,dc=org/ou=blah"))
.isEqualTo("dc=springframework,dc=org/ou=blah");
.isEqualTo("dc=springframework,dc=org/ou=blah");
assertThat(LdapUtils.parseRootDnFromUrl("ldap://monkeymachine.co.uk:389/dc=springframework,dc=org/ou=blah"))
.isEqualTo("dc=springframework,dc=org/ou=blah");
.isEqualTo("dc=springframework,dc=org/ou=blah");
}
}

View File

@@ -58,8 +58,9 @@ public class SpringSecurityAuthenticationSourceTests {
@Test
public void principalIsEmptyForAnonymousUser() {
AuthenticationSource source = new SpringSecurityAuthenticationSource();
SecurityContextHolder.getContext().setAuthentication(
new AnonymousAuthenticationToken("key", "anonUser", AuthorityUtils.createAuthorityList("ignored")));
SecurityContextHolder.getContext()
.setAuthentication(
new AnonymousAuthenticationToken("key", "anonUser", AuthorityUtils.createAuthorityList("ignored")));
assertThat(source.getPrincipal()).isEqualTo("");
}
@@ -84,7 +85,7 @@ public class SpringSecurityAuthenticationSourceTests {
user.setDn(new DistinguishedName("uid=joe,ou=users"));
AuthenticationSource source = new SpringSecurityAuthenticationSource();
SecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken(user.createUserDetails(), null));
.setAuthentication(new TestingAuthenticationToken(user.createUserDetails(), null));
assertThat(source.getPrincipal()).isEqualTo("uid=joe,ou=users");
}
@@ -95,7 +96,7 @@ public class SpringSecurityAuthenticationSourceTests {
user.setDn(new DistinguishedName("uid=joe,ou=users"));
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
given(strategy.getContext())
.willReturn(new SecurityContextImpl(new TestingAuthenticationToken(user.createUserDetails(), null)));
.willReturn(new SecurityContextImpl(new TestingAuthenticationToken(user.createUserDetails(), null)));
SpringSecurityAuthenticationSource source = new SpringSecurityAuthenticationSource();
source.setSecurityContextHolderStrategy(strategy);
assertThat(source.getPrincipal()).isEqualTo("uid=joe,ou=users");

View File

@@ -61,7 +61,7 @@ public class SpringSecurityLdapTemplateTests {
Object[] params = new Object[] {};
DirContextAdapter searchResultObject = mock(DirContextAdapter.class);
given(this.ctx.search(any(DistinguishedName.class), eq(filter), eq(params), this.searchControls.capture()))
.willReturn(this.resultsEnum);
.willReturn(this.resultsEnum);
given(this.resultsEnum.hasMore()).willReturn(true, false);
given(this.resultsEnum.next()).willReturn(this.searchResult);
given(this.searchResult.getObject()).willReturn(searchResultObject);

View File

@@ -39,8 +39,9 @@ class LdapSecurityRuntimeHintsTests {
@BeforeEach
void setup() {
SpringFactoriesLoader.forResourceLocation("META-INF/spring/aot.factories").load(RuntimeHintsRegistrar.class)
.forEach((registrar) -> registrar.registerHints(this.hints, ClassUtils.getDefaultClassLoader()));
SpringFactoriesLoader.forResourceLocation("META-INF/spring/aot.factories")
.load(RuntimeHintsRegistrar.class)
.forEach((registrar) -> registrar.registerHints(this.hints, ClassUtils.getDefaultClassLoader()));
}
@Test
@@ -51,7 +52,7 @@ class LdapSecurityRuntimeHintsTests {
@Test
void ldapCtxFactoryHasHints() {
assertThat(RuntimeHintsPredicates.reflection().onType(TypeReference.of("com.sun.jndi.ldap.LdapCtxFactory")))
.accepts(this.hints);
.accepts(this.hints);
}
}

View File

@@ -70,7 +70,7 @@ public class LdapAuthenticationProviderTests {
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(
() -> ldapProvider.authenticate(UsernamePasswordAuthenticationToken.unauthenticated(null, "password")));
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> ldapProvider
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("", "bobspassword")));
.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("", "bobspassword")));
}
@Test
@@ -151,7 +151,9 @@ public class LdapAuthenticationProviderTests {
given(mockAuthenticator.authenticate(authRequest)).willThrow(expectedCause);
LdapAuthenticationProvider ldapProvider = new LdapAuthenticationProvider(mockAuthenticator);
assertThatExceptionOfType(InternalAuthenticationServiceException.class)
.isThrownBy(() -> ldapProvider.authenticate(authRequest)).havingCause().isSameAs(expectedCause);
.isThrownBy(() -> ldapProvider.authenticate(authRequest))
.havingCause()
.isSameAs(expectedCause);
}
class MockAuthenticator implements LdapAuthenticator {

View File

@@ -52,7 +52,8 @@ public class PasswordComparisonAuthenticatorMockTests {
// Setup a single return value (i.e. success)
final NamingEnumeration searchResults = new BasicAttributes("", null).getAll();
given(dirCtx.search(eq("cn=Bob,ou=people"), eq("(userPassword={0})"), any(Object[].class),
any(SearchControls.class))).willReturn(searchResults);
any(SearchControls.class)))
.willReturn(searchResults);
authenticator.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("Bob", "bobspassword"));
}

View File

@@ -95,7 +95,7 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
DirContextAdapter dca = new DirContextAdapter();
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
given(ctx.search(any(Name.class), eq(customSearchFilter), any(Object[].class), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
.willReturn(new MockNamingEnumeration(sr));
ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider(
"mydomain.eu", "ldap://192.168.1.200/");
customProvider.contextFactory = createContextFactoryReturning(ctx);
@@ -112,7 +112,7 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
DirContextAdapter dca = new DirContextAdapter();
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
given(ctx.search(any(Name.class), eq(defaultSearchFilter), any(Object[].class), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
.willReturn(new MockNamingEnumeration(sr));
ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider(
"mydomain.eu", "ldap://192.168.1.200/");
customProvider.contextFactory = createContextFactoryReturning(ctx);
@@ -132,7 +132,7 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
DirContextAdapter dca = new DirContextAdapter();
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
given(ctx.search(any(Name.class), eq(defaultSearchFilter), captor.capture(), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
.willReturn(new MockNamingEnumeration(sr));
ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider(
"mydomain.eu", "ldap://192.168.1.200/");
customProvider.contextFactory = createContextFactoryReturning(ctx);
@@ -159,7 +159,8 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
DirContextAdapter dca = new DirContextAdapter();
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
given(ctx.search(eq(new DistinguishedName("DC=mydomain,DC=eu")), any(String.class), any(Object[].class),
any(SearchControls.class))).willReturn(new MockNamingEnumeration(sr));
any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
this.provider.contextFactory = createContextFactoryReturning(ctx);
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> this.provider.authenticate(this.joe));
this.provider.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("joe@mydomain.eu", "password"));
@@ -170,7 +171,7 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
given(ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
.willThrow(new NameNotFoundException());
.willThrow(new NameNotFoundException());
this.provider.contextFactory = createContextFactoryReturning(ctx);
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> this.provider.authenticate(this.joe));
}
@@ -181,7 +182,7 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
given(ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
.willReturn(new EmptyEnumeration<>());
.willReturn(new EmptyEnumeration<>());
this.provider.contextFactory = createContextFactoryReturning(ctx);
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> this.provider.authenticate(this.joe));
}
@@ -204,10 +205,10 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
given(searchResult.getObject()).willReturn(new DirContextAdapter("ou=1"), new DirContextAdapter("ou=2"));
given(searchResults.next()).willReturn(searchResult);
given(ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
.willReturn(searchResults);
.willReturn(searchResults);
this.provider.contextFactory = createContextFactoryReturning(ctx);
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> this.provider.authenticate(this.joe));
.isThrownBy(() -> this.provider.authenticate(this.joe));
}
static final String msg = "[LDAP: error code 49 - 80858585: LdapErr: DSID-DECAFF0, comment: AcceptSecurityContext error, data ";
@@ -240,9 +241,9 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
new AuthenticationException(msg + dataCode + ", xxxx]"));
this.provider.setConvertSubErrorCodesToExceptions(true);
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> this.provider.authenticate(this.joe))
.withCauseInstanceOf(ActiveDirectoryAuthenticationException.class)
.satisfies((ex) -> assertThat(((ActiveDirectoryAuthenticationException) ex.getCause()).getDataCode())
.isEqualTo(dataCode));
.withCauseInstanceOf(ActiveDirectoryAuthenticationException.class)
.satisfies((ex) -> assertThat(((ActiveDirectoryAuthenticationException) ex.getCause()).getDataCode())
.isEqualTo(dataCode));
}
@Test
@@ -251,7 +252,7 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> this.provider.authenticate(this.joe));
this.provider.setConvertSubErrorCodesToExceptions(true);
assertThatExceptionOfType(CredentialsExpiredException.class)
.isThrownBy(() -> this.provider.authenticate(this.joe));
.isThrownBy(() -> this.provider.authenticate(this.joe));
}
@Test
@@ -302,10 +303,10 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
ActiveDirectoryLdapAuthenticationProvider noneReachableProvider = new ActiveDirectoryLdapAuthenticationProvider(
"mydomain.eu", NON_EXISTING_LDAP_PROVIDER, "dc=ad,dc=eu,dc=mydomain");
noneReachableProvider
.setContextEnvironmentProperties(Collections.singletonMap("com.sun.jndi.ldap.connect.timeout", "5"));
.setContextEnvironmentProperties(Collections.singletonMap("com.sun.jndi.ldap.connect.timeout", "5"));
assertThatExceptionOfType(
org.springframework.security.authentication.InternalAuthenticationServiceException.class)
.isThrownBy(() -> noneReachableProvider.doAuthentication(this.joe));
.isThrownBy(() -> noneReachableProvider.doAuthentication(this.joe));
}
@Test
@@ -323,7 +324,7 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
@Test
public void setContextEnvironmentPropertiesEmpty() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.provider.setContextEnvironmentProperties(new Hashtable<>()));
.isThrownBy(() -> this.provider.setContextEnvironmentProperties(new Hashtable<>()));
}
@Test
@@ -332,9 +333,9 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
env.put("java.naming.ldap.factory.socket", "unknown.package.NonExistingSocketFactory");
this.provider.setContextEnvironmentProperties(env);
assertThatExceptionOfType(InternalAuthenticationServiceException.class)
.isThrownBy(() -> this.provider.authenticate(this.joe))
.withCauseInstanceOf(org.springframework.ldap.CommunicationException.class)
.withRootCauseInstanceOf(ClassNotFoundException.class);
.isThrownBy(() -> this.provider.authenticate(this.joe))
.withCauseInstanceOf(org.springframework.ldap.CommunicationException.class)
.withRootCauseInstanceOf(ClassNotFoundException.class);
}
ContextFactory createContextFactoryThrowing(final NamingException ex) {
@@ -364,7 +365,8 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {
@SuppressWarnings("deprecation")
DistinguishedName searchBaseDn = new DistinguishedName(rootDn);
given(ctx.search(eq(searchBaseDn), any(String.class), any(Object[].class), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr)).willReturn(new MockNamingEnumeration(sr));
.willReturn(new MockNamingEnumeration(sr))
.willReturn(new MockNamingEnumeration(sr));
provider.contextFactory = createContextFactoryReturning(ctx);
Authentication result = provider.authenticate(this.joe);
assertThat(result.getAuthorities()).isEmpty();

View File

@@ -115,7 +115,7 @@ public class InetOrgPersonMixinTests {
@Test
public void deserializeWhenMixinNotRegisteredThenThrowJsonProcessingException() {
assertThatExceptionOfType(JsonProcessingException.class)
.isThrownBy(() -> new ObjectMapper().readValue(INET_ORG_PERSON_JSON, InetOrgPerson.class));
.isThrownBy(() -> new ObjectMapper().readValue(INET_ORG_PERSON_JSON, InetOrgPerson.class));
}
@Test
@@ -129,7 +129,7 @@ public class InetOrgPersonMixinTests {
assertThat(authentication.getCarLicense()).isEqualTo(expectedAuthentication.getCarLicense());
assertThat(authentication.getDepartmentNumber()).isEqualTo(expectedAuthentication.getDepartmentNumber());
assertThat(authentication.getDestinationIndicator())
.isEqualTo(expectedAuthentication.getDestinationIndicator());
.isEqualTo(expectedAuthentication.getDestinationIndicator());
assertThat(authentication.getDn()).isEqualTo(expectedAuthentication.getDn());
assertThat(authentication.getDescription()).isEqualTo(expectedAuthentication.getDescription());
assertThat(authentication.getDisplayName()).isEqualTo(expectedAuthentication.getDisplayName());
@@ -153,14 +153,14 @@ public class InetOrgPersonMixinTests {
assertThat(authentication.getGivenName()).isEqualTo(expectedAuthentication.getGivenName());
assertThat(authentication.getTelephoneNumber()).isEqualTo(expectedAuthentication.getTelephoneNumber());
assertThat(authentication.getGraceLoginsRemaining())
.isEqualTo(expectedAuthentication.getGraceLoginsRemaining());
.isEqualTo(expectedAuthentication.getGraceLoginsRemaining());
assertThat(authentication.getTimeBeforeExpiration())
.isEqualTo(expectedAuthentication.getTimeBeforeExpiration());
.isEqualTo(expectedAuthentication.getTimeBeforeExpiration());
assertThat(authentication.isAccountNonExpired()).isEqualTo(expectedAuthentication.isAccountNonExpired());
assertThat(authentication.isAccountNonLocked()).isEqualTo(expectedAuthentication.isAccountNonLocked());
assertThat(authentication.isEnabled()).isEqualTo(expectedAuthentication.isEnabled());
assertThat(authentication.isCredentialsNonExpired())
.isEqualTo(expectedAuthentication.isCredentialsNonExpired());
.isEqualTo(expectedAuthentication.isCredentialsNonExpired());
}
private DirContextAdapter createUserContext() {

View File

@@ -91,14 +91,14 @@ public class LdapUserDetailsImplMixinTests {
@Test
public void deserializeWhenMixinNotRegisteredThenThrowJsonProcessingException() {
assertThatExceptionOfType(JsonProcessingException.class)
.isThrownBy(() -> new ObjectMapper().readValue(USER_JSON, LdapUserDetailsImpl.class));
.isThrownBy(() -> new ObjectMapper().readValue(USER_JSON, LdapUserDetailsImpl.class));
}
@Test
public void deserializeWhenMixinRegisteredThenDeserializes() throws Exception {
LdapUserDetailsMapper mapper = new LdapUserDetailsMapper();
LdapUserDetailsImpl expectedAuthentication = (LdapUserDetailsImpl) mapper
.mapUserFromContext(createUserContext(), "ghengis", AuthorityUtils.NO_AUTHORITIES);
.mapUserFromContext(createUserContext(), "ghengis", AuthorityUtils.NO_AUTHORITIES);
LdapUserDetailsImpl authentication = this.mapper.readValue(USER_JSON, LdapUserDetailsImpl.class);
assertThat(authentication.getAuthorities()).containsExactlyElementsOf(expectedAuthentication.getAuthorities());
@@ -106,14 +106,14 @@ public class LdapUserDetailsImplMixinTests {
assertThat(authentication.getUsername()).isEqualTo(expectedAuthentication.getUsername());
assertThat(authentication.getPassword()).isEqualTo(expectedAuthentication.getPassword());
assertThat(authentication.getGraceLoginsRemaining())
.isEqualTo(expectedAuthentication.getGraceLoginsRemaining());
.isEqualTo(expectedAuthentication.getGraceLoginsRemaining());
assertThat(authentication.getTimeBeforeExpiration())
.isEqualTo(expectedAuthentication.getTimeBeforeExpiration());
.isEqualTo(expectedAuthentication.getTimeBeforeExpiration());
assertThat(authentication.isAccountNonExpired()).isEqualTo(expectedAuthentication.isAccountNonExpired());
assertThat(authentication.isAccountNonLocked()).isEqualTo(expectedAuthentication.isAccountNonLocked());
assertThat(authentication.isEnabled()).isEqualTo(expectedAuthentication.isEnabled());
assertThat(authentication.isCredentialsNonExpired())
.isEqualTo(expectedAuthentication.isCredentialsNonExpired());
.isEqualTo(expectedAuthentication.isCredentialsNonExpired());
}
private DirContextAdapter createUserContext() {

View File

@@ -94,7 +94,7 @@ public class PersonMixinTests {
@Test
public void deserializeWhenMixinNotRegisteredThenThrowJsonProcessingException() {
assertThatExceptionOfType(JsonProcessingException.class)
.isThrownBy(() -> new ObjectMapper().readValue(PERSON_JSON, Person.class));
.isThrownBy(() -> new ObjectMapper().readValue(PERSON_JSON, Person.class));
}
@Test
@@ -113,14 +113,14 @@ public class PersonMixinTests {
assertThat(authentication.getGivenName()).isEqualTo(expectedAuthentication.getGivenName());
assertThat(authentication.getTelephoneNumber()).isEqualTo(expectedAuthentication.getTelephoneNumber());
assertThat(authentication.getGraceLoginsRemaining())
.isEqualTo(expectedAuthentication.getGraceLoginsRemaining());
.isEqualTo(expectedAuthentication.getGraceLoginsRemaining());
assertThat(authentication.getTimeBeforeExpiration())
.isEqualTo(expectedAuthentication.getTimeBeforeExpiration());
.isEqualTo(expectedAuthentication.getTimeBeforeExpiration());
assertThat(authentication.isAccountNonExpired()).isEqualTo(expectedAuthentication.isAccountNonExpired());
assertThat(authentication.isAccountNonLocked()).isEqualTo(expectedAuthentication.isAccountNonLocked());
assertThat(authentication.isEnabled()).isEqualTo(expectedAuthentication.isEnabled());
assertThat(authentication.isCredentialsNonExpired())
.isEqualTo(expectedAuthentication.isCredentialsNonExpired());
.isEqualTo(expectedAuthentication.isCredentialsNonExpired());
}
private DirContextAdapter createUserContext() {

View File

@@ -72,7 +72,7 @@ public class PasswordPolicyAwareContextSourceTests {
public void standardExceptionIsPropagatedWhenExceptionRaisedAndNoControlsAreSet() throws Exception {
willThrow(new NamingException("some LDAP exception")).given(this.ctx).reconnect(any(Control[].class));
assertThatExceptionOfType(UncategorizedLdapException.class)
.isThrownBy(() -> this.ctxSource.getContext("user", "ignored"));
.isThrownBy(() -> this.ctxSource.getContext("user", "ignored"));
}
@Test
@@ -81,7 +81,7 @@ public class PasswordPolicyAwareContextSourceTests {
new PasswordPolicyResponseControl(PasswordPolicyResponseControlTests.OPENLDAP_LOCKED_CTRL) });
willThrow(new NamingException("locked message")).given(this.ctx).reconnect(any(Control[].class));
assertThatExceptionOfType(PasswordPolicyException.class)
.isThrownBy(() -> this.ctxSource.getContext("user", "ignored"));
.isThrownBy(() -> this.ctxSource.getContext("user", "ignored"));
}
}

View File

@@ -43,7 +43,7 @@ public class LdapUserDetailsServiceTests {
@Test
public void rejectsNullSearchObject() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new LdapUserDetailsService(null, new NullLdapAuthoritiesPopulator()));
.isThrownBy(() -> new LdapUserDetailsService(null, new NullLdapAuthoritiesPopulator()));
}
@Test