Compare commits

...

13 Commits

12 changed files with 256 additions and 105 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/gcube-ckan-datacatalog-2.3.0-SNAPSHOT/WEB-INF/classes" path="src/main/java">
<classpathentry kind="src" output="target/gcube-ckan-datacatalog-2.3.1/WEB-INF/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
@ -30,10 +30,10 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/gcube-ckan-datacatalog-2.3.0-SNAPSHOT/WEB-INF/classes" path="src/main/resources">
<classpathentry excluding="**" kind="src" output="target/gcube-ckan-datacatalog-2.3.1/WEB-INF/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/gcube-ckan-datacatalog-2.3.0-SNAPSHOT/WEB-INF/classes"/>
<classpathentry kind="output" path="target/gcube-ckan-datacatalog-2.3.1/WEB-INF/classes"/>
</classpath>

View File

@ -1,6 +1,5 @@
>>>>>>>=refs/heads/task_20699
eclipse.preferences.version=1
jarsExcludedFromWebInfLib=
lastWarOutDir=/home/francescomangiacrapa/git/gcube-ckan-datacatalog/target/gcube-ckan-datacatalog-2.3.0-SNAPSHOT
lastWarOutDir=/home/francescomangiacrapa/git/gcube-ckan-datacatalog/target/gcube-ckan-datacatalog-2.3.1
warSrcDir=src/main/webapp
warSrcDirIsOutput=false

View File

@ -74,7 +74,29 @@
<wb-module deploy-name="gcube-ckan-datacatalog-2.3.0-SNAPSHOT">
<wb-module deploy-name="gcube-ckan-datacatalog-2.3.1">
@ -205,6 +227,17 @@
@ -281,6 +314,17 @@
@ -306,7 +350,32 @@
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<dependent-module archiveName="metadata-profile-form-builder-widget-2.1.1.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/metadata-profile-form-builder-widget/metadata-profile-form-builder-widget">
<dependency-type>uses</dependency-type>
</dependent-module>
@ -437,6 +506,17 @@
@ -513,6 +593,17 @@
@ -589,6 +680,17 @@

View File

@ -4,6 +4,10 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v2.3.1] - 2024-05-14
- Included `ckan-metadata-publisher-widget` with bug fix [#27455] and new feature [#27467]
## [v2.3.0] - 2024-02-02
- Supported the Edit facility [#26639]

View File

@ -1,6 +1,6 @@
# gCube D4Science Data Catalog
The "gCube Data Catalogue" or "Catalogue" is a system that provides facilities for: a) (meta)data publishing and management based on roles; b) vres' products publishing; c) making data products publicly available; d) enriching products of metadata to maximise their potential reuse and making them searchable (via title, tags etc) are based on the CKAN technology. The Catalogue application allows to show all the metadata available in the CKAN instance, as well as publish a new product, retrieve the list of organizations (i.e. Virtual Research Environments) to which the user belongs and his/her already published products. Moreover, the "Catalgoue" application (via configuration) provides moderation of its content enabling the user/s with the Moderator role to approve/reject the products under review.
The "gCube Data Catalogue" or "Catalogue" is a system that provides facilities for: a) (meta)data publishing and management based on roles; b) vres' products publishing; c) making data products publicly available; d) enriching products of metadata to maximise their potential reuse and making them searchable (via title, tags etc) are based on the CKAN technology. The Catalogue application allows to show all the metadata available in the CKAN instance, as well as publish a new product, retrieve the list of organizations (i.e. Virtual Research Environments) to which the user belongs and his/her already published products. Moreover, the "Catalogue" application (via configuration) provides moderation of its content enabling the user/s with the Moderator role to approve/reject the products under review.
## Built With

View File

@ -14,7 +14,7 @@
<groupId>org.gcube.portlets.gcubeckan</groupId>
<artifactId>gcube-ckan-datacatalog</artifactId>
<packaging>war</packaging>
<version>2.3.0</version>
<version>2.3.1</version>
<name>gCube CKAN Data Catalog</name>
<description>The gCube CKAN Data Catalog portlet</description>

View File

@ -27,6 +27,8 @@ public class GCubeCkanDataCatalog implements EntryPoint {
public static final String REVERT_QUERY_PARAM = "manage";
public static final String GCUBE_CKAN_IFRAME = "gcube-ckan-iframe";
//public static final String LOGGED_IN_DIV = "logged_in";
/**
* This is the entry point method.
*/
@ -37,4 +39,7 @@ public class GCubeCkanDataCatalog implements EntryPoint {
eventManager.setPanel(panel);
}
}

View File

@ -199,6 +199,7 @@ public class GCubeCkanDataCatalogPanel extends BaseViewTemplate {
managementPanel.visibilityEditItemButton(true);
managementPanel.visibilityDeleteItemButton(true);
managementPanel.enablePublishItemButton(true);
//RootPanel.get(GCubeCkanDataCatalog.LOGGED_IN_DIV).add(new HTML("Logged in as "+RolesCkanGroupOrOrg.ADMIN));
break;
}
case EDITOR: {
@ -206,6 +207,7 @@ public class GCubeCkanDataCatalogPanel extends BaseViewTemplate {
managementPanel.visibilityEditItemButton(true);
managementPanel.visibilityDeleteItemButton(true);
managementPanel.enablePublishItemButton(true);
//RootPanel.get(GCubeCkanDataCatalog.LOGGED_IN_DIV).add(new HTML("Logged in as "+RolesCkanGroupOrOrg.EDITOR));
break;
}
case MEMBER: {
@ -215,6 +217,7 @@ public class GCubeCkanDataCatalogPanel extends BaseViewTemplate {
// not the rights to publish
managementPanel.visibilityPublishItemButton(true, true);
managementPanel.enablePublishItemButton(false);
//RootPanel.get(GCubeCkanDataCatalog.LOGGED_IN_DIV).add(new HTML("Logged in as "+RolesCkanGroupOrOrg.MEMBER));
break;
}
default: {

View File

@ -6,6 +6,7 @@ package org.gcube.portlets.gcubeckan.gcubeckandatacatalog.server;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpSession;
@ -31,32 +32,30 @@ import org.gcube.vomanagement.usermanagement.model.GatewayRolesNames;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
/**
* The Class UserUtil.
*
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
* @author Costantino Perciante costantino.perciante@isti.cnr.it
* Jun 21, 2016
* @author Costantino Perciante costantino.perciante@isti.cnr.it Jun 21, 2016
*/
public class UserUtil {
//private static Logger LOG = LoggerFactory.getLogger(UserUtil.class);
// private static Logger LOG = LoggerFactory.getLogger(UserUtil.class);
private static final Log logger = LogFactoryUtil.getLog(UserUtil.class);
private static final String ADD_USER_TO_OTHER_ORG_KEY = "ADD_USER_TO_OTHER_ORG_KEY";
/**
* Gets the list vre for user and the role the user has in them.
* retrieve the groups to whom a given user belongs (given the user EMail)
* Gets the list vre for user and the role the user has in them. retrieve the
* groups to whom a given user belongs (given the user EMail)
*
* @param userEMail the user e mail
* @param httpSession
* @param pathVre
* @return the list vre for user
*/
public static Map<String, String> getVreRoleForUser(String userEMail, String context, DataCatalogue instance, boolean isViewPerVREEnabled,
HttpSession httpSession){
public static Map<String, String> getVreRoleForUser(String userEMail, String context, DataCatalogue instance,
boolean isViewPerVREEnabled, HttpSession httpSession) {
GroupManager groupManager = new LiferayGroupManager();
UserManager userManager = new LiferayUserManager();
@ -66,45 +65,40 @@ public class UserUtil {
try {
user = userManager.getUserByEmail(userEMail);
// filter according the current context: if it is a VO/VRE, we send all the VRES under the VO. If it is the root vo, we send all user's vres.
// filter according the current context: if it is a VO/VRE, we send all the VRES
// under the VO. If it is the root vo, we send all user's vres.
long groupIdContext = groupManager.getGroupIdFromInfrastructureScope(context);
GCubeGroup currentVRE = groupManager.getGroup(groupIdContext);
String localRoleInThisVre = RolesCkanGroupOrOrg.convertToCkanCapacity(getLiferayHighestRoleInOrg(roleManager.listRolesByUserAndGroup(user.getUserId(), currentVRE.getGroupId())));
String localRoleInThisVre = RolesCkanGroupOrOrg.convertToCkanCapacity(getLiferayHighestRoleInOrg(
roleManager.listRolesByUserAndGroup(user.getUserId(), currentVRE.getGroupId())));
// ckan-connector will do it
mapRoleByGroupSingleVre.put(currentVRE.getGroupName().toLowerCase(),
localRoleInThisVre);
mapRoleByGroupSingleVre.put(currentVRE.getGroupName().toLowerCase(), localRoleInThisVre);
// perform further checks
if(!isViewPerVREEnabled){
if (!isViewPerVREEnabled) {
String keyPerScope = context + ADD_USER_TO_OTHER_ORG_KEY;
Boolean alreadyAdded = (Boolean)httpSession.getAttribute(keyPerScope);
Boolean alreadyAdded = (Boolean) httpSession.getAttribute(keyPerScope);
if(alreadyAdded == null || !alreadyAdded){
new AddUserToOrganizationThread(
instance,
user,
groupManager.listGroupsByUser(user.getUserId()),
isViewPerVREEnabled,
groupIdContext,
roleManager,
groupManager,
localRoleInThisVre).
start();
if (alreadyAdded == null || !alreadyAdded) {
new AddUserToOrganizationThread(instance, user, groupManager.listGroupsByUser(user.getUserId()),
isViewPerVREEnabled, groupIdContext, roleManager, groupManager, localRoleInThisVre).start();
httpSession.setAttribute(keyPerScope, true);
}
}
logger.debug("Returning Map to the ckan connector : " + mapRoleByGroupSingleVre);
return mapRoleByGroupSingleVre;
}catch (UserManagementSystemException | UserRetrievalFault | GroupRetrievalFault e) {
logger.error("An error occurred during get list of VREs for user: "+userEMail, e);
} catch (UserManagementSystemException | UserRetrievalFault | GroupRetrievalFault e) {
logger.error("An error occurred during get list of VREs for user: " + userEMail, e);
return null;
}
}
/**
* 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
* 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
@ -112,12 +106,14 @@ public class UserUtil {
* @param orgsInWhichAdminRole
* @param ckanUtils ckanUtils
*/
public static RolesCkanGroupOrOrg getHighestRole(String currentScope, String username, String groupName, GcubeCkanDataCatalogServiceImpl gcubeCkanDataCatalogServiceImpl, List<OrganizationBean> orgsInWhichAtLeastEditorRole){
public static RolesCkanGroupOrOrg getHighestRole(String currentScope, String username, String groupName,
GcubeCkanDataCatalogServiceImpl gcubeCkanDataCatalogServiceImpl,
List<OrganizationBean> orgsInWhichAtLeastEditorRole) {
// base role as default value
RolesCkanGroupOrOrg toReturn = RolesCkanGroupOrOrg.MEMBER;
try{
try {
UserManager userManager = new LiferayUserManager();
RoleManager roleManager = new LiferayRoleManager();
@ -135,58 +131,65 @@ public class UserUtil {
List<GCubeGroup> groups = groupManager.listGroupsByUser(userid);
// root (so check into the root, the VOs and the VRES)
if(groupManager.isRootVO(currentGroupId)){
if (groupManager.isRootVO(currentGroupId)) {
logger.info("The current scope is the Root Vo, so 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) {
if(!groupManager.isVRE(gCubeGroup.getGroupId()))
if (!groupManager.isVRE(gCubeGroup.getGroupId()))
continue;
// get the name of this group
String gCubeGroupName = gCubeGroup.getGroupName();
// get the role of the users in this group
List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(userid, groupManager.getGroupId(gCubeGroupName));
List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(userid,
groupManager.getGroupId(gCubeGroupName));
// get highest role
RolesCkanGroupOrOrg correspondentRoleToCheck = getLiferayHighestRoleInOrg(roles);
// be sure it is so
checkIfRoleIsSetInCkanInstance(username, gCubeGroupName, gCubeGroup.getGroupId(),
correspondentRoleToCheck, groupManager, gcubeCkanDataCatalogServiceImpl, orgsInWhichAtLeastEditorRole);
correspondentRoleToCheck, groupManager, gcubeCkanDataCatalogServiceImpl,
orgsInWhichAtLeastEditorRole);
toReturn = RolesCkanGroupOrOrg.getHigher(toReturn, correspondentRoleToCheck);
}
}else if(groupManager.isVO(currentGroupId)){
} else if (groupManager.isVO(currentGroupId)) {
logger.debug("The list of organizations of the user " + username + " to scan is the one under the VO " + groupName);
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())
if (currentGroupId != gCubeGroup.getParentGroupId() || currentGroupId != gCubeGroup.getGroupId())
continue;
String gCubeGroupName = gCubeGroup.getGroupName();
List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(userid, groupManager.getGroupId(gCubeGroupName));
List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(userid,
groupManager.getGroupId(gCubeGroupName));
// get highest role
RolesCkanGroupOrOrg correspondentRoleToCheck = getLiferayHighestRoleInOrg(roles);
// be sure it is so
checkIfRoleIsSetInCkanInstance(username, gCubeGroupName, gCubeGroup.getGroupId(),
correspondentRoleToCheck, groupManager, gcubeCkanDataCatalogServiceImpl, orgsInWhichAtLeastEditorRole);
correspondentRoleToCheck, groupManager, gcubeCkanDataCatalogServiceImpl,
orgsInWhichAtLeastEditorRole);
toReturn = RolesCkanGroupOrOrg.getHigher(toReturn, correspondentRoleToCheck);
}
}else if(groupManager.isVRE(currentGroupId)){
List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(userManager.getUserId(username), groupManager.getGroupId(groupName));
} else if (groupManager.isVRE(currentGroupId)) {
List<GCubeRole> roles = roleManager.listRolesByUserAndGroup(userManager.getUserId(username),
groupManager.getGroupId(groupName));
logger.debug("The current scope is the vre " + groupName);
@ -194,13 +197,13 @@ public class UserUtil {
RolesCkanGroupOrOrg correspondentRoleToCheck = getLiferayHighestRoleInOrg(roles);
// the ckan connector already did the job for us but we need name and title
checkIfRoleIsSetInCkanInstance(username, groupName, currentGroupId,
correspondentRoleToCheck, groupManager, gcubeCkanDataCatalogServiceImpl, orgsInWhichAtLeastEditorRole);
checkIfRoleIsSetInCkanInstance(username, groupName, currentGroupId, correspondentRoleToCheck,
groupManager, gcubeCkanDataCatalogServiceImpl, orgsInWhichAtLeastEditorRole);
toReturn = correspondentRoleToCheck;
}
}catch(Exception e){
} catch (Exception e) {
logger.error("Unable to retrieve the role information for this user. Returning member role", e);
return RolesCkanGroupOrOrg.MEMBER;
}
@ -211,7 +214,9 @@ public class UserUtil {
}
/**
* Check if the role admin/editor is set or must be set into the ckan instance at this scope
* Check if the role admin/editor is set or must be set into the ckan instance
* at this scope
*
* @param username
* @param gCubeGroupName
* @param groupId
@ -222,47 +227,72 @@ public class UserUtil {
* @throws UserManagementSystemException
* @throws GroupRetrievalFault
*/
private static void checkIfRoleIsSetInCkanInstance(String username,
String gCubeGroupName, long groupId,
RolesCkanGroupOrOrg correspondentRoleToCheck,
GroupManager groupManager,
GcubeCkanDataCatalogServiceImpl gcubeCkanDataCatalogServiceImpl, List<OrganizationBean> orgsInWhichAtLeastEditorRole) throws UserManagementSystemException, GroupRetrievalFault {
private static void checkIfRoleIsSetInCkanInstance(String username, String gCubeGroupName, long groupId,
RolesCkanGroupOrOrg correspondentRoleToCheck, GroupManager groupManager,
GcubeCkanDataCatalogServiceImpl gcubeCkanDataCatalogServiceImpl,
List<OrganizationBean> orgsInWhichAtLeastEditorRole)
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 = gcubeCkanDataCatalogServiceImpl.getCatalogue(groupManager.getInfrastructureScope(groupId));
// with this invocation, we check if the role is present in ckan and if it is
// not it will be added
DataCatalogue catalogue = gcubeCkanDataCatalogServiceImpl
.getCatalogue(groupManager.getInfrastructureScope(groupId));
// if there is an instance of ckan in this scope..
if(catalogue != null){
if (catalogue != null) {
boolean res = catalogue.checkRoleIntoOrganization(username, gCubeGroupName, correspondentRoleToCheck);
if(res && !correspondentRoleToCheck.equals(RolesCkanGroupOrOrg.MEMBER)){
if (res && !correspondentRoleToCheck.equals(RolesCkanGroupOrOrg.MEMBER)) {
// get the orgs of the user and retrieve its title and name
CkanOrganization organization = catalogue.getOrganizationByName(gCubeGroupName.toLowerCase());
orgsInWhichAtLeastEditorRole.add(new OrganizationBean(organization.getTitle(), organization.getName(), true));
orgsInWhichAtLeastEditorRole
.add(new OrganizationBean(organization.getTitle(), organization.getName(), true));
}
}
else
logger.warn("It seems there is no ckan instance into scope " + groupManager.getInfrastructureScope(groupId));
} else
logger.warn(
"It seems there is no ckan instance into scope " + groupManager.getInfrastructureScope(groupId));
}
/**
* Retrieve the ckan role among a list of liferay roles
*
* @param roles
* @return MEMBER/EDITOR/ADMIN role
*/
public static RolesCkanGroupOrOrg getLiferayHighestRoleInOrg(
List<GCubeRole> roles) {
public static RolesCkanGroupOrOrg getLiferayHighestRoleInOrg(List<GCubeRole> roles) {
logger.info("getLiferayHighestRoleInOrg in: " + roles);
// NOTE: it is supposed that there is just one role for this person correspondent to the one in the catalog
for (GCubeRole gCubeRole : roles) {
if(gCubeRole.getRoleName().equalsIgnoreCase(GatewayRolesNames.CATALOGUE_ADMIN.getRoleName())){
return RolesCkanGroupOrOrg.ADMIN;
RolesCkanGroupOrOrg highestRoleFound = null;
if(roles==null || roles.isEmpty()) {
highestRoleFound = RolesCkanGroupOrOrg.MEMBER;
logger.info("getLiferayHighestRoleInOrg returns: " + highestRoleFound +", as default");
return highestRoleFound;
}
if(gCubeRole.getRoleName().equalsIgnoreCase(GatewayRolesNames.CATALOGUE_EDITOR.getRoleName())){
return RolesCkanGroupOrOrg.EDITOR;
List<GCubeRole> adminList = roles.stream()
.filter(a -> a.getRoleName().equalsIgnoreCase(GatewayRolesNames.CATALOGUE_ADMIN.getRoleName()))
.collect(Collectors.toList());
if (adminList.size() > 0) {
highestRoleFound = RolesCkanGroupOrOrg.ADMIN;
logger.info("getLiferayHighestRoleInOrg returns: " + highestRoleFound);
return highestRoleFound;
}
List<GCubeRole> editorList = roles.stream()
.filter(a -> a.getRoleName().equalsIgnoreCase(GatewayRolesNames.CATALOGUE_EDITOR.getRoleName()))
.collect(Collectors.toList());
if (editorList.size() > 0) {
highestRoleFound = RolesCkanGroupOrOrg.EDITOR;
logger.info("getLiferayHighestRoleInOrg returns: " + highestRoleFound);
return highestRoleFound;
}
return RolesCkanGroupOrOrg.MEMBER;
highestRoleFound = RolesCkanGroupOrOrg.MEMBER;
logger.info("getLiferayHighestRoleInOrg returns: " + highestRoleFound);
return highestRoleFound;
}
}

View File

@ -180,3 +180,10 @@ h1 {
padding: 10px 5px;
background-color: #FAFAFA;
}
.logged_in_label {
float: right;
margin-right: 20px;
font-size: 12px;
padding-top: 5px;
}

View File

@ -37,6 +37,7 @@
Your web browser must have JavaScript enabled in order for this
application to display correctly.</div>
</noscript>
<div id="logged_in" class="logged_in_label"></div>
<div id="gCubeCkanDataCatalog"></div>
</body>
</html>

View File

@ -32,5 +32,5 @@
<script type="text/javascript"
src='<%=request.getContextPath()%>/js/jquery.autosize.js'></script>
<div id="logged_in" class="logged_in_label"></div>
<div id="gCubeCkanDataCatalog"></div>