Skip to content

Commit

Permalink
added new configuration options for enabling/disabling data import/ex…
Browse files Browse the repository at this point in the history
…port and configuration editing from the UI
  • Loading branch information
albogdano committed Dec 6, 2024
1 parent 7fb3aef commit de81468
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 11 deletions.
20 changes: 20 additions & 0 deletions src/main/java/com/erudika/scoold/ScooldConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -3442,6 +3442,26 @@ public boolean automaticSpamProtectionEnabled() {
return getConfigBoolean("automatic_spam_protection_enabled", true);
}

@Documented(position = 3120,
identifier = "data_import_export_enabled",
value = "true",
type = Boolean.class,
category = "Miscellaneous",
description = "Enable/disable backup and restore features on the Administration page.")
public boolean dataImportExportEnabled() {
return getConfigBoolean("data_import_export_enabled", true);
}

@Documented(position = 3130,
identifier = "config_editing_enabled",
value = "true",
type = Boolean.class,
category = "Miscellaneous",
description = "Enable/disable live configuration editing for admins on the Administration page.")
public boolean configEditingEnabled() {
return getConfigBoolean("config_editing_enabled", true);
}

/* **********************************************************************************************************/

public boolean inDevelopment() {
Expand Down
22 changes: 13 additions & 9 deletions src/main/java/com/erudika/scoold/controllers/AdminController.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,20 @@ public String get(HttpServletRequest req, Model model) {
return "redirect:" + SIGNINLINK + "?returnto=" + ADMINLINK;
}
Map<String, Object> configMetadata = new LinkedHashMap<String, Object>();
try {
configMetadata = ParaObjectUtils.getJsonReader(Map.class).readValue(CONF.renderConfigDocumentation("json", true));
} catch (IOException ex) { }
if (CONF.configEditingEnabled()) {
try {
configMetadata = ParaObjectUtils.getJsonReader(Map.class).
readValue(CONF.renderConfigDocumentation("json", true));
} catch (IOException ex) { }
}

Pager itemcount = utils.getPager("page", req);
Pager itemcount1 = utils.getPager("page1", req);
itemcount.setLimit(40);
model.addAttribute("path", "admin.vm");
model.addAttribute("title", utils.getLang(req).get("administration.title"));
model.addAttribute("configMap", CONF);
model.addAttribute("configMetadata", configMetadata);
model.addAttribute("version", pc.getServerVersion());
model.addAttribute("endpoint", CONF.redirectUri());
model.addAttribute("paraapp", CONF.paraAccessKey());
Expand Down Expand Up @@ -354,8 +358,8 @@ public String forceDelete(@RequestParam Boolean confirmdelete, @RequestParam Str
@GetMapping(value = "/export", produces = "application/zip")
public ResponseEntity<StreamingResponseBody> backup(HttpServletRequest req, HttpServletResponse response) {
Profile authUser = utils.getAuthUser(req);
if (!utils.isAdmin(authUser)) {
return new ResponseEntity<StreamingResponseBody>(HttpStatus.UNAUTHORIZED);
if (!utils.isAdmin(authUser) || !CONF.dataImportExportEnabled()) {
return new ResponseEntity<StreamingResponseBody>(HttpStatus.FORBIDDEN);
}
String fileName = App.identifier(CONF.paraAccessKey()) + "_" + Utils.formatDate("YYYYMMdd_HHmmss", Locale.US);
response.setContentType("application/zip");
Expand Down Expand Up @@ -392,8 +396,8 @@ public String restore(@RequestParam("file") MultipartFile file,
@RequestParam(required = false, defaultValue = "false") Boolean deleteall,
HttpServletRequest req, HttpServletResponse res) {
Profile authUser = utils.getAuthUser(req);
if (!utils.isAdmin(authUser)) {
res.setStatus(403);
if (!utils.isAdmin(authUser) || !CONF.dataImportExportEnabled()) {
res.setStatus(HttpStatus.FORBIDDEN.value());
return null;
}
ObjectReader reader = ParaObjectUtils.getJsonMapper().readerFor(new TypeReference<List<Map<String, Object>>>() { });
Expand Down Expand Up @@ -535,7 +539,7 @@ public String reindex(HttpServletRequest req, Model model) {
@PostMapping("/save-config")
public String saveConfig(@RequestParam String key, @RequestParam(defaultValue = "") String value, HttpServletRequest req) {
Profile authUser = utils.getAuthUser(req);
if (utils.isAdmin(authUser)) {
if (utils.isAdmin(authUser) && CONF.configEditingEnabled()) {
if ("on".equals(value)) {
value = "true";
}
Expand All @@ -544,7 +548,7 @@ public String saveConfig(@RequestParam String key, @RequestParam(defaultValue =
} else {
System.clearProperty(key);
}
logger.info("Configuration was changed: user {} modified property '{}'.", authUser.getId(), key);
logger.info("Configuration property '{}' was modified by user {}.", key, authUser.getCreatorid());
CONF.store();
if (CONF.getParaAppSettings().containsKey(key)) {
pc.addAppSetting(key, value);
Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/templates/admin.vm
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@
<ul class="tabs adminpage">
<li class="tab col s2"><a href="#spaces-tab">$!{lang.get("spaces.title")} #showcount($itemcount.count)</a></li>
<li class="tab col s2"><a href="#webhooks-tab">Webhooks #showcount($itemcount1.count)</a></li>
#if($scooldUtils.config.dataImportExportEnabled())
<li class="tab col s2"><a href="#backup-tab">$!{lang.get("backups.title")} </a></li>
#end
<li class="tab col s2"><a href="#themes-tab">$!{lang.get("admin.themes")} </a></li>
<li class="tab col s2"><a href="#api-tab">API keys </a></li>
#if($scooldUtils.config.configEditingEnabled())
<li class="tab col s2"><a href="#configuration-tab">$!lang.get('admin.configuration') </a></li>
#end
</ul>
</div>

Expand Down Expand Up @@ -139,6 +143,7 @@
#end
</div>

#if($scooldUtils.config.dataImportExportEnabled())
<div id="backup-tab" class="col s12">
<div class="row">
<div class="col s12 m3">
Expand Down Expand Up @@ -232,6 +237,7 @@
</div>
#end
</div>
#end

<div id="themes-tab" class="col s12">
<form action="$adminlink/set-theme" method="post" id="select-theme-form" class="lightborder pal">
Expand Down Expand Up @@ -334,6 +340,7 @@
#end
</div>

#if($scooldUtils.config.configEditingEnabled())
<div id="configuration-tab" class="col s12">
<ul class="collapsible" data-collapsible="expandable">
#foreach($key in $configMetadata.keySet())
Expand Down Expand Up @@ -396,6 +403,7 @@
#end
</ul>
</div>
#end
</div>

<div class="ptl">
Expand Down
8 changes: 6 additions & 2 deletions src/main/resources/templates/api.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: "3.0.2"
info:
description: "This is the Scoold API. First, you need to generate an [API key](/admin) in order to access the API."
version: "1.6.0"
version: "1.6.1"
title: "Scoold API documentation"
externalDocs:
description: "README"
Expand Down Expand Up @@ -1504,6 +1504,8 @@ paths:
schema:
type: string
format: binary
'403':
description: Forbidden - this feature is disabled or invalid request.
/api/restore:
put:
summary: Restores (asynchronously) a backup ZIP archive, overwriting all existing data in Scoold
Expand Down Expand Up @@ -1531,7 +1533,9 @@ paths:
type: boolean
responses:
'200':
description: Restore operation hast started but is not necessarily complete.
description: Restore operation has started asynchronously but is not necessarily complete.
'403':
description: Forbidden - this feature is disabled or invalid request.
/api/config:
get:
summary: Returns the current Scoold configuration as a list of properties in the HOCON or JSON formats.
Expand Down

0 comments on commit de81468

Please sign in to comment.