package org.gcube.common.iam; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.gcube.common.keycloak.model.ModelUtils; import org.junit.After; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestD4ScienceIAMClient { protected static final Logger logger = LoggerFactory.getLogger(TestD4ScienceIAMClient.class); protected static final String DEV_ROOT_CONTEXT = "/gcube"; protected static final String CLIENT_ID = "keycloak-client-unit-test"; protected static final String CLIENT_SECRET = "ebf6f82e-9511-408e-8321-203081e472d8"; protected static final String TEST_AUDIENCE = "conductor-server"; protected static final Set REALM_ROLES = Collections.singleton("d4s-client"); protected static final Set CONDUCTOR_SERVER_ROLES = Collections.singleton("dummy-test-role"); protected static final Set OTHER_ROLES = new HashSet<>(Arrays.asList("uma_protection", "Member")); protected static final String NAME = "Keycloak-client unit-test"; protected static final String CONTACT_PERSON = "mauro.mugnaini"; protected static final String CONTACT_ORGANIZATION = "Nubisware S.r.l."; protected static Set ALL_ROLES; @Before public void setUp() throws Exception { ALL_ROLES = new HashSet<>(); ALL_ROLES.addAll(REALM_ROLES); ALL_ROLES.addAll(CONDUCTOR_SERVER_ROLES); ALL_ROLES.addAll(OTHER_ROLES); } @After public void tearDown() throws Exception { } @Test public void test1Authn() throws Exception { logger.info("*** [1] Testing authentication"); D4ScienceIAMClientAuthn authn = D4ScienceIAMClient.newInstance(DEV_ROOT_CONTEXT).authenticate(CLIENT_ID, CLIENT_SECRET); logger.info("Authn scope: {}", authn.getTokenResponse().getScope()); logger.info("Authn AUDIENCE: {}", (Object[]) authn.getAccessToken().getAudience()); logger.info("Authn RESOURCE ACCESS: {}", authn.getAccessToken().getResourceAccess()); logger.info("Authn ALL roles: {}", authn.getRoles()); logger.info("Authn REALM roles: {}", authn.getRealmRoles()); logger.info("Authn AUDIENCE's roles: {}", authn.getAudienceResourceRoles()); logger.info("Authn D4S identity: '{}' by {} [{}]", authn.getName(), authn.getContactPerson(), authn.getContactOrganization()); logger.info("Authn access token:\n{}", ModelUtils.getAccessTokenPayloadJSONStringFrom(authn.getTokenResponse())); assertEquals(ALL_ROLES, authn.getRoles()); assertEquals(REALM_ROLES, authn.getRealmRoles()); assertEquals(NAME, authn.getName()); assertEquals(CONTACT_PERSON, authn.getContactPerson()); assertEquals(CONTACT_ORGANIZATION, authn.getContactOrganization()); } @Test public void test2AuthnWithSpecificAudience() throws Exception { logger.info("*** [2] Testing authentication"); D4ScienceIAMClientAuthn authn = D4ScienceIAMClient.newInstance(DEV_ROOT_CONTEXT).authenticate(CLIENT_ID, CLIENT_SECRET, TEST_AUDIENCE); logger.info("Authn scope: {}", authn.getTokenResponse().getScope()); logger.info("Authn AUDIENCE: {}", (Object[]) authn.getAccessToken().getAudience()); logger.info("Authn RESOURCE ACCESS: {}", authn.getAccessToken().getResourceAccess()); logger.info("Authn ALL roles: {}", authn.getRoles()); logger.info("Authn REALM roles: {}", authn.getRealmRoles()); logger.info("Authn AUDIENCE's roles: {}", authn.getAudienceResourceRoles()); logger.info("Authn D4S identity: '{}' by {} [{}]", authn.getName(), authn.getContactPerson(), authn.getContactOrganization()); logger.info("Authn access token:\n{}", ModelUtils.getAccessTokenPayloadJSONStringFrom(authn.getTokenResponse())); assertEquals(TEST_AUDIENCE, authn.getAccessToken().getAudience()[0]); // assertEquals(ALL_ROLES, authn.getRoles()); // This depends on the mapper's "shrink" settings, so it's not safe to let it enabled assertEquals(CONDUCTOR_SERVER_ROLES, authn.getAudienceResourceRoles()); assertEquals(REALM_ROLES, authn.getRealmRoles()); assertEquals(NAME, authn.getName()); assertEquals(CONTACT_PERSON, authn.getContactPerson()); assertEquals(CONTACT_ORGANIZATION, authn.getContactOrganization()); } @Test public void test3AuthnAndAuthz() throws Exception { logger.info("*** [3] Testing authentication and then authorization"); D4ScienceIAMClientAuthz authz = D4ScienceIAMClient.newInstance(DEV_ROOT_CONTEXT).authenticate(CLIENT_ID, CLIENT_SECRET).authorize(TEST_AUDIENCE, null); logger.info("Authz scope: {}", authz.getTokenResponse().getScope()); logger.info("Authn AUDIENCE: {}", (Object[]) authz.getAccessToken().getAudience()); logger.info("Authn RESOURCE ACCESS: {}", authz.getAccessToken().getResourceAccess()); logger.info("Authz ALL roles: {}", authz.getRoles()); logger.info("Authz REALM roles: {}", authz.getRealmRoles()); logger.info("Authz AUDIENCE's roles: {}", authz.getAudienceResourceRoles()); logger.info("Authz D4S identity: '{}' by {} [{}]", authz.getName(), authz.getContactPerson(), authz.getContactOrganization()); logger.info("Authz access token:\n{}", ModelUtils.getAccessTokenPayloadJSONStringFrom(authz.getTokenResponse())); assertEquals(TEST_AUDIENCE, authz.getAccessToken().getAudience()[0]); assertNotEquals(ALL_ROLES, authz.getRoles()); assertEquals(CONDUCTOR_SERVER_ROLES, authz.getAudienceResourceRoles()); assertEquals(CONDUCTOR_SERVER_ROLES, authz.getRoles()); assertEquals(Collections.emptySet(), authz.getRealmRoles()); } @Test public void test4DirectAuthz() throws Exception { logger.info("*** [4] Testing direct authorization"); D4ScienceIAMClientAuthz authz = D4ScienceIAMClient.newInstance(DEV_ROOT_CONTEXT).authorize(CLIENT_ID, CLIENT_SECRET, TEST_AUDIENCE, null); logger.info("Authz scope: {}", authz.getTokenResponse().getScope()); logger.info("Authn AUDIENCE: {}", (Object[]) authz.getAccessToken().getAudience()); logger.info("Authn RESOURCE ACCESS: {}", authz.getAccessToken().getResourceAccess()); logger.info("Authz ALL roles: {}", authz.getRoles()); logger.info("Authz REALM roles: {}", authz.getRealmRoles()); logger.info("Authz AUDIENCE's roles: {}", authz.getAudienceResourceRoles()); logger.info("Authz D4S identity: '{}' by {} [{}]", authz.getName(), authz.getContactPerson(), authz.getContactOrganization()); logger.info("Authz access token:\n{}", ModelUtils.getAccessTokenPayloadJSONStringFrom(authz.getTokenResponse())); assertEquals(TEST_AUDIENCE, authz.getAccessToken().getAudience()[0]); assertNotEquals(ALL_ROLES, authz.getRoles()); assertEquals(TEST_AUDIENCE, authz.getAccessToken().getAudience()[0]); assertEquals(CONDUCTOR_SERVER_ROLES, authz.getAudienceResourceRoles()); assertEquals(CONDUCTOR_SERVER_ROLES, authz.getRoles()); assertEquals(Collections.emptySet(), authz.getRealmRoles()); } }