ready to release

git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/user/my-vres@142111 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Massimiliano Assante 2017-02-02 17:21:49 +00:00
parent 38fde43f0e
commit ec3fe3ddca
10 changed files with 143 additions and 86 deletions

View File

@ -5,7 +5,7 @@
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/target/generated-sources/gwt"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/target/generated-sources/gwt"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<dependent-module archiveName="gcube-widgets-2.1.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/gcube-widgets/gcube-widgets"> <dependent-module archiveName="gcube-widgets-2.2.0-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/gcube-widgets/gcube-widgets">
<dependency-type>uses</dependency-type> <dependency-type>uses</dependency-type>
</dependent-module> </dependent-module>
<property name="java-output-path" value="/${module}/target/www/WEB-INF/classes"/> <property name="java-output-path" value="/${module}/target/www/WEB-INF/classes"/>

View File

@ -1 +1,17 @@
{"ide":{"scriptPaths":[]},"plugins":{"aui":{},"liferay":{},"yui":{}},"libs":["ecma5","browser"]} {
"plugins": {
"aui": {
},
"liferay": {
},
"yui": {
}
},
"libs": [
"ecma5",
"browser"
]
}

19
pom.xml
View File

@ -65,10 +65,29 @@
<groupId>org.gcube.dvos</groupId> <groupId>org.gcube.dvos</groupId>
<artifactId>usermanagement-core</artifactId> <artifactId>usermanagement-core</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3</version>
<scope>compile</scope>
</dependency>
<!-- FWS DEPS --> <!-- FWS DEPS -->
<dependency> <dependency>
<groupId>org.gcube.resources.discovery</groupId> <groupId>org.gcube.resources.discovery</groupId>
<artifactId>ic-client</artifactId> <artifactId>ic-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.portal.auth</groupId>
<artifactId>portal-auth-library</artifactId>
<version>[1.0.0-SNAPSHOT,)</version>
<scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.gcube.core</groupId> <groupId>org.gcube.core</groupId>

View File

