Fix item permissions function added
parent
edd4727b9a
commit
e94bc51c8e
|
|
@ -18,18 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui.contentsections;
|
package org.librecms.ui.contentsections;
|
||||||
|
|
||||||
import org.libreccm.categorization.Categorization;
|
|
||||||
import org.libreccm.security.AuthorizationRequired;
|
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.ContentSection;
|
||||||
import org.librecms.contentsection.ContentSectionManager;
|
import org.librecms.ui.contentsections.fixpermissions.FixItemPermissionsTaskManager;
|
||||||
import org.librecms.contentsection.Folder;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
/*
|
|
||||||
* 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -16,12 +16,15 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui.contentsections;
|
package org.librecms.ui.contentsections.fixpermissions;
|
||||||
|
|
||||||
import org.apache.shiro.mgt.SecurityManager;
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
import org.librecms.contentsection.ContentSection;
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -65,4 +68,23 @@ public class FixItemPermissionsTask {
|
||||||
return securityManager;
|
return securityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format(
|
||||||
|
"%s{"
|
||||||
|
+ "contentSection = %s, "
|
||||||
|
+ "started = %s, "
|
||||||
|
+ "status = %s"
|
||||||
|
+ "}",
|
||||||
|
super.toString(),
|
||||||
|
Objects.toString(contentSection),
|
||||||
|
Optional
|
||||||
|
.ofNullable(started)
|
||||||
|
.map(
|
||||||
|
value -> DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(value)
|
||||||
|
).orElse("null"),
|
||||||
|
Objects.toString(status)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui.contentsections;
|
package org.librecms.ui.contentsections.fixpermissions;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
@ -76,7 +76,7 @@ public class FixItemPermissionsTaskManager {
|
||||||
.anyMatch(
|
.anyMatch(
|
||||||
task -> task.getContentSection().equals(name)
|
task -> task.getContentSection().equals(name)
|
||||||
&& task.getStatus()
|
&& task.getStatus()
|
||||||
== FixItemPermissionsStatus.RUNNING
|
== FixPermissionsTaskStatus.RUNNING
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ public class FixItemPermissionsTaskManager {
|
||||||
.anyMatch(
|
.anyMatch(
|
||||||
task -> task.getContentSection().equals(name)
|
task -> task.getContentSection().equals(name)
|
||||||
&& task.getStatus()
|
&& task.getStatus()
|
||||||
== FixItemPermissionsStatus.ERROR
|
== FixPermissionsTaskStatus.ERROR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,9 +115,9 @@ public class FixItemPermissionsTaskManager {
|
||||||
.stream()
|
.stream()
|
||||||
.filter(
|
.filter(
|
||||||
task -> task.getStatus()
|
task -> task.getStatus()
|
||||||
== FixItemPermissionsStatus.ERROR
|
== FixPermissionsTaskStatus.ERROR
|
||||||
|| task.getStatus()
|
|| task.getStatus()
|
||||||
== FixItemPermissionsStatus.FINISHED
|
== FixPermissionsTaskStatus.FINISHED
|
||||||
)
|
)
|
||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
);
|
);
|
||||||
|
|
@ -135,7 +135,7 @@ public class FixItemPermissionsTaskManager {
|
||||||
)
|
)
|
||||||
).handle((task, ex) -> handleTaskResult(task, ex, taskStatus));
|
).handle((task, ex) -> handleTaskResult(task, ex, taskStatus));
|
||||||
|
|
||||||
taskStatus.setStatus(FixItemPermissionsStatus.RUNNING);
|
taskStatus.setStatus(FixPermissionsTaskStatus.RUNNING);
|
||||||
tasks.add(taskStatus);
|
tasks.add(taskStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,9 +145,9 @@ public class FixItemPermissionsTaskManager {
|
||||||
final FixItemPermissionsTaskStatus status
|
final FixItemPermissionsTaskStatus status
|
||||||
) {
|
) {
|
||||||
if (ex == null) {
|
if (ex == null) {
|
||||||
status.setStatus(FixItemPermissionsStatus.FINISHED);
|
status.setStatus(FixPermissionsTaskStatus.FINISHED);
|
||||||
} else {
|
} else {
|
||||||
status.setStatus(FixItemPermissionsStatus.ERROR);
|
status.setStatus(FixPermissionsTaskStatus.ERROR);
|
||||||
status.setException(ex);
|
status.setException(ex);
|
||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
"Fix Item Permissions for Content Section {} failed ",
|
"Fix Item Permissions for Content Section {} failed ",
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui.contentsections;
|
package org.librecms.ui.contentsections.fixpermissions;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
|
|
@ -44,7 +44,7 @@ public class FixItemPermissionsTaskStatus
|
||||||
/**
|
/**
|
||||||
* The status of the task.
|
* The status of the task.
|
||||||
*/
|
*/
|
||||||
private FixItemPermissionsStatus status;
|
private FixPermissionsTaskStatus status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the proces throw an exception, it is stored here.
|
* If the proces throw an exception, it is stored here.
|
||||||
|
|
@ -67,11 +67,11 @@ public class FixItemPermissionsTaskStatus
|
||||||
this.started = started;
|
this.started = started;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FixItemPermissionsStatus getStatus() {
|
public FixPermissionsTaskStatus getStatus() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setStatus(final FixItemPermissionsStatus status) {
|
protected void setStatus(final FixPermissionsTaskStatus status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -16,7 +16,9 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui.contentsections;
|
package org.librecms.ui.contentsections.fixpermissions;
|
||||||
|
|
||||||
|
import org.librecms.ui.contentsections.ContentSectionModel;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
@ -0,0 +1,404 @@
|
||||||
|
/*
|
||||||
|
* 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.fixpermissions;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.shiro.util.ThreadContext;
|
||||||
|
import org.libreccm.categorization.Categorization;
|
||||||
|
import org.libreccm.core.CcmObject;
|
||||||
|
import org.libreccm.security.PermissionManager;
|
||||||
|
import org.libreccm.security.Shiro;
|
||||||
|
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 javax.enterprise.event.Event;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(
|
||||||
|
FixItemPermissionsTasks.class
|
||||||
|
);
|
||||||
|
|
||||||
|
private final Queue<FixPermissionsForItemTask> openItemTasks;
|
||||||
|
|
||||||
|
private final Queue<FixPermissionsForAssetTask> openAssetTasks;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private AssetManager assetManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentItemManager itemManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentSectionRepository sectionRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PermissionManager permissionManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Event<ReadyForNextItemTaskEvent> readyForItemTaskSender;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Event<ReadyForNextAssetTaskEvent> readyForAssetTaskSender;
|
||||||
|
|
||||||
|
private long timestamp = 0;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Shiro shiro;
|
||||||
|
|
||||||
|
public FixItemPermissionsTasks() {
|
||||||
|
openItemTasks = new LinkedList<>();
|
||||||
|
openAssetTasks = new LinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTaskOpenForContentSection(final ContentSection section) {
|
||||||
|
final String sectionUuid = section.getUuid();
|
||||||
|
|
||||||
|
return openItemTasks
|
||||||
|
.stream()
|
||||||
|
.anyMatch(task -> task.getSectionUuid().equals(sectionUuid))
|
||||||
|
|| openAssetTasks
|
||||||
|
.stream()
|
||||||
|
.anyMatch(task -> task.getSectionUuid().equals(sectionUuid));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRES_NEW)
|
||||||
|
public void fixItemPermissions(
|
||||||
|
@ObservesAsync final FixItemPermissionsTask task
|
||||||
|
) {
|
||||||
|
ThreadContext.bind(task.getSecurityManager());
|
||||||
|
shiro.getSystemUser().execute(() -> executeFixItemPermissions(task));
|
||||||
|
|
||||||
|
readyForItemTaskSender.fireAsync(new ReadyForNextItemTaskEvent());
|
||||||
|
readyForAssetTaskSender.fireAsync(new ReadyForNextAssetTaskEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRES_NEW)
|
||||||
|
public void startNextItemTask(
|
||||||
|
@ObservesAsync final ReadyForNextItemTaskEvent event
|
||||||
|
) {
|
||||||
|
LOGGER.info("Starting next fix permissions for item task...");
|
||||||
|
|
||||||
|
final FixPermissionsForItemTask task = openItemTasks.poll();
|
||||||
|
if (task == null) {
|
||||||
|
LOGGER.info("No more fix permissions for item tasks available.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadContext.bind(task.getSecurityManager());
|
||||||
|
shiro.getSystemUser().execute(() -> executeFixPermissionsForItem(task));
|
||||||
|
|
||||||
|
readyForItemTaskSender.fireAsync(new ReadyForNextItemTaskEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRES_NEW)
|
||||||
|
public void startNextAssetTask(
|
||||||
|
@ObservesAsync final ReadyForNextItemTaskEvent event
|
||||||
|
) {
|
||||||
|
LOGGER.info("Starting next fix permissions for asset task...");
|
||||||
|
|
||||||
|
final FixPermissionsForAssetTask task = openAssetTasks.poll();
|
||||||
|
if (task == null) {
|
||||||
|
LOGGER.info("No more fix permissions for asset tasks available.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadContext.bind(task.getSecurityManager());
|
||||||
|
shiro.getSystemUser().execute(() -> executeFixPermissionsForAsset(task));
|
||||||
|
|
||||||
|
readyForAssetTaskSender.fireAsync(new ReadyForNextAssetTaskEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeFixItemPermissions(final FixItemPermissionsTask task) {
|
||||||
|
Optional
|
||||||
|
.ofNullable(task)
|
||||||
|
.map(FixItemPermissionsTask::getContentSection)
|
||||||
|
.map(ContentSection::getUuid)
|
||||||
|
.map(uuid -> sectionRepo.findByUuid(uuid).orElse(null))
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new IllegalArgumentException(
|
||||||
|
String.format(
|
||||||
|
"Can't get ContentSection from "
|
||||||
|
+ "FixItemPermissionsTask %s",
|
||||||
|
Objects.toString(task)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
fixItemPermissions(
|
||||||
|
sectionRepo.findByUuid(
|
||||||
|
task.getContentSection().getUuid()
|
||||||
|
).orElseThrow(
|
||||||
|
() -> new IllegalArgumentException()
|
||||||
|
),
|
||||||
|
task.getSecurityManager()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public void fixItemPermissions(
|
||||||
|
final ContentSection contentSection,
|
||||||
|
final org.apache.shiro.mgt.SecurityManager securityManager
|
||||||
|
) {
|
||||||
|
LOGGER.info(
|
||||||
|
"Fixing item permissions for content section {}...",
|
||||||
|
contentSection.getLabel()
|
||||||
|
);
|
||||||
|
timestamp = System.currentTimeMillis();
|
||||||
|
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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
LOGGER.info(
|
||||||
|
"Retrieve content section in {} ms.",
|
||||||
|
System.currentTimeMillis() - timestamp
|
||||||
|
);
|
||||||
|
timestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
fixContentItemPermissions(
|
||||||
|
section,
|
||||||
|
section.getRootDocumentsFolder(),
|
||||||
|
securityManager
|
||||||
|
);
|
||||||
|
fixAssetPermissions(
|
||||||
|
section,
|
||||||
|
section.getRootAssetsFolder(),
|
||||||
|
securityManager
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fixContentItemPermissions(
|
||||||
|
final ContentSection section,
|
||||||
|
final Folder folder,
|
||||||
|
final org.apache.shiro.mgt.SecurityManager securityManager
|
||||||
|
) {
|
||||||
|
LOGGER.info(
|
||||||
|
"Fixing permissions for items in folder {}",
|
||||||
|
folder.getName()
|
||||||
|
);
|
||||||
|
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) {
|
||||||
|
final FixPermissionsForItemTask task
|
||||||
|
= createFixItemPermissionsForItemTask(
|
||||||
|
section,
|
||||||
|
folder,
|
||||||
|
item,
|
||||||
|
securityManager
|
||||||
|
);
|
||||||
|
openItemTasks.add(task);
|
||||||
|
|
||||||
|
if (itemManager.isLive(item)) {
|
||||||
|
final FixPermissionsForItemTask liveTask
|
||||||
|
= createFixItemPermissionsForItemTask(
|
||||||
|
section,
|
||||||
|
folder,
|
||||||
|
itemManager.getLiveVersion(item, ContentItem.class)
|
||||||
|
.get(),
|
||||||
|
securityManager
|
||||||
|
);
|
||||||
|
openItemTasks.add(liveTask);
|
||||||
|
}
|
||||||
|
// final long fixForItemStart = System.currentTimeMillis();
|
||||||
|
// LOGGER.info(
|
||||||
|
// "Fixing permissions for item {} {}",
|
||||||
|
// item.getUuid(),
|
||||||
|
// itemManager.getItemPath(item)
|
||||||
|
// );
|
||||||
|
// permissionManager.copyPermissions(folder, item, true);
|
||||||
|
// LOGGER.info(
|
||||||
|
// "in {} ms",
|
||||||
|
// System.currentTimeMillis() - fixForItemStart
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// final long fixForLiveStart = System.currentTimeMillis();
|
||||||
|
// if (itemManager.isLive(item)) {
|
||||||
|
// permissionManager.copyPermissions(
|
||||||
|
// folder,
|
||||||
|
// itemManager.getLiveVersion(item, ContentItem.class).get(),
|
||||||
|
// true
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// LOGGER.info(
|
||||||
|
// "Fixed permissions for live item in {} ms",
|
||||||
|
// System.currentTimeMillis() - fixForLiveStart
|
||||||
|
// );
|
||||||
|
// LOGGER.info(
|
||||||
|
// "Fixed permissions for item in {} ms",
|
||||||
|
// System.currentTimeMillis() - fixForItemStart
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
LOGGER.info(
|
||||||
|
"Fixed permissions for items in folder {} in {} ms",
|
||||||
|
folder.getName(),
|
||||||
|
System.currentTimeMillis() - timestamp
|
||||||
|
);
|
||||||
|
timestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
for (final Folder subFolder : folder.getSubFolders()) {
|
||||||
|
fixContentItemPermissions(section, subFolder, securityManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fixAssetPermissions(
|
||||||
|
final ContentSection section,
|
||||||
|
final Folder folder,
|
||||||
|
final org.apache.shiro.mgt.SecurityManager securityManager
|
||||||
|
) {
|
||||||
|
LOGGER.info(
|
||||||
|
"Fixing permissions for assets in folder {}",
|
||||||
|
folder.getName()
|
||||||
|
);
|
||||||
|
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) {
|
||||||
|
final FixPermissionsForAssetTask task
|
||||||
|
= createFixItemPermissionsForAssetTask(
|
||||||
|
section,
|
||||||
|
folder,
|
||||||
|
asset,
|
||||||
|
securityManager
|
||||||
|
);
|
||||||
|
openAssetTasks.add(task);
|
||||||
|
// LOGGER.info(
|
||||||
|
// "Fixing permissions for asset {} {}...",
|
||||||
|
// asset.getUuid(),
|
||||||
|
// assetManager.getAssetPath(asset)
|
||||||
|
// );
|
||||||
|
// permissionManager.copyPermissions(folder, asset, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final Folder subFolder : folder.getSubFolders()) {
|
||||||
|
fixAssetPermissions(section, subFolder, securityManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private FixPermissionsForItemTask createFixItemPermissionsForItemTask(
|
||||||
|
final ContentSection section,
|
||||||
|
final Folder folder,
|
||||||
|
final ContentItem item,
|
||||||
|
final org.apache.shiro.mgt.SecurityManager securityManager
|
||||||
|
) {
|
||||||
|
final FixPermissionsForItemTask task
|
||||||
|
= new FixPermissionsForItemTask(
|
||||||
|
section.getUuid(),
|
||||||
|
folder,
|
||||||
|
item,
|
||||||
|
securityManager
|
||||||
|
);
|
||||||
|
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private FixPermissionsForAssetTask createFixItemPermissionsForAssetTask(
|
||||||
|
final ContentSection section,
|
||||||
|
final Folder folder,
|
||||||
|
final Asset asset,
|
||||||
|
final org.apache.shiro.mgt.SecurityManager securityManager
|
||||||
|
) {
|
||||||
|
final FixPermissionsForAssetTask task
|
||||||
|
= new FixPermissionsForAssetTask(
|
||||||
|
section.getUuid(),
|
||||||
|
folder,
|
||||||
|
asset,
|
||||||
|
securityManager
|
||||||
|
);
|
||||||
|
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void executeFixPermissionsForItem(
|
||||||
|
final FixPermissionsForItemTask task
|
||||||
|
) {
|
||||||
|
permissionManager.copyPermissions(
|
||||||
|
task.getFolder(),
|
||||||
|
task.getItem(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeFixPermissionsForAsset(
|
||||||
|
final FixPermissionsForAssetTask task
|
||||||
|
) {
|
||||||
|
permissionManager.copyPermissions(
|
||||||
|
task.getFolder(),
|
||||||
|
task.getAsset(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* 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.fixpermissions;
|
||||||
|
|
||||||
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
|
import org.librecms.contentsection.Asset;
|
||||||
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
import org.librecms.contentsection.Folder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class FixPermissionsForAssetTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UUID of the {@link ContentSection} to which the item belongs.
|
||||||
|
*/
|
||||||
|
private final String sectionUuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Folder} in which the item is stored. Source for the
|
||||||
|
* permissions to be copied to the item.
|
||||||
|
*/
|
||||||
|
private final Folder folder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Asset} which permssions will be fixed.
|
||||||
|
*/
|
||||||
|
private final Asset asset;
|
||||||
|
|
||||||
|
private final org.apache.shiro.mgt.SecurityManager securityManager;
|
||||||
|
|
||||||
|
public FixPermissionsForAssetTask(
|
||||||
|
final String sectionUuid,
|
||||||
|
final Folder folder,
|
||||||
|
final Asset asset,
|
||||||
|
final SecurityManager securityManager
|
||||||
|
) {
|
||||||
|
this.sectionUuid = sectionUuid;
|
||||||
|
this.folder = folder;
|
||||||
|
this.asset = asset;
|
||||||
|
this.securityManager = securityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSectionUuid() {
|
||||||
|
return sectionUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Folder getFolder() {
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Asset getAsset() {
|
||||||
|
return asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public org.apache.shiro.mgt.SecurityManager getSecurityManager() {
|
||||||
|
return securityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* 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.fixpermissions;
|
||||||
|
|
||||||
|
import org.apache.shiro.mgt.SecurityManager;
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
import org.librecms.contentsection.Folder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class FixPermissionsForItemTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UUID of the {@link ContentSection} to which the item belongs.
|
||||||
|
*/
|
||||||
|
private final String sectionUuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Folder} in which the item is stored. Source for the
|
||||||
|
* permissions to be copied to the item.
|
||||||
|
*/
|
||||||
|
private final Folder folder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ContentItem} which permssions will be fixed.
|
||||||
|
*/
|
||||||
|
private final ContentItem item;
|
||||||
|
|
||||||
|
private final org.apache.shiro.mgt.SecurityManager securityManager;
|
||||||
|
|
||||||
|
public FixPermissionsForItemTask(
|
||||||
|
final String sectionUuid,
|
||||||
|
final Folder folder,
|
||||||
|
final ContentItem item,
|
||||||
|
final SecurityManager securityManager
|
||||||
|
) {
|
||||||
|
this.sectionUuid = sectionUuid;
|
||||||
|
this.folder = folder;
|
||||||
|
this.item = item;
|
||||||
|
this.securityManager = securityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSectionUuid() {
|
||||||
|
return sectionUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Folder getFolder() {
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContentItem getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SecurityManager getSecurityManager() {
|
||||||
|
return securityManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -16,13 +16,13 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
* MA 02110-1301 USA
|
* MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
package org.librecms.ui.contentsections;
|
package org.librecms.ui.contentsections.fixpermissions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
*/
|
*/
|
||||||
public enum FixItemPermissionsStatus {
|
public enum FixPermissionsTaskStatus {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An error occured during the process.
|
* An error occured during the process.
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.fixpermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ReadyForNextAssetTaskEvent {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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.fixpermissions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
public class ReadyForNextItemTaskEvent {
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue