diff --git a/.classpath b/.classpath index 57c104b..5b3b122 100644 --- a/.classpath +++ b/.classpath @@ -12,11 +12,6 @@ - - - - - @@ -32,5 +27,10 @@ + + + + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 443e085..b90405e 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,7 +1,12 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning diff --git a/pom.xml b/pom.xml index b507ff5..1c5a542 100644 --- a/pom.xml +++ b/pom.xml @@ -30,7 +30,7 @@ distro 1.7 - 1.7 + 1.8 UTF-8 UTF-8 @@ -211,7 +211,7 @@ 2.3.2 1.7 - 1.7 + 1.8 diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherService.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherService.java index f466364..1054fb1 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherService.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherService.java @@ -75,11 +75,10 @@ public interface CKanPublisherService extends RemoteService { * @return a list of groups' beans */ List getUserGroups(String orgName); - - // /** - // * Return a tree object representing the whole folder hierarchy - // * @param folderId - // * @return ResourceElementBean - // */ - // ResourceElementBean getTreeFolder(String folderId); + + /** + * The method checks if the user is a publisher or he/she doesn't have the rights to publish + * @return true if he/she can publish, false otherwise + */ + boolean isPublisherUser(boolean isWorkspaceRequest); } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherServiceAsync.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherServiceAsync.java index 19201be..5a8be48 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherServiceAsync.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/CKanPublisherServiceAsync.java @@ -83,4 +83,11 @@ public interface CKanPublisherServiceAsync { * @return a list of groups' beans */ void getUserGroups(String orgName, AsyncCallback> callback); + + /** + * The method checks if the user is a publisher or he/she doesn't have the rights to publish + * @return true if he/she can publish, false otherwise + */ + void isPublisherUser(boolean isWorkspaceRequest, + AsyncCallback callback); } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.java index 1a352af..96ef33e 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.java @@ -150,6 +150,9 @@ public class CreateDatasetForm extends Composite{ @UiField Icon infoIconGroups; @UiField FocusPanel focusPanelGroups; @UiField Popover popoverTitle; + @UiField Icon infoIconDescription; + @UiField Popover popoverDescription; + @UiField FocusPanel focusPanelDescription; @UiField ControlGroup metadataProfilesControlGroup; @UiField ControlGroup productTitleGroup; @UiField ControlGroup maintainerControlGroup; @@ -168,6 +171,7 @@ public class CreateDatasetForm extends Composite{ protected static final String ERROR_PRODUCT_CREATION = "There was an error while trying to publish your product, sorry.. Retry later"; protected static final String PRODUCT_CREATED_OK = "Product correctly published!"; private static final String TRYING_TO_CREATE_PRODUCT = "Trying to publish the product, please wait"; + protected static final String MISSING_PUBLISH_RIGHTS = "It seems you are not authorized to publish on catalogue. Request it to the VRE manager or the portal administrator."; // tab panel private TabPanel tabPanel; @@ -252,7 +256,7 @@ public class CreateDatasetForm extends Composite{ * @param owner * @param eventBus */ - private void createDatasetFormBody(final boolean isWorkspaceRequest, String idFolderWorkspace, final HandlerManager eventBus){ + private void createDatasetFormBody(final boolean isWorkspaceRequest, final String idFolderWorkspace, final HandlerManager eventBus){ initWidget(uiBinder.createAndBindUi(this)); this.eventBus = eventBus; @@ -264,203 +268,227 @@ public class CreateDatasetForm extends Composite{ continueButton.setEnabled(false); resetButton.setEnabled(false); - // set info block - setAlertBlock("Retrieving information, please wait...", AlertType.INFO, true); + // check if the user has publishing rights + setAlertBlock("Checking your permissions, please wait...", AlertType.INFO, true); - // get back the licenses and the metadata information - ckanServices.getDatasetBean(idFolderWorkspace, new AsyncCallback() { + ckanServices.isPublisherUser(isWorkspaceRequest, new AsyncCallback() { @Override - public void onFailure(Throwable caught) { + public void onSuccess(Boolean result) { - setAlertBlock("Error while retrieving information, try to refresh the page and retry", AlertType.ERROR, true); + if(result){ - } + // set info block + setAlertBlock("Retrieving information, please wait...", AlertType.INFO, true); - @Override - public void onSuccess(final DatasetMetadataBean bean) { - - if(bean == null){ - - setAlertBlock("Error while retrieving information, try to refresh the page and retry", AlertType.ERROR, true); - } - else{ - - // save it - receivedBean = bean; - - // fill the form - titleTextBox.setText(bean.getTitle()); - descriptionTextarea.setText(bean.getDescription()); - versionTextbox.setText(String.valueOf(bean.getVersion())); - authorTextbox.setText(bean.getAuthorSurname() + " " + bean.getAuthorName()); - authorEmailTextbox.setText(bean.getAuthorEmail()); - maintainerTextbox.setText(bean.getAuthorSurname() + " " + bean.getAuthorName()); - maintainerEmailTextbox.setText(bean.getMaintainerEmail()); - - // retrieve custom fields - Map> customFieldsMap = bean.getCustomFields(); - - if(customFieldsMap != null){ - - // get the keys and put them as tags - Iterator>> iteratorOverCustomField = customFieldsMap.entrySet().iterator(); - - while (iteratorOverCustomField.hasNext()) { - Map.Entry> entry = (Map.Entry>) iteratorOverCustomField - .next(); - - List values = entry.getValue(); - - for (String value : values) { - // these are fixed key, variable value custom fields - CustomFieldEntry toAdd = new CustomFieldEntry(eventBus, entry.getKey(), value, false); - customFieldEntriesList.add(toAdd); - customFields.add(toAdd); - - // add as tag - tagsPanel.addTagElement(entry.getKey()); - } - } - } - - if(isWorkspaceRequest){ - - boolean showAlertMissingResources = bean.getResources() == null || bean.getResources().isEmpty() || bean.getResources().get(0).getChildren() == null || - bean.getResources().get(0).getChildren().isEmpty(); - - // if there are not resources, for now just checked it ( and hide so that the step will be skipped) - if(showAlertMissingResources){ - alertNoResources.setType(AlertType.WARNING); - alertNoResources.setVisible(true); - }else - resourcesTwinPanel = new TwinColumnSelectionMainPanel(bean.getResources().get(0)); - } - - // set organizations - List organizations = bean.getOrganizationList(); - - for (OrganizationBean organization : organizations) { - organizationsListbox.addItem(organization.getTitle()); - nameTitleOrganizationMap.put(organization.getTitle(), organization.getName()); - } - - // force the selection of the first one, and retrieve the list of profiles - organizationsListbox.setSelectedIndex(0); - - // add change handler to dinamycally retrieve the list of profiles - organizationsListbox.addChangeHandler(new ChangeHandler() { - - @Override - public void onChange(ChangeEvent event) { - event.preventDefault(); - organizationsListboxChangeHandlerBody(); - } - }); - - // try to retrieve the profiles - setAlertBlock("Retrieving profiles, please wait...", AlertType.INFO, true); - - // get the name of the organization from the title - final String orgName = nameTitleOrganizationMap.get(organizationsListbox.getSelectedItemText()); - - // perform remote request of profiles for the selected organization - ckanServices.getProfiles(orgName, new AsyncCallback>() { + // get back the licenses and the metadata information + ckanServices.getDatasetBean(idFolderWorkspace, new AsyncCallback() { @Override public void onFailure(Throwable caught) { - setAlertBlock("Error while retrieving profiles, try later", AlertType.ERROR, true); + + setAlertBlock("Error while retrieving information, try to refresh the page and retry", AlertType.ERROR, true); + } @Override - public void onSuccess(final List profiles) { + public void onSuccess(final DatasetMetadataBean bean) { - if(profiles == null){ - setAlertBlock("Error while retrieving profiles, try later", AlertType.ERROR, true); + if(bean == null){ + + setAlertBlock("Error while retrieving information, try to refresh the page and retry", AlertType.ERROR, true); } else{ - receivedBean.setMetadataList(profiles); - prepareMetadataList(receivedBean); - organizationsListbox.setEnabled(true); - metadataProfilesFormatListbox.setEnabled(true); + // save it + receivedBean = bean; - // try to retrieve the licenses - setAlertBlock("Retrieving licenses, please wait...", AlertType.INFO, true); - ckanServices.getLicenses(new AsyncCallback() { + // fill the form + titleTextBox.setText(bean.getTitle()); + descriptionTextarea.setText(bean.getDescription()); + versionTextbox.setText(String.valueOf(bean.getVersion())); + authorTextbox.setText(bean.getAuthorSurname() + " " + bean.getAuthorName()); + authorEmailTextbox.setText(bean.getAuthorEmail()); + maintainerTextbox.setText(bean.getAuthorSurname() + " " + bean.getAuthorName()); + maintainerEmailTextbox.setText(bean.getMaintainerEmail()); + + // retrieve custom fields + Map> customFieldsMap = bean.getCustomFields(); + + if(customFieldsMap != null){ + + // get the keys and put them as tags + Iterator>> iteratorOverCustomField = customFieldsMap.entrySet().iterator(); + + while (iteratorOverCustomField.hasNext()) { + Map.Entry> entry = (Map.Entry>) iteratorOverCustomField + .next(); + + List values = entry.getValue(); + + for (String value : values) { + // these are fixed key, variable value custom fields + CustomFieldEntry toAdd = new CustomFieldEntry(eventBus, entry.getKey(), value, false); + customFieldEntriesList.add(toAdd); + customFields.add(toAdd); + + // add as tag + tagsPanel.addTagElement(entry.getKey()); + } + } + } + + if(isWorkspaceRequest){ + + boolean showAlertMissingResources = bean.getResources() == null || bean.getResources().isEmpty() || bean.getResources().get(0).getChildren() == null || + bean.getResources().get(0).getChildren().isEmpty(); + + // if there are not resources, for now just checked it ( and hide so that the step will be skipped) + if(showAlertMissingResources){ + alertNoResources.setType(AlertType.WARNING); + alertNoResources.setVisible(true); + }else + resourcesTwinPanel = new TwinColumnSelectionMainPanel(bean.getResources().get(0)); + } + + // set organizations + List organizations = bean.getOrganizationList(); + + for (OrganizationBean organization : organizations) { + organizationsListbox.addItem(organization.getTitle()); + nameTitleOrganizationMap.put(organization.getTitle(), organization.getName()); + } + + // force the selection of the first one, and retrieve the list of profiles + organizationsListbox.setSelectedIndex(0); + + // add change handler to dinamycally retrieve the list of profiles + organizationsListbox.addChangeHandler(new ChangeHandler() { @Override - public void onFailure(Throwable caught){ - setAlertBlock("Error while retrieving licenses, try later", AlertType.ERROR, true); + public void onChange(ChangeEvent event) { + event.preventDefault(); + organizationsListboxChangeHandlerBody(); + } + }); + + // try to retrieve the profiles + setAlertBlock("Retrieving profiles, please wait...", AlertType.INFO, true); + + // get the name of the organization from the title + final String orgName = nameTitleOrganizationMap.get(organizationsListbox.getSelectedItemText()); + + // perform remote request of profiles for the selected organization + ckanServices.getProfiles(orgName, new AsyncCallback>() { + + @Override + public void onFailure(Throwable caught) { + setAlertBlock("Error while retrieving profiles, try later", AlertType.ERROR, true); } @Override - public void onSuccess(LicensesBean lBean) { + public void onSuccess(final List profiles) { - if(lBean != null && !lBean.getLicenseTitles().isEmpty()){ + if(profiles == null){ + setAlertBlock("Error while retrieving profiles, try later", AlertType.ERROR, true); + } + else{ - licenseBean = lBean; - - // sort the list - List listOfNames = new ArrayList(); - Collections.copy(listOfNames, licenseBean.getLicenseTitles()); - Collections.sort(listOfNames); - - // fill the listbox - for(int i = 0; i < listOfNames.size(); i++){ - licenseListbox.addItem(listOfNames.get(i)); - } - - // set the url of the license, if any - showLicenseUrl(); + receivedBean.setMetadataList(profiles); + prepareMetadataList(receivedBean); + organizationsListbox.setEnabled(true); + metadataProfilesFormatListbox.setEnabled(true); // try to retrieve the licenses - setAlertBlock("Retrieving groups, please wait...", AlertType.INFO, true); - - // request groups - ckanServices.getUserGroups(orgName, new AsyncCallback>() { + setAlertBlock("Retrieving licenses, please wait...", AlertType.INFO, true); + ckanServices.getLicenses(new AsyncCallback() { @Override - public void onSuccess(List groups) { - if(groups == null){ - setAlertBlock("Error while retrieving groups", AlertType.ERROR, true); - }else{ - if(groups.isEmpty()){ - groupsControlGroup.setVisible(false); - } - else{ + public void onFailure(Throwable caught){ + setAlertBlock("Error while retrieving licenses, try later", AlertType.ERROR, true); + } - // add groups - for (GroupBean group : groups) { - groupsListbox.addItem(group.getGroupTitle(), group.getGroupName()); - } - hideGroupsAlreadyInProfile(profiles); + @Override + public void onSuccess(LicensesBean lBean) { + + if(lBean != null && !lBean.getLicenseTitles().isEmpty()){ + + licenseBean = lBean; + + // sort the list + List listOfNames = new ArrayList(); + Collections.copy(listOfNames, licenseBean.getLicenseTitles()); + Collections.sort(listOfNames); + + // fill the listbox + for(int i = 0; i < listOfNames.size(); i++){ + licenseListbox.addItem(listOfNames.get(i)); } - // everything went ok - setAlertBlock("", AlertType.ERROR, false); - continueButton.setEnabled(true); - resetButton.setEnabled(true); + + // set the url of the license, if any + showLicenseUrl(); + + // try to retrieve the licenses + setAlertBlock("Retrieving groups, please wait...", AlertType.INFO, true); + + // request groups + ckanServices.getUserGroups(orgName, new AsyncCallback>() { + + @Override + public void onSuccess(List groups) { + if(groups == null){ + setAlertBlock("Error while retrieving groups", AlertType.ERROR, true); + }else{ + if(groups.isEmpty()){ + groupsControlGroup.setVisible(false); + } + else{ + + // add groups + for (GroupBean group : groups) { + groupsListbox.addItem(group.getGroupTitle(), group.getGroupName()); + } + hideGroupsAlreadyInProfile(profiles); + } + // everything went ok + setAlertBlock("", AlertType.ERROR, false); + continueButton.setEnabled(true); + resetButton.setEnabled(true); + } + } + + @Override + public void onFailure(Throwable caught) { + setAlertBlock("Error while retrieving groups, try later", AlertType.ERROR, true); + } + }); + + }else{ + setAlertBlock("Error while retrieving licenses, try later", AlertType.ERROR, true); } } - - @Override - public void onFailure(Throwable caught) { - setAlertBlock("Error while retrieving groups, try later", AlertType.ERROR, true); - } }); - - }else{ - setAlertBlock("Error while retrieving licenses, try later", AlertType.ERROR, true); } } }); } } }); + + }else{ + setAlertBlock(MISSING_PUBLISH_RIGHTS, AlertType.ERROR, true); } + + } + + @Override + public void onFailure(Throwable caught) { + setAlertBlock(MISSING_PUBLISH_RIGHTS, AlertType.ERROR, true); } }); + + } @@ -1094,6 +1122,17 @@ public class CreateDatasetForm extends Composite{ focusPanelTitle, popupOpenedIds ); + + // description + InfoIconsLabels.preparePopupPanelAndPopover( + InfoIconsLabels.DESCRIPTION_INFO_ID_POPUP, + InfoIconsLabels.DESCRIPTION_INFO_TEXT, + InfoIconsLabels.DESCRIPTION_INFO_CAPTION, + infoIconDescription, + popoverDescription, + focusPanelDescription, + popupOpenedIds + ); // groups InfoIconsLabels.preparePopupPanelAndPopover( @@ -1194,6 +1233,7 @@ public class CreateDatasetForm extends Composite{ versionControlGroup.setType(ControlGroupType.NONE); metadataProfilesControlGroup.setType(ControlGroupType.NONE); organizationsGroup.setType(ControlGroupType.NONE); + tagsPanel.setGroupPanelType(ControlGroupType.NONE); String title = titleTextBox.getText().trim(); if(title.isEmpty()){ @@ -1239,6 +1279,12 @@ public class CreateDatasetForm extends Composite{ organizationsGroup.setType(ControlGroupType.ERROR); return "You must select an organization in which you want to publish"; } + + // at least one tag.. + if(tagsPanel.getTags().isEmpty()){ + tagsPanel.setGroupPanelType(ControlGroupType.ERROR); + return "Please add at least one meaningful tag for the product"; + } return null; } diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.ui.xml b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.ui.xml index c093afb..bcb7a47 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.ui.xml +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/CreateDatasetForm.ui.xml @@ -89,6 +89,14 @@ + + + + + + + @@ -263,11 +271,14 @@ - + Product Groups: - + - + Tags: diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java index 1fec732..d2a4344 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/client/ui/utils/InfoIconsLabels.java @@ -78,14 +78,21 @@ public class InfoIconsLabels { // TITLE public static final String TITLE_INFO_ID_POPUP = "title-popup-panel-info"; - public static final String TITLE_INFO_TEXT = "Product Title must contain only alphanumer characters, dots, underscore or hyphen minus. No others symbols are allowed."; + public static final String TITLE_INFO_TEXT = "Product Title must contain only alphanumer characters, dots, underscore or hyphen minus. No others symbols are allowed. Please note that this field will be always visible, despite the product's visibility."; public static final String TITLE_INFO_CAPTION = "Product Title"; + // DESCRIPTION + public static final String DESCRIPTION_INFO_ID_POPUP = "description-popup-panel-info"; + public static final String DESCRIPTION_INFO_TEXT = "Description of a few sentences, written in plain language. Should provide a sufficiently comprehensive overview of the resource for anyone, " + + "to understand its content, origins, and any continuing work on it. The description can be written at the end, since it summarizes key, information from the other metadata fields. Please note that this field will be always visible, despite the product's visibility."; + public static final String DESCRIPTION_INFO_CAPTION = null; + // GROUPS public static final String GROUPS_INFO_ID_POPUP = "groups-popup-panel-info"; public static final String GROUPS_INFO_TEXT = "Associate this product to groups. A group is a view of products belonging to one or more organization."; public static final String GROUPS_INFO_CAPTION = "Product Groups"; + /** * Prepare the popover and the gcube popup panel for information. * @param text diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java index 91b42da..36a50c2 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/CKANPublisherServicesImpl.java @@ -10,11 +10,12 @@ import java.util.concurrent.ConcurrentHashMap; import javax.servlet.http.HttpSession; -import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; -import org.gcube.datacatalogue.ckanutillibrary.DataCatalogueFactory; -import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean; -import org.gcube.datacatalogue.ckanutillibrary.utils.SessionCatalogueAttributes; -import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods; +import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; +import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogueFactory; +import org.gcube.datacatalogue.ckanutillibrary.server.models.ResourceBean; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.SessionCatalogueAttributes; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods; +import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; import org.gcube.portlets.widgets.ckandatapublisherwidget.client.CKanPublisherService; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads.AssociationToGroupAndNotifyThread; import org.gcube.portlets.widgets.ckandatapublisherwidget.server.threads.WritePostCatalogueManagerThread; @@ -26,9 +27,11 @@ import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.LicensesBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.MetaDataProfileBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.OrganizationBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; +import org.gcube.vomanagement.usermanagement.GroupManager; import org.gcube.vomanagement.usermanagement.UserManager; import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException; +import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager; import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeUser; @@ -76,7 +79,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } /** - * Retrieve the list of organizations in which the user can publish (roles ADMIN) + * Retrieve the list of organizations in which the user can publish (roles ADMIN/EDITOR) * @param username * @return the list of organizations * @throws GroupRetrievalFault @@ -95,7 +98,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C logger.info("List of organizations was into session " + orgsName); } else{ - orgsName = Utils.getUserOrganizationsListAdminEditor(scope, username, Utils.getGroupFromScope(scope).getGroupName(), this); + Utils.getHighestRole(scope, username, Utils.getGroupFromScope(scope).getGroupName(), this, orgsName); httpSession.setAttribute(keyPerScope, orgsName); logger.info("Organizations name for user " + username + " has been saved into session " + orgsName); } @@ -429,7 +432,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C return true; // it's an error somehow try{ String scope = Utils.getScopeFromClientUrl(getThreadLocalRequest()); - String idFromTitle = org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods.fromProductTitleToName(title); + String idFromTitle = UtilMethods.fromProductTitleToName(title); return getCatalogue(scope).existProductWithNameOrId(idFromTitle); }catch(Exception e){ logger.error("Unable to check if such a dataset id already exists", e); @@ -464,47 +467,6 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C return toReturn; } - // @Override - // public ResourceElementBean getTreeFolder(String folderId) { - // - // if(folderId == null || folderId.isEmpty()){ - // logger.warn("Empty folder id or null, returning"); - // return null; - // } - // ASLSession session = getASLSession(); - // try{ - // if(!isWithinPortal()){ - // logger.warn("Running outside the portal"); - // Workspace ws = getFakeWS(); - // ResourceElementBean toReturn = WorkspaceUtils.getTreeFromFolder(folderId, ws); - // logger.debug("Returning " + toReturn); - // return toReturn; - // }else{ - // if(session.getUsername().equals(TEST_USER)){ - // return null; - // }else{ - // // TODO - // return null; - // } - // } - // }catch(Exception e){ - // logger.error("Failed to build the tree", e); - // } - // return null; - // } - // - // /** - // * Retrieve the workspace for the development user - // * @return - // * @throws Exception - // */ - // private Workspace getFakeWS() throws Exception{ - // return HomeLibrary - // .getHomeManagerFactory() - // .getHomeManager() - // .getHome(getDevelopmentUser()).getWorkspace(); - // } - @Override public List getUserGroups(String orgName) { @@ -513,7 +475,7 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C if(isWithinPortal()){ String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername(); - logger.debug("Request for user " + username + " groups"); + logger.debug("Request for user " + username + " groups. Organization name is " + orgName); // get http session HttpSession httpSession = getThreadLocalRequest().getSession(); @@ -548,4 +510,74 @@ public class CKANPublisherServicesImpl extends RemoteServiceServlet implements C } return toReturn; } + + + @Override + public boolean isPublisherUser(boolean isWorkspaceRequest) { + + String username = Utils.getCurrentUser(getThreadLocalRequest()).getUsername(); + logger.info("Checking if the user " + username + " can publish or not"); + + try{ + + HttpSession httpSession = this.getThreadLocalRequest().getSession(); + + if(!isWithinPortal()){ + logger.warn("OUT FROM PORTAL DETECTED RETURNING TRUE"); + return false; + } + + // retrieve scope per current portlet url + String scopePerCurrentUrl = Utils.getScopeFromClientUrl(getThreadLocalRequest()); + + // get key per scope + String keyPerScopeRole = UtilMethods.concatenateSessionKeyScope(SessionCatalogueAttributes.CKAN_HIGHEST_ROLE, scopePerCurrentUrl); + String keyPerScopeOrganizations = UtilMethods.concatenateSessionKeyScope(SessionCatalogueAttributes.CKAN_ORGANIZATIONS_PUBLISH_KEY, scopePerCurrentUrl); + String keyPerScopeGroups = UtilMethods.concatenateSessionKeyScope(SessionCatalogueAttributes.CKAN_GROUPS_MEMBER, scopePerCurrentUrl); + + // check if this information was already into session(true means the user has at least in one org + // the role editor), false that he is just a member so he cannot publish + RolesCkanGroupOrOrg role = (RolesCkanGroupOrOrg) httpSession.getAttribute(keyPerScopeRole); + + // if the attribute was already set.. + if(role != null) + return !role.equals(RolesCkanGroupOrOrg.MEMBER); + else{ + + try{ + + GroupManager gm = new LiferayGroupManager(); + String groupName = gm.getGroup(gm.getGroupIdFromInfrastructureScope(scopePerCurrentUrl)).getGroupName(); + + // we build up also a list that keeps track of the scopes (orgs) in which the user has role ADMIN/EDITOR + List orgsInWhichAtLeastEditorRole = new ArrayList(); + role = Utils.getHighestRole(scopePerCurrentUrl, username, groupName, this, orgsInWhichAtLeastEditorRole); + + // if he is an admin/editor preload: + // 1) organizations in which he can publish (the widget will find these info in session) + if(!role.equals(RolesCkanGroupOrOrg.MEMBER)){ + httpSession.setAttribute(keyPerScopeOrganizations, orgsInWhichAtLeastEditorRole); + String orgName = scopePerCurrentUrl.split("/")[scopePerCurrentUrl.split("/").length - 1]; + httpSession.setAttribute(keyPerScopeGroups, getUserGroups(orgName)); + } + }catch(Exception e){ + logger.error("Unable to retrieve the role information for this user. Returning FALSE", e); + return false; + } + } + + // set role in session for this scope + httpSession.setAttribute(keyPerScopeRole, role); + + logger.info("Does the user have the right to publish on the catalogue? " + role); + return !role.equals(RolesCkanGroupOrOrg.MEMBER); + + }catch(Exception e){ + logger.error("Failed to check the user's role", e); + } + + // return false + return false; + } + } \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/AssociationToGroupAndNotifyThread.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/AssociationToGroupAndNotifyThread.java index b422b26..34ef2c1 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/AssociationToGroupAndNotifyThread.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/threads/AssociationToGroupAndNotifyThread.java @@ -8,9 +8,9 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.gcube.common.portal.mailing.EmailNotification; -import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; -import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg; -import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods; +import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods; +import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.GroupBean; import org.gcube.vomanagement.usermanagement.UserManager; import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/ServiceEndPointReaderSocial.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/ServiceEndPointReaderSocial.java index 98e13ec..efc13f3 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/ServiceEndPointReaderSocial.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/ServiceEndPointReaderSocial.java @@ -66,18 +66,12 @@ public class ServiceEndPointReaderSocial { } }catch(Exception e){ - logger.error("Unable to retrieve such service endpoint information!", e); - }finally{ - if(oldContext != null && !oldContext.equals(context)) ScopeProvider.instance.set(oldContext); - } - logger.info("Found base path " + basePath + " for the service"); - } /** diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/Utils.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/Utils.java index acd7521..8203584 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/Utils.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/Utils.java @@ -18,11 +18,11 @@ import org.gcube.common.homelibrary.home.workspace.WorkspaceItem; import org.gcube.common.homelibrary.home.workspace.folder.items.GCubeItem; import org.gcube.common.portal.PortalContext; import org.gcube.common.scope.api.ScopeProvider; -import org.gcube.datacatalogue.ckanutillibrary.ApplicationProfileScopePerUrlReader; -import org.gcube.datacatalogue.ckanutillibrary.DataCatalogue; -import org.gcube.datacatalogue.ckanutillibrary.models.RolesCkanGroupOrOrg; -import org.gcube.datacatalogue.ckanutillibrary.utils.SessionCatalogueAttributes; -import org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods; +import org.gcube.datacatalogue.ckanutillibrary.server.ApplicationProfileScopePerUrlReader; +import org.gcube.datacatalogue.ckanutillibrary.server.DataCatalogue; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.SessionCatalogueAttributes; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods; +import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; import org.gcube.datacatalogue.metadatadiscovery.DataCalogueMetadataFormatReader; import org.gcube.datacatalogue.metadatadiscovery.bean.MetadataType; import org.gcube.datacatalogue.metadatadiscovery.bean.jaxb.MetadataField; @@ -101,17 +101,20 @@ public class Utils { } return null; } - + /** - * Retrieve the list of organizations in which the user has the admin/editor role + * Retrieve the highest ckan role the user has and also retrieve the list of organizations (scopes) in which the user has the ckan-admin or ckan-editor role * @param currentScope the current scope * @param username the current username * @param groupName the current groupName - * @param ckanPublisherServicesImpl + * @param gcubeCkanDataCatalogServiceImpl + * @param orgsInWhichAdminRole + * @param ckanUtils ckanUtils */ - public static List getUserOrganizationsListAdminEditor(String currentScope, String username, String groupName, CKANPublisherServicesImpl ckanPublisherServicesImpl){ + public static RolesCkanGroupOrOrg getHighestRole(String currentScope, String username, String groupName, CKANPublisherServicesImpl gcubeCkanDataCatalogServiceImpl, List orgsInWhichAtLeastEditorRole){ - List toReturn = new ArrayList(); + // base role as default value + RolesCkanGroupOrOrg toReturn = RolesCkanGroupOrOrg.MEMBER; try{ @@ -127,36 +130,45 @@ public class Utils { logger.debug("Group id is " + currentGroupId + " and scope is " + currentScope); - // retrieve the flat list of organizations + // retrieve the flat list of organizations for the current user List groups = groupManager.listGroupsByUser(userid); // root (so check into the root, the VOs and the VRES) if(groupManager.isRootVO(currentGroupId)){ - logger.debug("The list of organizations of the user " + username + " is " + groups); + logger.info("The current scope is the Root Vo, so the list of organizations of the user " + username + " is " + groups); for (GCubeGroup gCubeGroup : groups) { - // get the name of this vre + // get the name of this group String gCubeGroupName = gCubeGroup.getGroupName(); - // get the role of the users in this vre + // get the role of the users in this group List roles = roleManager.listRolesByUserAndGroup(userid, groupManager.getGroupId(gCubeGroupName)); - // get highest role according liferay + // get highest role RolesCkanGroupOrOrg correspondentRoleToCheck = getLiferayHighestRoleInOrg(roles); - // this is a tricky part... because we actually do not know if it is a member or there is no ckan instance there - if(correspondentRoleToCheck.equals(RolesCkanGroupOrOrg.MEMBER)) - continue; + // be sure it is so + checkIfRoleIsSetInCkanInstance(username, gCubeGroupName, gCubeGroup.getGroupId(), + correspondentRoleToCheck, groupManager, gcubeCkanDataCatalogServiceImpl, orgsInWhichAtLeastEditorRole); + + if(toReturn.equals(RolesCkanGroupOrOrg.ADMIN)) + continue; + else if(toReturn.equals(RolesCkanGroupOrOrg.EDITOR) && correspondentRoleToCheck.equals(RolesCkanGroupOrOrg.ADMIN)) + toReturn = RolesCkanGroupOrOrg.ADMIN; + else // it was MEMBER + toReturn = correspondentRoleToCheck; - checkIfRoleIsSetInCkanInstance(username, gCubeGroupName, gCubeGroup.getGroupId(), correspondentRoleToCheck, toReturn, groupManager, ckanPublisherServicesImpl); } }else if(groupManager.isVO(currentGroupId)){ + logger.debug("The list of organizations of the user " + username + " to scan is the one under the VO " + groupName); + for (GCubeGroup gCubeGroup : groups) { + // if the gCubeGroup is not under the VO or it is not the VO continue if(currentGroupId != gCubeGroup.getParentGroupId() || currentGroupId != gCubeGroup.getGroupId()) continue; @@ -164,31 +176,43 @@ public class Utils { List roles = roleManager.listRolesByUserAndGroup(userid, groupManager.getGroupId(gCubeGroupName)); - // get highest role according liferay - RolesCkanGroupOrOrg correspondentRoleToCheck = getLiferayHighestRoleInOrg(roles); + // get highest role + RolesCkanGroupOrOrg correspondentRoleToCheck = getLiferayHighestRoleInOrg(roles); - // this is a tricky part... because we actually do not know if it is a member or there is no ckan instance there - if(correspondentRoleToCheck.equals(RolesCkanGroupOrOrg.MEMBER)) + // be sure it is so + checkIfRoleIsSetInCkanInstance(username, gCubeGroupName, gCubeGroup.getGroupId(), + correspondentRoleToCheck, groupManager, gcubeCkanDataCatalogServiceImpl, orgsInWhichAtLeastEditorRole); + + if(toReturn.equals(RolesCkanGroupOrOrg.ADMIN)) continue; - - checkIfRoleIsSetInCkanInstance(username, gCubeGroupName, gCubeGroup.getGroupId(), correspondentRoleToCheck, toReturn, groupManager, ckanPublisherServicesImpl); + else if(toReturn.equals(RolesCkanGroupOrOrg.EDITOR) && correspondentRoleToCheck.equals(RolesCkanGroupOrOrg.ADMIN)) + toReturn = RolesCkanGroupOrOrg.ADMIN; + else + toReturn = correspondentRoleToCheck; } - }else if(groupManager.isVRE(currentGroupId)){ // vre + }else if(groupManager.isVRE(currentGroupId)){ List roles = roleManager.listRolesByUserAndGroup(userManager.getUserId(username), groupManager.getGroupId(groupName)); - logger.debug("The list of roles for " + username + " into " + groupName + " is " + roles); + logger.debug("The current scope is the vre " + groupName); - // get highest role according liferay - RolesCkanGroupOrOrg correspondentRoleToCheck = getLiferayHighestRoleInOrg(roles); + // get highest role + RolesCkanGroupOrOrg correspondentRoleToCheck = getLiferayHighestRoleInOrg(roles); + + // be sure it is so + checkIfRoleIsSetInCkanInstance(username, groupName, currentGroupId, + correspondentRoleToCheck, groupManager, gcubeCkanDataCatalogServiceImpl, orgsInWhichAtLeastEditorRole); + + toReturn = correspondentRoleToCheck; - checkIfRoleIsSetInCkanInstance(username, groupName, currentGroupId, correspondentRoleToCheck, toReturn, groupManager, ckanPublisherServicesImpl); } }catch(Exception e){ logger.error("Unable to retrieve the role information for this user. Returning member role", e); + return RolesCkanGroupOrOrg.MEMBER; } - logger.info("Retrieved orgs in which the user has admin roles " + toReturn); + // return the role + logger.debug("Returning role " + toReturn + " for user " + username); return toReturn; } @@ -207,7 +231,7 @@ public class Utils { private static void checkIfRoleIsSetInCkanInstance(String username, String gCubeGroupName, long groupId, RolesCkanGroupOrOrg correspondentRoleToCheck, - List orgs, GroupManager groupManager, CKANPublisherServicesImpl ckanPublisherServicesImpl) throws UserManagementSystemException, GroupRetrievalFault { + GroupManager groupManager, CKANPublisherServicesImpl ckanPublisherServicesImpl, List orgs) throws UserManagementSystemException, GroupRetrievalFault { // with this invocation, we check if the role is present in ckan and if it is not it will be added DataCatalogue catalogue = ckanPublisherServicesImpl.getCatalogue(groupManager.getInfrastructureScope(groupId)); @@ -599,4 +623,5 @@ public class Utils { return gm.getGroup(groupId); } + } \ No newline at end of file diff --git a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/WorkspaceUtils.java b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/WorkspaceUtils.java index d6de0eb..8201013 100644 --- a/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/WorkspaceUtils.java +++ b/src/main/java/org/gcube/portlets/widgets/ckandatapublisherwidget/server/utils/WorkspaceUtils.java @@ -15,7 +15,8 @@ import org.gcube.common.homelibrary.home.workspace.WorkspaceFolder; import org.gcube.common.homelibrary.home.workspace.WorkspaceItem; import org.gcube.common.homelibrary.home.workspace.catalogue.WorkspaceCatalogue; import org.gcube.common.homelibrary.home.workspace.folder.FolderItem; -import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean; +import org.gcube.datacatalogue.ckanutillibrary.server.models.ResourceBean; +import org.gcube.datacatalogue.ckanutillibrary.server.utils.UtilMethods; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.DatasetMetadataBean; import org.gcube.portlets.widgets.ckandatapublisherwidget.shared.ResourceElementBean; @@ -62,7 +63,7 @@ public class WorkspaceUtils { // change name of the copied folder to match the title (append the timestamp to avoid ties) long referenceTime = System.currentTimeMillis(); - ((WorkspaceFolder)copiedFolder).rename(org.gcube.datacatalogue.ckanutillibrary.utils.UtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime); + ((WorkspaceFolder)copiedFolder).rename(UtilMethods.fromProductTitleToName(bean.getTitle()) + "_" + referenceTime); // copy only the selected ones for(ResourceElementBean resource : resourcesToAdd){ diff --git a/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml b/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml index a334571..8536846 100644 --- a/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml +++ b/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/CKanMetadataPublisher.gwt.xml @@ -10,7 +10,7 @@ - + diff --git a/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/client/Messages_fr.properties b/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/client/Messages_fr.properties deleted file mode 100644 index b4a7627..0000000 --- a/src/main/resources/org/gcube/portlets/widgets/ckandatapublisherwidget/client/Messages_fr.properties +++ /dev/null @@ -1,2 +0,0 @@ -sendButton = Envoyer -nameField = Entrez votre nom \ No newline at end of file