diff --git a/celements-model/src/main/java/com/celements/init/DiskDocumentImporter.java b/celements-model/src/main/java/com/celements/init/DiskDocumentImporter.java index efefdcc77..16af4a803 100644 --- a/celements-model/src/main/java/com/celements/init/DiskDocumentImporter.java +++ b/celements-model/src/main/java/com/celements/init/DiskDocumentImporter.java @@ -30,6 +30,7 @@ import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.plugin.packaging.DocumentInfo; import com.xpn.xwiki.plugin.packaging.Package; +import com.xpn.xwiki.plugin.packaging.PackageException; import one.util.streamex.StreamEx; @@ -119,12 +120,15 @@ private void importDocs(Path path, boolean force) throws XWikiException { var skipAll = true; for (DocumentInfo docInfo : importer.getFiles()) { var docRef = modelUtils.resolveRef(docInfo.getFullName(), DocumentReference.class); - var skip = !force && modelAccess.exists(docRef); + var skip = !force && modelAccess.existsLang(docRef, docInfo.getLanguage()); docInfo.setAction(skip ? ACTION_SKIP : ACTION_OVERWRITE); skipAll &= skip; } if (!skipAll) { - importer.install(getXContext()); + int status = importer.install(getXContext()); + if ((status == INSTALL_ERROR) || (status == INSTALL_IMPOSSIBLE)) { + throw new PackageException(0, "Failed to import disk docs from [" + path + "]"); + } LOGGER.debug("imported [{}]", path); } else { LOGGER.debug("skipped import [{}], nothing to do", path); diff --git a/celements-wiki-manager/component/src/main/java/com/celements/wiki/api/WikiController.java b/celements-wiki-manager/component/src/main/java/com/celements/wiki/api/WikiController.java index 53a4849a7..2d2bbde5b 100644 --- a/celements-wiki-manager/component/src/main/java/com/celements/wiki/api/WikiController.java +++ b/celements-wiki-manager/component/src/main/java/com/celements/wiki/api/WikiController.java @@ -10,6 +10,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -33,6 +34,7 @@ @RestController @RequestMapping("/v1/wikis") +@PreAuthorize("permitAll()") // endpoints are protected by requireSuperAdmin checks public class WikiController extends AuthenticatedBaseController { private final WikiService wikiService; diff --git a/celements-xwiki-core/src/main/java/com/celements/init/CelementsBootstrap.java b/celements-xwiki-core/src/main/java/com/celements/init/CelementsBootstrap.java index 3b9086196..7d742cd4d 100644 --- a/celements-xwiki-core/src/main/java/com/celements/init/CelementsBootstrap.java +++ b/celements-xwiki-core/src/main/java/com/celements/init/CelementsBootstrap.java @@ -2,6 +2,7 @@ import static com.celements.execution.XWikiExecutionProp.*; import static com.google.common.base.Preconditions.*; +import static com.xpn.xwiki.XWikiConstant.*; import static com.xpn.xwiki.user.api.XWikiRightService.*; import java.util.concurrent.CompletableFuture; @@ -24,12 +25,11 @@ import org.xwiki.context.ExecutionContext; import org.xwiki.context.ExecutionContextException; import org.xwiki.context.ExecutionContextManager; -import org.xwiki.model.reference.WikiReference; +import com.celements.init.update.WikiUpdater; import com.celements.wiki.WikiCreator; import com.celements.wiki.exception.WikiCreationException; import com.xpn.xwiki.XWiki; -import com.xpn.xwiki.XWikiConfigSource; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.internal.XWikiExecutionContextInitializer; import com.xpn.xwiki.store.XWikiCacheStoreInterface; @@ -54,8 +54,8 @@ public class CelementsBootstrap implements ApplicationListener getFiles() { - return this.files; + return files; } public List getCustomMappingFiles() { @@ -242,7 +244,7 @@ public boolean add(XWikiDocument doc, int defaultAction, XWikiContext context) return false; } LOG.debug("add - doc [{}:{}]", doc.getFullName(), doc.getLanguage()); - for (DocumentInfo di : this.files) { + for (DocumentInfo di : getFiles()) { if (di.getFullName().equals(doc.getFullName()) && (di.getLanguage().equals(doc.getLanguage()))) { if (defaultAction != DocumentInfo.ACTION_NOT_DEFINED) { @@ -263,7 +265,7 @@ public boolean add(XWikiDocument doc, int defaultAction, XWikiContext context) DocumentInfo docinfo = new DocumentInfo(doc, checkEditRights); docinfo.setAction(defaultAction); - this.files.add(docinfo); + getFiles().add(docinfo); BaseClass bclass = doc.getxWikiClass(); if (bclass.getFieldList().size() > 0) { this.classFiles.add(docinfo); @@ -333,12 +335,12 @@ public void filter(XWikiDocument doc, XWikiContext context) throws ExcludeDocume } public String export(OutputStream os, XWikiContext context) throws IOException, XWikiException { - if (this.files.size() == 0) { + if (getFiles().size() == 0) { return "No Selected file"; } ZipOutputStream zos = new ZipOutputStream(os); - for (DocumentInfo docinfo : this.files) { + for (DocumentInfo docinfo : getFiles()) { XWikiDocument doc = docinfo.getDoc(); addToZip(doc, zos, this.withVersions, context); } @@ -357,7 +359,7 @@ public String exportToDir(File dir, XWikiContext context) throws IOException, XW "Error creating directory {0}", null, args); } - for (DocumentInfo docinfo : this.files) { + for (DocumentInfo docinfo : getFiles()) { XWikiDocument doc = docinfo.getDoc(); addToDir(doc, dir, this.withVersions, context); } @@ -524,10 +526,7 @@ private void updateFileInfos(Document xml) { } private void setDocumentDefaultAction(String docName, String language, int defaultAction) { - if (this.files == null) { - return; - } - for (DocumentInfo docInfo : this.files) { + for (DocumentInfo docInfo : getFiles()) { if (docInfo.getFullName().equals(docName) && docInfo.getLanguage().equals(language)) { docInfo.setAction(defaultAction); return; @@ -542,12 +541,12 @@ public int testInstall(boolean isAdmin, XWikiContext context) { int result = DocumentInfo.INSTALL_IMPOSSIBLE; try { - if (this.files.size() == 0) { + if (getFiles().size() == 0) { return result; } - result = this.files.get(0).testInstall(isAdmin, context); - for (DocumentInfo docInfo : this.files) { + result = getFiles().get(0).testInstall(isAdmin, context); + for (DocumentInfo docInfo : getFiles()) { int res = docInfo.testInstall(isAdmin, context); if (res < result) { result = res; @@ -598,7 +597,9 @@ public int install(XWikiContext context) throws XWikiException { } // Install the remaining documents (without class definitions). - for (DocumentInfo docInfo : this.files) { + // sorting: ensure translations are always installed last + for (DocumentInfo docInfo : StreamEx.of(getFiles()).sorted(Comparator + .comparing((DocumentInfo doc) -> !doc.getLanguage().isEmpty()))) { if (!this.classFiles.contains(docInfo) && (installDocument(docInfo, isAdmin, backup, context) == DocumentInfo.INSTALL_ERROR)) { status = DocumentInfo.INSTALL_ERROR; @@ -942,7 +943,7 @@ public void toXML(XMLWriter wr) throws IOException { Element elfiles = new DOMElement("files"); wr.writeOpen(elfiles); - for (DocumentInfo docInfo : this.files) { + for (DocumentInfo docInfo : getFiles()) { Element elfile = new DOMElement("file"); elfile.addAttribute("defaultAction", String.valueOf(docInfo.getAction())); elfile.addAttribute("language", String.valueOf(docInfo.getLanguage())); @@ -1264,7 +1265,7 @@ public JSONObject toJSON(XWikiContext wikiContext) { Map>>> files = new HashMap<>(); - for (DocumentInfo docInfo : this.files) { + for (DocumentInfo docInfo : getFiles()) { Map fileInfos = new HashMap<>(); fileInfos.put("defaultAction", String.valueOf(docInfo.getAction())); fileInfos.put("language", String.valueOf(docInfo.getLanguage())); diff --git a/celements-xwiki-core/src/main/java/com/xpn/xwiki/util/AbstractXWikiRunnable.java b/celements-xwiki-core/src/main/java/com/xpn/xwiki/util/AbstractXWikiRunnable.java index 06f431bbb..c0d0b6cfe 100644 --- a/celements-xwiki-core/src/main/java/com/xpn/xwiki/util/AbstractXWikiRunnable.java +++ b/celements-xwiki-core/src/main/java/com/xpn/xwiki/util/AbstractXWikiRunnable.java @@ -75,9 +75,12 @@ public final void run() { try { initExecutionContext(); runInternal(); - } catch (Exception e) { + } catch (ExecutionContextException e) { logger.error("Failed to initialize execution context", e); throw new RuntimeException(e); + } catch (Exception e) { + logger.error("execution failed", e); + throw new RuntimeException(e); } finally { cleanupExecutionContext(); }