@ -18,11 +18,11 @@ import com.google.gwt.user.client.ui.RootPanel;
public class MyVREs implements EntryPoint { public class MyVREs implements EntryPoint {
public static final String GET_REDIRECTURI_PARAMETER = "redirect_uri"; public static final String GET_REDIRECTURI_PARAMETER = "redirect_uri";
public static final String GET_STATE_PARAMETER = "state"; public static final String GET_STATE_PARAMETER = "state";
public static final String GET_CONTEXT_PARAMETER = "context"; public static final String GET_CONTEXT_PARAMETER = "scope";
public static final String GET_CLIENT_ID_PARAMETER = "client_id"; public static final String GET_CLIENT_ID_PARAMETER = "client_id";
public static final String GET_CLIENT_SECRET_PARAMETER = "client_secret"; public static final String GET_CLIENT_SECRET_PARAMETER = "client_secret";
public static final String GET_AUTH_TOKEN_PARAMETER = "gcube-token"; public static final String GET_AUTH_TOKEN_PARAMETER = "code";
private final MyVREsServiceAsync myVREsService = GWT.create(MyVREsService.class); private final MyVREsServiceAsync myVREsService = GWT.create(MyVREsService.class);
@ -49,11 +49,11 @@ public class MyVREs implements EntryPoint {
RootPanel.get("myVREsDIV").add(new VresPanel(params)); RootPanel.get("myVREsDIV").add(new VresPanel(params));
} }
else { else {
myVREsService.getUserToken(params.context, params.state, params.clientId, params.redirectURI, new AsyncCallback<AuthorizationBean>() { myVREsService.getUserQualifierToken(params.context, params.state, params.clientId, params.redirectURI, new AsyncCallback<AuthorizationBean>() {
@Override @Override
public void onSuccess(AuthorizationBean result) { public void onSuccess(AuthorizationBean result) {
if (result.isSuccess()) { if (result.isSuccess()) {
Location.assign(params.redirectURI+"?"+GET_AUTH_TOKEN_PARAMETER+"="+result.getToken()+"&"+GET_STATE_PARAMETER+"="+result.getState()); Location.assign(params.redirectURI+"?"+GET_AUTH_TOKEN_PARAMETER+"="+result.getOAuth2TemporaryCode()+"&"+GET_STATE_PARAMETER+"="+result.getState());
} else { } else {
HTML message = new HTML("There were issues in managing this request: " + result.getErrorDescription()); HTML message = new HTML("There were issues in managing this request: " + result.getErrorDescription());
message.setStyleName("portlet-msg-error"); message.setStyleName("portlet-msg-error");

View File

@ -18,5 +18,5 @@ public interface MyVREsService extends RemoteService {
String getSiteLandingPagePath(); String getSiteLandingPagePath();
AuthorizationBean getUserToken(String context, String state, String clientId, String authorisedRedirectURL); AuthorizationBean getUserQualifierToken(String context, String state, String clientId, String authorisedRedirectURL);
} }

View File

@ -15,7 +15,7 @@ public interface MyVREsServiceAsync {
void getSiteLandingPagePath(AsyncCallback<String> callback); void getSiteLandingPagePath(AsyncCallback<String> callback);
void getUserToken(String context, String state, String clientId, String authorisedRedirectURI, void getUserQualifierToken(String context, String state, String clientId, String authorisedRedirectURI,
AsyncCallback<AuthorizationBean> callback); AsyncCallback<AuthorizationBean> callback);
} }

View File

@ -62,11 +62,11 @@ public class ClickableVRE extends HTML {
if (params != null) { if (params != null) {
addClickHandler(new ClickHandler() { addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) { public void onClick(ClickEvent event) {
myVREsService.getUserToken(vre.getContext(), params.getState(), params.getClientId(), params.getRedirectURI(), new AsyncCallback<AuthorizationBean>() { myVREsService.getUserQualifierToken(vre.getContext(), params.getState(), params.getClientId(), params.getRedirectURI(), new AsyncCallback<AuthorizationBean>() {
@Override @Override
public void onSuccess(AuthorizationBean result) { public void onSuccess(AuthorizationBean result) {
if (result.isSuccess()) { if (result.isSuccess()) {
Location.assign(params.getRedirectURI()+"?"+MyVREs.GET_AUTH_TOKEN_PARAMETER+"="+result.getToken()+"&"+MyVREs.GET_STATE_PARAMETER+"="+result.getState()); Location.assign(params.getRedirectURI()+"?"+MyVREs.GET_AUTH_TOKEN_PARAMETER+"="+result.getOAuth2TemporaryCode()+"&"+MyVREs.GET_STATE_PARAMETER+"="+result.getState());
} else { } else {
HTML message = new HTML("There were issues in managing this request: " + result.getErrorDescription()); HTML message = new HTML("There were issues in managing this request: " + result.getErrorDescription());
message.setStyleName("portlet-msg-error"); message.setStyleName("portlet-msg-error");

View File

@ -1,27 +1,29 @@
package org.gcube.portlet.user.my_vres.server; package org.gcube.portlet.user.my_vres.server;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.gcube.common.portal.GCubePortalConstants; import org.gcube.common.portal.GCubePortalConstants;
import org.gcube.common.portal.PortalContext; import org.gcube.common.portal.PortalContext;
import org.gcube.common.resources.gcore.ServiceEndpoint; import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; import org.gcube.portal.auth.AuthUtil;
import org.gcube.common.resources.gcore.utils.Group;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portlet.user.my_vres.client.MyVREsService; import org.gcube.portlet.user.my_vres.client.MyVREsService;
import org.gcube.portlet.user.my_vres.shared.AuthorizationBean; import org.gcube.portlet.user.my_vres.shared.AuthorizationBean;
import org.gcube.portlet.user.my_vres.shared.UserBelonging; import org.gcube.portlet.user.my_vres.shared.UserBelonging;
import org.gcube.portlet.user.my_vres.shared.VRE; import org.gcube.portlet.user.my_vres.shared.VRE;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.gcube.vomanagement.usermanagement.GroupManager; import org.gcube.vomanagement.usermanagement.GroupManager;
import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault;
import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException; import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException;
@ -32,6 +34,7 @@ import org.gcube.vomanagement.usermanagement.model.GCubeGroup;
import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.gcube.vomanagement.usermanagement.model.GCubeUser;
import org.gcube.vomanagement.usermanagement.model.VirtualGroup; import org.gcube.vomanagement.usermanagement.model.VirtualGroup;
import org.gcube.vomanagement.usermanagement.util.ManagementUtils; import org.gcube.vomanagement.usermanagement.util.ManagementUtils;
import org.json.simple.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -260,16 +263,27 @@ public class MyVREsServiceImpl extends RemoteServiceServlet implements MyVREsSer
} }
@Override @Override
public AuthorizationBean getUserToken(String context, String state, String clientId, String redirectURL) { public AuthorizationBean getUserQualifierToken(String context, String state, String clientId, String redirectURL) {
String infraName = PortalContext.getConfiguration().getInfrastructureName();
if (clientId == null || clientId.compareTo("")== 0) { if (clientId == null || clientId.compareTo("")== 0) {
return new AuthorizationBean(null, null, false, "client_id is null, you MUST register your application to allow users connect with their D4Science Credentials"); return new AuthorizationBean(null, null, false, "client_id is null, you MUST register your application to allow users connect with their D4Science Credentials");
} }
if (redirectURL == null || redirectURL.compareTo("")== 0) { if (redirectURL == null || redirectURL.compareTo("")== 0) {
return new AuthorizationBean(null, null, false, "authorised redirect URL is null, you MUST pass the authorisedRedirectURI related to your client_id registered application to allow users connect with their D4Science Credentials"); return new AuthorizationBean(null, null, false, "authorised redirect URL is null, you MUST pass the authorisedRedirectURI related to your client_id registered application to allow users connect with their D4Science Credentials");
} }
List<String> authorisedRedirectURLs = getAuthorisedRedirectURLsFromIs(clientId); ServiceEndpoint authorisedApp = null;
try {
authorisedApp = AuthUtil.getAuthorisedApplicationInfoFromIsICClient(infraName, clientId);
} catch (Exception e1) {
e1.printStackTrace();
return new AuthorizationBean(null, null, false, "Ops!, we failed to check if ("+ clientId + ") is a valid clientId, some error occurred, please try in a few minutes. If the problem persists please open an incident ticket");
}
if (authorisedApp == null) {
return new AuthorizationBean(null, null, false, "Your application ("+ clientId + ") is not authorized in the infrastructure");
}
List<String> authorisedRedirectURLs = AuthUtil.getAuthorisedRedirectURLsFromIs(authorisedApp);
if (authorisedRedirectURLs == null || authorisedRedirectURLs.isEmpty()) { if (authorisedRedirectURLs == null || authorisedRedirectURLs.isEmpty()) {
return new AuthorizationBean(null, null, false, "Your application ("+ clientId + ") is not registered or there are no authorised redirect URLs registered for your application"); return new AuthorizationBean(null, null, false, "Your application ("+ clientId + ") have no authorised redirect URLs");
} }
boolean urlAuthorised = false; boolean urlAuthorised = false;
for (String authorisedURL : authorisedRedirectURLs) for (String authorisedURL : authorisedRedirectURLs)
@ -310,63 +324,70 @@ public class MyVREsServiceImpl extends RemoteServiceServlet implements MyVREsSer
_log.error("Something wrong in retrieving the user"); _log.error("Something wrong in retrieving the user");
return new AuthorizationBean(null, null, false, "Something wrong in retrieving the logged in user, is session expired?"); return new AuthorizationBean(null, null, false, "Something wrong in retrieving the logged in user, is session expired?");
} }
String token = pContext.getCurrentUserToken(context, username); //no errors, proceed to step 2
if (token == null) { String userToken = pContext.getCurrentUserToken(context, username);
_log.error("Something wrong in retrieving the user token in this context: " + context + " username="+username); String appName = authorisedApp.profile().name();
return new AuthorizationBean(null, null, false, "Something wrong in retrieving the user token in this context: " + context + " username="+username); String qToken = AuthUtil.generateAuthorizationQualifierToken(appName, userToken);
_log.info("Received qualifier token for useer " + username + "=" + qToken);
if (qToken == null) {
_log.error("Something wrong in retrieving the user qualifier token in this context: " + context + " username="+username);
return new AuthorizationBean(null, null, false, "Something wrong in retrieving the user qualifier token in this context: " + context + " username="+username);
} }
_log.debug("Authorisation OAUTH returning user token in this context: " + context + " username="+username); String tempCode = UUID.randomUUID().toString();
return new AuthorizationBean(token, state, true, null); if (! authorizeApplication(infraName, qToken, tempCode, clientId, redirectURL)) {
_log.error("Something wrong in authorizing this application in this context: " + context );
return new AuthorizationBean(null, null, false, "Something wrong in authorizing this application in this context: " + context + " an error occurred in the oAuth Service");
} }
//TODO: check the query, it doesn work _log.debug("Authorisation OAUTH 2 OK returning temporary code in this context: " + context + " username="+username);
private List<ServiceEndpoint> getPortalConfigurationFromIS(String infrastructureName, String clientId) throws Exception { return new AuthorizationBean(tempCode, state, true, null);
String scope = "/" + infrastructureName;
String currScope = ScopeProvider.instance.get();
ScopeProvider.instance.set(scope);
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Category/text() eq '"+ SERVICE_ENDPOINT_CATEGORY +"'");
query.addCondition("$resource/Profile/Name/text() eq '"+ clientId +"'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> toReturn = client.submit(query);
ScopeProvider.instance.set(currScope);
return toReturn;
} }
/** /**
* look for the clientId AccessEndpoint passes as parameter * we post to the auth service a temporary code to be used within seconds from the application
* @param gatewayName * @param qToken the user qualifier token
* @param clientId * @param tempCode the temporary code
* @return the client secret related to the id, or null if non existent * @param clientId tha app id
* @param redirectURI the authorised redirect URI
* @return
*/ */
private List<String> getAuthorisedRedirectURLsFromIs(String clientId) { @SuppressWarnings("unchecked")
PortalContext pContext = PortalContext.getConfiguration(); private boolean authorizeApplication(String infrastructureName, String qToken, String tempCode, String clientId, String redirectURL) {
String scope = "/"+pContext.getInfrastructureName();
List<String> autRedirectURLs = new ArrayList<>(); String fullPath2oAuthService = null;
try { try {
List<ServiceEndpoint> list = getPortalConfigurationFromIS(pContext.getInfrastructureName(), clientId); fullPath2oAuthService = AuthUtil.getOAuthServiceEndPoint(infrastructureName) +
if (list.size() > 1) { "/v2/push-authentication-code?gcube-token=" + qToken;
_log.error("Too many Service Endpoints having name " + clientId +" in this scope having Category " + SERVICE_ENDPOINT_CATEGORY); } catch (Exception e1) {
_log.error("failed to discover oauth service endpoint ");
return false;
} }
else if (list.size() == 0){ fullPath2oAuthService = fullPath2oAuthService.replaceAll("http", "https");
_log.warn("There is no Service Endpoint having name " + clientId +" and Category " + SERVICE_ENDPOINT_CATEGORY + " in this scope: " + scope); fullPath2oAuthService = fullPath2oAuthService.replaceAll("80", "443");
}
else { JSONObject object = new JSONObject();
for (ServiceEndpoint res : list) { object.put("code", tempCode);
Group<AccessPoint> apGroup = res.profile().accessPoints(); object.put("redirect_uri", redirectURL);
AccessPoint[] accessPoints = (AccessPoint[]) apGroup.toArray(new AccessPoint[apGroup.size()]); object.put("client_id", clientId);
for (int i = 0; i < accessPoints.length; i++) {
if (accessPoints[i].name().compareTo(REDIRECT_URL) == 0) { try (CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build()) {
AccessPoint found = accessPoints[i]; HttpPost httpPostRequest = new HttpPost(fullPath2oAuthService);
autRedirectURLs.add(found.address()); httpPostRequest.addHeader("Content-type", "application/json");
} StringEntity params = new StringEntity(object.toJSONString(), ContentType.APPLICATION_JSON);
} httpPostRequest.setEntity(params);
} HttpResponse response = httpClient.execute(httpPostRequest);
} if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() >= 300) {
} catch (Exception e) { _log.error("failed to patch the product. response status line from "
e.printStackTrace(); + fullPath2oAuthService + " was: " + response.getStatusLine());
return null; return false;
}
return autRedirectURLs;
} }
}catch(Exception e){
_log.error("Failed to perform request", e);
}
return true;
}
} }

View File

@ -13,6 +13,8 @@ import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest; import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse; import javax.portlet.RenderResponse;
import org.gcube.common.portal.PortalContext;
import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.log.LogFactoryUtil;
@ -36,7 +38,7 @@ public class MyVREsPortlet extends GenericPortlet {
protected void include(String path, RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { protected void include(String path, RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException {
PortletRequestDispatcher portletRequestDispatcher = getPortletContext().getRequestDispatcher(path); PortletRequestDispatcher portletRequestDispatcher = getPortletContext().getRequestDispatcher(path);
PortalContext.setUserInSession(renderRequest);
if (portletRequestDispatcher == null) { if (portletRequestDispatcher == null) {
_log.error(path + " is not a valid include"); _log.error(path + " is not a valid include");
} }

View File

@ -4,30 +4,29 @@ import java.io.Serializable;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class AuthorizationBean implements Serializable { public class AuthorizationBean implements Serializable {
private String token; private String oAuth2TemporaryCode;
private String state; private String state;
private boolean success; private boolean success;
private String errorDescription; private String errorDescription;
public AuthorizationBean() { public AuthorizationBean() {
super(); super();
// TODO Auto-generated constructor stub
} }
public AuthorizationBean(String token, String state, boolean success, String errorDescription) { public AuthorizationBean(String oAuth2TemporaryCode, String state, boolean success, String errorDescription) {
super(); super();
this.token = token; this.oAuth2TemporaryCode = oAuth2TemporaryCode;
this.state = state; this.state = state;
this.success = success; this.success = success;
this.errorDescription = errorDescription; this.errorDescription = errorDescription;
} }
public String getToken() { public String getOAuth2TemporaryCode() {
return token; return oAuth2TemporaryCode;
} }
public void setToken(String token) { public void seOAuth2TemporaryCode(String oAuth2TemporaryCode) {
this.token = token; this.oAuth2TemporaryCode = oAuth2TemporaryCode;
} }
public String getState() { public String getState() {
@ -56,7 +55,7 @@ public class AuthorizationBean implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "AuthorizationBean [token=" + token + ", state=" + state + ", success=" + success + ", errorDescription=" return "AuthorizationBean [oAuth2TemporaryCode=" + oAuth2TemporaryCode + ", state=" + state + ", success=" + success + ", errorDescription="
+ errorDescription + "]"; + errorDescription + "]";
} }