diff --git a/src/main/java/org/gcube/common/authorization/utils/manager/SecretHolder.java b/src/main/java/org/gcube/common/authorization/utils/manager/SecretHolder.java index 23a1aaf..7f4a2c8 100644 --- a/src/main/java/org/gcube/common/authorization/utils/manager/SecretHolder.java +++ b/src/main/java/org/gcube/common/authorization/utils/manager/SecretHolder.java @@ -5,6 +5,7 @@ import java.util.SortedSet; import java.util.TreeSet; import org.gcube.common.authorization.utils.secret.Secret; +import org.gcube.common.authorization.utils.user.User; import org.gcube.common.scope.api.ScopeProvider; /** @@ -61,10 +62,10 @@ public class SecretHolder { return secrets; } - public String getUsername() { + public User getUser() { for(Secret secret : secrets) { try { - return secret.getUsername(); + return secret.getUser(); }catch (Exception e) { // trying the next one } @@ -83,17 +84,6 @@ public class SecretHolder { return ScopeProvider.instance.get(); } - public Collection getRoles() { - for(Secret secret : secrets) { - try { - return secret.getRoles(); - }catch (Exception e) { - // trying the next one - } - } - return null; - } - public void reset() { for(Secret secret : secrets) { try { @@ -104,48 +94,4 @@ public class SecretHolder { } } - public String getName() { - for(Secret secret : secrets) { - try { - return secret.getName(); - }catch (Exception e) { - // trying the next one - } - } - return null; - } - - public String getSurname() { - for(Secret secret : secrets) { - try { - return secret.getSurname(); - }catch (Exception e) { - // trying the next one - } - } - return null; - } - - public String getEMail() { - for(Secret secret : secrets) { - try { - return secret.getEMail(); - }catch (Exception e) { - // trying the next one - } - } - return null; - } - - - public String getTitle() { - for(Secret secret : secrets) { - try { - return secret.getTitle(); - }catch (Exception e) { - // trying the next one - } - } - return ""; - } } diff --git a/src/main/java/org/gcube/common/authorization/utils/manager/SecretManager.java b/src/main/java/org/gcube/common/authorization/utils/manager/SecretManager.java index 6d98ee8..5fe8dfc 100644 --- a/src/main/java/org/gcube/common/authorization/utils/manager/SecretManager.java +++ b/src/main/java/org/gcube/common/authorization/utils/manager/SecretManager.java @@ -1,7 +1,6 @@ package org.gcube.common.authorization.utils.manager; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.SortedSet; @@ -9,6 +8,7 @@ import org.gcube.common.authorization.utils.provider.GCubeSecretProvider; import org.gcube.common.authorization.utils.provider.SecretProvider; import org.gcube.common.authorization.utils.secret.JWTSecret; import org.gcube.common.authorization.utils.secret.Secret; +import org.gcube.common.authorization.utils.user.User; /** * @author Luca Frosini (ISTI - CNR) @@ -83,18 +83,6 @@ public class SecretManager { } } - public String getUsername() { - return currentSecretHolder.getUsername(); - } - - public String getContext() { - return currentSecretHolder.getContext(); - } - - public Collection getRoles() { - return currentSecretHolder.getRoles(); - } - public void reset() { initialSecretHolder.reset(); if(initialSecretHolder!=currentSecretHolder) { @@ -103,19 +91,12 @@ public class SecretManager { instance.remove(); } - public String getName() { - return currentSecretHolder.getName(); + public String getContext() { + return currentSecretHolder.getContext(); } - public String getSurname() { - return currentSecretHolder.getSurname(); + public User getUser() { + return currentSecretHolder.getUser(); } - public String getEMail() { - return currentSecretHolder.getEMail(); - } - - public String getTitle() { - return currentSecretHolder.getTitle(); - } } 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 f3b81eb..64ae7d5 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,6 +1,5 @@ package org.gcube.common.authorization.utils.secret; -import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; @@ -11,7 +10,8 @@ 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; +import org.gcube.common.authorization.utils.socialservice.SocialService; +import org.gcube.common.authorization.utils.user.User; /** * @author Luca Frosini (ISTI - CNR) @@ -21,7 +21,6 @@ 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 { @@ -87,36 +86,15 @@ public class GCubeSecret extends Secret { return false; } - protected PortalUser getPortalUser() { - if(portalUser==null) { - portalUser = new PortalUser(); + public User getUser() { + if(user==null) { + try { + user = SocialService.getSocialService().getUser(this); + } catch (Exception e) { + throw new RuntimeException(); + } } - return portalUser; + return user; } - - @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().getEMail(); - } - - @Override - public String getTitle() { - return getPortalUser().getJobTitle(); - } - + } diff --git a/src/main/java/org/gcube/common/authorization/utils/secret/JWTSecret.java b/src/main/java/org/gcube/common/authorization/utils/secret/JWTSecret.java index 9827f90..7057a16 100644 --- a/src/main/java/org/gcube/common/authorization/utils/secret/JWTSecret.java +++ b/src/main/java/org/gcube/common/authorization/utils/secret/JWTSecret.java @@ -4,7 +4,6 @@ import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Base64; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -15,6 +14,8 @@ import org.gcube.common.authorization.library.provider.ClientInfo; import org.gcube.common.authorization.library.provider.UserInfo; import org.gcube.common.authorization.library.utils.Caller; import org.gcube.common.authorization.utils.clientid.RenewalProvider; +import org.gcube.common.authorization.utils.user.KeycloakUser; +import org.gcube.common.authorization.utils.user.User; import org.gcube.common.keycloak.model.AccessToken; import org.gcube.common.keycloak.model.RefreshToken; import org.gcube.common.keycloak.model.util.Time; @@ -158,27 +159,17 @@ public class JWTSecret extends Secret { } @Override - public Collection getRoles() throws Exception { - return getAccessToken().getRealmAccess().getRoles(); - } - - @Override - public String getName() throws Exception { - return getAccessToken().getGivenName(); - } - - @Override - public String getSurname() throws Exception { - return getAccessToken().getFamilyName(); - } - - @Override - public String getEMail() throws Exception { - return getAccessToken().getEmail(); - } - - @Override - public String getTitle() throws Exception { - return ""; + public User getUser() { + if(user==null) { + try { + ObjectMapper objectMapper = new ObjectMapper(); + String accessTokenString = objectMapper.writeValueAsString(accessToken); + user = objectMapper.readValue(accessTokenString, KeycloakUser.class); + } catch (Exception e) { + throw new RuntimeException(); + } + } + return user; } + } \ No newline at end of file diff --git a/src/main/java/org/gcube/common/authorization/utils/secret/Secret.java b/src/main/java/org/gcube/common/authorization/utils/secret/Secret.java index 81dd5f0..2dfa5fd 100644 --- a/src/main/java/org/gcube/common/authorization/utils/secret/Secret.java +++ b/src/main/java/org/gcube/common/authorization/utils/secret/Secret.java @@ -1,6 +1,5 @@ package org.gcube.common.authorization.utils.secret; -import java.util.Collection; import java.util.Map; import java.util.Objects; @@ -9,6 +8,7 @@ import org.gcube.common.authorization.library.exception.AuthorizationException; import org.gcube.common.authorization.library.provider.AuthorizationProvider; import org.gcube.common.authorization.library.provider.ClientInfo; import org.gcube.common.authorization.library.utils.Caller; +import org.gcube.common.authorization.utils.user.User; import org.gcube.common.scope.api.ScopeProvider; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,6 +22,7 @@ public abstract class Secret implements Comparable { protected int priority; protected String token; + protected User user; protected void check(String token) throws AuthorizationException { if(token == null) { @@ -117,14 +118,6 @@ public abstract class Secret implements Comparable { public abstract boolean isRefreshable(); - public abstract Collection getRoles() throws Exception; - - public abstract String getName() throws Exception; - - public abstract String getSurname() throws Exception; - - public abstract String getEMail() throws Exception; - - public abstract String getTitle() throws Exception; + public abstract User getUser(); } 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 deleted file mode 100644 index 48a9290..0000000 --- a/src/main/java/org/gcube/common/authorization/utils/socialservice/PortalUser.java +++ /dev/null @@ -1,166 +0,0 @@ -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 index f6da2f6..48291aa 100644 --- a/src/main/java/org/gcube/common/authorization/utils/socialservice/SocialService.java +++ b/src/main/java/org/gcube/common/authorization/utils/socialservice/SocialService.java @@ -3,11 +3,26 @@ 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.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; import java.util.HashMap; import java.util.List; import java.util.Map; +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.ObjectMapper; import org.gcube.common.authorization.utils.manager.SecretManager; +import org.gcube.common.authorization.utils.secret.Secret; +import org.gcube.common.authorization.utils.user.GCubeUser; +import org.gcube.common.authorization.utils.user.User; +import org.gcube.common.gxhttp.request.GXHTTPStringRequest; import org.gcube.common.resources.gcore.GCoreEndpoint; import org.gcube.resources.discovery.client.api.DiscoveryClient; import org.gcube.resources.discovery.client.queries.api.SimpleQuery; @@ -92,4 +107,62 @@ public class SocialService { return serviceBasePath; } + + 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; + } + + protected static final String SOCIAL_SERVICE_GET_OAUTH_USER_PROFILE_PATH = "2/users/get-oauth-profile"; + + protected static final String RESPONSE_SUCCESS_KEY = "success"; + protected static final String RESPONSE_MESSAGE_KEY = "message"; + protected static final String RESPONSE_RESULT_KEY = "result"; + + + public User getUser(Secret secret) throws Exception { + try { + String socialServiceBasePath = SocialService.getSocialService().getServiceBasePath(); + + GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(socialServiceBasePath); + gxhttpStringRequest.from("authorization-utils"); + gxhttpStringRequest.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON); + Map authzHeaders = secret.getHTTPAuthorizationHeaders(); + for(String key : authzHeaders.keySet()) { + gxhttpStringRequest.header(key, authzHeaders.get(key)); + } + gxhttpStringRequest.path(SOCIAL_SERVICE_GET_OAUTH_USER_PROFILE_PATH); + HttpURLConnection httpURLConnection = gxhttpStringRequest.get(); + + String ret = getResultAsString(httpURLConnection); + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(ret, GCubeUser.class); + } catch(Exception e) { + throw new Exception("Unable to retrive User from Social Service", e); + } + + } + } diff --git a/src/main/java/org/gcube/common/authorization/utils/user/GCubeUser.java b/src/main/java/org/gcube/common/authorization/utils/user/GCubeUser.java new file mode 100644 index 0000000..17b61da --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/utils/user/GCubeUser.java @@ -0,0 +1,95 @@ +package org.gcube.common.authorization.utils.user; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.gcube.com.fasterxml.jackson.annotation.JsonAnyGetter; +import org.gcube.com.fasterxml.jackson.annotation.JsonAnySetter; +import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore; +import org.gcube.com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class GCubeUser implements User { + + // This key contains the fullname + // protected static final String OAUTH_USER_PROFILE_FULLNAME_KEY = "name"; + + protected static final String USERNAME_KEY = "id"; + + protected static final String ROLES_KEY = "roles"; + + protected static final String NAME_KEY = "given_name"; + protected static final String MIDDLE_NAME_KEY = "middle_name"; + protected static final String SURNAME_KEY = "family_name"; + protected static final String EMAIL_KEY = "email"; + + + @JsonProperty(USERNAME_KEY) + protected String username; + + @JsonProperty(ROLES_KEY) + protected Set roles; + + @JsonProperty(NAME_KEY) + protected String name; + @JsonProperty(SURNAME_KEY) + protected String surname; + @JsonProperty(EMAIL_KEY) + protected String eMail; + + + @JsonIgnore + protected Map additionalProperties; + + public GCubeUser() { + this.additionalProperties = new HashMap<>(); + } + + @Override + public String getUsername() { + return username; + } + + @Override + public Collection getRoles() { + return roles; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getSurname() { + return surname; + } + + @Override + public String getEmail() { + return eMail; + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return additionalProperties; + } + + public void setAdditionalProperties(Map additionalProperties) { + this.additionalProperties = additionalProperties; + } + + public Object getAdditionalProperty(String key) { + return this.additionalProperties.get(key); + } + + @JsonAnySetter + public void setAdditionalProperty(String key, Object value) { + this.additionalProperties.put(key, value); + } + +} diff --git a/src/main/java/org/gcube/common/authorization/utils/user/KeycloakUser.java b/src/main/java/org/gcube/common/authorization/utils/user/KeycloakUser.java new file mode 100644 index 0000000..f17df95 --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/utils/user/KeycloakUser.java @@ -0,0 +1,36 @@ +package org.gcube.common.authorization.utils.user; + +import java.util.Collection; + +import org.gcube.com.fasterxml.jackson.annotation.JsonIgnore; +import org.gcube.common.keycloak.model.AccessToken; + +/** + * @author Luca Frosini (ISTI-CNR) + */ +public class KeycloakUser extends AccessToken implements User { + + /** + * Generated Serial Version UID + */ + private static final long serialVersionUID = -7083648026885406300L; + + @Override + @JsonIgnore + public String getUsername() { + return getId(); + } + + @Override + @JsonIgnore + public Collection getRoles() { + return getRealmAccess().getRoles(); + } + + @Override + @JsonIgnore + public String getSurname() { + return getFamilyName(); + } + +} diff --git a/src/main/java/org/gcube/common/authorization/utils/user/User.java b/src/main/java/org/gcube/common/authorization/utils/user/User.java new file mode 100644 index 0000000..62dc43e --- /dev/null +++ b/src/main/java/org/gcube/common/authorization/utils/user/User.java @@ -0,0 +1,28 @@ +package org.gcube.common.authorization.utils.user; + +import java.util.Collection; + +/** + * @author Luca Frosini (ISTI-CNR) + */ +public interface User { + + public String getUsername(); + + public Collection getRoles(); + + public String getName(); + + public String getSurname(); + + public String getEmail(); + + public default String getSurnameName() { + return String.format("%s %s", getSurname(), getName()); + } + + public default String getNameSurname() { + return String.format("%s %s", getName(), getSurname()); + } + +}