Skip to content

Commit

Permalink
EEA / Streamlining publication and groups
Browse files Browse the repository at this point in the history
  • Loading branch information
josegar74 committed Feb 27, 2024
1 parent fab399c commit acb5203
Show file tree
Hide file tree
Showing 4 changed files with 327 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (C) 2001-2024 Food and Agriculture Organization of the
* United Nations (FAO-UN), United Nations World Food Programme (WFP)
* and United Nations Environment Programme (UNEP)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
* Rome - Italy. email: [email protected]
*/

package org.fao.geonet.listener.metadata.publication;

import jeeves.server.context.ServiceContext;
import org.fao.geonet.constants.Geonet;
import org.fao.geonet.domain.Group;
import org.fao.geonet.events.md.MetadataPublished;
import org.fao.geonet.repository.GroupRepository;
import org.fao.geonet.utils.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

@Component
public class ChangeOwnershipPublishedRecord implements ApplicationListener<MetadataPublished> {
ChangeOwnershipService metadataPrivilegesService;

GroupRepository groupRepository;

@Value("${groupowner.unpublished}")
private String groupOwnerNameUnpublished;

@Value("${groupowner.published}")
private String groupOwnerNamePublished;

@Autowired
public ChangeOwnershipPublishedRecord(ChangeOwnershipService metadataPrivilegesService, GroupRepository groupRepository) {
this.metadataPrivilegesService = metadataPrivilegesService;
this.groupRepository = groupRepository;
}

@Override
public void onApplicationEvent(MetadataPublished event) {
// Implementation in doBeforeCommit before the transaction is committed
}

@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
public void doBeforeCommit(MetadataPublished event) {
try {
ServiceContext serviceContext = ServiceContext.get();

Group groupOwnerPublished = groupRepository.findByName(groupOwnerNamePublished);
if (groupOwnerPublished == null) {
Log.warning(Geonet.DATA_MANAGER,
String.format("Couldn't update the ownership of the metadata %s. Group %s doesn't exist", event.getMd().getUuid(), groupOwnerNamePublished));
return;
}

Group groupOwnerUnpublished = groupRepository.findByName(groupOwnerNameUnpublished);
if (groupOwnerUnpublished == null) {
Log.warning(Geonet.DATA_MANAGER,
String.format("Couldn't update the ownership of the metadata %s. Group %s doesn't exist", event.getMd().getUuid(), groupOwnerNameUnpublished));
return;
}

Integer groupOwnerPublishedId = groupOwnerPublished.getId();
Integer originGroupOwner = groupOwnerUnpublished.getId();

// Change the ownership from groupOwnerNameUnpublished to groupOwnerNamePublished
metadataPrivilegesService.changeMetadataGroupOwnership(serviceContext, event.getMd(), originGroupOwner, groupOwnerPublishedId);
} catch (Throwable e) {
Log.error(Geonet.DATA_MANAGER, "Couldn't update the ownership of the metadata " + event.getMd(), e);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright (C) 2001-2024 Food and Agriculture Organization of the
* United Nations (FAO-UN), United Nations World Food Programme (WFP)
* and United Nations Environment Programme (UNEP)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
* Rome - Italy. email: [email protected]
*/

package org.fao.geonet.listener.metadata.publication;

import com.google.common.base.Optional;
import jeeves.server.context.ServiceContext;
import org.fao.geonet.constants.Geonet;
import org.fao.geonet.domain.AbstractMetadata;
import org.fao.geonet.domain.OperationAllowed;
import org.fao.geonet.domain.OperationAllowedId;
import org.fao.geonet.kernel.datamanager.IMetadataIndexer;
import org.fao.geonet.kernel.datamanager.IMetadataManager;
import org.fao.geonet.kernel.datamanager.IMetadataOperations;
import org.fao.geonet.kernel.search.IndexingMode;
import org.fao.geonet.repository.OperationAllowedRepository;
import org.fao.geonet.utils.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static org.fao.geonet.repository.specification.OperationAllowedSpecs.hasGroupId;
import static org.fao.geonet.repository.specification.OperationAllowedSpecs.hasMetadataId;
import static org.springframework.data.jpa.domain.Specification.where;

@Service
public class ChangeOwnershipService {
OperationAllowedRepository operationAllowedRepository;

IMetadataManager metadataManager;

IMetadataOperations metadataOperations;

IMetadataIndexer metadataIndexer;

@Autowired
public ChangeOwnershipService(OperationAllowedRepository operationAllowedRepository,
IMetadataManager metadataManager, IMetadataOperations metadataOperations,
IMetadataIndexer metadataIndexer) {
this.operationAllowedRepository = operationAllowedRepository;
this.metadataManager = metadataManager;
this.metadataOperations = metadataOperations;
this.metadataIndexer = metadataIndexer;
}

/**
* Changes the metadata group ownership to a new group.
*
* @param serviceContext
* @param metadata
* @param newGroupOwnerId
* @throws Exception
*/
public void changeMetadataGroupOwnership(ServiceContext serviceContext,
AbstractMetadata metadata, Integer fromGroupOwnerId, Integer newGroupOwnerId) throws Exception {
Integer metadataId = metadata.getId();
Integer userOwnerId = metadata.getSourceInfo().getOwner();
Integer groupOwnerId = metadata.getSourceInfo().getGroupOwner();

// If the group owner is not the one expected, don't apply any changes
if (!Objects.equals(groupOwnerId, fromGroupOwnerId)) {
Log.warning(Geonet.DATA_MANAGER, String.format("Ignoring update the ownership of the metadata with uuid '%s'. Current group owner (%d) is not the expected one (%d)", metadata.getUuid(), groupOwnerId, fromGroupOwnerId));
return;
}

List<OperationAllowedId> metadataPrivilegesForOwner =
retrievePrivilegesForUserAndGroup(
String.valueOf(metadataId), userOwnerId, groupOwnerId);

for (OperationAllowedId priv : metadataPrivilegesForOwner) {
if (groupOwnerId != null) {
metadataOperations.unsetOperation(
serviceContext,
metadataId,
groupOwnerId,
priv.getOperationId());
}
metadataOperations.setOperation(serviceContext,
metadataId,
newGroupOwnerId,
priv.getOperationId());
}

metadataManager.updateMetadataOwner(metadataId, String.valueOf(userOwnerId), String.valueOf(newGroupOwnerId));

metadataIndexer.indexMetadata(String.valueOf(metadataId), true, IndexingMode.full);
}


private List<OperationAllowedId> retrievePrivilegesForUserAndGroup(String id, Integer userId, Integer groupId) {
int iMetadataId = Integer.parseInt(id);
Specification<OperationAllowed> spec =
where(hasMetadataId(iMetadataId));
if (groupId != null) {
spec = spec.and(hasGroupId(groupId));
}

List<OperationAllowed> operationsAllowed = operationAllowedRepository.findAllWithOwner(userId, Optional.of(spec));

List<OperationAllowedId> result = new ArrayList<>();
for (OperationAllowed operationAllowed : operationsAllowed) {
result.add(operationAllowed.getId());
}

return result;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (C) 2001-2024 Food and Agriculture Organization of the
* United Nations (FAO-UN), United Nations World Food Programme (WFP)
* and United Nations Environment Programme (UNEP)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
* Rome - Italy. email: [email protected]
*/

package org.fao.geonet.listener.metadata.publication;

import jeeves.server.context.ServiceContext;
import org.fao.geonet.constants.Geonet;
import org.fao.geonet.domain.Group;
import org.fao.geonet.events.md.MetadataUnpublished;
import org.fao.geonet.repository.GroupRepository;
import org.fao.geonet.utils.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

@Component
public class ChangeOwnershipUnpublishedRecord implements ApplicationListener<MetadataUnpublished> {
ChangeOwnershipService metadataPrivilegesService;

GroupRepository groupRepository;

@Value("${groupowner.unpublished}")
private String groupOwnerNameUnpublished;

@Value("${groupowner.published}")
private String groupOwnerNamePublished;

@Autowired
public ChangeOwnershipUnpublishedRecord(ChangeOwnershipService metadataPrivilegesService, GroupRepository groupRepository) {
this.metadataPrivilegesService = metadataPrivilegesService;
this.groupRepository = groupRepository;
}

@Override
public void onApplicationEvent(MetadataUnpublished event) {
// Implementation in doBeforeCommit before the transaction is committed
}

@TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT)
public void doBeforeCommit(MetadataUnpublished event) {
try {
ServiceContext serviceContext = ServiceContext.get();

Group groupOwnerUnpublished = groupRepository.findByName(groupOwnerNameUnpublished);
if (groupOwnerUnpublished == null) {
Log.warning(Geonet.DATA_MANAGER,
String.format("Couldn't update the ownership of the metadata %s. Group %s doesn't exist", event.getMd().getUuid(), groupOwnerNameUnpublished));
return;
}

Group groupOwnerPublished = groupRepository.findByName(groupOwnerNamePublished);
if (groupOwnerPublished == null) {
Log.warning(Geonet.DATA_MANAGER,
String.format("Couldn't update the ownership of the metadata %s. Group %s doesn't exist", event.getMd().getUuid(), groupOwnerNamePublished));
return;
}

Integer groupOwnerUnpublishedId = groupOwnerUnpublished.getId();
Integer originGroupOwner = groupOwnerPublished.getId();

// Change the ownership from groupOwnerNamePublished to groupOwnerNameUnpublished
metadataPrivilegesService.changeMetadataGroupOwnership(serviceContext, event.getMd(), originGroupOwner, groupOwnerUnpublishedId);
} catch (Throwable e) {
Log.error(Geonet.DATA_MANAGER, "Couldn't update the ownership of the metadata " + event.getMd(), e);
}

}
}
13 changes: 13 additions & 0 deletions web/src/main/webResources/WEB-INF/config.properties
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,16 @@ db.migration_onstartup=true
# Analytics service: (empty value: no analytics),matomo,google
analytics.web.service=matomo
analytics.web.jscode=var _paq = _paq || [];_paq.push(['trackPageView']);_paq.push(['enableLinkTracking']);(function() {var u="https://matomo.eea.europa.eu/";_paq.push(['setTrackerUrl', u+'piwik.php']);_paq.push(['setSiteId', '23']);var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);})();var currentUrl = location.href; window.addEventListener('hashchange', function() {_paq.push(['setReferrerUrl', currentUrl]);currentUrl = window.location.href;_paq.push(['setCustomUrl', currentUrl]);_paq.push(['setDocumentTitle', currentUrl]);_paq.push(['deleteCustomVariables', 'page']);_paq.push(['trackPageView']);var content = document.getElementsByTagName('body')[0];_paq.push(['MediaAnalytics::scanForMedia', content]);_paq.push(['FormAnalytics::scanForForms', content]);_paq.push(['trackContentImpressionsWithinNode', content]);_paq.push(['enableLinkTracking']);});

# Configuration of the group owner to set for published / unpublished metadata
# - When a metadata is published, if the group owner is SDI_DRAFT
# - Privileges are removed from SDI_DRAFT
# - Privileges are set to SDI_INTERNAL
# - Ownership is set to SDI_INTERNAL
# - When a metadata is unpublished, if the group owner is SDI_INTERNAL:
# - Privileges are removed from SDI_INTERNAL
# - Privileges are set to SDI_DRAFT
# - Ownership is set to SDI_DRAFT
# - If the metadata is not owned by one of these groups, no processing is done
groupowner.published=SDI_INTERNAL
groupowner.unpublished=SDI_DRAFT

0 comments on commit acb5203

Please sign in to comment.