Skip to content

Commit 1579d52

Browse files
authored
batch edit user profile check in APIs (geonetwork#7243)
* batch edit user profile check in APIs * protect search-and-replace API
1 parent 7f3230b commit 1579d52

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed

core/src/main/java/org/fao/geonet/kernel/setting/Settings.java

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ public class Settings {
138138
public static final String METADATA_LINK_EXCLUDEPATTERN = "metadata/link/excludedUrlPattern";
139139
public static final String METADATA_IMPORT_RESTRICT = "metadata/import/restrict";
140140
public static final String METADATA_IMPORT_USERPROFILE = "metadata/import/userprofile";
141+
public static final String METADATA_BATCH_EDITING_ACCESS_LEVEL = "metadata/batchediting/accesslevel";
141142
public static final String METADATA_PUBLISHED_DELETE_USERPROFILE = "metadata/delete/profilePublishedMetadata";
142143
public static final String METADATA_PUBLISH_USERPROFILE = "metadata/publication/profilePublishMetadata";
143144
public static final String METADATA_UNPUBLISH_USERPROFILE = "metadata/publication/profileUnpublishMetadata";

services/src/main/java/org/fao/geonet/api/processing/DatabaseProcessApi.java

+33-2
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,19 @@
3636
import org.fao.geonet.ApplicationContextHolder;
3737
import org.fao.geonet.api.ApiParams;
3838
import org.fao.geonet.api.ApiUtils;
39+
import org.fao.geonet.api.exception.NotAllowedException;
3940
import org.fao.geonet.api.processing.report.MetadataReplacementProcessingReport;
4041
import org.fao.geonet.api.processing.report.XsltMetadataProcessingReport;
4142
import org.fao.geonet.domain.AbstractMetadata;
43+
import org.fao.geonet.domain.Profile;
4244
import org.fao.geonet.events.history.RecordProcessingChangeEvent;
4345
import org.fao.geonet.kernel.DataManager;
4446
import org.fao.geonet.kernel.MetadataIndexerProcessor;
4547
import org.fao.geonet.kernel.SchemaManager;
4648
import org.fao.geonet.kernel.datamanager.IMetadataUtils;
4749
import org.fao.geonet.kernel.setting.SettingManager;
50+
import org.fao.geonet.kernel.setting.Settings;
51+
import org.fao.geonet.util.UserUtil;
4852
import org.fao.geonet.utils.Diff;
4953
import org.fao.geonet.utils.DiffType;
5054
import org.fao.geonet.utils.Log;
@@ -56,6 +60,7 @@
5660
import org.springframework.http.HttpStatus;
5761
import org.springframework.http.MediaType;
5862
import org.springframework.http.ResponseEntity;
63+
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
5964
import org.springframework.security.access.prepost.PreAuthorize;
6065
import org.springframework.stereotype.Controller;
6166
import org.springframework.web.bind.annotation.*;
@@ -91,6 +96,9 @@ public class DatabaseProcessApi {
9196
@Autowired
9297
SettingManager settingManager;
9398

99+
@Autowired
100+
RoleHierarchy roleHierarchy;
101+
94102
@io.swagger.v3.oas.annotations.Operation(
95103
summary = "Preview of search and replace text.",
96104
description =" When errors occur during processing, the processing report is returned in JSON format.")
@@ -175,14 +183,17 @@ public ResponseEntity<Object> previewProcessSearchAndReplace(
175183
Element preview = new Element("preview");
176184

177185
try {
186+
ServiceContext serviceContext = ApiUtils.createServiceContext(request);
187+
checkUserProfileToBatchEditMetadata(serviceContext.getUserSession());
188+
178189
Set<String> records = ApiUtils.getUuidsParameterOrSelection(uuids, bucket, session);
179190

180191
final String siteURL = request.getRequestURL().toString() + "?" + request.getQueryString();
181192
for (String uuid : records) {
182193
String id = dataMan.getMetadataId(uuid);
183194
Log.info("org.fao.geonet.services.metadata",
184195
"Processing metadata for preview with id:" + id);
185-
ServiceContext serviceContext = ApiUtils.createServiceContext(request);
196+
186197
Element record = DatabaseProcessUtils.process(
187198
serviceContext,
188199
id, useRegexp, search, replace, regexpFlags,
@@ -307,6 +318,8 @@ public XsltMetadataProcessingReport processSearchAndReplace(
307318
new MetadataReplacementProcessingReport(search + "-" + replace);
308319

309320
try {
321+
ServiceContext serviceContext = ApiUtils.createServiceContext(request);
322+
checkUserProfileToBatchEditMetadata(serviceContext.getUserSession());
310323
Set<String> records = ApiUtils.getUuidsParameterOrSelection(uuids, bucket, session);
311324
UserSession userSession = ApiUtils.getUserSession(httpSession);
312325

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

317330
BatchDatabaseUpdateMetadataReindexer m = new BatchDatabaseUpdateMetadataReindexer(
318-
ApiUtils.createServiceContext(request),
331+
serviceContext,
319332
dataMan, records, useRegexp, search, replace, regexpFlags, httpSession, siteURL,
320333
processingReport, request, index, updateDateStamp, userSession.getUserIdAsInt());
321334
m.process(settingManager.getSiteId());
@@ -402,4 +415,22 @@ public void process(String catalogueId) throws Exception {
402415
}
403416
}
404417
}
418+
419+
/**
420+
* Checks if the user profile is allowed to batch edit metadata.
421+
*
422+
* @param userSession
423+
*/
424+
private void checkUserProfileToBatchEditMetadata(UserSession userSession) {
425+
if (userSession.getProfile() != Profile.Administrator) {
426+
String allowedUserProfileToImportMetadata =
427+
StringUtils.defaultIfBlank(settingManager.getValue(Settings.METADATA_BATCH_EDITING_ACCESS_LEVEL), Profile.Editor.toString());
428+
429+
// Is the user profile is higher than the profile allowed to import metadata?
430+
if (!UserUtil.hasHierarchyRole(allowedUserProfileToImportMetadata, this.roleHierarchy)) {
431+
throw new NotAllowedException("The user has no permissions to batch edit metadata.");
432+
}
433+
}
434+
435+
}
405436
}

services/src/main/java/org/fao/geonet/api/records/editing/BatchEditsApi.java

+30
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,20 @@
3737
import org.fao.geonet.ApplicationContextHolder;
3838
import org.fao.geonet.api.ApiParams;
3939
import org.fao.geonet.api.ApiUtils;
40+
import org.fao.geonet.api.exception.NotAllowedException;
4041
import org.fao.geonet.api.processing.report.IProcessingReport;
4142
import org.fao.geonet.api.processing.report.SimpleMetadataProcessingReport;
4243
import org.fao.geonet.domain.AbstractMetadata;
4344
import org.fao.geonet.domain.Pair;
45+
import org.fao.geonet.domain.Profile;
4446
import org.fao.geonet.events.history.RecordUpdatedEvent;
4547
import org.fao.geonet.kernel.*;
4648
import org.fao.geonet.kernel.datamanager.IMetadataUtils;
4749
import org.fao.geonet.kernel.schema.MetadataSchema;
4850
import org.fao.geonet.kernel.search.IndexingMode;
4951
import org.fao.geonet.kernel.setting.SettingManager;
5052
import org.fao.geonet.kernel.setting.Settings;
53+
import org.fao.geonet.util.UserUtil;
5154
import org.fao.geonet.utils.Diff;
5255
import org.fao.geonet.utils.DiffType;
5356
import org.fao.geonet.utils.Xml;
@@ -59,6 +62,7 @@
5962
import org.springframework.context.ConfigurableApplicationContext;
6063
import org.springframework.http.HttpStatus;
6164
import org.springframework.http.MediaType;
65+
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
6266
import org.springframework.security.access.prepost.PreAuthorize;
6367
import org.springframework.stereotype.Controller;
6468
import org.springframework.web.bind.annotation.*;
@@ -79,6 +83,13 @@
7983
public class BatchEditsApi implements ApplicationContextAware {
8084
@Autowired
8185
SchemaManager _schemaManager;
86+
87+
@Autowired
88+
SettingManager settingManager;
89+
90+
@Autowired
91+
RoleHierarchy roleHierarchy;
92+
8293
private ApplicationContext context;
8394

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

181192

182193
ServiceContext serviceContext = ApiUtils.createServiceContext(request);
194+
checkUserProfileToBatchEditMetadata(serviceContext.getUserSession());
183195
final Set<String> setOfUuidsToEdit;
184196
if (uuids == null) {
185197
SelectionManager selectionManager =
@@ -294,4 +306,22 @@ private Pair<SimpleMetadataProcessingReport, Element> applyBatchEdits(
294306
report.close();
295307
return Pair.write(report, preview);
296308
}
309+
310+
/**
311+
* Checks if the user profile is allowed to batch edit metadata.
312+
*
313+
* @param userSession
314+
*/
315+
private void checkUserProfileToBatchEditMetadata(UserSession userSession) {
316+
if (userSession.getProfile() != Profile.Administrator) {
317+
String allowedUserProfileToImportMetadata =
318+
StringUtils.defaultIfBlank(settingManager.getValue(Settings.METADATA_BATCH_EDITING_ACCESS_LEVEL), Profile.Editor.toString());
319+
320+
// Is the user profile is higher than the profile allowed to import metadata?
321+
if (!UserUtil.hasHierarchyRole(allowedUserProfileToImportMetadata, this.roleHierarchy)) {
322+
throw new NotAllowedException("The user has no permissions to batch edit metadata.");
323+
}
324+
}
325+
326+
}
297327
}

0 commit comments

Comments
 (0)