Some code formattig, added function for fixing item and asset permissions (sometimes they are not correctly inherited from the folder.
parent
4251fd1df9
commit
7cea45560a
|
|
@ -580,16 +580,28 @@ public class PagesController {
|
|||
|
||||
final Page page = pageManager.findPageForCategory(category);
|
||||
pagePropertiesModel.setProperties(page.getProperties());
|
||||
try {
|
||||
final String result;
|
||||
if (itemName.equals("index") || itemName.isBlank()) {
|
||||
return themesMvc.getMvcTemplate(
|
||||
result = themesMvc.getMvcTemplate(
|
||||
uriInfo, "pages", page.getDisplayName()
|
||||
);
|
||||
|
||||
} else {
|
||||
return themesMvc.getMvcTemplate(
|
||||
result = themesMvc.getMvcTemplate(
|
||||
uriInfo, "pages", "item-page"
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (Exception ex) {
|
||||
throw new WebApplicationException(
|
||||
"An error occured while rendering the page.",
|
||||
ex,
|
||||
Response.serverError().entity(
|
||||
"An error occured while rendering the page."
|
||||
).build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void initSiteInfoModel(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.pages.models;
|
||||
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class ContentItemListItemModel extends AbstractContentItemListItemModel {
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return ContentItem.class.getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.pages.models;
|
||||
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
public class ContentItemListModelBuilder
|
||||
extends AbstractContentItemListItemModelBuilder<ContentItem, ContentItemListItemModel> {
|
||||
|
||||
@Override
|
||||
public Class<ContentItem> buildsListItemModelFor() {
|
||||
return ContentItem.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ContentItemListItemModel buildModel() {
|
||||
return new ContentItemListItemModel();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -251,10 +251,11 @@ public class ItemListModel {
|
|||
criteriaBuilder.isNull(catJoin.get("type")),
|
||||
criteriaBuilder.equal(
|
||||
from.get("version"), ContentItemVersion.LIVE
|
||||
),
|
||||
buildPermissionsCheck(
|
||||
criteriaBuilder, from, permissionsJoin
|
||||
)
|
||||
// ,
|
||||
// buildPermissionsCheck(
|
||||
// criteriaBuilder, from, permissionsJoin
|
||||
// )
|
||||
)
|
||||
);
|
||||
|
||||
|
|
@ -265,7 +266,7 @@ public class ItemListModel {
|
|||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
return entityManager
|
||||
final List<? extends AbstractContentItemListItemModel> result = entityManager
|
||||
.createQuery(criteriaQuery)
|
||||
.getResultList()
|
||||
.stream()
|
||||
|
|
@ -278,6 +279,8 @@ public class ItemListModel {
|
|||
.limit(pageSize)
|
||||
.map(this::buildListItemModel)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Category> collectCategories(final Category category) {
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ public class ConfigurationController {
|
|||
return "org/librecms/ui/contentsection/configuration/index.xhtml";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the current user is permitted to access the configurations page
|
||||
* of the content section.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections;
|
||||
|
||||
import org.libreccm.categorization.Categorization;
|
||||
import org.libreccm.security.AuthorizationRequired;
|
||||
import org.libreccm.security.PermissionManager;
|
||||
import org.librecms.contentsection.Asset;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentSectionManager;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.mvc.Controller;
|
||||
import javax.transaction.Transactional;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
/**
|
||||
* Controller for the fix item and asset permissions function.
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
@Controller
|
||||
@Path("/{sectionIdentifier}/configuration/fix-item-and-asset-permissions")
|
||||
public class ConfigurationFixItemPermissionsController {
|
||||
|
||||
/**
|
||||
* Used to check the admin permissions of a content section.
|
||||
*/
|
||||
@Inject
|
||||
private AdminPermissionsChecker adminPermissionsChecker;
|
||||
|
||||
// @Inject
|
||||
// private ContentSectionManager sectionManager;
|
||||
@Inject
|
||||
private ContentSectionModel sectionModel;
|
||||
|
||||
/**
|
||||
* Common functions for views working with {@link ContentSection}s.
|
||||
*/
|
||||
@Inject
|
||||
private ContentSectionsUi sectionsUi;
|
||||
|
||||
// @Inject
|
||||
// private PermissionManager permissionManager;
|
||||
//
|
||||
|
||||
@Inject
|
||||
private FixItemPermissionsTaskManager taskManager;
|
||||
|
||||
@POST
|
||||
@Path("/")
|
||||
@AuthorizationRequired
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public String fixItemAndAssetPermissions(
|
||||
@PathParam("sectionIdentifier") final String sectionIdentifierParam
|
||||
) {
|
||||
final Optional<ContentSection> sectionResult = sectionsUi
|
||||
.findContentSection(sectionIdentifierParam);
|
||||
if (!sectionResult.isPresent()) {
|
||||
return sectionsUi.showContentSectionNotFound(sectionIdentifierParam);
|
||||
}
|
||||
final ContentSection section = sectionResult.get();
|
||||
sectionModel.setSection(section);
|
||||
if (!adminPermissionsChecker.canAdministerContentTypes(section)) {
|
||||
return sectionsUi.showAccessDenied(
|
||||
"sectionIdentifier", sectionIdentifierParam
|
||||
);
|
||||
}
|
||||
|
||||
// fixContentItemPermissions(section.getRootDocumentsFolder());
|
||||
// fixAssetPermissions(section.getRootAssetsFolder());
|
||||
|
||||
taskManager.fixItemPermissions(section);
|
||||
|
||||
return String.format(
|
||||
"redirect:%s/configuration", sectionIdentifierParam
|
||||
);
|
||||
}
|
||||
|
||||
// private void fixContentItemPermissions(final Folder folder) {
|
||||
// final List<ContentItem> items = folder
|
||||
// .getObjects()
|
||||
// .stream()
|
||||
// .map(Categorization::getCategorizedObject)
|
||||
// .filter(obj -> obj instanceof ContentItem)
|
||||
// .map(obj -> (ContentItem) obj)
|
||||
// .collect(Collectors.toList());
|
||||
//
|
||||
// for(final ContentItem item : items) {
|
||||
// permissionManager.copyPermissions(folder, item, true);
|
||||
// }
|
||||
//
|
||||
// for(final Folder subFolder : folder.getSubFolders()) {
|
||||
// fixContentItemPermissions(subFolder);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void fixAssetPermissions(final Folder folder) {
|
||||
// final List<Asset> assets = folder
|
||||
// .getObjects()
|
||||
// .stream()
|
||||
// .map(Categorization::getCategorizedObject)
|
||||
// .filter(obj -> obj instanceof Asset)
|
||||
// .map(obj -> (Asset) obj)
|
||||
// .collect(Collectors.toList());
|
||||
//
|
||||
// for(final Asset asset : assets) {
|
||||
// permissionManager.copyPermissions(folder, asset, true);
|
||||
// }
|
||||
//
|
||||
// for(final Folder subFolder : folder.getSubFolders()) {
|
||||
// fixAssetPermissions(subFolder);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
|
@ -76,6 +76,7 @@ public class ContentSectionApplication extends Application {
|
|||
classes.add(ConfigurationController.class);
|
||||
classes.add(ConfigurationContactEntryKeysController.class);
|
||||
classes.add(ConfigurationDocumentTypesController.class);
|
||||
classes.add(ConfigurationFixItemPermissionsController.class);
|
||||
classes.add(ConfigurationLifecyclesController.class);
|
||||
classes.add(ConfigurationRolesController.class);
|
||||
classes.add(ConfigurationWorkflowController.class);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.libreccm.categorization.Categorization;
|
||||
import org.libreccm.core.CcmObject;
|
||||
import org.libreccm.security.PermissionManager;
|
||||
import org.librecms.contentsection.Asset;
|
||||
import org.librecms.contentsection.AssetManager;
|
||||
import org.librecms.contentsection.ContentItem;
|
||||
import org.librecms.contentsection.ContentItemManager;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
import org.librecms.contentsection.ContentSectionRepository;
|
||||
import org.librecms.contentsection.Folder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.enterprise.context.ApplicationScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class FixItemPermissions {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(
|
||||
FixItemPermissions.class
|
||||
);
|
||||
|
||||
@Inject
|
||||
private AssetManager assetManager;
|
||||
|
||||
@Inject
|
||||
private ContentItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private ContentSectionRepository sectionRepo;
|
||||
|
||||
@Inject
|
||||
private PermissionManager permissionManager;
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void fixItemPermissions(final ContentSection contentSection) {
|
||||
final String sectionUuid = Optional
|
||||
.ofNullable(contentSection)
|
||||
.map(ContentSection::getUuid)
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException(
|
||||
"Can't fix ItemPermissions for content section null"
|
||||
)
|
||||
);
|
||||
|
||||
final ContentSection section = sectionRepo
|
||||
.findByUuid(sectionUuid)
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException(
|
||||
String.format(
|
||||
"No ContentSection with UUID %s in the database.",
|
||||
sectionUuid
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
fixContentItemPermissions(section.getRootDocumentsFolder());
|
||||
fixAssetPermissions(section.getRootAssetsFolder());
|
||||
}
|
||||
|
||||
private void fixContentItemPermissions(final Folder folder) {
|
||||
final List<ContentItem> items = new ArrayList<>();
|
||||
for (final Categorization categorization : folder.getObjects()) {
|
||||
final CcmObject categorized = categorization.getCategorizedObject();
|
||||
if (categorized instanceof ContentItem) {
|
||||
items.add((ContentItem) categorized);
|
||||
}
|
||||
}
|
||||
|
||||
// final List<ContentItem> items = folder
|
||||
// .getObjects()
|
||||
// .stream()
|
||||
// .map(Categorization::getCategorizedObject)
|
||||
// .filter(obj -> obj instanceof ContentItem)
|
||||
// .map(obj -> (ContentItem) obj)
|
||||
// .collect(Collectors.toList());
|
||||
for (final ContentItem item : items) {
|
||||
LOGGER.info(
|
||||
"Fixing permissions for item {} {}",
|
||||
item.getUuid(),
|
||||
itemManager.getItemPath(item)
|
||||
);
|
||||
permissionManager.copyPermissions(folder, item, true);
|
||||
|
||||
if (itemManager.isLive(item)) {
|
||||
permissionManager.copyPermissions(
|
||||
folder,
|
||||
itemManager.getLiveVersion(item, ContentItem.class).get(),
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (final Folder subFolder : folder.getSubFolders()) {
|
||||
fixContentItemPermissions(subFolder);
|
||||
}
|
||||
}
|
||||
|
||||
private void fixAssetPermissions(final Folder folder) {
|
||||
final List<Asset> assets = folder
|
||||
.getObjects()
|
||||
.stream()
|
||||
.map(Categorization::getCategorizedObject)
|
||||
.filter(obj -> obj instanceof Asset)
|
||||
.map(obj -> (Asset) obj)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (final Asset asset : assets) {
|
||||
LOGGER.info(
|
||||
"Fixing permissions for asset {} {}...",
|
||||
asset.getUuid(),
|
||||
assetManager.getAssetPath(asset)
|
||||
);
|
||||
permissionManager.copyPermissions(folder, asset, true);
|
||||
}
|
||||
|
||||
for (final Folder subFolder : folder.getSubFolders()) {
|
||||
fixAssetPermissions(subFolder);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public enum FixItemPermissionsStatus {
|
||||
|
||||
/**
|
||||
* An error occured during the process.
|
||||
*/
|
||||
ERROR,
|
||||
/**
|
||||
* The import or export task is finished.
|
||||
*/
|
||||
FINISHED,
|
||||
/**
|
||||
* The task is still running.
|
||||
*/
|
||||
RUNNING,
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections;
|
||||
|
||||
import org.apache.shiro.mgt.SecurityManager;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class FixItemPermissionsTask {
|
||||
|
||||
private final ContentSection contentSection;
|
||||
|
||||
private final LocalDate started;
|
||||
|
||||
private final FixItemPermissionsTaskStatus status;
|
||||
|
||||
private final org.apache.shiro.mgt.SecurityManager securityManager;
|
||||
|
||||
public FixItemPermissionsTask(
|
||||
final ContentSection contentSection,
|
||||
final LocalDate started,
|
||||
final FixItemPermissionsTaskStatus status,
|
||||
final org.apache.shiro.mgt.SecurityManager securityManager
|
||||
) {
|
||||
this.contentSection = contentSection;
|
||||
this.started = started;
|
||||
this.status = status;
|
||||
this.securityManager = securityManager;
|
||||
}
|
||||
|
||||
public ContentSection getContentSection() {
|
||||
return contentSection;
|
||||
}
|
||||
|
||||
public LocalDate getStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
public FixItemPermissionsTaskStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public SecurityManager getSecurityManager() {
|
||||
return securityManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.librecms.contentsection.ContentSection;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Optional;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.enterprise.context.ApplicationScoped;
|
||||
import javax.enterprise.event.Event;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class FixItemPermissionsTaskManager {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(
|
||||
FixItemPermissionsTaskManager.class
|
||||
);
|
||||
|
||||
@Inject
|
||||
private Event<FixItemPermissionsTask> taskSender;
|
||||
|
||||
private final SortedSet<FixItemPermissionsTaskStatus> tasks;
|
||||
|
||||
public SortedSet<FixItemPermissionsTaskStatus> getTasks() {
|
||||
return Collections.unmodifiableSortedSet(tasks);
|
||||
}
|
||||
|
||||
public boolean isTaskActiveForContentSection(final ContentSection section) {
|
||||
return isTaskActiveForContentSection(
|
||||
Optional
|
||||
.ofNullable(section)
|
||||
.map(ContentSection::getLabel)
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException(
|
||||
"Can't check task status for ContentSection null."
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public boolean isTaskActiveForContentSection(final String name) {
|
||||
return tasks
|
||||
.stream()
|
||||
.anyMatch(
|
||||
task -> task.getContentSection().equals(name)
|
||||
&& task.getStatus()
|
||||
== FixItemPermissionsStatus.RUNNING
|
||||
);
|
||||
}
|
||||
|
||||
public boolean isTaskFailedForContentSection(final String name) {
|
||||
return tasks
|
||||
.stream()
|
||||
.anyMatch(
|
||||
task -> task.getContentSection().equals(name)
|
||||
&& task.getStatus()
|
||||
== FixItemPermissionsStatus.ERROR
|
||||
);
|
||||
}
|
||||
|
||||
public FixItemPermissionsTaskManager() {
|
||||
tasks = new TreeSet<>(
|
||||
Comparator
|
||||
.comparing(FixItemPermissionsTaskStatus::getStarted)
|
||||
.thenComparing(FixItemPermissionsTaskStatus::getContentSection)
|
||||
);
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void fixItemPermissions(final ContentSection section) {
|
||||
if (isTaskActiveForContentSection(section)) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"A FixItemPermissionsTask is already active for content "
|
||||
+ "section %s.",
|
||||
section.getLabel()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
tasks.removeAll(
|
||||
tasks
|
||||
.stream()
|
||||
.filter(task -> task.getStatus()
|
||||
== FixItemPermissionsStatus.ERROR
|
||||
|| task.getStatus()
|
||||
== FixItemPermissionsStatus.FINISHED)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
|
||||
final FixItemPermissionsTaskStatus taskStatus
|
||||
= new FixItemPermissionsTaskStatus();
|
||||
taskStatus.setContentSection(section.getLabel());
|
||||
taskStatus.setStarted(LocalDateTime.now());
|
||||
taskSender.fireAsync(
|
||||
new FixItemPermissionsTask(
|
||||
section,
|
||||
LocalDate.now(),
|
||||
taskStatus,
|
||||
SecurityUtils.getSecurityManager()
|
||||
)
|
||||
).handle((task, ex) -> handleTaskResult(task, ex, taskStatus));
|
||||
|
||||
taskStatus.setStatus(FixItemPermissionsStatus.RUNNING);
|
||||
}
|
||||
|
||||
private Object handleTaskResult(
|
||||
final FixItemPermissionsTask task,
|
||||
final Throwable ex,
|
||||
final FixItemPermissionsTaskStatus status
|
||||
) {
|
||||
if (ex == null) {
|
||||
status.setStatus(FixItemPermissionsStatus.FINISHED);
|
||||
} else {
|
||||
status.setStatus(FixItemPermissionsStatus.ERROR);
|
||||
status.setException(ex);
|
||||
LOGGER.error(
|
||||
"Fix Item Permissions for Content Section {} failed ",
|
||||
status.getContentSection()
|
||||
);
|
||||
LOGGER.error("with exception:", ex);
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class FixItemPermissionsTaskStatus
|
||||
implements Comparable<FixItemPermissionsTaskStatus> {
|
||||
|
||||
/**
|
||||
* The content section for which the task was started.
|
||||
*/
|
||||
private String contentSection;
|
||||
|
||||
/**
|
||||
* When was the task started?
|
||||
*/
|
||||
private LocalDateTime started;
|
||||
|
||||
/**
|
||||
* The status of the task.
|
||||
*/
|
||||
private FixItemPermissionsStatus status;
|
||||
|
||||
/**
|
||||
* If the proces throw an exception, it is stored here.
|
||||
*/
|
||||
private Throwable exception;
|
||||
|
||||
public String getContentSection() {
|
||||
return contentSection;
|
||||
}
|
||||
|
||||
protected void setContentSection(final String contentSection) {
|
||||
this.contentSection = contentSection;
|
||||
}
|
||||
|
||||
public LocalDateTime getStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
protected void setStarted(final LocalDateTime started) {
|
||||
this.started = started;
|
||||
}
|
||||
|
||||
public FixItemPermissionsStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
protected void setStatus(final FixItemPermissionsStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Throwable getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
protected void setException(final Throwable exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 17 * hash + Objects.hashCode(contentSection);
|
||||
hash = 17 * hash + Objects.hashCode(started);
|
||||
hash = 17 * hash + Objects.hashCode(status);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (obj instanceof FixItemPermissionsTaskStatus) {
|
||||
return false;
|
||||
}
|
||||
final FixItemPermissionsTaskStatus other
|
||||
= (FixItemPermissionsTaskStatus) obj;
|
||||
if (!other.canEqual(this)) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(contentSection, other.getContentSection())) {
|
||||
return false;
|
||||
}
|
||||
if (!Objects.equals(started, other.getStarted())) {
|
||||
return false;
|
||||
}
|
||||
return status == other.getStatus();
|
||||
}
|
||||
|
||||
public boolean canEqual(final Object obj) {
|
||||
return obj instanceof FixItemPermissionsTaskStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final FixItemPermissionsTaskStatus other) {
|
||||
return Comparator
|
||||
.nullsFirst(
|
||||
Comparator
|
||||
.comparing(FixItemPermissionsTaskStatus::getContentSection)
|
||||
.thenComparing(FixItemPermissionsTaskStatus::getStarted)
|
||||
)
|
||||
.compare(this, other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"%s{"
|
||||
+ "contentSection = %s, "
|
||||
+ "started = %s, "
|
||||
+ "status = %s"
|
||||
+ "}",
|
||||
super.toString(),
|
||||
contentSection,
|
||||
DateTimeFormatter.ISO_DATE_TIME
|
||||
.withZone(ZoneId.systemDefault())
|
||||
.format(started),
|
||||
Objects.toString(status)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
@Named("FixItemPermissionsTaskStatusModel")
|
||||
public class FixItemPermissionsTaskStatusModel {
|
||||
|
||||
@Inject
|
||||
private ContentSectionModel sectionModel;
|
||||
|
||||
@Inject
|
||||
private FixItemPermissionsTaskManager taskManager;
|
||||
|
||||
public boolean isTaskRunningForContentSection() {
|
||||
return taskManager.isTaskActiveForContentSection(
|
||||
sectionModel.getSectionName()
|
||||
);
|
||||
}
|
||||
|
||||
public boolean isTaskFailedForContentSection() {
|
||||
return taskManager.isTaskFailedForContentSection(
|
||||
sectionModel.getSectionName()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2023 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections;
|
||||
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.libreccm.security.Shiro;
|
||||
|
||||
import javax.enterprise.context.ApplicationScoped;
|
||||
import javax.enterprise.event.ObservesAsync;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class FixItemPermissionsTasks {
|
||||
|
||||
@Inject
|
||||
private FixItemPermissions fixItemPermissions;
|
||||
|
||||
@Inject
|
||||
private Shiro shiro;
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void fixItemPermissions(
|
||||
@ObservesAsync final FixItemPermissionsTask task
|
||||
) {
|
||||
ThreadContext.bind(task.getSecurityManager());
|
||||
shiro.getSystemUser().execute(() -> executeFixItemPermissions(task));
|
||||
}
|
||||
|
||||
|
||||
private void executeFixItemPermissions(final FixItemPermissionsTask task) {
|
||||
fixItemPermissions.fixItemPermissions(task.getContentSection());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -136,6 +136,51 @@
|
|||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col mb-4">
|
||||
<div aria-describedby="configuration-fixitemandassetspermissions-body"
|
||||
class="card pt-2"
|
||||
id="configuration-fixitemandassetspermissions">
|
||||
<svg aria-hidden="true"
|
||||
class="card-img-top"
|
||||
fill="currentColor">
|
||||
<use xlink:href="#{request.contextPath}/assets/bootstrap/bootstrap-icons.svg#screwdriver" />
|
||||
</svg>
|
||||
</div>
|
||||
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/configuration/fix-item-and-asset-permissions"
|
||||
class="card-body"
|
||||
id="configuration-fixitemandassetspermissions-body"
|
||||
method="post">
|
||||
<h2 class="card-title">
|
||||
<c:choose>
|
||||
<c:when test="#{FixItemPermissionsTaskStatusModel.taskRunningForContentSection}">
|
||||
#{CmsAdminMessages['contentsection.configuration.fixitemandassetspermissions.title']}
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
<button class="btn btn-link stretched-link"
|
||||
type="submit">
|
||||
#{CmsAdminMessages['contentsection.configuration.fixitemandassetspermissions.title']}
|
||||
</button>
|
||||
</c:otherwise>
|
||||
|
||||
</c:choose>
|
||||
</h2>
|
||||
<p class="card-text">
|
||||
<c:if test="#{FixItemPermissionsTaskStatusModel.taskFailedForContentSection}">
|
||||
<div class="alert alert-danger" role="alert">
|
||||
#{CmsAdminMessages['contentsection.configuration.fixitemandassetspermissions.failed']}
|
||||
</div>
|
||||
</c:if>
|
||||
<c:choose>
|
||||
<c:when test="#{FixItemPermissionsTaskStatusModel.taskRunningForContentSection}">
|
||||
#{CmsAdminMessages['contentsection.configuration.fixitemandassetspermissions.running']}
|
||||
</c:when>
|
||||
<c:otherwise>
|
||||
#{CmsAdminMessages['contentsection.configuration.fixitemandassetspermissions.description']}
|
||||
</c:otherwise>
|
||||
</c:choose>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
|
|
|||
|
|
@ -1030,3 +1030,7 @@ pages.page.details.displayname.dialog.displayname.help=The display name of the p
|
|||
pages.page.details.displayname.dialog.submit=Save
|
||||
pages.page.details.displayname.edit=Edit display name
|
||||
pages.page.details.dialog.displayname.label=Display name
|
||||
contentsection.configuration.fixitemandassetspermissions.title=Fix permissions
|
||||
contentsection.configuration.fixitemandassetspermissions.description=Repairs the permissions for items and assets
|
||||
contentsection.configuration.fixitemandassetspermissions.running=Fixing permissions for item and assets...
|
||||
contentsection.configuration.fixitemandassetspermissions.failed=Failed to repair permissions for items and assets. Check the log for details.
|
||||
|
|
|
|||
|
|
@ -1031,3 +1031,7 @@ pages.page.details.displayname.dialog.displayname.help=The display name of the p
|
|||
pages.page.details.displayname.dialog.submit=Speichern
|
||||
pages.page.details.displayname.edit=Display Name bearbeiten
|
||||
pages.page.details.dialog.displayname.label=Display Name
|
||||
contentsection.configuration.fixitemandassetspermissions.title=Berechtigungen reparieren
|
||||
contentsection.configuration.fixitemandassetspermissions.description=Repariert die Berechtigungen f\u00fcr Dokumente und Assets
|
||||
contentsection.configuration.fixitemandassetspermissions.running=Repariere Berechtigungen f\u00fcr Dokumente und Assets
|
||||
contentsection.configuration.fixitemandassetspermissions.failed=Reparieren der Berechtigungen f\u00fcr Dokumente und Assets fehlgeschlagen. Weitere Informationen im Log.
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.libreccm.mvc.freemarker;
|
||||
|
||||
import com.arsdigita.kernel.KernelConfig;
|
||||
|
||||
import freemarker.cache.ClassTemplateLoader;
|
||||
import freemarker.cache.MultiTemplateLoader;
|
||||
import freemarker.cache.TemplateLoader;
|
||||
|
|
@ -26,6 +28,7 @@ import freemarker.template.Configuration;
|
|||
import freemarker.template.TemplateExceptionHandler;
|
||||
import org.eclipse.krazo.engine.ViewEngineConfig;
|
||||
import org.eclipse.krazo.ext.freemarker.DefaultConfigurationProducer;
|
||||
import org.libreccm.configuration.ConfigurationManager;
|
||||
import org.libreccm.theming.Themes;
|
||||
|
||||
import javax.enterprise.inject.Produces;
|
||||
|
|
@ -43,6 +46,9 @@ import javax.servlet.ServletContext;
|
|||
public class MvcFreemarkerConfigurationProducer
|
||||
extends DefaultConfigurationProducer {
|
||||
|
||||
@Inject
|
||||
private ConfigurationManager confManager;
|
||||
|
||||
@Inject
|
||||
private Models models;
|
||||
|
||||
|
|
@ -60,15 +66,27 @@ public class MvcFreemarkerConfigurationProducer
|
|||
@Specializes
|
||||
@Override
|
||||
public Configuration getConfiguration() {
|
||||
final KernelConfig kernelConfig = confManager.findConfiguration(
|
||||
KernelConfig.class
|
||||
);
|
||||
|
||||
final Configuration configuration = new Configuration(
|
||||
Configuration.VERSION_2_3_30
|
||||
);
|
||||
|
||||
configuration.setDefaultEncoding("UTF-8");
|
||||
if (kernelConfig.isDebugEnabled()) {
|
||||
configuration.setTemplateExceptionHandler(
|
||||
TemplateExceptionHandler.DEBUG_HANDLER
|
||||
);
|
||||
configuration.setLogTemplateExceptions(true);
|
||||
} else {
|
||||
configuration.setTemplateExceptionHandler(
|
||||
TemplateExceptionHandler.RETHROW_HANDLER
|
||||
);
|
||||
configuration.setLogTemplateExceptions(false);
|
||||
}
|
||||
|
||||
configuration.setWrapUncheckedExceptions(false);
|
||||
configuration.setLocalizedLookup(false);
|
||||
configuration.setTemplateLoader(
|
||||
|
|
|
|||
|
|
@ -57,8 +57,10 @@ public class PermissionManager implements Serializable {
|
|||
|
||||
@SuppressWarnings("PMD.LongVariable")
|
||||
private static final String QUERY_PARAM_OBJECT = "object";
|
||||
|
||||
@SuppressWarnings("PMD.LongVariable")
|
||||
private static final String QUERY_PARAM_GRANTEE = "grantee";
|
||||
|
||||
@SuppressWarnings("PMD.LongVariable")
|
||||
private static final String QUERY_PARAM_PRIVILEGE = "privilege";
|
||||
|
||||
|
|
@ -79,8 +81,12 @@ public class PermissionManager implements Serializable {
|
|||
* @return The permission identified by the provided {@code permissionId).
|
||||
*/
|
||||
public Optional<Permission> findById(final long permissionId) {
|
||||
return Optional.ofNullable(entityManager.find(Permission.class,
|
||||
permissionId));
|
||||
return Optional.ofNullable(
|
||||
entityManager.find(
|
||||
Permission.class,
|
||||
permissionId
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,7 +99,9 @@ public class PermissionManager implements Serializable {
|
|||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public List<Permission> findPermissionsForRole(final Role role) {
|
||||
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
||||
"Permission.findPermissionsForRole", Permission.class);
|
||||
"Permission.findPermissionsForRole",
|
||||
Permission.class
|
||||
);
|
||||
query.setParameter("grantee", role);
|
||||
|
||||
return query.getResultList();
|
||||
|
|
@ -110,17 +118,22 @@ public class PermissionManager implements Serializable {
|
|||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public List<Permission> findPermissionsForObject(final CcmObject object) {
|
||||
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
||||
"Permission.findPermissionsForCcmObject", Permission.class);
|
||||
"Permission.findPermissionsForCcmObject",
|
||||
Permission.class
|
||||
);
|
||||
query.setParameter("object", object);
|
||||
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
public List<Permission> findPermissionsForRoleAndObject(
|
||||
final Role role, final CcmObject object) {
|
||||
|
||||
final Role role,
|
||||
final CcmObject object
|
||||
) {
|
||||
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
||||
"Permission.findPermissionsForRoleAndObject", Permission.class);
|
||||
"Permission.findPermissionsForRoleAndObject",
|
||||
Permission.class
|
||||
);
|
||||
query.setParameter("object", object);
|
||||
query.setParameter("grantee", role);
|
||||
|
||||
|
|
@ -148,9 +161,11 @@ public class PermissionManager implements Serializable {
|
|||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public Permission grantPrivilege(final String privilege,
|
||||
public Permission grantPrivilege(
|
||||
final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object) {
|
||||
final CcmObject object
|
||||
) {
|
||||
if (privilege == null || privilege.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't grant a permission without a privilege.");
|
||||
|
|
@ -182,7 +197,13 @@ public class PermissionManager implements Serializable {
|
|||
|
||||
entityManager.persist(permission);
|
||||
|
||||
grantRecursive(privilege, grantee, object, object.getClass(), object);
|
||||
grantRecursive(
|
||||
privilege,
|
||||
grantee,
|
||||
object,
|
||||
object.getClass(),
|
||||
object
|
||||
);
|
||||
|
||||
return permission;
|
||||
}
|
||||
|
|
@ -202,32 +223,44 @@ public class PermissionManager implements Serializable {
|
|||
* {@link #grantPrivilege(java.lang.String, org.libreccm.security.Role, org.libreccm.core.CcmObject)}
|
||||
* was invoked.
|
||||
*/
|
||||
private void grantRecursive(final String privilege,
|
||||
private void grantRecursive(
|
||||
final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object,
|
||||
final Class<?> clazz,
|
||||
final CcmObject inheritedFrom) {
|
||||
final CcmObject inheritedFrom
|
||||
) {
|
||||
final Field[] fields = clazz.getDeclaredFields();
|
||||
Arrays.stream(fields)
|
||||
.filter(field -> field.isAnnotationPresent(
|
||||
RecursivePermissions.class))
|
||||
.filter(field -> {
|
||||
return checkIfPrivilegeIsRecursive(
|
||||
.filter(
|
||||
field -> checkIfPrivilegeIsRecursive(
|
||||
field.getAnnotation(RecursivePermissions.class),
|
||||
privilege);
|
||||
})
|
||||
.forEach(field -> {
|
||||
privilege
|
||||
)
|
||||
)
|
||||
.forEach(
|
||||
field -> {
|
||||
field.setAccessible(true);
|
||||
grantRecursive(privilege, grantee, field, object, inheritedFrom);
|
||||
grantRecursive(
|
||||
privilege,
|
||||
grantee,
|
||||
field,
|
||||
object,
|
||||
inheritedFrom
|
||||
);
|
||||
});
|
||||
|
||||
// Repeat for superclass of the current class.
|
||||
if (clazz.getSuperclass() != null) {
|
||||
grantRecursive(privilege,
|
||||
grantRecursive(
|
||||
privilege,
|
||||
grantee,
|
||||
object,
|
||||
clazz.getSuperclass(),
|
||||
inheritedFrom);
|
||||
inheritedFrom
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,13 +279,14 @@ public class PermissionManager implements Serializable {
|
|||
*/
|
||||
private boolean checkIfPrivilegeIsRecursive(
|
||||
final RecursivePermissions annotation,
|
||||
final String privilege) {
|
||||
|
||||
final String privilege
|
||||
) {
|
||||
if (annotation.privileges() == null
|
||||
|| annotation.privileges().length == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return Arrays.stream(annotation.privileges())
|
||||
return Arrays
|
||||
.stream(annotation.privileges())
|
||||
.anyMatch(privilege::equals);
|
||||
}
|
||||
}
|
||||
|
|
@ -266,24 +300,35 @@ public class PermissionManager implements Serializable {
|
|||
* @param owner The object which own the provided {@code field}.
|
||||
* @param inheritedFrom The object from which the permission is inherited.
|
||||
*/
|
||||
private void grantRecursive(final String privilege,
|
||||
private void grantRecursive(
|
||||
final String privilege,
|
||||
final Role grantee,
|
||||
final Field field,
|
||||
final CcmObject owner,
|
||||
final CcmObject inheritedFrom) {
|
||||
|
||||
final CcmObject inheritedFrom
|
||||
) {
|
||||
final CcmObject ownerObject = ccmObjectRepo
|
||||
.findObjectById(owner.getObjectId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException(
|
||||
String.format(
|
||||
"No CcmObject with ID %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
owner.getObjectId())));
|
||||
owner.getObjectId()
|
||||
)
|
||||
)
|
||||
);
|
||||
final CcmObject inheritedFromObject = ccmObjectRepo
|
||||
.findObjectById(inheritedFrom.getObjectId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException(
|
||||
String.format(
|
||||
"No CcmObject with ID %d in the database. "
|
||||
+ "Where did that ID come from?",
|
||||
inheritedFrom.getObjectId())));
|
||||
inheritedFrom.getObjectId()
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
final Object value;
|
||||
try {
|
||||
|
|
@ -303,10 +348,14 @@ public class PermissionManager implements Serializable {
|
|||
collection.stream()
|
||||
.filter(obj -> obj instanceof CcmObject)
|
||||
.map(obj -> (CcmObject) obj)
|
||||
.forEach(obj -> grantInherited(privilege,
|
||||
.forEach(
|
||||
obj -> grantInherited(
|
||||
privilege,
|
||||
grantee,
|
||||
obj,
|
||||
inheritedFromObject));
|
||||
inheritedFromObject
|
||||
)
|
||||
);
|
||||
// Relations between two CcmObjects with attributes or n:m relations
|
||||
// use an object to represent the relation. The object must implement
|
||||
// the Relation interface. For each Relation object in the collection
|
||||
|
|
@ -316,33 +365,44 @@ public class PermissionManager implements Serializable {
|
|||
.map(obj -> (Relation) obj)
|
||||
.filter(relation -> relation.getRelatedObject() != null)
|
||||
.map(relation -> relation.getRelatedObject())
|
||||
.forEach(obj -> grantInherited(privilege,
|
||||
.forEach(
|
||||
obj -> grantInherited(
|
||||
privilege,
|
||||
grantee,
|
||||
obj,
|
||||
inheritedFromObject));
|
||||
inheritedFromObject
|
||||
)
|
||||
);
|
||||
} else if (CcmObject.class.isAssignableFrom(field.getType())) {
|
||||
// If the provided object is a CcmObject create an inherited
|
||||
// permission for this object.
|
||||
grantInherited(privilege,
|
||||
grantInherited(
|
||||
privilege,
|
||||
grantee,
|
||||
(CcmObject) value,
|
||||
inheritedFromObject);
|
||||
inheritedFromObject
|
||||
);
|
||||
} else if (Relation.class.isAssignableFrom(field.getType())) {
|
||||
// If the provided field is a Relation object created an inherited
|
||||
// permission on the related object.
|
||||
final Relation relation = (Relation) value;
|
||||
if (relation.getRelatedObject() != null) {
|
||||
grantInherited(privilege,
|
||||
grantInherited(
|
||||
privilege,
|
||||
grantee,
|
||||
relation.getRelatedObject(),
|
||||
inheritedFromObject);
|
||||
inheritedFromObject
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"Found a field annotated with \"%s\" but the field is not a "
|
||||
+ "collection nor a CcmObject nore a Relation object. This "
|
||||
+ "is not supported.",
|
||||
RecursivePermissions.class));
|
||||
RecursivePermissions.class
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -355,11 +415,12 @@ public class PermissionManager implements Serializable {
|
|||
* granted.
|
||||
* @param inheritedFrom The object from which the permission is inherited.
|
||||
*/
|
||||
private void grantInherited(final String privilege,
|
||||
private void grantInherited(
|
||||
final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object,
|
||||
final CcmObject inheritedFrom) {
|
||||
|
||||
final CcmObject inheritedFrom
|
||||
) {
|
||||
if (!existsPermission(privilege, grantee, object)) {
|
||||
final Permission permission = new Permission();
|
||||
permission.setGrantee(grantee);
|
||||
|
|
@ -371,11 +432,13 @@ public class PermissionManager implements Serializable {
|
|||
|
||||
entityManager.persist(permission);
|
||||
|
||||
grantRecursive(privilege,
|
||||
grantRecursive(
|
||||
privilege,
|
||||
grantee,
|
||||
object,
|
||||
object.getClass(),
|
||||
inheritedFrom);
|
||||
inheritedFrom
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -389,16 +452,20 @@ public class PermissionManager implements Serializable {
|
|||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void grantPrivilege(final String privilege,
|
||||
final Role grantee) {
|
||||
public void grantPrivilege(
|
||||
final String privilege,
|
||||
final Role grantee
|
||||
) {
|
||||
if (privilege == null || privilege.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't grant a permission without a privilege.");
|
||||
"Can't grant a permission without a privilege."
|
||||
);
|
||||
}
|
||||
|
||||
if (grantee == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't grant a permission to grantee null.");
|
||||
"Can't grant a permission to grantee null."
|
||||
);
|
||||
}
|
||||
|
||||
if (!existsPermission(privilege, grantee)) {
|
||||
|
|
@ -423,42 +490,52 @@ public class PermissionManager implements Serializable {
|
|||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void revokePrivilege(final String privilege,
|
||||
public void revokePrivilege(
|
||||
final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object) {
|
||||
final CcmObject object
|
||||
) {
|
||||
|
||||
if (privilege == null || privilege.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't revoke a permission without a privilege.");
|
||||
"Can't revoke a permission without a privilege."
|
||||
);
|
||||
}
|
||||
|
||||
if (grantee == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't revoke a permission from grantee null.");
|
||||
"Can't revoke a permission from grantee null."
|
||||
);
|
||||
}
|
||||
|
||||
if (object == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't revoke a permission from object NULL.");
|
||||
"Can't revoke a permission from object NULL."
|
||||
);
|
||||
}
|
||||
|
||||
LOGGER.debug("Revoking permission granting privilege \"{}\" "
|
||||
LOGGER.debug(
|
||||
"Revoking permission granting privilege \"{}\" "
|
||||
+ "on object \"{}\" to role \"{}\"...",
|
||||
privilege,
|
||||
grantee.getName(),
|
||||
object.getUuid());
|
||||
object.getUuid()
|
||||
);
|
||||
|
||||
if (existsPermission(privilege, grantee, object)
|
||||
|| existsInheritedPermission(privilege, grantee, object)) {
|
||||
|
||||
LOGGER.debug("There is a permission for the provided parameters, "
|
||||
+ "revoking it...");
|
||||
LOGGER.debug(
|
||||
"There is a permission for the provided parameters, "
|
||||
+ "revoking it..."
|
||||
);
|
||||
|
||||
final Query deleteQuery = entityManager.createQuery(
|
||||
"DELETE FROM Permission p "
|
||||
+ "WHERE p.grantedPrivilege = :privilege "
|
||||
+ "AND p.grantee = :grantee "
|
||||
+ "AND p.object = :object");
|
||||
+ "AND p.object = :object"
|
||||
);
|
||||
deleteQuery.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
deleteQuery.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
deleteQuery.setParameter(QUERY_PARAM_OBJECT, object);
|
||||
|
|
@ -470,18 +547,21 @@ public class PermissionManager implements Serializable {
|
|||
+ "WHERE p.grantedPrivilege = :privilege "
|
||||
+ "AND p.grantee = :grantee "
|
||||
+ "AND p.inheritedFrom = :object "
|
||||
+ "AND p.inherited = true");
|
||||
+ "AND p.inherited = true"
|
||||
);
|
||||
deleteInheritedQuery.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
deleteInheritedQuery.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
deleteInheritedQuery.setParameter("object", object);
|
||||
final int deletedInherited = deleteInheritedQuery.executeUpdate();
|
||||
LOGGER.debug("{} inherited permissions deleted.", deletedInherited);
|
||||
} else {
|
||||
LOGGER.warn("No permission granting privilege \"{}\" "
|
||||
LOGGER.warn(
|
||||
"No permission granting privilege \"{}\" "
|
||||
+ "on object \"{}\" to role \"{}\". Ignoring.",
|
||||
privilege,
|
||||
grantee.getName(),
|
||||
object.getUuid());
|
||||
object.getUuid()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -495,16 +575,20 @@ public class PermissionManager implements Serializable {
|
|||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void revokePrivilege(final String privilege,
|
||||
final Role grantee) {
|
||||
public void revokePrivilege(
|
||||
final String privilege,
|
||||
final Role grantee
|
||||
) {
|
||||
if (privilege == null || privilege.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't revoke a permission without a privilege.");
|
||||
"Can't revoke a permission without a privilege."
|
||||
);
|
||||
}
|
||||
|
||||
if (grantee == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't revoke a permission from grantee null.");
|
||||
"Can't revoke a permission from grantee null."
|
||||
);
|
||||
}
|
||||
|
||||
if (existsPermission(privilege, grantee)) {
|
||||
|
|
@ -512,7 +596,8 @@ public class PermissionManager implements Serializable {
|
|||
"DELETE FROM Permission p "
|
||||
+ "WHERE p.grantedPrivilege = :privilege "
|
||||
+ "AND p.grantee = :grantee "
|
||||
+ "AND p.object IS NULL");
|
||||
+ "AND p.object IS NULL"
|
||||
);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
query.executeUpdate();
|
||||
|
|
@ -532,8 +617,10 @@ public class PermissionManager implements Serializable {
|
|||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void copyPermissions(final CcmObject source,
|
||||
final CcmObject target) {
|
||||
public void copyPermissions(
|
||||
final CcmObject source,
|
||||
final CcmObject target
|
||||
) {
|
||||
copyPermissions(source, target, false);
|
||||
}
|
||||
|
||||
|
|
@ -552,21 +639,27 @@ public class PermissionManager implements Serializable {
|
|||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void copyPermissions(final CcmObject source,
|
||||
public void copyPermissions(
|
||||
final CcmObject source,
|
||||
final CcmObject target,
|
||||
final boolean inherited) {
|
||||
final boolean inherited
|
||||
) {
|
||||
if (source == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't copy permissions from source NULL.");
|
||||
"Can't copy permissions from source NULL."
|
||||
);
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't copy permissions to target NULL.");
|
||||
"Can't copy permissions to target NULL."
|
||||
);
|
||||
}
|
||||
|
||||
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
||||
"Permission.findPermissionsForCcmObject", Permission.class);
|
||||
"Permission.findPermissionsForCcmObject",
|
||||
Permission.class
|
||||
);
|
||||
query.setParameter(QUERY_PARAM_OBJECT, source);
|
||||
final List<Permission> result = query.getResultList();
|
||||
|
||||
|
|
@ -574,7 +667,11 @@ public class PermissionManager implements Serializable {
|
|||
final Permission granted = grantPrivilege(
|
||||
permission.getGrantedPrivilege(),
|
||||
permission.getGrantee(),
|
||||
target);
|
||||
target
|
||||
);
|
||||
if (granted == null) {
|
||||
continue;
|
||||
}
|
||||
granted.setInherited(inherited);
|
||||
if (inherited) {
|
||||
granted.setInheritedFrom(source);
|
||||
|
|
@ -598,12 +695,17 @@ public class PermissionManager implements Serializable {
|
|||
* @return A list with all privileges defined by the provided class.
|
||||
*/
|
||||
public List<String> listDefiniedPrivileges(final Class<?> clazz) {
|
||||
return Arrays.stream(clazz.getDeclaredFields())
|
||||
return Arrays
|
||||
.stream(clazz.getDeclaredFields())
|
||||
.filter(field -> field.getType().isAssignableFrom(String.class))
|
||||
.filter(field -> Modifier.isStatic(field.getModifiers())
|
||||
&& Modifier.isFinal(field.getModifiers()))
|
||||
.filter(field -> field.getName().startsWith("PRIVILEGE_")
|
||||
|| clazz.getSimpleName().endsWith("Privileges"))
|
||||
.filter(
|
||||
field -> Modifier.isStatic(field.getModifiers())
|
||||
&& Modifier.isFinal(field.getModifiers())
|
||||
)
|
||||
.filter(
|
||||
field -> field.getName().startsWith("PRIVILEGE_")
|
||||
|| clazz.getSimpleName().endsWith("Privileges")
|
||||
)
|
||||
.map(field -> getPrivilegeString(field))
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
|
|
@ -629,11 +731,15 @@ public class PermissionManager implements Serializable {
|
|||
* @return {@code true} if there is a matching permission, {@code false} if
|
||||
* not.
|
||||
*/
|
||||
private boolean existsPermission(final String privilege,
|
||||
private boolean existsPermission(
|
||||
final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object) {
|
||||
final CcmObject object
|
||||
) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Permission.existsDirectForPrivilegeRoleObject", Long.class);
|
||||
"Permission.existsDirectForPrivilegeRoleObject",
|
||||
Long.class
|
||||
);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
query.setParameter(QUERY_PARAM_OBJECT, object);
|
||||
|
|
@ -641,11 +747,15 @@ public class PermissionManager implements Serializable {
|
|||
return query.getSingleResult() > 0;
|
||||
}
|
||||
|
||||
private boolean existsInheritedPermission(final String privilege,
|
||||
private boolean existsInheritedPermission(
|
||||
final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object) {
|
||||
final CcmObject object
|
||||
) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Permission.existsInheritedForPrivilegeRoleObject", Long.class);
|
||||
"Permission.existsInheritedForPrivilegeRoleObject",
|
||||
Long.class
|
||||
);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
query.setParameter(QUERY_PARAM_OBJECT, object);
|
||||
|
|
@ -663,10 +773,14 @@ public class PermissionManager implements Serializable {
|
|||
* @return {@code true} if there is a matching permission, {@code false} if
|
||||
* not.
|
||||
*/
|
||||
private boolean existsPermission(final String privilege,
|
||||
final Role grantee) {
|
||||
private boolean existsPermission(
|
||||
final String privilege,
|
||||
final Role grantee
|
||||
) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Permission.existsForPrivilegeAndRole", Long.class);
|
||||
"Permission.existsForPrivilegeAndRole",
|
||||
Long.class
|
||||
);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,32 +57,36 @@ class FreemarkerConfigurationProvider {
|
|||
private final Map<ThemeInfo, Configuration> configurations = new HashMap<>();
|
||||
|
||||
protected Configuration getConfiguration(final ThemeInfo forTheme) {
|
||||
|
||||
if (configurations.containsKey(forTheme)) {
|
||||
|
||||
return configurations.get(forTheme);
|
||||
} else {
|
||||
|
||||
final Configuration configuration = new Configuration(
|
||||
Configuration.VERSION_2_3_27);
|
||||
Configuration.VERSION_2_3_27
|
||||
);
|
||||
configuration.setDefaultEncoding("UTF-8");
|
||||
configuration
|
||||
.setTemplateExceptionHandler(
|
||||
TemplateExceptionHandler.RETHROW_HANDLER);
|
||||
configuration.setLogTemplateExceptions(false);
|
||||
TemplateExceptionHandler.DEBUG_HANDLER
|
||||
);
|
||||
configuration.setLogTemplateExceptions(true);
|
||||
configuration.setWrapUncheckedExceptions(false);
|
||||
configuration.setLocalizedLookup(false);
|
||||
|
||||
configuration.setTemplateLoader(
|
||||
new MultiTemplateLoader(new TemplateLoader[]{
|
||||
new MultiTemplateLoader(
|
||||
new TemplateLoader[]{
|
||||
// For for files from themes
|
||||
new CcmTemplateLoader(forTheme),
|
||||
// Loader for MacroLibs provided by CCM modules
|
||||
new WebappTemplateLoader(
|
||||
servletContext, "/themes/freemarker"
|
||||
),
|
||||
new ClassTemplateLoader(getClass(), "/themes/freemarker")
|
||||
})
|
||||
new ClassTemplateLoader(
|
||||
getClass(),
|
||||
"/themes/freemarker"
|
||||
)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
configurations.put(forTheme, configuration);
|
||||
|
|
@ -103,7 +107,8 @@ class FreemarkerConfigurationProvider {
|
|||
public Object findTemplateSource(final String name) throws IOException {
|
||||
|
||||
final Optional<InputStream> source = themes.getFileFromTheme(
|
||||
fromTheme, name);
|
||||
fromTheme, name
|
||||
);
|
||||
if (source.isPresent()) {
|
||||
return source.get();
|
||||
} else {
|
||||
|
|
@ -118,9 +123,10 @@ class FreemarkerConfigurationProvider {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Reader getReader(final Object templateSource,
|
||||
final String encoding) throws IOException {
|
||||
|
||||
public Reader getReader(
|
||||
final Object templateSource,
|
||||
final String encoding
|
||||
) throws IOException {
|
||||
final InputStream inputStream = (InputStream) templateSource;
|
||||
return new InputStreamReader(inputStream, encoding);
|
||||
}
|
||||
|
|
@ -128,7 +134,6 @@ class FreemarkerConfigurationProvider {
|
|||
@Override
|
||||
public void closeTemplateSource(final Object templateSource)
|
||||
throws IOException {
|
||||
|
||||
final InputStream inputStream = (InputStream) templateSource;
|
||||
inputStream.close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,7 +217,9 @@ public class ImportExportTaskManager {
|
|||
* @see CompletionStage#handle(java.util.function.BiFunction)
|
||||
*/
|
||||
private Object handleExportTaskResult(
|
||||
final ExportTask task, final Throwable ex, final ExportTaskStatus status
|
||||
final ExportTask task,
|
||||
final Throwable ex,
|
||||
final ExportTaskStatus status
|
||||
) {
|
||||
if (ex == null) {
|
||||
status.setStatus(ImExportTaskStatus.FINISHED);
|
||||
|
|
|
|||
Loading…
Reference in New Issue