fix and devel for the client

This commit is contained in:
Alfredo Oliviero 2024-05-15 17:57:25 +02:00
parent 8f00186a50
commit 4b87f742fc
19 changed files with 1650 additions and 368 deletions

57
pom.xml
View File

@ -59,9 +59,9 @@
<dependency>
<groupId>org.gcube.idm</groupId>
<artifactId>idm-common-library</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
@ -86,10 +86,27 @@
<version>${jackson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.activation/jakarta.activation-api -->
<dependency>
<groupId>jakarta.activation</groupId>
<artifactId>jakarta.activation-api</artifactId>
<version>2.1.2</version>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency> -->
<dependency>
<groupId>jakarta.xml.ws</groupId>
<artifactId>jakarta.xml.ws-api</artifactId>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
@ -140,16 +157,23 @@ solution: bind version, or exclude them in usermanagement-core
</exclusions>
</dependency>
<dependency>
<!-- <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
</dependency> -->
<!-- smartgears -->
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-smartgears</artifactId>
<!-- <exclusions>
<exclusion>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</exclusion>
</exclusions> -->
</dependency>
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>common-security</artifactId>
@ -160,6 +184,12 @@ solution: bind version, or exclude them in usermanagement-core
<artifactId>common-authorization</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-utils</artifactId>
<version>2.2.0</version>
</dependency> -->
<dependency>
<groupId>org.gcube.common</groupId>
<artifactId>authorization-control-library</artifactId>
@ -168,7 +198,7 @@ solution: bind version, or exclude them in usermanagement-core
<groupId>org.gcube.core</groupId>
<artifactId>common-smartgears-app</artifactId>
</dependency>
<!-- jersey -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
@ -193,10 +223,10 @@ solution: bind version, or exclude them in usermanagement-core
</dependency>
<!-- add jackson as json provider -->
<dependency>
<!-- <dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
</dependency>
</dependency> -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
@ -235,8 +265,8 @@ solution: bind version, or exclude them in usermanagement-core
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.7</version>
<scope>runtime</scope>
<!-- <version>1.9.7</version> -->
<!-- <scope>runtime</scope> -->
</dependency>
<dependency>
@ -287,14 +317,17 @@ java.lang.NoClassDefFoundError: org/apache/http/ssl/TrustStrategy
<groupId>org.gcube.resources.discovery</groupId>
<artifactId>ic-client</artifactId>
<scope>provided</scope>
</dependency>
</dependency>-->
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-scope</artifactId>
<scope>provided</scope>
</dependency> -->
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>

View File

@ -20,7 +20,6 @@ import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.WebApplicationException;
public class AdminKeycloakController {

View File

@ -3,13 +3,13 @@ package org.gcube.service.idm.controller;
import java.util.List;
import java.util.Map;
import javax.ws.rs.ForbiddenException;
import org.gcube.common.keycloak.model.ModelUtils;
import org.gcube.common.security.Owner;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.common.security.secrets.Secret;
import jakarta.ws.rs.ForbiddenException;
public class AuthController {
public final static String IDM_SERVICE_READ = "idm-service-read";

View File

@ -1,8 +1,6 @@
package org.gcube.service.idm.controller;
import java.util.HashMap;
import java.util.Map;
import org.gcube.idm.common.models.IdmVerifyObject;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
import com.auth0.jwt.JWT;
@ -12,7 +10,9 @@ import com.fasterxml.jackson.databind.JsonMappingException;
public class JWTController {
public static Map<String, Object> decodeJwtToken(String token)
// public static Map<String, Object> decodeJwtToken(String token)
public static IdmVerifyObject decodeJwtToken(String token)
throws JsonMappingException, JsonProcessingException {
DecodedJWT decodedJWT = JWT.decode(token);
@ -21,15 +21,25 @@ public class JWTController {
// String signatureJson =
// ContextSerializator.decodeBase64String(decodedJWT.getSignature());
Map<String, Object> decoded = new HashMap<String, Object>();
decoded.put("jwt_token", token);
decoded.put("token", decodedJWT.getToken());
decoded.put("header", IdmObjectSerializator.jsonStringToHasmap(headerJson));
decoded.put("payload", IdmObjectSerializator.jsonStringToHasmap(payloadJson));
// decoded.put("signature",
// ContextSerializator.jsonStringToHasmap(signatureJson));
decoded.put("decodedJWT", decodedJWT);
return decoded;
IdmVerifyObject verify = new IdmVerifyObject();
verify.setJwt_token(token);
verify.setToken(decodedJWT.getToken());
verify.setHeader(IdmObjectSerializator.jsonStringToHasmap(headerJson));
verify.setJwt_token(token);
verify.setPayload(IdmObjectSerializator.jsonStringToHasmap(payloadJson));
verify.setJwt_decoded(decodedJWT);
return verify;
// Map<String, Object> decoded = new HashMap<String, Object>();
// decoded.put("jwt_token", token);
// decoded.put("token", decodedJWT.getToken());
// decoded.put("header", IdmObjectSerializator.jsonStringToHasmap(headerJson));
// decoded.put("payload",
// IdmObjectSerializator.jsonStringToHasmap(payloadJson));
// // decoded.put("signature",
// // ContextSerializator.jsonStringToHasmap(signatureJson));
// decoded.put("jwt_decoded", decodedJWT);
// return decoded;
}
}

View File

@ -1,7 +1,6 @@
package org.gcube.service.idm.controller;
import java.rmi.ServerException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

View File

@ -1,6 +1,5 @@
package org.gcube.service.idm.controller;
import java.rmi.ServerException;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

View File

@ -1,10 +1,7 @@
package org.gcube.service.idm.controller;
import java.rmi.ServerException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@ -166,8 +163,10 @@ public class KCUserController {
logger.info("Searching user by username: {}", username);
RealmResource realm = KkClientFactory.getSingleton().getKKRealm();
UserRepresentation user = realm.users()
.search(username, true).stream().findFirst().orElse(null);
UsersResource users = realm.users();
List<UserRepresentation> search_user = users.search(username, true);
UserRepresentation user = search_user.stream().findFirst().orElse(null);
if (user == null) {
throw new NotFoundException("cannot retrieve user " + username);

View File

@ -58,18 +58,23 @@ public class KkClientFactory {
config = configuration;
}
public Secret getSecretForInfrastructure(){
public Secret getSecretForInfrastructure() {
return InfrastrctureServiceClient.getSecretForInfrastructure();
}
public IsServerConfig fetchIsConfig(Secret secret) throws InternalServerErrorException {
public IsServerConfig fetchIsConfig() throws InternalServerErrorException {
if (this.secret == null) {
this.secret = getSecretForInfrastructure();
}
return fetchIsConfig(this.secret);
}
public IsServerConfig fetchIsConfig(Secret secret) throws InternalServerErrorException {
if (secret == null) {
throw new InternalServerErrorException("null secret for fetchIsConfig");
}
try {
if (secret == null){
throw new InternalServerErrorException("null secret for fetchIsConfig");
}
IsServerConfig cfg = InfrastrctureServiceClient.serviceConfigFromIS(RUNTIME_RESOURCE_NAME, CATEGORY,
END_POINT_NAME, IS_ROOT_SERVICE, secret);
logger.info("KeycloakAPICredentials object built {} - {}", cfg.getServerUrl(), cfg.getName());
@ -93,7 +98,6 @@ public class KkClientFactory {
}
public static KeycloackApiClient createtKeycloakInstance(IsServerConfig config, String context) {
Keycloak kclient = KeycloakBuilder.builder()
.serverUrl(config.getServerUrl())
.realm(config.getName())

View File

@ -20,6 +20,11 @@ public class LiferayClientFactory {
LiferayWSUserManager client = null;
/**
* keycloak configuration obtained from IS in the private constructor
* using the singleton pattern, it's retrieved from IS only for the first
* access, then kept in the singleton object
*/
private IsServerConfig config;
private Secret secret;
@ -31,20 +36,39 @@ public class LiferayClientFactory {
return singleton;
}
// set a custom secret, instead of fetch it from IS
public Secret getSecret() {
return secret;
}
public void setSecret(Secret secret) {
this.secret = secret;
this.config = fetchIsConfig(this.secret);
// this.setConfig(null) = null;
// this.client = null;
}
// set a custom config for the factory, skipping or overriding the fetch from IS
public void setConfig(IsServerConfig config) {
this.config = config;
this.client = null;
}
public Secret getSecretForInfrastructure() {
return InfrastrctureServiceClient.getSecretForInfrastructure();
}
public IsServerConfig fetchIsConfig() throws InternalServerErrorException {
if (this.secret == null) {
this.secret = getSecretForInfrastructure();
}
return fetchIsConfig(this.secret);
}
public IsServerConfig fetchIsConfig(Secret secret) throws InternalServerErrorException {
if (secret == null) {
throw new InternalServerErrorException("null secret for fetchIsConfig");
}
try {
if (this.secret == null)
this.secret = InfrastrctureServiceClient.getSecretForInfrastructure();
IsServerConfig cfg = InfrastrctureServiceClient.serviceConfigFromIS(RUNTIME_RESOURCE_NAME, CATEGORY,
END_POINT_NAME, IS_ROOT_SERVICE, secret);
logger.info("KeycloakAPICredentials object built {} - {}", cfg.getServerUrl(), cfg.getName());
@ -58,7 +82,7 @@ public class LiferayClientFactory {
public LiferayWSUserManager createtLiferayClientInstance() {
if (this.config == null) {
this.config = fetchIsConfig(this.secret);
this.config = fetchIsConfig();
}
return createtLiferayClientInstance(this.config);
}
@ -79,22 +103,14 @@ public class LiferayClientFactory {
throw new InternalServerErrorException("cannot create Liferay client");
}
if (client == null) {
throw new InternalServerErrorException("cannot create Liferay client");
}
// if (client == null) {
// throw new InternalServerErrorException("cannot create Liferay client");
// }
logger.info("Liferay object built {} - {}", config.getServerUrl(), config.getName());
return client;
}
// public IsServerConfig getConfig() {
// if (this.config == null) {
// this.config = fetchIsConfig();
// }
// return this.config;
// }
public LiferayWSUserManager getClient() {
if (this.client == null) {
this.client = createtLiferayClientInstance();

View File

@ -1,300 +0,0 @@
package org.gcube.service.idm.models;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gcube.idm.common.models.IdmProfileInterface;
public class IdmUser implements IdmProfileInterface {
protected String self; // link
protected String id;
// protected String origin;
protected Long createdTimestamp;
protected String username;
protected Boolean enabled;
// protected Boolean totp;
protected Boolean emailVerified;
protected String firstName;
protected String lastName;
protected String email;
protected String federationLink;
protected String serviceAccountClientId; // For rep, it points to clientId (not DB ID)
// @JsonDeserialize(using = StringListMapDeserializer.class)
protected Map<String, List<String>> attributes;
// protected List<CredentialRepresentation> credentials;
// protected Set<String> disableableCredentialTypes;
protected List<String> requiredActions;
// protected List<FederatedIdentityRepresentation> federatedIdentities;
protected List<String> realmRoles;
protected Map<String, List<String>> clientRoles;
// protected List<UserConsentRepresentation> clientConsents;
protected Integer notBefore;
// @Deprecated
// protected Map<String, List<String>> applicationRoles;
// @Deprecated
// protected List<SocialLinkRepresentation> socialLinks;
protected List<String> groups;
private Map<String, Boolean> access;
public String getSelf() {
return self;
}
public void setSelf(String self) {
this.self = self;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Long getCreatedTimestamp() {
return createdTimestamp;
}
public void setCreatedTimestamp(Long createdTimestamp) {
this.createdTimestamp = createdTimestamp;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Boolean isEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
// @Deprecated
// public Boolean isTotp() {
// return totp;
// }
// @Deprecated
// public void setTotp(Boolean totp) {
// this.totp = totp;
// }
public Boolean isEmailVerified() {
return emailVerified;
}
public void setEmailVerified(Boolean emailVerified) {
this.emailVerified = emailVerified;
}
public Map<String, List<String>> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, List<String>> attributes) {
this.attributes = attributes;
}
// public UserRepresentation singleAttribute(String name, String value) {
// if (this.attributes == null)
// this.attributes = new HashMap<>();
// attributes.put(name, (value == null ? new ArrayList<String>() :
// Arrays.asList(value)));
// return this;
// }
// public String firstAttribute(String key) {
// return this.attributes == null ? null
// : this.attributes.get(key) == null ? null
// : this.attributes.get(key).isEmpty() ? null :
// this.attributes.get(key).get(0);
// }
// public List<CredentialRepresentation> getCredentials() {
// return credentials;
// }
// public void setCredentials(List<CredentialRepresentation> credentials) {
// this.credentials = credentials;
// }
public List<String> getRequiredActions() {
return requiredActions;
}
public void setRequiredActions(List<String> requiredActions) {
this.requiredActions = requiredActions;
}
// public List<FederatedIdentityRepresentation> getFederatedIdentities() {
// return federatedIdentities;
// }
// public void setFederatedIdentities(List<FederatedIdentityRepresentation>
// federatedIdentities) {
// this.federatedIdentities = federatedIdentities;
// }
// public List<SocialLinkRepresentation> getSocialLinks() {
// return socialLinks;
// }
// public void setSocialLinks(List<SocialLinkRepresentation> socialLinks) {
// this.socialLinks = socialLinks;
// }
public List<String> getRealmRoles() {
return realmRoles;
}
public void setRealmRoles(List<String> realmRoles) {
this.realmRoles = realmRoles;
}
public Map<String, List<String>> getClientRoles() {
return clientRoles;
}
public void setClientRoles(Map<String, List<String>> clientRoles) {
this.clientRoles = clientRoles;
}
// public List<UserConsentRepresentation> getClientConsents() {
// return clientConsents;
// }
// public void setClientConsents(List<UserConsentRepresentation> clientConsents)
// {
// this.clientConsents = clientConsents;
// }
public Integer getNotBefore() {
return notBefore;
}
public void setNotBefore(Integer notBefore) {
this.notBefore = notBefore;
}
// @Deprecated
// public Map<String, List<String>> getApplicationRoles() {
// return applicationRoles;
// }
public String getFederationLink() {
return federationLink;
}
public void setFederationLink(String federationLink) {
this.federationLink = federationLink;
}
public String getServiceAccountClientId() {
return serviceAccountClientId;
}
public void setServiceAccountClientId(String serviceAccountClientId) {
this.serviceAccountClientId = serviceAccountClientId;
}
public List<String> getGroups() {
return groups;
}
public void setGroups(List<String> groups) {
this.groups = groups;
}
// /**
// * Returns id of UserStorageProvider that loaded this user
// *
// * @return NULL if user stored locally
// */
// public String getOrigin() {
// return origin;
// }
// public void setOrigin(String origin) {
// this.origin = origin;
// }
// public Set<String> getDisableableCredentialTypes() {
// return disableableCredentialTypes;
// }
// public void setDisableableCredentialTypes(Set<String>
// disableableCredentialTypes) {
// this.disableableCredentialTypes = disableableCredentialTypes;
// }
public Map<String, Boolean> getAccess() {
return access;
}
public void setAccess(Map<String, Boolean> access) {
this.access = access;
}
public Map<String, List<String>> toAttributes() {
Map<String, List<String>> attrs = new HashMap<>();
if (getAttributes() != null)
attrs.putAll(getAttributes());
if (getUsername() != null)
attrs.put("username", Collections.singletonList(getUsername()));
else
attrs.remove("username");
if (getEmail() != null)
attrs.put("email", Collections.singletonList(getEmail()));
else
attrs.remove("email");
if (getLastName() != null)
attrs.put("lastName", Collections.singletonList(getLastName()));
if (getFirstName() != null)
attrs.put("firstName", Collections.singletonList(getFirstName()));
return attrs;
}
}

View File

@ -3,6 +3,7 @@ package org.gcube.service.idm.rest;
import java.util.HashMap;
import java.util.Map;
import org.gcube.idm.common.models.IdmVerifyObject;
import org.gcube.service.idm.controller.AuthController;
import org.gcube.service.idm.controller.JWTController;
import org.gcube.service.idm.serializers.IdmObjectSerializator;
@ -50,7 +51,7 @@ public class JwtAPI {
try {
ObjectMapper objectMapper = IdmObjectSerializator.getSerializer();
Map<String, Object> decoded = JWTController.decodeJwtToken(token);
IdmVerifyObject decoded = JWTController.decodeJwtToken(token);
responseBean.setResult(decoded);
responseBean.setSuccess(true);

View File

@ -23,6 +23,7 @@ import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.GroupRepresentation;
// import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.MappingsRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
@ -225,18 +226,23 @@ public class UserAPI {
MappingsRepresentation roles = userResource.roles().getAll();
result.put("roles", roles);
List<GroupRepresentation> groups = userResource.groups();
result.put("groups", groups);
// TODO: update keycloak library to 24. GroupRepresentation
// https://www.keycloak.org/docs-api/24.0.1/rest-api/index.html#GroupRepresentation
// https://www.keycloak.org/docs-api/21.1.2/rest-api/index.html#_grouprepresentation
// cannot deserialize using lib 21
// List<GroupRepresentation> groups = userResource.groups();
// result.put("groups", groups);
HashMap<String, Object> groupRolesRealm = new HashMap<String, Object>();
HashMap<String, Object> groupRolesClients = new HashMap<String, Object>();
// HashMap<String, Object> groupRolesRealm = new HashMap<String, Object>();
// HashMap<String, Object> groupRolesClients = new HashMap<String, Object>();
result.put("groupRolesRealm", groupRolesRealm);
result.put("groupRolesClients", groupRolesClients);
// result.put("groupRolesRealm", groupRolesRealm);
// result.put("groupRolesClients", groupRolesClients);
for (GroupRepresentation g : groups) {
groupRolesClients.put(g.getId(), g.getClientRoles());
}
// for (GroupRepresentation g : groups) {
// groupRolesClients.put(g.getId(), g.getClientRoles());
// }
}
return result;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,26 @@
.d4science_intro {
top: 0;
z-index: 2000;
position: fixed;
display: block ruby;
padding: 10px;
background: white;
width: 100%;
height: 100px;
}
.navbar-fixed-top {
top: 100px !important;
}
.sidebar {
top: 160px !important;
}
.navbar {
margin-bottom: 40px !important;
}
.main {
top: 90px;
}

View File

@ -0,0 +1,21 @@
package org.gcube.service.idm.test;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class EmptyTest {
private static final Logger logger = LoggerFactory.getLogger(EmptyTest.class);
@Test
public void testVersions() {
logger.debug("Testing works");
return;
}
}

View File

@ -0,0 +1,71 @@
package org.gcube.service.idm.test;
import org.gcube.idm.common.is.IsServerConfig;
import org.gcube.service.idm.keycloack.KkClientFactory;
import org.gcube.service.idm.liferay.LiferayClientFactory;
import org.gcube.smartgears.ContextProvider;
import org.gcube.smartgears.configuration.container.ContainerConfiguration;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.gcube.smartgears.context.container.ContainerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.ws.rs.NotFoundException;
public class IsTest extends ServiceContextTest {
private static final Logger logger = LoggerFactory.getLogger(IsTest.class);
// @Test
// @Ignore
public void checkContext() throws Exception {
ApplicationContext ctx = ContextProvider.get();
ContainerContext container = ctx.container();
ContainerConfiguration configuration = container.configuration();
String infra_context = "/" + configuration.infrastructure();
logger.debug("Testing Keycloak service IS config %s", infra_context );
}
// @Test
public void testIsKeycloak() throws Exception {
logger.debug("Testing Keycloak service IS config");
IsServerConfig config = null;
KkClientFactory client = KkClientFactory.getSingleton();
org.junit.Assert.assertNotNull(client);
client.setSecret(ServiceContextTest.current_secret);
try {
config = client.fetchIsConfig(ServiceContextTest.current_secret);
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
org.junit.Assert.assertNotNull(config);
logger.debug("fetched Keycloak service IS config ");
}
//@Test
public void testIsLiferay() {
logger.debug("Testing Liferay service IS config");
IsServerConfig config = null;
LiferayClientFactory client = LiferayClientFactory.getSingleton();
org.junit.Assert.assertNotNull(client);
try {
client.setSecret(ServiceContextTest.current_secret);
config = client.fetchIsConfig();
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
org.junit.Assert.assertNotNull(config);
logger.debug("fetched Liferay service IS config ");
}
}

View File

@ -0,0 +1,194 @@
package org.gcube.service.idm.test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.gcube.common.keycloak.KeycloakClientFactory;
import org.gcube.common.keycloak.KeycloakClientHelper;
import org.gcube.common.keycloak.model.TokenResponse;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.common.security.secrets.AccessTokenSecret;
import org.gcube.common.security.secrets.Secret;
import org.gcube.smartgears.ContextProvider;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*
*/
public abstract class ServiceContextTest {
private static final Logger logger = LoggerFactory.getLogger(ServiceContextTest.class);
protected static final String CONFIG_INI_FILENAME = "config.ini";
public static final String DEFAULT_TEST_SCOPE;
public static Secret current_secret;
// public static final String GCUBE;
// public static final String DEVNEXT;
// public static final String NEXTNEXT;
// public static final String DEVSEC;
// public static final String DEVVRE;
// public static final String ROOT;
// public static final String VO;
public static final String VRE;
// private static final String ROOT_PRE;
// private static final String VO_PREPROD;
// protected static final String VRE_GRSF_PRE;
// private static final String ROOT_PROD;
protected static final Properties properties;
public static final String TYPE_PROPERTY_KEY = "type";
public static final String USERNAME_PROPERTY_KEY = "username";
public static final String PASSWORD_PROPERTY_KEY = "password";
public static final String CLIENT_ID_PROPERTY_KEY = "clientId";
static {
try {
// GCUBE = "/gcube";
// DEVNEXT = GCUBE + "/devNext";
// NEXTNEXT = DEVNEXT + "/NextNext";
// DEVSEC = GCUBE + "/devsec";
// DEVVRE = DEVSEC + "/devVRE";
// ROOT = GCUBE;
// VO = DEVSEC;
// VRE = DEVVRE;
// ROOT_PRE = "/pred4s";
// VO_PREPROD = ROOT_PRE + "/preprod";
// VRE_GRSF_PRE = VO_PREPROD + "/GRSF_Pre";
// ROOT_PROD = "/d4science.research-infrastructures.eu";
properties = readProperties(CONFIG_INI_FILENAME);
VRE = properties.getProperty("context");
DEFAULT_TEST_SCOPE = VRE;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static Properties readProperties(String filename) throws IOException {
Properties p = new Properties();
InputStream input = ServiceContextTest.class.getClassLoader().getResourceAsStream(CONFIG_INI_FILENAME);
// load the properties file
p.load(input);
return p;
}
private enum Type {
USER, CLIENT_ID
};
public static void set(Secret secret) throws Exception {
SecretManagerProvider.reset();
SecretManagerProvider.set(secret);
current_secret = secret;
ContextProvider.set(null);
}
public static void setContextByName(String fullContextName) throws Exception {
logger.debug("Going to set credentials for context {}", fullContextName);
Secret secret = getSecretByContextName(fullContextName);
set(secret);
}
private static TokenResponse getJWTAccessToken(String context) throws Exception {
Type type = Type.valueOf(properties.get(TYPE_PROPERTY_KEY).toString());
TokenResponse tr = null;
int index = context.indexOf('/', 1);
String root = context.substring(0, index == -1 ? context.length() : index);
switch (type) {
case CLIENT_ID:
String clientId = properties.getProperty(CLIENT_ID_PROPERTY_KEY);
String clientSecret = properties.getProperty(root);
tr = KeycloakClientFactory.newInstance().queryUMAToken(context, clientId, clientSecret, context, null);
break;
case USER:
default:
String username = properties.getProperty(USERNAME_PROPERTY_KEY);
String password = properties.getProperty(PASSWORD_PROPERTY_KEY);
switch (root) {
case "/gcube":
default:
clientId = "next.d4science.org";
break;
case "/pred4s":
clientId = "pre.d4science.org";
break;
case "/d4science.research-infrastructures.eu":
clientId = "services.d4science.org";
break;
}
clientSecret = null;
tr = KeycloakClientHelper.getTokenForUser(context, username, password);
break;
}
return tr;
}
public static Secret getSecretByContextName(String context) throws Exception {
TokenResponse tr = getJWTAccessToken(context);
Secret secret = new AccessTokenSecret(tr.getAccessToken(), context);
return secret;
}
public static void setContext(String token) throws Exception {
Secret secret = getSecret(token);
set(secret);
}
private static Secret getSecret(String token) throws Exception {
// TODO: verificare classe (AccessTokenSecret anziche JWTToken) e context(VRE)
Secret secret = new AccessTokenSecret(token, VRE);
return secret;
}
public static String getUser() {
String user = "UNKNOWN";
try {
user = SecretManagerProvider.get().getOwner().getId();
} catch (Exception e) {
logger.error("Unable to retrieve user. {} will be used", user);
}
return user;
}
@BeforeClass
public static void beforeClass() throws Exception {
setContextByName(DEFAULT_TEST_SCOPE);
}
@AfterClass
public static void afterClass() throws Exception {
SecretManagerProvider.reset();
}
}

View File

@ -0,0 +1,5 @@
context=/gcube
type=CLIENT_ID
clientId=id.d4science.org
/gcube=09c26f24-3c65-4039-9fa0-e5cc4f4032cd
root

View File

@ -0,0 +1,14 @@
type=USER
#type=CLIENT_ID
username=alfredo.oliviero
context=/gcube/devsec/devVRE
/gcube/devsec/devVRE=eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJSSklZNEpoNF9qdDdvNmREY0NlUDFfS1l0akcxVExXVW9oMkQ2Tzk1bFNBIn0.eyJleHAiOjE3MTQ5ODkwMzMsImlhdCI6MTcxNDk4NzIzMywianRpIjoiMDA2OTBhZjAtYTQzZC00NjcwLThkNTQtOTc3OTMyMjAxYzQxIiwiaXNzIjoiaHR0cHM6Ly9hY2NvdW50cy5kZXYuZDRzY2llbmNlLm9yZy9hdXRoL3JlYWxtcy9kNHNjaWVuY2UiLCJhdWQiOiIlMkZnY3ViZSUyRmRldnNlYyUyRmRldlZSRSIsInN1YiI6ImI5OTY5YjUxLTU3OGYtNGI2OS1hNTNmLTJjOGFkZjllZmNjNyIsInR5cCI6IkJlYXJlciIsImF6cCI6ImlkLmQ0c2NpZW5jZS5vcmciLCJzZXNzaW9uX3N0YXRlIjoiZmZjZjQ5ZDUtNTFkZS00NGM2LTk4MWUtYzk4ZmMxMGJmMDRkIiwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtZDRzY2llbmNlIiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7IiUyRmdjdWJlJTJGZGV2c2VjJTJGZGV2VlJFIjp7InJvbGVzIjpbIkNhdGFsb2d1ZS1FZGl0b3IiLCJNZW1iZXIiXX19LCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJzaWQiOiJmZmNmNDlkNS01MWRlLTQ0YzYtOTgxZS1jOThmYzEwYmYwNGQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ2VuZGVyIjoiTWFsZSIsIm5hbWUiOiJBbGZyZWRvIE9saXZpZXJvIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWxmcmVkby5vbGl2aWVybyIsImdpdmVuX25hbWUiOiJBbGZyZWRvIiwiZmFtaWx5X25hbWUiOiJPbGl2aWVybyIsImVtYWlsIjoiYWxmcmVkby5vbGl2aWVyb0Bpc3RpLmNuci5pdCJ9.J-fM7Wkx-qBG_eBVW_j7EHILJOtcKlqD39R-uTU3660KEuueu85PX_29kArTgoZpgcLoxs2nUrEtEMnHjMS2kNRDIvcbCC3ZNMSggCHp8cyNIigYNwhIJdB1OGZjZdi3qxeRwV7xCRAG1qrgmUirMZN-4My-1dUfPjgGxpXw7AroQQ-sMRXGYzO5nVYml4q_61yWPoGHzyEnElG6FOsIl0owhEALOAPwdqRBg03hXUXm6z4kfhb6KzFNzQyTFcE8M3w_WC1Oy033GDAEfZtPrs1XAbAsTschqOc2wyrluaXeG3NLKv5gBByoY1k9QwYmb7wEWTvYBpIMWaxlSpMV0A
#username=grsf.publisher
#password=
#clientId=grsf-publisher
#/gcube=
#/pred4s=
#/d4science.research-infrastructures.eu=
password=