diff --git a/src/main/java/org/gcube/common/authorization/utils/secret/GCubeSecret.java b/src/main/java/org/gcube/common/authorization/utils/secret/GCubeSecret.java index 4aa50fd..c86ecdc 100644 --- a/src/main/java/org/gcube/common/authorization/utils/secret/GCubeSecret.java +++ b/src/main/java/org/gcube/common/authorization/utils/secret/GCubeSecret.java @@ -1,5 +1,6 @@ package org.gcube.common.authorization.utils.secret; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; @@ -10,6 +11,7 @@ import org.gcube.common.authorization.library.exception.AuthorizationException; import org.gcube.common.authorization.library.provider.ClientInfo; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.library.utils.Caller; +import org.gcube.common.authorization.utils.socialservice.PortalUser; /** * @author Luca Frosini (ISTI - CNR) @@ -19,6 +21,7 @@ public class GCubeSecret extends Secret { public static final String GCUBE_TOKEN_REGEX = "^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}-[a-fA-F0-9]{8,9}){1}$"; protected AuthorizationEntry authorizationEntry; + protected PortalUser portalUser; @Override protected void check(String token) throws AuthorizationException { @@ -74,4 +77,46 @@ public class GCubeSecret extends Secret { return authorizationHeaders; } + @Override + public boolean isExpired() { + return false; + } + + @Override + public boolean isRefreshable() { + return false; + } + + protected PortalUser getPortalUser() { + if(portalUser==null) { + portalUser = new PortalUser(); + } + return portalUser; + } + + @Override + public Collection getRoles() throws Exception { + return getPortalUser().getRoles(); + } + + @Override + public String getName() { + return getPortalUser().getName(); + } + + @Override + public String getSurname() { + return getPortalUser().getSurname(); + } + + @Override + public String getEMail() { + return getPortalUser().getName(); + } + + @Override + public String getTitle() { + return getPortalUser().getJobTitle(); + } + } diff --git a/src/main/java/org/gcube/common/authorization/utils/socialservice/PortalUser.java b/src/main/java/org/gcube/common/authorization/utils/socialservice/PortalUser.java new file mode 100644 index 0000000..48a9290 --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/utils/socialservice/PortalUser.java @@ -0,0 +1,166 @@ +package org.gcube.common.authorization.utils.socialservice; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.ws.rs.InternalServerErrorException; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response.Status; + +import org.gcube.com.fasterxml.jackson.databind.JsonNode; +import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; +import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode; +import org.gcube.common.gxhttp.request.GXHTTPStringRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class PortalUser { + + private static final Logger logger = LoggerFactory.getLogger(PortalUser.class); + + protected static final String RESPONSE_SUCCESS_KEY = "success"; + protected static final String RESPONSE_MESSAGE_KEY = "message"; + protected static final String RESPONSE_RESULT_KEY = "result"; + + protected static final String SOCIAL_SERVICE_GET_OAUTH_USER_PROFILE_PATH = "2/users/get-oauth-profile"; + + // This key contains the fullname + //protected static final String OAUTH_USER_PROFILE_FULLNAME_KEY = "name"; + + protected static final String OAUTH_USER_PROFILE_NAME_KEY = "given_name"; + protected static final String OAUTH_USER_PROFILE_SURNAME_KEY = "family_name"; + + protected static final String OAUTH_USER_PROFILE_EMAIL_KEY = "email"; + protected static final String OAUTH_USER_PROFILE_JOB_TITLE_KEY = "job_title"; + protected static final String OAUTH_USER_PROFILE_ROLES_KEY = "roles"; + + protected final ObjectMapper objectMapper; + + protected JsonNode oAuthUserProfile; + + protected String name; + protected String surname; + + protected String eMail; + protected String jobTitle; + + protected List roles; + + protected Boolean catalogueModerator; + + public PortalUser() { + this.objectMapper = new ObjectMapper(); + } + + public StringBuilder getStringBuilder(InputStream inputStream) throws IOException { + StringBuilder result = new StringBuilder(); + try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { + String line; + while((line = reader.readLine()) != null) { + result.append(line); + } + } + + return result; + } + + public String getResultAsString(HttpURLConnection httpURLConnection) throws IOException { + int responseCode = httpURLConnection.getResponseCode(); + if(responseCode >= Status.BAD_REQUEST.getStatusCode()) { + Status status = Status.fromStatusCode(responseCode); + InputStream inputStream = httpURLConnection.getErrorStream(); + StringBuilder result = getStringBuilder(inputStream); + logger.trace(result.toString()); + throw new WebApplicationException(result.toString(), status); + } + InputStream inputStream = httpURLConnection.getInputStream(); + String ret = getStringBuilder(inputStream).toString(); + logger.trace("Got Respose is {}", ret); + return ret; + } + + public JsonNode getOAuthUserProfile() { + if(oAuthUserProfile == null) { + try { + String socialServiceBasePath = SocialService.getSocialService().getServiceBasePath(); + + GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(socialServiceBasePath); + gxhttpStringRequest.from("authorization-utils"); + gxhttpStringRequest.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON); + gxhttpStringRequest.path(SOCIAL_SERVICE_GET_OAUTH_USER_PROFILE_PATH); + HttpURLConnection httpURLConnection = gxhttpStringRequest.get(); + + String ret = getResultAsString(httpURLConnection); + oAuthUserProfile = objectMapper.readTree(ret); + } catch(Exception e) { + throw new InternalServerErrorException("Unable to retrive Infrastructure User Information from Social Service", e); + } + } + return oAuthUserProfile; + } + + public String getSurnameName() { + return String.format("%s %s", getSurname(), getName()); + } + + public String getNameSurname() { + return String.format("%s %s", getName(), getSurname()); + } + + public String getName() { + if(name == null) { + name = getOAuthUserProfile().get(OAUTH_USER_PROFILE_NAME_KEY).asText(); + } + return name; + } + + public String getSurname() { + if(surname == null) { + surname = getOAuthUserProfile().get(OAUTH_USER_PROFILE_SURNAME_KEY).asText(); + } + return surname; + } + + public String getEMail() { + if(eMail == null) { + eMail = getOAuthUserProfile().get(OAUTH_USER_PROFILE_EMAIL_KEY).asText(); + } + return eMail; + } + + public List getRoles() { + if(roles == null) { + JsonNode jsonNode = getOAuthUserProfile().get(OAUTH_USER_PROFILE_ROLES_KEY); + roles = new ArrayList(); + if(jsonNode.isArray()) { + ArrayNode arrayNode = (ArrayNode) jsonNode; + if(arrayNode.size() > 0) { + Iterator iterator = arrayNode.iterator(); + while(iterator.hasNext()) { + roles.add(iterator.next().asText()); + } + } + } + } + return roles; + } + + public String getJobTitle() { + if(jobTitle == null) { + jobTitle = getOAuthUserProfile().get(OAUTH_USER_PROFILE_JOB_TITLE_KEY).asText(); + } + return jobTitle; + } + +} diff --git a/src/main/java/org/gcube/common/authorization/utils/socialservice/SocialService.java b/src/main/java/org/gcube/common/authorization/utils/socialservice/SocialService.java new file mode 100644 index 0000000..f6da2f6 --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/utils/socialservice/SocialService.java @@ -0,0 +1,95 @@ +package org.gcube.common.authorization.utils.socialservice; + +import static org.gcube.resources.discovery.icclient.ICFactory.client; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.gcube.common.authorization.utils.manager.SecretManager; +import org.gcube.common.resources.gcore.GCoreEndpoint; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Discover the Social Networking Service in the Infrastructure. + * @author Luca Frosini (ISTI - CNR) + */ +public class SocialService { + + private static final String RESOURCE = "jersey-servlet"; + private static final String SERVICE_NAME = "SocialNetworking"; + private static final String SERVICE_CLASSE = "Portal"; + + private static Logger logger = LoggerFactory.getLogger(SocialService.class); + private String serviceBasePath; + + // Map + private static Map socialServicePerContext; + + static { + socialServicePerContext = new HashMap<>(); + } + + public static SocialService getSocialService() throws Exception { + String contex = SecretManager.instance.get().getContext(); + SocialService socialService = socialServicePerContext.get(contex); + if(socialService == null) { + socialService = new SocialService(); + socialServicePerContext.put(contex, socialService); + } + return socialService; + } + + /** + * Discover the gcore endpoint for the social networking service. + * @throws Exception the exception + */ + private SocialService() throws Exception { + getServiceBasePathViaGCoreEndpoint(); + } + + protected void getServiceBasePathViaGCoreEndpoint() throws Exception { + try { + SimpleQuery query = queryFor(GCoreEndpoint.class); + query.addCondition(String.format("$resource/Profile/ServiceClass/text() eq '%s'", SERVICE_CLASSE)); + query.addCondition("$resource/Profile/DeploymentData/Status/text() eq 'ready'"); + query.addCondition(String.format("$resource/Profile/ServiceName/text() eq '%s'", SERVICE_NAME)); + query.setResult( + "$resource/Profile/AccessPoint/RunningInstanceInterfaces//Endpoint[@EntryName/string() eq \"" + + RESOURCE + "\"]/text()"); + + DiscoveryClient client = client(); + List endpoints = client.submit(query); + if(endpoints == null || endpoints.isEmpty()) { + throw new Exception("Cannot retrieve the GCoreEndpoint SERVICE_NAME: " + SERVICE_NAME + + ", SERVICE_CLASSE: " + SERVICE_CLASSE + ", in scope: " + SecretManager.instance.get().getContext()); + } + + this.serviceBasePath = endpoints.get(0); + + if(serviceBasePath == null) + throw new Exception("Endpoint:" + RESOURCE + ", is null for SERVICE_NAME: " + SERVICE_NAME + + ", SERVICE_CLASSE: " + SERVICE_CLASSE + ", in scope: " + SecretManager.instance.get().getContext()); + + serviceBasePath = serviceBasePath.endsWith("/") ? serviceBasePath : serviceBasePath + "/"; + + } catch(Exception e) { + String error = "An error occurred during GCoreEndpoint discovery, SERVICE_NAME: " + SERVICE_NAME + + ", SERVICE_CLASSE: " + SERVICE_CLASSE + ", in scope: " + SecretManager.instance.get().getContext() + "."; + logger.error(error, e); + throw new Exception(error); + } + } + + /** + * @return the base path of the service + */ + public String getServiceBasePath() { + return serviceBasePath; + } + +}