160 lines
6.7 KiB
Java
160 lines
6.7 KiB
Java
package org.gcube.keycloak.protocol.oidc.mapper;
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
import static org.mockito.Mockito.when;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
import java.util.stream.Collectors;
|
|
|
|
import org.junit.Test;
|
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
|
import org.keycloak.models.ClientModel;
|
|
import org.keycloak.models.ClientSessionContext;
|
|
import org.keycloak.models.KeycloakContext;
|
|
import org.keycloak.models.KeycloakSession;
|
|
import org.keycloak.models.ProtocolMapperModel;
|
|
import org.keycloak.models.UserModel;
|
|
import org.keycloak.models.UserSessionModel;
|
|
import org.keycloak.protocol.oidc.mappers.FullNameMapper;
|
|
import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper;
|
|
import org.keycloak.provider.ProviderConfigProperty;
|
|
import org.keycloak.representations.AccessToken;
|
|
import org.mockito.Mockito;
|
|
|
|
import jakarta.ws.rs.core.HttpHeaders;
|
|
|
|
/**
|
|
* Original code repo: https://github.com/mschwartau/keycloak-custom-protocol-mapper-example
|
|
*/
|
|
public class D4ScienceContextMapperTest {
|
|
|
|
static final String HEADER_VALUE = "ginostilla";
|
|
|
|
@Test
|
|
public void shouldTokenMapperDisplayCategory() {
|
|
final String tokenMapperDisplayCategory = new FullNameMapper().getDisplayCategory();
|
|
assertThat(new D4ScienceContextMapper().getDisplayCategory()).isEqualTo(tokenMapperDisplayCategory);
|
|
}
|
|
|
|
@Test
|
|
public void shouldHaveDisplayType() {
|
|
assertThat(new D4ScienceContextMapper().getDisplayType()).isNotBlank();
|
|
}
|
|
|
|
@Test
|
|
public void shouldHaveHelpText() {
|
|
assertThat(new D4ScienceContextMapper().getHelpText()).isNotBlank();
|
|
}
|
|
|
|
@Test
|
|
public void shouldHaveIdId() {
|
|
assertThat(new D4ScienceContextMapper().getId()).isNotBlank();
|
|
}
|
|
|
|
@Test
|
|
public void shouldHaveProperties() {
|
|
final List<String> configPropertyNames = new D4ScienceContextMapper().getConfigProperties().stream()
|
|
.map(ProviderConfigProperty::getName)
|
|
.collect(Collectors.toList());
|
|
|
|
assertThat(configPropertyNames).containsExactly(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME,
|
|
OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, D4ScienceContextMapper.HTTP_REQUEST_HEADER_NAME,
|
|
D4ScienceContextMapper.NARROW_RESOURCE_ACCESS);
|
|
}
|
|
|
|
@Test
|
|
public void shouldAddClaimAndNotNarrow() {
|
|
final UserSessionModel session = givenUserSession();
|
|
final KeycloakSession keycloakSession = givenKeycloakSession(true);
|
|
final AccessToken accessToken = transformAccessToken(session, keycloakSession, true, false);
|
|
assertThat(accessToken.getAudience()[0]).isEqualTo(HEADER_VALUE);
|
|
assertThat(accessToken.getResourceAccess().size()).isEqualTo(2);
|
|
assertThat(accessToken.getResourceAccess().keySet()).contains(HEADER_VALUE);
|
|
}
|
|
|
|
@Test
|
|
public void shouldAddClaimAndNarrow() {
|
|
final UserSessionModel session = givenUserSession();
|
|
final KeycloakSession keycloakSession = givenKeycloakSession(true);
|
|
final AccessToken accessToken = transformAccessToken(session, keycloakSession, true, true);
|
|
assertThat(accessToken.getAudience()[0]).isEqualTo(HEADER_VALUE);
|
|
assertThat(accessToken.getResourceAccess().size()).isEqualTo(1);
|
|
assertThat(accessToken.getResourceAccess().keySet().iterator().next()).isEqualTo(HEADER_VALUE);
|
|
}
|
|
|
|
@Test
|
|
public void shouldNotAddClaim() {
|
|
final UserSessionModel session = givenUserSession();
|
|
final KeycloakSession keycloakSession = givenKeycloakSession(false);
|
|
final AccessToken accessToken = transformAccessToken(session, keycloakSession, true, false);
|
|
assertThat(accessToken.getAudience()).isNull();
|
|
}
|
|
|
|
@Test
|
|
public void shouldNotAddClaimAndLogWarning() {
|
|
final UserSessionModel session = givenUserSession();
|
|
final KeycloakSession keycloakSession = givenKeycloakSession(true);
|
|
final AccessToken accessToken = transformAccessToken(session, keycloakSession, false, false);
|
|
assertThat(accessToken.getAudience()).isNull();
|
|
}
|
|
|
|
private UserSessionModel givenUserSession() {
|
|
UserSessionModel userSession = Mockito.mock(UserSessionModel.class);
|
|
UserModel user = Mockito.mock(UserModel.class);
|
|
when(userSession.getUser()).thenReturn(user);
|
|
return userSession;
|
|
}
|
|
|
|
private KeycloakSession givenKeycloakSession(boolean withHeader) {
|
|
KeycloakSession keycloakSession = Mockito.mock(KeycloakSession.class);
|
|
KeycloakContext context = Mockito.mock(KeycloakContext.class);
|
|
when(keycloakSession.getContext()).thenReturn(context);
|
|
HttpHeaders headers = Mockito.mock(HttpHeaders.class);
|
|
when(context.getRequestHeaders()).thenReturn(headers);
|
|
|
|
if (withHeader) {
|
|
when(headers.getHeaderString(D4ScienceContextMapper.DEFAULT_HEADER_NAME)).thenReturn(HEADER_VALUE);
|
|
} else {
|
|
when(headers.getHeaderString(D4ScienceContextMapper.DEFAULT_HEADER_NAME)).thenReturn("");
|
|
}
|
|
return keycloakSession;
|
|
}
|
|
|
|
private AccessToken transformAccessToken(UserSessionModel userSessionModel, KeycloakSession keycloakSession,
|
|
boolean withResourceAccess, boolean withNarrowRA) {
|
|
|
|
final ProtocolMapperModel mappingModel = new ProtocolMapperModel();
|
|
mappingModel.setConfig(createConfig(withNarrowRA));
|
|
AccessToken at = new AccessToken();
|
|
if (withResourceAccess) {
|
|
at.addAccess(HEADER_VALUE);
|
|
at.addAccess(UUID.randomUUID().toString());
|
|
}
|
|
|
|
return new D4ScienceContextMapper().transformAccessToken(at, mappingModel, keycloakSession,
|
|
userSessionModel, givenClientSessionContext());
|
|
}
|
|
|
|
private ClientSessionContext givenClientSessionContext() {
|
|
ClientModel clientModel = Mockito.mock(ClientModel.class);
|
|
when(clientModel.getName()).thenReturn("test-client-id");
|
|
AuthenticatedClientSessionModel acsm = Mockito.mock(AuthenticatedClientSessionModel.class);
|
|
when(acsm.getClient()).thenReturn(clientModel);
|
|
ClientSessionContext csc = Mockito.mock(ClientSessionContext.class);
|
|
when(csc.getClientSession()).thenReturn(acsm);
|
|
return csc;
|
|
}
|
|
|
|
private Map<String, String> createConfig(boolean narrowRA) {
|
|
final Map<String, String> config = new HashMap<>();
|
|
config.put(D4ScienceContextMapper.HTTP_REQUEST_HEADER_NAME, D4ScienceContextMapper.DEFAULT_HEADER_NAME);
|
|
config.put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, D4ScienceContextMapper.DEFAULT_TOKEN_CLAIM);
|
|
config.put(D4ScienceContextMapper.NARROW_RESOURCE_ACCESS, Boolean.toString(narrowRA));
|
|
config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
|
|
return config;
|
|
}
|
|
|
|
} |