mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-01 14:41:46 +00:00
MNT-23880 Integrate the Alfresco Admin Console with the IDS (#2362)
* MNT-23880 Integrate IDS with the Admin Console * MNT-23880 Remove diamond expressions * MNT-23880 Refactor * MNT-23880 Move requesting authentication * MNT-23880 Fix comment * MNT-23880 Check if AdminConsoleAuthenticator is active * MNT-23880 Fix DefaultAdminConsoleAuthenticator + PMD issues * MNT-23880 Fix PMD issues * MNT-23880 Refactor * MNT-23880 Refactor RemoteUserAuthenticatorFactory
This commit is contained in:
@@ -29,6 +29,9 @@ import org.alfresco.repo.security.authentication.identityservice.IdentityService
|
||||
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceJITProvisioningHandlerUnitTest;
|
||||
import org.alfresco.repo.security.authentication.identityservice.LazyInstantiatingIdentityServiceFacadeUnitTest;
|
||||
import org.alfresco.repo.security.authentication.identityservice.SpringBasedIdentityServiceFacadeUnitTest;
|
||||
import org.alfresco.repo.security.authentication.identityservice.admin.AdminConsoleAuthenticationCookiesServiceUnitTest;
|
||||
import org.alfresco.repo.security.authentication.identityservice.admin.AdminConsoleHttpServletRequestWrapperUnitTest;
|
||||
import org.alfresco.repo.security.authentication.identityservice.admin.IdentityServiceAdminConsoleAuthenticatorUnitTest;
|
||||
import org.alfresco.util.testing.category.DBTests;
|
||||
import org.alfresco.util.testing.category.NonBuildTests;
|
||||
import org.junit.experimental.categories.Categories;
|
||||
@@ -145,6 +148,9 @@ import org.junit.runners.Suite;
|
||||
LazyInstantiatingIdentityServiceFacadeUnitTest.class,
|
||||
SpringBasedIdentityServiceFacadeUnitTest.class,
|
||||
IdentityServiceJITProvisioningHandlerUnitTest.class,
|
||||
AdminConsoleAuthenticationCookiesServiceUnitTest.class,
|
||||
AdminConsoleHttpServletRequestWrapperUnitTest.class,
|
||||
IdentityServiceAdminConsoleAuthenticatorUnitTest.class,
|
||||
org.alfresco.repo.security.authentication.CompositePasswordEncoderTest.class,
|
||||
org.alfresco.repo.security.authentication.PasswordHashingTest.class,
|
||||
org.alfresco.repo.security.authority.script.ScriptAuthorityService_RegExTest.class,
|
||||
|
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.security.authentication.identityservice.admin;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.alfresco.repo.admin.SysAdminParams;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
|
||||
public class AdminConsoleAuthenticationCookiesServiceUnitTest
|
||||
{
|
||||
private static final int DEFAULT_COOKIE_LIFETIME = 86400;
|
||||
private static final String COOKIE_NAME = "cookie";
|
||||
private static final String COOKIE_VALUE = "value";
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
@Mock
|
||||
private HttpServletResponse response;
|
||||
@Mock
|
||||
private SysAdminParams sysAdminParams;
|
||||
@Captor
|
||||
private ArgumentCaptor<Cookie> cookieCaptor;
|
||||
private AdminConsoleAuthenticationCookiesService cookiesService;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
initMocks(this);
|
||||
cookiesService = new AdminConsoleAuthenticationCookiesService(sysAdminParams, DEFAULT_COOKIE_LIFETIME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cookieShouldBeFoundInRequestThatContainsIt()
|
||||
{
|
||||
when(request.getCookies()).thenReturn(new Cookie[] { new Cookie(COOKIE_NAME, COOKIE_VALUE) });
|
||||
|
||||
String cookie = cookiesService.getCookie(COOKIE_NAME, request);
|
||||
|
||||
assertNotNull("The cookie should not be null", cookie);
|
||||
assertEquals("The cookie's value should match", COOKIE_VALUE, cookie);
|
||||
verify(request).getCookies();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cookieShouldNotBeFoundInRequestThatDoesNotContainIt()
|
||||
{
|
||||
when(request.getCookies()).thenReturn(new Cookie[] { new Cookie(COOKIE_NAME, COOKIE_VALUE) });
|
||||
|
||||
assertNull("The cookie should be null", cookiesService.getCookie("non-contained-cookie", request));
|
||||
|
||||
verify(request).getCookies();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cookieShouldNotBeFoundInRequestWithoutCookies()
|
||||
{
|
||||
when(request.getCookies()).thenReturn(null);
|
||||
|
||||
assertNull("The cookie should be null", cookiesService.getCookie(COOKIE_NAME, request));
|
||||
|
||||
verify(request).getCookies();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cookieShouldBeAddedToTheResponseWithDefaultParams()
|
||||
{
|
||||
when(sysAdminParams.getAlfrescoProtocol()).thenReturn("http");
|
||||
|
||||
cookiesService.addCookie(COOKIE_NAME, COOKIE_VALUE, response);
|
||||
|
||||
verify(sysAdminParams).getAlfrescoProtocol();
|
||||
verify(response).addCookie(cookieCaptor.capture());
|
||||
|
||||
Cookie cookie = cookieCaptor.getValue();
|
||||
assertNotNull("The cookie should not be null", cookie);
|
||||
assertEquals("Cookie's name should match", COOKIE_NAME, cookie.getName());
|
||||
assertEquals("Cookie's value should match", COOKIE_VALUE, cookie.getValue());
|
||||
assertEquals("Cookie's path should be the root", "/", cookie.getPath());
|
||||
assertEquals("Cookie's maxAge should match the default lifetime", DEFAULT_COOKIE_LIFETIME, cookie.getMaxAge());
|
||||
assertFalse("Cookie's secure flag should be false", cookie.getSecure());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureCookieShouldBeAddedToTheResponseWhenAlfrescoProtocolIsHttps()
|
||||
{
|
||||
when(sysAdminParams.getAlfrescoProtocol()).thenReturn("https");
|
||||
|
||||
cookiesService.addCookie(COOKIE_NAME, COOKIE_VALUE, response);
|
||||
|
||||
verify(sysAdminParams).getAlfrescoProtocol();
|
||||
verify(response).addCookie(cookieCaptor.capture());
|
||||
|
||||
Cookie cookie = cookieCaptor.getValue();
|
||||
assertNotNull("The cookie should not be null", cookie);
|
||||
assertTrue("Cookie's secure flag should be true", cookie.getSecure());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cookieWithCustomMaxAgeShouldBeAddedToTheResponse()
|
||||
{
|
||||
int customMaxAge = 60;
|
||||
cookiesService = new AdminConsoleAuthenticationCookiesService(sysAdminParams, customMaxAge);
|
||||
when(sysAdminParams.getAlfrescoProtocol()).thenReturn("https");
|
||||
|
||||
cookiesService.addCookie(COOKIE_NAME, COOKIE_VALUE, response);
|
||||
|
||||
verify(sysAdminParams).getAlfrescoProtocol();
|
||||
verify(response).addCookie(cookieCaptor.capture());
|
||||
|
||||
Cookie cookie = cookieCaptor.getValue();
|
||||
assertNotNull("The cookie should not be null", cookie);
|
||||
assertEquals("Cookie's maxAge should match the custom lifetime", customMaxAge, cookie.getMaxAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cookieShouldBeReset()
|
||||
{
|
||||
when(sysAdminParams.getAlfrescoProtocol()).thenReturn("http");
|
||||
|
||||
cookiesService.resetCookie(COOKIE_NAME, response);
|
||||
|
||||
verify(sysAdminParams).getAlfrescoProtocol();
|
||||
verify(response).addCookie(cookieCaptor.capture());
|
||||
|
||||
Cookie cookie = cookieCaptor.getValue();
|
||||
assertNotNull("The cookie should not be null", cookie);
|
||||
assertEquals("Cookie's name should match", COOKIE_NAME, cookie.getName());
|
||||
assertEquals("Cookie's value should be reset", "", cookie.getValue());
|
||||
assertEquals("Cookie's path should be the root", "/", cookie.getPath());
|
||||
assertEquals("Cookie's maxAge should be 0", 0, cookie.getMaxAge());
|
||||
assertFalse("Cookie's secure flag should be false", cookie.getSecure());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureCookieShouldBeReset()
|
||||
{
|
||||
when(sysAdminParams.getAlfrescoProtocol()).thenReturn("https");
|
||||
|
||||
cookiesService.resetCookie(COOKIE_NAME, response);
|
||||
|
||||
verify(sysAdminParams).getAlfrescoProtocol();
|
||||
verify(response).addCookie(cookieCaptor.capture());
|
||||
|
||||
Cookie cookie = cookieCaptor.getValue();
|
||||
assertNotNull("The cookie should not be null", cookie);
|
||||
assertTrue("Cookie's secure flag should be true", cookie.getSecure());
|
||||
}
|
||||
}
|
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.security.authentication.identityservice.admin;
|
||||
|
||||
import static java.util.Collections.enumeration;
|
||||
import static java.util.Collections.list;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
|
||||
@SuppressWarnings("PMD.UseDiamondOperator")
|
||||
public class AdminConsoleHttpServletRequestWrapperUnitTest
|
||||
{
|
||||
|
||||
private static final String DEFAULT_HEADER = "default_header";
|
||||
private static final String DEFAULT_HEADER_VALUE = "default_value";
|
||||
private static final String ADDITIONAL_HEADER = "additional_header";
|
||||
private static final String ADDITIONAL_HEADER_VALUE = "additional_value";
|
||||
private static final Map<String, String> DEFAULT_HEADERS = new HashMap<String, String>()
|
||||
{{
|
||||
put(DEFAULT_HEADER, DEFAULT_HEADER_VALUE);
|
||||
}};
|
||||
private static final Map<String, String> ADDITIONAL_HEADERS = new HashMap<String, String>()
|
||||
{{
|
||||
put(ADDITIONAL_HEADER, ADDITIONAL_HEADER_VALUE);
|
||||
}};
|
||||
|
||||
@Mock
|
||||
private HttpServletRequest request;
|
||||
private AdminConsoleHttpServletRequestWrapper requestWrapper;
|
||||
|
||||
@Before
|
||||
public void setUp()
|
||||
{
|
||||
initMocks(this);
|
||||
requestWrapper = new AdminConsoleHttpServletRequestWrapper(ADDITIONAL_HEADERS, request);
|
||||
}
|
||||
|
||||
@Test(expected = AlfrescoRuntimeException.class)
|
||||
public void wrapperShouldNotBeInstancedWithoutAdditionalHeaders()
|
||||
{
|
||||
new AdminConsoleHttpServletRequestWrapper(null, request);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void wrapperShouldNotBeInstancedWithoutRequestsToWrap()
|
||||
{
|
||||
new AdminConsoleHttpServletRequestWrapper(new HashMap<>(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperShouldReturnAdditionalHeaderNamesOnTopOfDefaultOnes()
|
||||
{
|
||||
when(request.getHeaderNames()).thenReturn(enumeration(DEFAULT_HEADERS.keySet()));
|
||||
|
||||
Enumeration<String> headerNames = requestWrapper.getHeaderNames();
|
||||
assertNotNull("headerNames should not be null", headerNames);
|
||||
assertTrue("headerNames should not be empty", headerNames.hasMoreElements());
|
||||
|
||||
List<String> headers = list(headerNames);
|
||||
assertEquals("There should be 2 headers", 2, headers.size());
|
||||
assertTrue("The default header should be included", headers.contains(DEFAULT_HEADER));
|
||||
assertTrue("The additional header should be included", headers.contains(ADDITIONAL_HEADER));
|
||||
|
||||
verify(request).getHeaderNames();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperShouldReturnDefaultHeaderNamesIfNoAdditionalHeaders()
|
||||
{
|
||||
when(request.getHeaderNames()).thenReturn(enumeration(DEFAULT_HEADERS.keySet()));
|
||||
|
||||
requestWrapper = new AdminConsoleHttpServletRequestWrapper(new HashMap<>(), request);
|
||||
Enumeration<String> headerNames = requestWrapper.getHeaderNames();
|
||||
assertNotNull("headerNames should not be null", headerNames);
|
||||
assertTrue("headerNames should not be empty", headerNames.hasMoreElements());
|
||||
assertEquals("The returned header should be the default header", DEFAULT_HEADER, headerNames.nextElement());
|
||||
assertFalse("There should be no additional headers", headerNames.hasMoreElements());
|
||||
|
||||
verify(request).getHeaderNames();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperShouldReturnAdditionalHeaderNamesIfNoDefaultHeaders()
|
||||
{
|
||||
when(request.getHeaderNames()).thenReturn(null);
|
||||
|
||||
Enumeration<String> headerNames = requestWrapper.getHeaderNames();
|
||||
assertNotNull("headerNames should not be null", headerNames);
|
||||
assertTrue("headerNames should not be empty", headerNames.hasMoreElements());
|
||||
assertEquals("The returned header should be the additional header", ADDITIONAL_HEADER,
|
||||
headerNames.nextElement());
|
||||
assertFalse("There should be no more headers", headerNames.hasMoreElements());
|
||||
|
||||
verify(request).getHeaderNames();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperShouldReturnDefaultHeaderValues()
|
||||
{
|
||||
when(request.getHeader(DEFAULT_HEADER)).thenReturn(DEFAULT_HEADER_VALUE);
|
||||
|
||||
String header = requestWrapper.getHeader(DEFAULT_HEADER);
|
||||
assertEquals("The header should be the default one", DEFAULT_HEADER_VALUE, header);
|
||||
|
||||
verify(request).getHeader(DEFAULT_HEADER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperShouldReturnAdditionalHeaderValues()
|
||||
{
|
||||
String header = requestWrapper.getHeader(ADDITIONAL_HEADER);
|
||||
assertEquals("The header should be the additional one", ADDITIONAL_HEADER_VALUE, header);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperShouldPreferAdditionalHeaderValuesToDefaultOnes()
|
||||
{
|
||||
when(request.getHeader(DEFAULT_HEADER)).thenReturn(DEFAULT_HEADER_VALUE);
|
||||
|
||||
String overrideHeaderValue = "override";
|
||||
Map<String, String> overrideHeaders = new HashMap<>();
|
||||
overrideHeaders.put(DEFAULT_HEADER, overrideHeaderValue);
|
||||
|
||||
requestWrapper = new AdminConsoleHttpServletRequestWrapper(overrideHeaders, request);
|
||||
String header = requestWrapper.getHeader(DEFAULT_HEADER);
|
||||
assertEquals("The header should have the overridden value", overrideHeaderValue, header);
|
||||
|
||||
verify(request).getHeader(DEFAULT_HEADER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperShouldReturnDefaultHeaderEnumeration()
|
||||
{
|
||||
when(request.getHeader(DEFAULT_HEADER)).thenReturn(DEFAULT_HEADER_VALUE);
|
||||
|
||||
Enumeration<String> headers = requestWrapper.getHeaders(DEFAULT_HEADER);
|
||||
assertNotNull("The headers enumeration should not be null", headers);
|
||||
assertTrue("The headers enumeration should not be empty", headers.hasMoreElements());
|
||||
assertEquals("The header should be the default one", DEFAULT_HEADER_VALUE, headers.nextElement());
|
||||
assertFalse("There should be no more headers", headers.hasMoreElements());
|
||||
|
||||
verify(request).getHeader(DEFAULT_HEADER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperShouldReturnAdditionalHeaderEnumeration()
|
||||
{
|
||||
Enumeration<String> headers = requestWrapper.getHeaders(ADDITIONAL_HEADER);
|
||||
assertNotNull("The headers enumeration should not be null", headers);
|
||||
assertTrue("The headers enumeration should not be empty", headers.hasMoreElements());
|
||||
assertEquals("The header should be the additional one", ADDITIONAL_HEADER_VALUE, headers.nextElement());
|
||||
assertFalse("There should be no more headers", headers.hasMoreElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrapperShouldPreferAdditionalHeaderEnumerationValuesToDefaultOnes()
|
||||
{
|
||||
when(request.getHeader(DEFAULT_HEADER)).thenReturn(DEFAULT_HEADER_VALUE);
|
||||
|
||||
String overrideHeaderValue = "override";
|
||||
Map<String, String> overrideHeaders = new HashMap<>();
|
||||
overrideHeaders.put(DEFAULT_HEADER, overrideHeaderValue);
|
||||
|
||||
requestWrapper = new AdminConsoleHttpServletRequestWrapper(overrideHeaders, request);
|
||||
Enumeration<String> headers = requestWrapper.getHeaders(DEFAULT_HEADER);
|
||||
assertNotNull("The headers enumeration should not be null", headers);
|
||||
assertTrue("The headers enumeration should not be empty", headers.hasMoreElements());
|
||||
assertEquals("The header should be the overridden one", overrideHeaderValue, headers.nextElement());
|
||||
assertFalse("There should be no more headers", headers.hasMoreElements());
|
||||
|
||||
verify(request).getHeader(DEFAULT_HEADER);
|
||||
}
|
||||
}
|
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.security.authentication.identityservice.admin;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.alfresco.repo.security.authentication.external.RemoteUserMapper;
|
||||
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade;
|
||||
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AccessToken;
|
||||
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AccessTokenAuthorization;
|
||||
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AuthorizationException;
|
||||
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.AuthorizationGrant;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails;
|
||||
|
||||
@SuppressWarnings("PMD.AvoidStringBufferField")
|
||||
public class IdentityServiceAdminConsoleAuthenticatorUnitTest
|
||||
{
|
||||
|
||||
private static final String ALFRESCO_ACCESS_TOKEN = "ALFRESCO_ACCESS_TOKEN";
|
||||
private static final String ALFRESCO_REFRESH_TOKEN = "ALFRESCO_REFRESH_TOKEN";
|
||||
private static final String ALFRESCO_TOKEN_EXPIRATION = "ALFRESCO_TOKEN_EXPIRATION";
|
||||
|
||||
@Mock
|
||||
HttpServletRequest request;
|
||||
@Mock
|
||||
HttpServletResponse response;
|
||||
@Mock
|
||||
IdentityServiceFacade identityServiceFacade;
|
||||
@Mock
|
||||
AdminConsoleAuthenticationCookiesService cookiesService;
|
||||
@Mock
|
||||
RemoteUserMapper remoteUserMapper;
|
||||
@Mock
|
||||
AccessTokenAuthorization accessTokenAuthorization;
|
||||
@Mock
|
||||
AccessToken accessToken;
|
||||
@Captor
|
||||
ArgumentCaptor<AdminConsoleHttpServletRequestWrapper> requestCaptor;
|
||||
|
||||
IdentityServiceAdminConsoleAuthenticator authenticator;
|
||||
|
||||
StringBuffer adminConsoleURL = new StringBuffer("http://localhost:8080/admin-console");
|
||||
|
||||
@Before
|
||||
public void setup()
|
||||
{
|
||||
initMocks(this);
|
||||
ClientRegistration clientRegistration = mock(ClientRegistration.class);
|
||||
ProviderDetails providerDetails = mock(ProviderDetails.class);
|
||||
when(clientRegistration.getProviderDetails()).thenReturn(providerDetails);
|
||||
when(clientRegistration.getClientId()).thenReturn("alfresco");
|
||||
when(providerDetails.getAuthorizationUri()).thenReturn("http://localhost:8999/auth");
|
||||
when(identityServiceFacade.getClientRegistration()).thenReturn(clientRegistration);
|
||||
when(request.getRequestURL()).thenReturn(adminConsoleURL);
|
||||
when(remoteUserMapper.getRemoteUser(request)).thenReturn(null);
|
||||
|
||||
authenticator = new IdentityServiceAdminConsoleAuthenticator();
|
||||
authenticator.setActive(true);
|
||||
authenticator.setIdentityServiceFacade(identityServiceFacade);
|
||||
authenticator.setCookiesService(cookiesService);
|
||||
authenticator.setRemoteUserMapper(remoteUserMapper);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCallRemoteMapperIfTokenIsInCookies()
|
||||
{
|
||||
when(cookiesService.getCookie(ALFRESCO_ACCESS_TOKEN, request)).thenReturn("JWT_TOKEN");
|
||||
when(cookiesService.getCookie(ALFRESCO_TOKEN_EXPIRATION, request)).thenReturn(
|
||||
String.valueOf(Instant.now().plusSeconds(60).toEpochMilli()));
|
||||
when(remoteUserMapper.getRemoteUser(requestCaptor.capture())).thenReturn("admin");
|
||||
|
||||
String username = authenticator.getAdminConsoleUser(request, response);
|
||||
|
||||
assertEquals("Bearer JWT_TOKEN", requestCaptor.getValue().getHeader("Authorization"));
|
||||
assertEquals("admin", username);
|
||||
assertTrue(authenticator.isActive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRefreshExpiredTokenAndCallRemoteMapper()
|
||||
{
|
||||
when(cookiesService.getCookie(ALFRESCO_ACCESS_TOKEN, request)).thenReturn("EXPIRED_JWT_TOKEN");
|
||||
when(cookiesService.getCookie(ALFRESCO_REFRESH_TOKEN, request)).thenReturn("REFRESH_TOKEN");
|
||||
when(cookiesService.getCookie(ALFRESCO_TOKEN_EXPIRATION, request)).thenReturn(
|
||||
String.valueOf(Instant.now().minusSeconds(60).toEpochMilli()));
|
||||
when(accessToken.getTokenValue()).thenReturn("REFRESHED_JWT_TOKEN");
|
||||
when(accessToken.getExpiresAt()).thenReturn(Instant.now().plusSeconds(60));
|
||||
when(accessTokenAuthorization.getAccessToken()).thenReturn(accessToken);
|
||||
when(accessTokenAuthorization.getRefreshTokenValue()).thenReturn("REFRESH_TOKEN");
|
||||
when(identityServiceFacade.authorize(any(AuthorizationGrant.class))).thenReturn(accessTokenAuthorization);
|
||||
when(remoteUserMapper.getRemoteUser(requestCaptor.capture())).thenReturn("admin");
|
||||
|
||||
String username = authenticator.getAdminConsoleUser(request, response);
|
||||
|
||||
verify(cookiesService).addCookie(ALFRESCO_ACCESS_TOKEN, "REFRESHED_JWT_TOKEN", response);
|
||||
verify(cookiesService).addCookie(ALFRESCO_REFRESH_TOKEN, "REFRESH_TOKEN", response);
|
||||
assertEquals("Bearer REFRESHED_JWT_TOKEN", requestCaptor.getValue().getHeader("Authorization"));
|
||||
assertEquals("admin", username);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCallAuthChallenge() throws IOException
|
||||
{
|
||||
String authenticationRequest = "http://localhost:8999/auth?client_id=alfresco&redirect_uri=" + adminConsoleURL
|
||||
+ "&response_type=code&scope=openid";
|
||||
authenticator.requestAuthentication(request, response);
|
||||
|
||||
verify(response).sendRedirect(authenticationRequest);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldResetCookiesAndCallAuthChallenge() throws IOException
|
||||
{
|
||||
when(cookiesService.getCookie(ALFRESCO_ACCESS_TOKEN, request)).thenReturn("EXPIRED_JWT_TOKEN");
|
||||
when(cookiesService.getCookie(ALFRESCO_REFRESH_TOKEN, request)).thenReturn("REFRESH_TOKEN");
|
||||
when(cookiesService.getCookie(ALFRESCO_TOKEN_EXPIRATION, request)).thenReturn(
|
||||
String.valueOf(Instant.now().minusSeconds(60).toEpochMilli()));
|
||||
|
||||
when(identityServiceFacade.authorize(any(AuthorizationGrant.class))).thenThrow(AuthorizationException.class);
|
||||
|
||||
String username = authenticator.getAdminConsoleUser(request, response);
|
||||
|
||||
verify(cookiesService).resetCookie(ALFRESCO_ACCESS_TOKEN, response);
|
||||
verify(cookiesService).resetCookie(ALFRESCO_REFRESH_TOKEN, response);
|
||||
verify(cookiesService).resetCookie(ALFRESCO_TOKEN_EXPIRATION, response);
|
||||
assertNull(username);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAuthorizeCodeAndSetCookies()
|
||||
{
|
||||
when(request.getParameter("code")).thenReturn("auth_code");
|
||||
when(accessToken.getTokenValue()).thenReturn("JWT_TOKEN");
|
||||
when(accessToken.getExpiresAt()).thenReturn(Instant.now().plusSeconds(60));
|
||||
when(accessTokenAuthorization.getAccessToken()).thenReturn(accessToken);
|
||||
when(accessTokenAuthorization.getRefreshTokenValue()).thenReturn("REFRESH_TOKEN");
|
||||
when(identityServiceFacade.authorize(
|
||||
AuthorizationGrant.authorizationCode("auth_code", adminConsoleURL.toString())))
|
||||
.thenReturn(accessTokenAuthorization);
|
||||
when(remoteUserMapper.getRemoteUser(requestCaptor.capture())).thenReturn("admin");
|
||||
|
||||
String username = authenticator.getAdminConsoleUser(request, response);
|
||||
|
||||
verify(cookiesService).addCookie(ALFRESCO_ACCESS_TOKEN, "JWT_TOKEN", response);
|
||||
verify(cookiesService).addCookie(ALFRESCO_REFRESH_TOKEN, "REFRESH_TOKEN", response);
|
||||
assertEquals("Bearer JWT_TOKEN", requestCaptor.getValue().getHeader("Authorization"));
|
||||
assertEquals("admin", username);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldExtractUsernameFromAuthorizationHeader()
|
||||
{
|
||||
when(remoteUserMapper.getRemoteUser(request)).thenReturn("admin");
|
||||
|
||||
String username = authenticator.getAdminConsoleUser(request, response);
|
||||
|
||||
assertEquals("admin", username);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user