Skip to content

Commit

Permalink
batch edit user profile check in APIs (geonetwork#7243)
Browse files Browse the repository at this point in the history
* batch edit user profile check in APIs

* protect search-and-replace API
  • Loading branch information
wangf1122 authored Sep 29, 2023
1 parent 7f3230b commit 1579d52
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ public class Settings {
public static final String METADATA_LINK_EXCLUDEPATTERN = "metadata/link/excludedUrlPattern";
public static final String METADATA_IMPORT_RESTRICT = "metadata/import/restrict";
public static final String METADATA_IMPORT_USERPROFILE = "metadata/import/userprofile";
public static final String METADATA_BATCH_EDITING_ACCESS_LEVEL = "metadata/batchediting/accesslevel";
public static final String METADATA_PUBLISHED_DELETE_USERPROFILE = "metadata/delete/profilePublishedMetadata";
public static final String METADATA_PUBLISH_USERPROFILE = "metadata/publication/profilePublishMetadata";
public static final String METADATA_UNPUBLISH_USERPROFILE = "metadata/publication/profileUnpublishMetadata";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,19 @@
import org.fao.geonet.ApplicationContextHolder;
import org.fao.geonet.api.ApiParams;
import org.fao.geonet.api.ApiUtils;
import org.fao.geonet.api.exception.NotAllowedException;
import org.fao.geonet.api.processing.report.MetadataReplacementProcessingReport;
import org.fao.geonet.api.processing.report.XsltMetadataProcessingReport;
import org.fao.geonet.domain.AbstractMetadata;
import org.fao.geonet.domain.Profile;
import org.fao.geonet.events.history.RecordProcessingChangeEvent;
import org.fao.geonet.kernel.DataManager;
import org.fao.geonet.kernel.MetadataIndexerProcessor;
import org.fao.geonet.kernel.SchemaManager;
import org.fao.geonet.kernel.datamanager.IMetadataUtils;
import org.fao.geonet.kernel.setting.SettingManager;
import org.fao.geonet.kernel.setting.Settings;
import org.fao.geonet.util.UserUtil;
import org.fao.geonet.utils.Diff;
import org.fao.geonet.utils.DiffType;
import org.fao.geonet.utils.Log;
Expand All @@ -56,6 +60,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
Expand Down Expand Up @@ -91,6 +96,9 @@ public class DatabaseProcessApi {
@Autowired
SettingManager settingManager;

@Autowired
RoleHierarchy roleHierarchy;

@io.swagger.v3.oas.annotations.Operation(
summary = "Preview of search and replace text.",
description =" When errors occur during processing, the processing report is returned in JSON format.")
Expand Down Expand Up @@ -175,14 +183,17 @@ public ResponseEntity<Object> previewProcessSearchAndReplace(
Element preview = new Element("preview");

try {
ServiceContext serviceContext = ApiUtils.createServiceContext(request);
checkUserProfileToBatchEditMetadata(serviceContext.getUserSession());

Set<String> records = ApiUtils.getUuidsParameterOrSelection(uuids, bucket, session);

final String siteURL = request.getRequestURL().toString() + "?" + request.getQueryString();
for (String uuid : records) {
String id = dataMan.getMetadataId(uuid);
Log.info("org.fao.geonet.services.metadata",
"Processing metadata for preview with id:" + id);
ServiceContext serviceContext = ApiUtils.createServiceContext(request);

Element record = DatabaseProcessUtils.process(
serviceContext,
id, useRegexp, search, replace, regexpFlags,
Expand Down Expand Up @@ -307,6 +318,8 @@ public XsltMetadataProcessingReport processSearchAndReplace(
new MetadataReplacementProcessingReport(search + "-" + replace);

try {
ServiceContext serviceContext = ApiUtils.createServiceContext(request);
checkUserProfileToBatchEditMetadata(serviceContext.getUserSession());
Set<String> records = ApiUtils.getUuidsParameterOrSelection(uuids, bucket, session);
UserSession userSession = ApiUtils.getUserSession(httpSession);

Expand All @@ -315,7 +328,7 @@ public XsltMetadataProcessingReport processSearchAndReplace(
processingReport.setTotalRecords(records.size());

BatchDatabaseUpdateMetadataReindexer m = new BatchDatabaseUpdateMetadataReindexer(
ApiUtils.createServiceContext(request),
serviceContext,
dataMan, records, useRegexp, search, replace, regexpFlags, httpSession, siteURL,
processingReport, request, index, updateDateStamp, userSession.getUserIdAsInt());
m.process(settingManager.getSiteId());
Expand Down Expand Up @@ -402,4 +415,22 @@ public void process(String catalogueId) throws Exception {
}
}
}

/**
* Checks if the user profile is allowed to batch edit metadata.
*
* @param userSession
*/
private void checkUserProfileToBatchEditMetadata(UserSession userSession) {
if (userSession.getProfile() != Profile.Administrator) {
String allowedUserProfileToImportMetadata =
StringUtils.defaultIfBlank(settingManager.getValue(Settings.METADATA_BATCH_EDITING_ACCESS_LEVEL), Profile.Editor.toString());

// Is the user profile is higher than the profile allowed to import metadata?
if (!UserUtil.hasHierarchyRole(allowedUserProfileToImportMetadata, this.roleHierarchy)) {
throw new NotAllowedException("The user has no permissions to batch edit metadata.");
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,20 @@
import org.fao.geonet.ApplicationContextHolder;
import org.fao.geonet.api.ApiParams;
import org.fao.geonet.api.ApiUtils;
import org.fao.geonet.api.exception.NotAllowedException;
import org.fao.geonet.api.processing.report.IProcessingReport;
import org.fao.geonet.api.processing.report.SimpleMetadataProcessingReport;
import org.fao.geonet.domain.AbstractMetadata;
import org.fao.geonet.domain.Pair;
import org.fao.geonet.domain.Profile;
import org.fao.geonet.events.history.RecordUpdatedEvent;
import org.fao.geonet.kernel.*;
import org.fao.geonet.kernel.datamanager.IMetadataUtils;
import org.fao.geonet.kernel.schema.MetadataSchema;
import org.fao.geonet.kernel.search.IndexingMode;
import org.fao.geonet.kernel.setting.SettingManager;
import org.fao.geonet.kernel.setting.Settings;
import org.fao.geonet.util.UserUtil;
import org.fao.geonet.utils.Diff;
import org.fao.geonet.utils.DiffType;
import org.fao.geonet.utils.Xml;
Expand All @@ -59,6 +62,7 @@
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
Expand All @@ -79,6 +83,13 @@
public class BatchEditsApi implements ApplicationContextAware {
@Autowired
SchemaManager _schemaManager;

@Autowired
SettingManager settingManager;

@Autowired
RoleHierarchy roleHierarchy;

private ApplicationContext context;

public synchronized void setApplicationContext(ApplicationContext context) {
Expand Down Expand Up @@ -180,6 +191,7 @@ private Pair<SimpleMetadataProcessingReport, Element> applyBatchEdits(


ServiceContext serviceContext = ApiUtils.createServiceContext(request);
checkUserProfileToBatchEditMetadata(serviceContext.getUserSession());
final Set<String> setOfUuidsToEdit;
if (uuids == null) {
SelectionManager selectionManager =
Expand Down Expand Up @@ -294,4 +306,22 @@ private Pair<SimpleMetadataProcessingReport, Element> applyBatchEdits(
report.close();
return Pair.write(report, preview);
}

/**
* Checks if the user profile is allowed to batch edit metadata.
*
* @param userSession
*/
private void checkUserProfileToBatchEditMetadata(UserSession userSession) {
if (userSession.getProfile() != Profile.Administrator) {
String allowedUserProfileToImportMetadata =
StringUtils.defaultIfBlank(settingManager.getValue(Settings.METADATA_BATCH_EDITING_ACCESS_LEVEL), Profile.Editor.toString());

// Is the user profile is higher than the profile allowed to import metadata?
if (!UserUtil.hasHierarchyRole(allowedUserProfileToImportMetadata, this.roleHierarchy)) {
throw new NotAllowedException("The user has no permissions to batch edit metadata.");
}
}

}
}

0 comments on commit 1579d52

Please sign in to comment.