Skip to content

Factor out some common object mocking in tests #15396

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
* Tests for {@link AuthorizationManagerAfterMethodInterceptor}.
*
* @author Evgeniy Cheban
* @author Gengwu Zhao
*/
public class AuthorizationManagerAfterMethodInterceptorTests {

Expand Down Expand Up @@ -84,9 +85,9 @@ public void beforeWhenMockAuthorizationManagerThenCheckAndReturnedObject() throw

@Test
public void afterWhenMockSecurityContextHolderStrategyThenUses() throws Throwable {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
Authentication authentication = TestAuthentication.authenticatedUser();
given(strategy.getContext()).willReturn(new SecurityContextImpl(authentication));
SecurityContextHolderStrategy strategy = mockSecurityContextHolderStrategy(
new SecurityContextImpl(authentication));
MethodInvocation invocation = mock(MethodInvocation.class);
AuthorizationManager<MethodInvocationResult> authorizationManager = AuthenticatedAuthorizationManager
.authenticated();
Expand All @@ -100,10 +101,10 @@ public void afterWhenMockSecurityContextHolderStrategyThenUses() throws Throwabl
// gh-12877
@Test
public void afterWhenStaticSecurityContextHolderStrategyAfterConstructorThenUses() throws Throwable {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
Authentication authentication = new TestingAuthenticationToken("john", "password",
AuthorityUtils.createAuthorityList("authority"));
given(strategy.getContext()).willReturn(new SecurityContextImpl(authentication));
SecurityContextHolderStrategy strategy = mockSecurityContextHolderStrategy(
new SecurityContextImpl(authentication));
MethodInvocation invocation = mock(MethodInvocation.class);
AuthorizationManager<MethodInvocationResult> authorizationManager = AuthenticatedAuthorizationManager
.authenticated();
Expand Down Expand Up @@ -159,6 +160,12 @@ public void invokeWhenCustomAuthorizationDeniedExceptionThenThrows() throws Thro
assertThatExceptionOfType(MyAuthzDeniedException.class).isThrownBy(() -> advice.invoke(mi));
}

private SecurityContextHolderStrategy mockSecurityContextHolderStrategy(SecurityContextImpl securityContextImpl) {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
given(strategy.getContext()).willReturn(securityContextImpl);
return strategy;
}

static class MyAuthzDeniedException extends AuthorizationDeniedException {

MyAuthzDeniedException(String msg, AuthorizationResult authorizationResult) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* Tests for {@link AuthorizationManagerBeforeMethodInterceptor}.
*
* @author Evgeniy Cheban
* @author Gengwu Zhao
*/
public class AuthorizationManagerBeforeMethodInterceptorTests {

Expand Down Expand Up @@ -79,10 +80,10 @@ public void beforeWhenMockAuthorizationManagerThenCheck() throws Throwable {

@Test
public void beforeWhenMockSecurityContextHolderStrategyThenUses() throws Throwable {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
Authentication authentication = new TestingAuthenticationToken("user", "password",
AuthorityUtils.createAuthorityList("authority"));
given(strategy.getContext()).willReturn(new SecurityContextImpl(authentication));
SecurityContextHolderStrategy strategy = mockSecurityContextHolderStrategy(
new SecurityContextImpl(authentication));
MethodInvocation invocation = mock(MethodInvocation.class);
AuthorizationManager<MethodInvocation> authorizationManager = AuthenticatedAuthorizationManager.authenticated();
AuthorizationManagerBeforeMethodInterceptor advice = new AuthorizationManagerBeforeMethodInterceptor(
Expand All @@ -95,10 +96,11 @@ public void beforeWhenMockSecurityContextHolderStrategyThenUses() throws Throwab
// gh-12877
@Test
public void beforeWhenStaticSecurityContextHolderStrategyAfterConstructorThenUses() throws Throwable {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);

Authentication authentication = new TestingAuthenticationToken("john", "password",
AuthorityUtils.createAuthorityList("authority"));
given(strategy.getContext()).willReturn(new SecurityContextImpl(authentication));
SecurityContextHolderStrategy strategy = mockSecurityContextHolderStrategy(
new SecurityContextImpl(authentication));
MethodInvocation invocation = mock(MethodInvocation.class);
AuthorizationManager<MethodInvocation> authorizationManager = AuthenticatedAuthorizationManager.authenticated();
AuthorizationManagerBeforeMethodInterceptor advice = new AuthorizationManagerBeforeMethodInterceptor(
Expand Down Expand Up @@ -150,6 +152,13 @@ public void invokeWhenCustomAuthorizationDeniedExceptionThenThrows() {
assertThatExceptionOfType(MyAuthzDeniedException.class).isThrownBy(() -> advice.invoke(null));
}

private SecurityContextHolderStrategy mockSecurityContextHolderStrategy(SecurityContextImpl securityContextImpl) {

SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
given(strategy.getContext()).willReturn(securityContextImpl);
return strategy;
}

static class MyAuthzDeniedException extends AuthorizationDeniedException {

MyAuthzDeniedException(String msg, AuthorizationResult authorizationResult) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
* Tests for {@link PostFilterAuthorizationMethodInterceptor}.
*
* @author Evgeniy Cheban
* @author Gengwu Zhao
*/
public class PostFilterAuthorizationMethodInterceptorTests {

Expand Down Expand Up @@ -120,10 +121,11 @@ public void checkInheritedAnnotationsWhenConflictingThenAnnotationConfigurationE

@Test
public void postFilterWhenMockSecurityContextHolderStrategyThenUses() throws Throwable {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);

Authentication authentication = new TestingAuthenticationToken("john", "password",
AuthorityUtils.createAuthorityList("authority"));
given(strategy.getContext()).willReturn(new SecurityContextImpl(authentication));
SecurityContextHolderStrategy strategy = mockSecurityContextHolderStrategy(
new SecurityContextImpl(authentication));
String[] array = { "john", "bob" };
MockMethodInvocation invocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingArrayAuthentication", new Class[] { String[].class }, new Object[] { array }) {
Expand All @@ -141,10 +143,11 @@ public Object proceed() {
// gh-12877
@Test
public void postFilterWhenStaticSecurityContextHolderStrategyAfterConstructorThenUses() throws Throwable {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);

Authentication authentication = new TestingAuthenticationToken("john", "password",
AuthorityUtils.createAuthorityList("authority"));
given(strategy.getContext()).willReturn(new SecurityContextImpl(authentication));
SecurityContextHolderStrategy strategy = mockSecurityContextHolderStrategy(
new SecurityContextImpl(authentication));
String[] array = { "john", "bob" };
MockMethodInvocation invocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingArrayAuthentication", new Class[] { String[].class }, new Object[] { array }) {
Expand All @@ -161,6 +164,13 @@ public Object proceed() {
SecurityContextHolder.setContextHolderStrategy(saved);
}

private SecurityContextHolderStrategy mockSecurityContextHolderStrategy(SecurityContextImpl securityContextImpl) {

SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
given(strategy.getContext()).willReturn(securityContextImpl);
return strategy;
}

@PostFilter("filterObject == 'john'")
public static class TestClass implements InterfaceAnnotationsOne, InterfaceAnnotationsTwo {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
* Tests for {@link PreFilterAuthorizationMethodInterceptor}.
*
* @author Evgeniy Cheban
* @author Gengwu Zhao
*/
public class PreFilterAuthorizationMethodInterceptorTests {

Expand Down Expand Up @@ -180,10 +181,10 @@ public void checkInheritedAnnotationsWhenConflictingThenAnnotationConfigurationE

@Test
public void preFilterWhenMockSecurityContextHolderStrategyThenUses() throws Throwable {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
Authentication authentication = new TestingAuthenticationToken("john", "password",
AuthorityUtils.createAuthorityList("authority"));
given(strategy.getContext()).willReturn(new SecurityContextImpl(authentication));
SecurityContextHolderStrategy strategy = mockSecurityContextHolderStrategy(
new SecurityContextImpl(authentication));
List<String> list = new ArrayList<>();
list.add("john");
list.add("bob");
Expand All @@ -198,10 +199,10 @@ public void preFilterWhenMockSecurityContextHolderStrategyThenUses() throws Thro
// gh-12877
@Test
public void preFilterWhenStaticSecurityContextHolderStrategyAfterConstructorThenUses() throws Throwable {
SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
Authentication authentication = new TestingAuthenticationToken("john", "password",
AuthorityUtils.createAuthorityList("authority"));
given(strategy.getContext()).willReturn(new SecurityContextImpl(authentication));
SecurityContextHolderStrategy strategy = mockSecurityContextHolderStrategy(
new SecurityContextImpl(authentication));
List<String> list = new ArrayList<>();
list.add("john");
list.add("bob");
Expand All @@ -215,6 +216,13 @@ public void preFilterWhenStaticSecurityContextHolderStrategyAfterConstructorThen
SecurityContextHolder.setContextHolderStrategy(saved);
}

private SecurityContextHolderStrategy mockSecurityContextHolderStrategy(SecurityContextImpl securityContextImpl) {

SecurityContextHolderStrategy strategy = mock(SecurityContextHolderStrategy.class);
given(strategy.getContext()).willReturn(securityContextImpl);
return strategy;
}

@PreFilter("filterObject == 'john'")
public static class TestClass implements InterfaceAnnotationsOne, InterfaceAnnotationsTwo {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 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.
Expand Down Expand Up @@ -59,6 +59,7 @@
/**
* @author Luke Taylor
* @author Rob Winch
* @author Gengwu Zhao
*/
public class ActiveDirectoryLdapAuthenticationProviderTests {

Expand All @@ -70,9 +71,13 @@ public class ActiveDirectoryLdapAuthenticationProviderTests {

UsernamePasswordAuthenticationToken joe = UsernamePasswordAuthenticationToken.unauthenticated("joe", "password");

DirContext ctx;

@BeforeEach
public void setUp() {
public void setUp() throws NamingException {
this.provider = new ActiveDirectoryLdapAuthenticationProvider("mydomain.eu", "ldap://192.168.1.200/");
this.ctx = mock(DirContext.class);
given(this.ctx.getNameInNamespace()).willReturn("");
}

@Test
Expand All @@ -90,15 +95,13 @@ public void successfulAuthenticationProducesExpectedAuthorities() throws Excepti
@Test
public void customSearchFilterIsUsedForSuccessfulAuthentication() throws Exception {
String customSearchFilter = "(&(objectClass=user)(sAMAccountName={0}))";
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
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)))
given(this.ctx.search(any(Name.class), eq(customSearchFilter), any(Object[].class), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider(
"mydomain.eu", "ldap://192.168.1.200/");
customProvider.contextFactory = createContextFactoryReturning(ctx);
customProvider.contextFactory = createContextFactoryReturning(this.ctx);
customProvider.setSearchFilter(customSearchFilter);
Authentication result = customProvider.authenticate(this.joe);
assertThat(result.isAuthenticated()).isTrue();
Expand All @@ -107,34 +110,31 @@ public void customSearchFilterIsUsedForSuccessfulAuthentication() throws Excepti
@Test
public void defaultSearchFilter() throws Exception {
final String defaultSearchFilter = "(&(objectClass=user)(userPrincipalName={0}))";
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
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)))
given(this.ctx.search(any(Name.class), eq(defaultSearchFilter), any(Object[].class), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider(
"mydomain.eu", "ldap://192.168.1.200/");
customProvider.contextFactory = createContextFactoryReturning(ctx);
customProvider.contextFactory = createContextFactoryReturning(this.ctx);
Authentication result = customProvider.authenticate(this.joe);
assertThat(result.isAuthenticated()).isTrue();
verify(ctx).search(any(Name.class), eq(defaultSearchFilter), any(Object[].class), any(SearchControls.class));
verify(this.ctx).search(any(Name.class), eq(defaultSearchFilter), any(Object[].class),
any(SearchControls.class));
}

// SEC-2897,SEC-2224
@Test
public void bindPrincipalAndUsernameUsed() throws Exception {
final String defaultSearchFilter = "(&(objectClass=user)(userPrincipalName={0}))";
ArgumentCaptor<Object[]> captor = ArgumentCaptor.forClass(Object[].class);
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
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)))
given(this.ctx.search(any(Name.class), eq(defaultSearchFilter), captor.capture(), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
ActiveDirectoryLdapAuthenticationProvider customProvider = new ActiveDirectoryLdapAuthenticationProvider(
"mydomain.eu", "ldap://192.168.1.200/");
customProvider.contextFactory = createContextFactoryReturning(ctx);
customProvider.contextFactory = createContextFactoryReturning(this.ctx);
Authentication result = customProvider.authenticate(this.joe);
assertThat(captor.getValue()).containsExactly("joe@mydomain.eu", "joe");
assertThat(result.isAuthenticated()).isTrue();
Expand All @@ -153,36 +153,30 @@ public void setSearchFilterEmpty() {
@Test
public void nullDomainIsSupportedIfAuthenticatingWithFullUserPrincipal() throws Exception {
this.provider = new ActiveDirectoryLdapAuthenticationProvider(null, "ldap://192.168.1.200/");
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
DirContextAdapter dca = new DirContextAdapter();
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
given(ctx.search(eq(LdapNameBuilder.newInstance("DC=mydomain,DC=eu").build()), any(String.class),
given(this.ctx.search(eq(LdapNameBuilder.newInstance("DC=mydomain,DC=eu").build()), any(String.class),
any(Object[].class), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr));
this.provider.contextFactory = createContextFactoryReturning(ctx);
this.provider.contextFactory = createContextFactoryReturning(this.ctx);
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> this.provider.authenticate(this.joe));
this.provider.authenticate(UsernamePasswordAuthenticationToken.unauthenticated("joe@mydomain.eu", "password"));
}

@Test
public void failedUserSearchCausesBadCredentials() throws Exception {
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
given(ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
given(this.ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
.willThrow(new NameNotFoundException());
this.provider.contextFactory = createContextFactoryReturning(ctx);
this.provider.contextFactory = createContextFactoryReturning(this.ctx);
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> this.provider.authenticate(this.joe));
}

// SEC-2017
@Test
public void noUserSearchCausesUsernameNotFound() throws Exception {
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
given(ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
given(this.ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
.willReturn(new EmptyEnumeration<>());
this.provider.contextFactory = createContextFactoryReturning(ctx);
this.provider.contextFactory = createContextFactoryReturning(this.ctx);
assertThatExceptionOfType(BadCredentialsException.class).isThrownBy(() -> this.provider.authenticate(this.joe));
}

Expand All @@ -196,16 +190,14 @@ public void sec2500PreventAnonymousBind() {
@Test
@SuppressWarnings("unchecked")
public void duplicateUserSearchCausesError() throws Exception {
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
NamingEnumeration<SearchResult> searchResults = mock(NamingEnumeration.class);
given(searchResults.hasMore()).willReturn(true, true, false);
SearchResult searchResult = mock(SearchResult.class);
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)))
given(this.ctx.search(any(Name.class), any(String.class), any(Object[].class), any(SearchControls.class)))
.willReturn(searchResults);
this.provider.contextFactory = createContextFactoryReturning(ctx);
this.provider.contextFactory = createContextFactoryReturning(this.ctx);
assertThatExceptionOfType(IncorrectResultSizeDataAccessException.class)
.isThrownBy(() -> this.provider.authenticate(this.joe));
}
Expand Down Expand Up @@ -357,16 +349,14 @@ DirContext createContext(Hashtable<?, ?> env) {

private void checkAuthentication(String rootDn, ActiveDirectoryLdapAuthenticationProvider provider)
throws NamingException {
DirContext ctx = mock(DirContext.class);
given(ctx.getNameInNamespace()).willReturn("");
DirContextAdapter dca = new DirContextAdapter();
SearchResult sr = new SearchResult("CN=Joe Jannsen,CN=Users", dca, dca.getAttributes());
@SuppressWarnings("deprecation")
Name searchBaseDn = LdapNameBuilder.newInstance(rootDn).build();
given(ctx.search(eq(searchBaseDn), any(String.class), any(Object[].class), any(SearchControls.class)))
given(this.ctx.search(eq(searchBaseDn), any(String.class), any(Object[].class), any(SearchControls.class)))
.willReturn(new MockNamingEnumeration(sr))
.willReturn(new MockNamingEnumeration(sr));
provider.contextFactory = createContextFactoryReturning(ctx);
provider.contextFactory = createContextFactoryReturning(this.ctx);
Authentication result = provider.authenticate(this.joe);
assertThat(result.getAuthorities()).isEmpty();
dca.addAttributeValue("memberOf", "CN=Admin,CN=Users,DC=mydomain,DC=eu");
Expand Down
Loading