Compare commits
No commits in common. "master" and "deploy_packages_to_gitea" have entirely different histories.
master
...
deploy_pac
|
|
@ -20,10 +20,6 @@ pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage("Deploy") {
|
stage("Deploy") {
|
||||||
environment {
|
|
||||||
DEPLOY_TOKEN = credentials('gitea_libreccm_ci_packages')
|
|
||||||
NPM_TOKEN = credentials('gitea_libreccm_ci_packages')
|
|
||||||
}
|
|
||||||
steps {
|
steps {
|
||||||
dir('') {
|
dir('') {
|
||||||
configFileProvider([configFile(fileId: 'libreccm-packages-deploy', variable: 'MAVEN_SETTINGS')]) {
|
configFileProvider([configFile(fileId: 'libreccm-packages-deploy', variable: 'MAVEN_SETTINGS')]) {
|
||||||
|
|
|
||||||
|
|
@ -93,16 +93,6 @@
|
||||||
<goal>npm</goal>
|
<goal>npm</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
<!-- Sync Maven module version and NPM module version -->
|
|
||||||
<execution>
|
|
||||||
<id>npm version</id>
|
|
||||||
<goals>
|
|
||||||
<goal>npm</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<arguments>version --allow-same-version=true ${project.version}</arguments>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
<execution>
|
||||||
<id>build</id>
|
<id>build</id>
|
||||||
<goals>
|
<goals>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
@ -8,7 +7,6 @@
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<timestamp>${maven.build.timestamp}</timestamp>
|
<timestamp>${maven.build.timestamp}</timestamp>
|
||||||
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'Z</maven.build.timestamp.format>
|
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'Z</maven.build.timestamp.format>
|
||||||
<buildNumber></buildNumber>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
@ -157,16 +155,6 @@
|
||||||
<goal>npm</goal>
|
<goal>npm</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
<!-- Sync Maven module version and NPM module version -->
|
|
||||||
<execution>
|
|
||||||
<id>npm version</id>
|
|
||||||
<goals>
|
|
||||||
<goal>npm</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<arguments>version --allow-same-version=true ${project.version}${buildNumber}</arguments>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
<execution>
|
||||||
<id>build</id>
|
<id>build</id>
|
||||||
<goals>
|
<goals>
|
||||||
|
|
@ -195,7 +183,7 @@
|
||||||
<phase>deploy</phase>
|
<phase>deploy</phase>
|
||||||
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<arguments>publish -userconfig ../libreccm.npmrc</arguments>
|
<arguments>publish --userconfig ../libreccm.npmrc</arguments>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
@ -203,18 +191,4 @@
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>with-buildnumber</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>env.BUILD_NUMBER</name>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<properties>
|
|
||||||
<buildNumber>.${env.BUILD_NUMBER}</buildNumber>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@librecms/ccm-cms",
|
"name": "@librecms/ccm-cms",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0-SNAPSHOT.2023-03-23T131710",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@librecms/ccm-cms",
|
"name": "@librecms/ccm-cms",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0-SNAPSHOT.2023-03-23T131710",
|
||||||
"license": "LGPL-3.0-or-later",
|
"license": "LGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tiptap/core": "^2.0.0-beta.127",
|
"@tiptap/core": "^2.0.0-beta.127",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@librecms/ccm-cms",
|
"name": "@librecms/ccm-cms",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0-SNAPSHOT.2023-03-23T131710",
|
||||||
"description": "JavaScript stuff for ccm-cms",
|
"description": "JavaScript stuff for ccm-cms",
|
||||||
"main": "target/generated-resources/assets/@content-sections/cms-admin.js",
|
"main": "target/generated-resources/assets/@content-sections/cms-admin.js",
|
||||||
"types": "target/generated-resources/assets/@content-sections/cms-admin.d.ts",
|
"types": "target/generated-resources/assets/@content-sections/cms-admin.d.ts",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|
@ -14,7 +13,6 @@
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<timestamp>${maven.build.timestamp}</timestamp>
|
<timestamp>${maven.build.timestamp}</timestamp>
|
||||||
<maven.build.timestamp.format>yyyy-MM-dd'T'HHmmss</maven.build.timestamp.format>
|
<maven.build.timestamp.format>yyyy-MM-dd'T'HHmmss</maven.build.timestamp.format>
|
||||||
<buildNumber></buildNumber>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<groupId>org.librecms</groupId>
|
<groupId>org.librecms</groupId>
|
||||||
|
|
@ -235,20 +233,20 @@
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
<id>npm install</id>
|
<id>set package version</id>
|
||||||
<goals>
|
|
||||||
<goal>npm</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>npm version</id>
|
|
||||||
<goals>
|
<goals>
|
||||||
<goal>npm</goal>
|
<goal>npm</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<arguments>version --allow-same-version=true ${project.version}${buildNumber}</arguments>
|
<arguments>pkg set version=${project.version}.${timestamp}</arguments>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>npm install</id>
|
||||||
|
<goals>
|
||||||
|
<goal>npm</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
<id>build</id>
|
<id>build</id>
|
||||||
<goals>
|
<goals>
|
||||||
|
|
@ -268,7 +266,7 @@
|
||||||
<phase>deploy</phase>
|
<phase>deploy</phase>
|
||||||
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<arguments>publish -userconfig ../libreccm.npmrc</arguments>
|
<arguments>publish --userconfig ../libreccm.npmrc</arguments>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
@ -428,18 +426,6 @@
|
||||||
|
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
|
||||||
<id>with-buildnumber</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>env.BUILD_NUMBER</name>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<properties>
|
|
||||||
<buildNumber>.${env.BUILD_NUMBER}</buildNumber>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
|
|
||||||
<profile>
|
<profile>
|
||||||
<id>run-its-with-wildfly-h2mem</id>
|
<id>run-its-with-wildfly-h2mem</id>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
||||||
|
|
@ -246,12 +246,7 @@ public class PagesController {
|
||||||
final Versions versions = generateFromPreviewParam(preview);
|
final Versions versions = generateFromPreviewParam(preview);
|
||||||
final String language = determineLanguage(category, versions);
|
final String language = determineLanguage(category, versions);
|
||||||
|
|
||||||
categoryModel.init(
|
initPageUrlModel(uriInfo);
|
||||||
pages.getCategoryDomain(),
|
|
||||||
category,
|
|
||||||
generateFromPreviewParam(preview).getContentItemVersion()
|
|
||||||
);
|
|
||||||
pageUrlModel.init(uriInfo);
|
|
||||||
|
|
||||||
final String indexPage = String.format(
|
final String indexPage = String.format(
|
||||||
"/index.%s.html%s",
|
"/index.%s.html%s",
|
||||||
|
|
@ -282,12 +277,7 @@ public class PagesController {
|
||||||
final Versions versions = generateFromPreviewParam(preview);
|
final Versions versions = generateFromPreviewParam(preview);
|
||||||
final String language = determineLanguage(category, versions);
|
final String language = determineLanguage(category, versions);
|
||||||
|
|
||||||
categoryModel.init(
|
initPageUrlModel(uriInfo);
|
||||||
pages.getCategoryDomain(),
|
|
||||||
category,
|
|
||||||
generateFromPreviewParam(preview).getContentItemVersion()
|
|
||||||
);
|
|
||||||
pageUrlModel.init(uriInfo);
|
|
||||||
|
|
||||||
final String itemPage = String.format(
|
final String itemPage = String.format(
|
||||||
"/%s.%s.html%s",
|
"/%s.%s.html%s",
|
||||||
|
|
@ -319,12 +309,7 @@ public class PagesController {
|
||||||
final Versions versions = generateFromPreviewParam(preview);
|
final Versions versions = generateFromPreviewParam(preview);
|
||||||
final String language = determineLanguage(category, itemName, versions);
|
final String language = determineLanguage(category, itemName, versions);
|
||||||
|
|
||||||
categoryModel.init(
|
initPageUrlModel(uriInfo);
|
||||||
pages.getCategoryDomain(),
|
|
||||||
category,
|
|
||||||
generateFromPreviewParam(preview).getContentItemVersion()
|
|
||||||
);
|
|
||||||
pageUrlModel.init(uriInfo);
|
|
||||||
|
|
||||||
final String itemPage = String.format(
|
final String itemPage = String.format(
|
||||||
"/%s.%s.html", itemName, language
|
"/%s.%s.html", itemName, language
|
||||||
|
|
@ -432,7 +417,7 @@ public class PagesController {
|
||||||
final Versions versions = generateFromPreviewParam(preview);
|
final Versions versions = generateFromPreviewParam(preview);
|
||||||
final String language = determineLanguage(category, versions);
|
final String language = determineLanguage(category, versions);
|
||||||
|
|
||||||
pageUrlModel.init(uriInfo);
|
initPageUrlModel(uriInfo);
|
||||||
|
|
||||||
final String redirectTo;
|
final String redirectTo;
|
||||||
if (uriInfo.getPath().endsWith("/")) {
|
if (uriInfo.getPath().endsWith("/")) {
|
||||||
|
|
@ -488,7 +473,7 @@ public class PagesController {
|
||||||
final Versions versions = generateFromPreviewParam(preview);
|
final Versions versions = generateFromPreviewParam(preview);
|
||||||
final String language = determineLanguage(category, versions);
|
final String language = determineLanguage(category, versions);
|
||||||
|
|
||||||
pageUrlModel.init(uriInfo);
|
initPageUrlModel(uriInfo);
|
||||||
|
|
||||||
final String redirectTo;
|
final String redirectTo;
|
||||||
if (uriInfo.getPath().endsWith("/")) {
|
if (uriInfo.getPath().endsWith("/")) {
|
||||||
|
|
@ -564,7 +549,7 @@ public class PagesController {
|
||||||
.sorted()
|
.sorted()
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
);
|
);
|
||||||
|
initPageUrlModel(uriInfo);
|
||||||
siteInfoModel.setDomain(site.getDomainOfSite());
|
siteInfoModel.setDomain(site.getDomainOfSite());
|
||||||
siteInfoModel.setHost(domain);
|
siteInfoModel.setHost(domain);
|
||||||
siteInfoModel.setName(
|
siteInfoModel.setName(
|
||||||
|
|
@ -572,36 +557,20 @@ public class PagesController {
|
||||||
.ofNullable(site.getDisplayName())
|
.ofNullable(site.getDisplayName())
|
||||||
.orElse("")
|
.orElse("")
|
||||||
);
|
);
|
||||||
|
|
||||||
final Category category = getCategory(domain, pages, pagePath);
|
final Category category = getCategory(domain, pages, pagePath);
|
||||||
categoryModel.init(pages.getCategoryDomain(), category, version);
|
categoryModel.init(pages.getCategoryDomain(), category, version);
|
||||||
|
|
||||||
pageUrlModel.init(uriInfo);
|
|
||||||
|
|
||||||
final Page page = pageManager.findPageForCategory(category);
|
final Page page = pageManager.findPageForCategory(category);
|
||||||
pagePropertiesModel.setProperties(page.getProperties());
|
pagePropertiesModel.setProperties(page.getProperties());
|
||||||
try {
|
|
||||||
final String result;
|
|
||||||
if (itemName.equals("index") || itemName.isBlank()) {
|
if (itemName.equals("index") || itemName.isBlank()) {
|
||||||
result = themesMvc.getMvcTemplate(
|
return themesMvc.getMvcTemplate(
|
||||||
uriInfo, "pages", page.getDisplayName()
|
uriInfo, "pages", page.getDisplayName()
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
result = themesMvc.getMvcTemplate(
|
return themesMvc.getMvcTemplate(
|
||||||
uriInfo, "pages", "item-page"
|
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(
|
private void initSiteInfoModel(
|
||||||
|
|
@ -744,7 +713,7 @@ public class PagesController {
|
||||||
private String buildQueryParamsStr(
|
private String buildQueryParamsStr(
|
||||||
final String previewParam, final String themeParam
|
final String previewParam, final String themeParam
|
||||||
) {
|
) {
|
||||||
final String queryString = List
|
return List
|
||||||
.of(
|
.of(
|
||||||
Optional
|
Optional
|
||||||
.of(themeParam)
|
.of(themeParam)
|
||||||
|
|
@ -760,12 +729,6 @@ public class PagesController {
|
||||||
.stream()
|
.stream()
|
||||||
.filter(String::isBlank)
|
.filter(String::isBlank)
|
||||||
.collect(Collectors.joining("&", "?", ""));
|
.collect(Collectors.joining("&", "?", ""));
|
||||||
|
|
||||||
if (queryString.length() <= 1) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return queryString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ThemeInfo getTheme(
|
private ThemeInfo getTheme(
|
||||||
|
|
@ -865,60 +828,25 @@ public class PagesController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void pageUrlModel.init(final UriInfo uriInfo) {
|
private void initPageUrlModel(final UriInfo uriInfo) {
|
||||||
// pageUrlModel.setBasePath(uriInfo.getBaseUri().toString());
|
pageUrlModel.setHost(uriInfo.getRequestUri().getHost());
|
||||||
// pageUrlModel.setBaseUri(uriInfo.getBaseUri());
|
pageUrlModel.setPath(uriInfo.getPath());
|
||||||
// pageUrlModel.setHost(uriInfo.getRequestUri().getHost());
|
pageUrlModel.setPort(uriInfo.getRequestUri().getPort());
|
||||||
//
|
pageUrlModel.setProtocol(uriInfo.getRequestUri().getScheme());
|
||||||
// final List<PathSegment> pathSegments = uriInfo.getPathSegments();
|
pageUrlModel.setQueryParameters(
|
||||||
// if (pathSegments.isEmpty()) {
|
uriInfo
|
||||||
// throw new IllegalArgumentException("No page segements available.");
|
.getQueryParameters()
|
||||||
// }
|
.entrySet()
|
||||||
// pageUrlModel.setPath(
|
.stream()
|
||||||
// pathSegments
|
.collect(
|
||||||
// .subList(0, pathSegments.size())
|
Collectors.toMap(
|
||||||
// .stream()
|
entry -> entry.getKey(),
|
||||||
// .map(PathSegment::getPath)
|
entry -> entry.getValue().get(0)
|
||||||
// .collect(Collectors.joining("/"))
|
)
|
||||||
// );
|
)
|
||||||
// final String pageSegment = pathSegments
|
);
|
||||||
// .get(pathSegments.size() - 1)
|
}
|
||||||
// .getPath();
|
|
||||||
// final String[] pageTokens = pageSegment.split("\\.");
|
|
||||||
// if (pageTokens.length != 3) {
|
|
||||||
// throw new IllegalArgumentException(
|
|
||||||
// String.format(
|
|
||||||
// "Unexpected number of tokens for page segement of path."
|
|
||||||
// + "Expected 3 tokens, separated by '.', but got %d "
|
|
||||||
// + "tokens.",
|
|
||||||
// pageTokens.length
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// final String pageName = pageTokens[0];
|
|
||||||
// final String pageLocale = pageTokens[1];
|
|
||||||
// final String pageFormat = pageTokens[2];
|
|
||||||
//
|
|
||||||
// pageUrlModel.setPageName(pageName);
|
|
||||||
// pageUrlModel.setPageLocale(pageLocale);
|
|
||||||
// pageUrlModel.setPageFormat(pageFormat);
|
|
||||||
//
|
|
||||||
// pageUrlModel.setPath(uriInfo.getPath());
|
|
||||||
// pageUrlModel.setPort(uriInfo.getRequestUri().getPort());
|
|
||||||
// pageUrlModel.setProtocol(uriInfo.getRequestUri().getScheme());
|
|
||||||
// pageUrlModel.setQueryParameters(
|
|
||||||
// uriInfo
|
|
||||||
// .getQueryParameters()
|
|
||||||
// .entrySet()
|
|
||||||
// .stream()
|
|
||||||
// .collect(
|
|
||||||
// Collectors.toMap(
|
|
||||||
// entry -> entry.getKey(),
|
|
||||||
// entry -> entry.getValue().get(0)
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
/**
|
/**
|
||||||
* Encapsulate the result of converting the value of the {@code preview}
|
* Encapsulate the result of converting the value of the {@code preview}
|
||||||
* query parameter.
|
* query parameter.
|
||||||
|
|
|
||||||
|
|
@ -1,57 +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.pages.models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
public class BreadcrumbData {
|
|
||||||
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
private String path;
|
|
||||||
|
|
||||||
private String link;
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTitle(final String title) {
|
|
||||||
this.title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPath() {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPath(final String path) {
|
|
||||||
this.path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLink() {
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLink(final String link) {
|
|
||||||
this.link = link;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -20,13 +20,14 @@ package org.librecms.pages.models;
|
||||||
|
|
||||||
import org.libreccm.categorization.Category;
|
import org.libreccm.categorization.Category;
|
||||||
import org.libreccm.categorization.CategoryManager;
|
import org.libreccm.categorization.CategoryManager;
|
||||||
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
import org.libreccm.categorization.Domain;
|
import org.libreccm.categorization.Domain;
|
||||||
import org.libreccm.categorization.DomainRepository;
|
import org.libreccm.categorization.DomainRepository;
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.librecms.contentsection.ContentItemVersion;
|
import org.librecms.contentsection.ContentItemVersion;
|
||||||
|
import org.librecms.pages.PagesService;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
@ -56,6 +57,9 @@ public class CategoryModel implements Serializable {
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private PagesService pagesService;
|
||||||
|
|
||||||
private CategoryDomainData domain;
|
private CategoryDomainData domain;
|
||||||
|
|
||||||
private CategoryData category;
|
private CategoryData category;
|
||||||
|
|
@ -122,11 +126,6 @@ public class CategoryModel implements Serializable {
|
||||||
|
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public CategoryTreeNode getCategoryTree() {
|
public CategoryTreeNode getCategoryTree() {
|
||||||
if (domain == null) {
|
|
||||||
final CategoryTreeNode emptyNode = new CategoryTreeNode();
|
|
||||||
emptyNode.setSubCategories(Collections.emptyList());
|
|
||||||
return emptyNode;
|
|
||||||
}
|
|
||||||
final Domain currentDomain = domainRepository
|
final Domain currentDomain = domainRepository
|
||||||
.findById(domain.getDomainId())
|
.findById(domain.getDomainId())
|
||||||
.orElseThrow(
|
.orElseThrow(
|
||||||
|
|
@ -149,26 +148,17 @@ public class CategoryModel implements Serializable {
|
||||||
) {
|
) {
|
||||||
final CategoryTreeNode node = new CategoryTreeNode();
|
final CategoryTreeNode node = new CategoryTreeNode();
|
||||||
node.setCategoryPath(categoryManager.getCategoryPath(fromCategory));
|
node.setCategoryPath(categoryManager.getCategoryPath(fromCategory));
|
||||||
node.setCategoyLink(
|
|
||||||
String.format(
|
|
||||||
"/pages/%s/index.%s.html",
|
|
||||||
node.getCategoryPath(),
|
|
||||||
globalizationHelper.getNegotiatedLocale().toString()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
node.setDescription(
|
node.setDescription(
|
||||||
globalizationHelper.getValueFromLocalizedString(
|
globalizationHelper.getValueFromLocalizedString(
|
||||||
fromCategory.getDescription())
|
fromCategory.getDescription())
|
||||||
);
|
);
|
||||||
node.setName(fromCategory.getName());
|
node.setName(fromCategory.getName());
|
||||||
node.setVisible(fromCategory.isVisible());
|
|
||||||
node.setSelected(fromCategory.getUuid().equals(category.getUuid()));
|
node.setSelected(fromCategory.getUuid().equals(category.getUuid()));
|
||||||
node.setParentCategory(parent);
|
node.setParentCategory(parent);
|
||||||
node.setSubCategories(
|
node.setSubCategories(
|
||||||
fromCategory
|
fromCategory
|
||||||
.getSubCategories()
|
.getSubCategories()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(cat -> !cat.isAbstractCategory())
|
|
||||||
.sorted(Comparator.comparing(Category::getCategoryOrder))
|
.sorted(Comparator.comparing(Category::getCategoryOrder))
|
||||||
.map(cat -> buildTreeNode(cat, node))
|
.map(cat -> buildTreeNode(cat, node))
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
|
|
|
||||||
|
|
@ -38,10 +38,6 @@ public class CategoryTreeNode {
|
||||||
|
|
||||||
private String categoryPath;
|
private String categoryPath;
|
||||||
|
|
||||||
private String categoryLink;
|
|
||||||
|
|
||||||
private boolean visible;
|
|
||||||
|
|
||||||
private boolean selected;
|
private boolean selected;
|
||||||
|
|
||||||
private boolean subCategorySelected;
|
private boolean subCategorySelected;
|
||||||
|
|
@ -90,14 +86,6 @@ public class CategoryTreeNode {
|
||||||
this.categoryPath = categoryPath;
|
this.categoryPath = categoryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCategoryLink() {
|
|
||||||
return categoryLink;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setCategoyLink(final String categoryLink) {
|
|
||||||
this.categoryLink = categoryLink;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<CategoryTreeNode> getSubCategories() {
|
public List<CategoryTreeNode> getSubCategories() {
|
||||||
return Collections.unmodifiableList(subCategories);
|
return Collections.unmodifiableList(subCategories);
|
||||||
}
|
}
|
||||||
|
|
@ -108,14 +96,6 @@ public class CategoryTreeNode {
|
||||||
this.subCategories = new ArrayList<>(subCategories);
|
this.subCategories = new ArrayList<>(subCategories);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVisible() {
|
|
||||||
return visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setVisible(boolean visible) {
|
|
||||||
this.visible = visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSelected() {
|
public boolean isSelected() {
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
@ -124,6 +104,7 @@ public class CategoryTreeNode {
|
||||||
this.selected = selected;
|
this.selected = selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CategoryTreeNode getParentCategory() {
|
public CategoryTreeNode getParentCategory() {
|
||||||
return parentCategory;
|
return parentCategory;
|
||||||
}
|
}
|
||||||
|
|
@ -136,6 +117,7 @@ public class CategoryTreeNode {
|
||||||
return subCategorySelected;
|
return subCategorySelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void setSubCategorySelected(final boolean subCategorySelected) {
|
protected void setSubCategorySelected(final boolean subCategorySelected) {
|
||||||
this.subCategorySelected = subCategorySelected;
|
this.subCategorySelected = subCategorySelected;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +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.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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +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.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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -170,17 +170,6 @@ public class ContentItemModel {
|
||||||
return contentItem.isPresent();
|
return contentItem.isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * A convient getter for checking if a content item is available from a
|
|
||||||
// * template.
|
|
||||||
// *
|
|
||||||
// * @return {@code true} if an item is available, {@code false} if not.
|
|
||||||
// */
|
|
||||||
// @Transactional(Transactional.TxType.REQUIRED)
|
|
||||||
// public boolean getItemAvailable() {
|
|
||||||
// init();
|
|
||||||
// return contentItem.isPresent();
|
|
||||||
// }
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@code objectId)} (see {@link CcmObject#objectId} of the current
|
* Gets the {@code objectId)} (see {@link CcmObject#objectId} of the current
|
||||||
* item.
|
* item.
|
||||||
|
|
@ -433,11 +422,6 @@ public class ContentItemModel {
|
||||||
*/
|
*/
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
private Optional<ContentItem> retrieveContentItem() {
|
private Optional<ContentItem> retrieveContentItem() {
|
||||||
if (categoryModel.getCategory() == null) {
|
|
||||||
// For none-category pages, for example login
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Optional<ContentItem> item;
|
final Optional<ContentItem> item;
|
||||||
if (itemName == null || "index".equals(itemName)) {
|
if (itemName == null || "index".equals(itemName)) {
|
||||||
item = pagesService.findIndexItem(
|
item = pagesService.findIndexItem(
|
||||||
|
|
|
||||||
|
|
@ -186,14 +186,12 @@ public class ItemListModel {
|
||||||
public List<? extends AbstractContentItemListItemModel> getItems(
|
public List<? extends AbstractContentItemListItemModel> getItems(
|
||||||
final String listName
|
final String listName
|
||||||
) {
|
) {
|
||||||
// If no category is available, for example in the login application
|
final List<? extends AbstractContentItemListItemModel> items
|
||||||
if (categoryModel.getCategory() == null) {
|
= Collections.unmodifiableList(
|
||||||
return Collections.emptyList();
|
buildList(
|
||||||
}
|
buildLimitToType(getLimitToTypeSetting(listName)),
|
||||||
|
collectCategories(
|
||||||
final Class<? extends ContentItem> limitToType = buildLimitToType(
|
categoryRepository
|
||||||
getLimitToTypeSetting(listName));
|
|
||||||
final Category currentCategory = categoryRepository
|
|
||||||
.findById(categoryModel.getCategory().getCategoryId())
|
.findById(categoryModel.getCategory().getCategoryId())
|
||||||
.orElseThrow(
|
.orElseThrow(
|
||||||
() -> new RuntimeException(
|
() -> new RuntimeException(
|
||||||
|
|
@ -204,20 +202,11 @@ public class ItemListModel {
|
||||||
categoryModel.getCategory().getCategoryId()
|
categoryModel.getCategory().getCategoryId()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
)
|
||||||
final List<Category> categories = collectCategories(currentCategory);
|
),
|
||||||
final List<String> listOrder = getListOrderSetting(listName);
|
getListOrderSetting(listName),
|
||||||
final int pageSize = getPageSizeSetting(listName);
|
getPageSizeSetting(listName),
|
||||||
final int offset = getOffset(listName, getPageSizeSetting(listName));
|
getOffset(listName, getPageSizeSetting(listName))
|
||||||
|
|
||||||
final List<? extends AbstractContentItemListItemModel> items
|
|
||||||
= Collections.unmodifiableList(
|
|
||||||
buildList(
|
|
||||||
limitToType,
|
|
||||||
categories,
|
|
||||||
listOrder,
|
|
||||||
pageSize,
|
|
||||||
offset
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -251,11 +240,10 @@ public class ItemListModel {
|
||||||
criteriaBuilder.isNull(catJoin.get("type")),
|
criteriaBuilder.isNull(catJoin.get("type")),
|
||||||
criteriaBuilder.equal(
|
criteriaBuilder.equal(
|
||||||
from.get("version"), ContentItemVersion.LIVE
|
from.get("version"), ContentItemVersion.LIVE
|
||||||
|
),
|
||||||
|
buildPermissionsCheck(
|
||||||
|
criteriaBuilder, from, permissionsJoin
|
||||||
)
|
)
|
||||||
// ,
|
|
||||||
// buildPermissionsCheck(
|
|
||||||
// criteriaBuilder, from, permissionsJoin
|
|
||||||
// )
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -266,7 +254,7 @@ public class ItemListModel {
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
);
|
);
|
||||||
|
|
||||||
final List<? extends AbstractContentItemListItemModel> result = entityManager
|
return entityManager
|
||||||
.createQuery(criteriaQuery)
|
.createQuery(criteriaQuery)
|
||||||
.getResultList()
|
.getResultList()
|
||||||
.stream()
|
.stream()
|
||||||
|
|
@ -279,8 +267,6 @@ public class ItemListModel {
|
||||||
.limit(pageSize)
|
.limit(pageSize)
|
||||||
.map(this::buildListItemModel)
|
.map(this::buildListItemModel)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Category> collectCategories(final Category category) {
|
private List<Category> collectCategories(final Category category) {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ package org.librecms.pages.models;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
@ -37,10 +36,7 @@ public class PagePropertiesModel {
|
||||||
private Map<String, String> properties;
|
private Map<String, String> properties;
|
||||||
|
|
||||||
public Map<String, String> getProperties() {
|
public Map<String, String> getProperties() {
|
||||||
return Optional
|
return Collections.unmodifiableMap(properties);
|
||||||
.ofNullable(properties)
|
|
||||||
.map(Collections::unmodifiableMap)
|
|
||||||
.orElse(Collections.emptyMap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProperties(final Map<String, String> properties) {
|
public void setProperties(final Map<String, String> properties) {
|
||||||
|
|
|
||||||
|
|
@ -18,21 +18,13 @@
|
||||||
*/
|
*/
|
||||||
package org.librecms.pages.models;
|
package org.librecms.pages.models;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.enterprise.context.RequestScoped;
|
import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.core.PathSegment;
|
|
||||||
import javax.ws.rs.core.UriBuilder;
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Model initialized by the Pages application containing information about the
|
* Model initialized by the Pages application containing information about the
|
||||||
|
|
@ -44,128 +36,50 @@ import javax.ws.rs.core.UriInfo;
|
||||||
@Named("CmsPagesPageUrlModel")
|
@Named("CmsPagesPageUrlModel")
|
||||||
public class PageUrlModel {
|
public class PageUrlModel {
|
||||||
|
|
||||||
@Inject
|
|
||||||
private CategoryModel categoryModel;
|
|
||||||
|
|
||||||
private String protocol;
|
private String protocol;
|
||||||
|
|
||||||
private String host;
|
private String host;
|
||||||
|
|
||||||
private int port;
|
private int port;
|
||||||
|
|
||||||
private URI baseUri;
|
|
||||||
|
|
||||||
private String basePath;
|
|
||||||
|
|
||||||
private String path;
|
private String path;
|
||||||
|
|
||||||
private List<BreadcrumbData> breadcrumbs;
|
|
||||||
|
|
||||||
private String pageName;
|
|
||||||
|
|
||||||
private String pageLocale;
|
|
||||||
|
|
||||||
private String pageFormat;
|
|
||||||
|
|
||||||
private Map<String, String> queryParameters;
|
private Map<String, String> queryParameters;
|
||||||
|
|
||||||
public PageUrlModel() {
|
|
||||||
queryParameters = new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(final UriInfo uriInfo) {
|
|
||||||
basePath = uriInfo.getBaseUri().toString();
|
|
||||||
baseUri = uriInfo.getBaseUri();
|
|
||||||
host = uriInfo.getRequestUri().getHost();
|
|
||||||
|
|
||||||
final List<PathSegment> pathSegments = uriInfo.getPathSegments();
|
|
||||||
if (pathSegments.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("No page segements available.");
|
|
||||||
}
|
|
||||||
path = pathSegments
|
|
||||||
.subList(0, pathSegments.size())
|
|
||||||
.stream()
|
|
||||||
.map(PathSegment::getPath)
|
|
||||||
.collect(Collectors.joining("/"));
|
|
||||||
final String pageSegment = pathSegments
|
|
||||||
.get(pathSegments.size() - 1)
|
|
||||||
.getPath();
|
|
||||||
final String[] pageTokens = pageSegment.split("\\.");
|
|
||||||
if (pageTokens.length != 3) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
String.format(
|
|
||||||
"Unexpected number of tokens for page segement of path."
|
|
||||||
+ "Expected 3 tokens, separated by '.', but got %d "
|
|
||||||
+ "tokens.",
|
|
||||||
pageTokens.length
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
pageName = pageTokens[0];
|
|
||||||
pageLocale = pageTokens[1];
|
|
||||||
pageFormat = pageTokens[2];
|
|
||||||
|
|
||||||
path = uriInfo.getPath();
|
|
||||||
port = uriInfo.getRequestUri().getPort();
|
|
||||||
protocol = uriInfo.getRequestUri().getScheme();
|
|
||||||
queryParameters.putAll(
|
|
||||||
uriInfo
|
|
||||||
.getQueryParameters()
|
|
||||||
.entrySet()
|
|
||||||
.stream()
|
|
||||||
.collect(
|
|
||||||
Collectors.toMap(
|
|
||||||
entry -> entry.getKey(),
|
|
||||||
entry -> entry.getValue().get(0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
breadcrumbs = new ArrayList<>();
|
|
||||||
breadcrumbs = buildBreadcrumbs(categoryModel.getCategoryTree());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getProtocol() {
|
public String getProtocol() {
|
||||||
return protocol;
|
return protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProtocol(final String protocol) {
|
||||||
|
this.protocol = protocol;
|
||||||
|
}
|
||||||
|
|
||||||
public String getHost() {
|
public String getHost() {
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHost(final String host) {
|
||||||
|
this.host = host;
|
||||||
|
}
|
||||||
|
|
||||||
public int getPort() {
|
public int getPort() {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getBaseUri() {
|
public void setPort(final int port) {
|
||||||
return baseUri;
|
this.port = port;
|
||||||
}
|
|
||||||
|
|
||||||
public String getBasePath() {
|
|
||||||
return basePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BreadcrumbData> getBreadcrumbs() {
|
public void setPath(final String path) {
|
||||||
return Optional
|
this.path = path;
|
||||||
.ofNullable(breadcrumbs)
|
|
||||||
.map(Collections::unmodifiableList)
|
|
||||||
.orElse(Collections.emptyList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPageName() {
|
public PageUrlModel() {
|
||||||
return pageName;
|
queryParameters = new HashMap<>();
|
||||||
}
|
|
||||||
|
|
||||||
public String getPageLocale() {
|
|
||||||
return pageLocale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPageFormat() {
|
|
||||||
return pageFormat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getQueryParameters() {
|
public Map<String, String> getQueryParameters() {
|
||||||
|
|
@ -180,42 +94,7 @@ public class PageUrlModel {
|
||||||
this.queryParameters = new HashMap<>(queryParameters);
|
this.queryParameters = new HashMap<>(queryParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPageUrl() {
|
|
||||||
final UriBuilder uriBuilder = UriBuilder
|
|
||||||
.fromUri(baseUri)
|
|
||||||
.path(path)
|
|
||||||
.path(String.format("%s.%s.%s", pageName, pageLocale, pageFormat));
|
|
||||||
|
|
||||||
for (Map.Entry<String, String> parameter : queryParameters.entrySet()) {
|
|
||||||
uriBuilder.queryParam(
|
|
||||||
parameter.getKey(),
|
|
||||||
parameter.getValue()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return uriBuilder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPageUrl(final String locale) {
|
|
||||||
final UriBuilder uriBuilder = UriBuilder
|
|
||||||
.fromUri(baseUri)
|
|
||||||
.path(path)
|
|
||||||
.path(String.format("%s.%s.%s", pageName, locale, pageFormat));
|
|
||||||
|
|
||||||
for (Map.Entry<String, String> parameter : queryParameters.entrySet()) {
|
|
||||||
uriBuilder.queryParam(
|
|
||||||
parameter.getKey(),
|
|
||||||
parameter.getValue()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return uriBuilder.build().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getQueryString() {
|
public String getQueryString() {
|
||||||
if (queryParameters == null || queryParameters.isEmpty()) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return queryParameters
|
return queryParameters
|
||||||
.entrySet()
|
.entrySet()
|
||||||
.stream()
|
.stream()
|
||||||
|
|
@ -231,32 +110,4 @@ public class PageUrlModel {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<BreadcrumbData> buildBreadcrumbs(
|
|
||||||
final CategoryTreeNode category
|
|
||||||
) {
|
|
||||||
return buildBreadcrumbs(category, new ArrayList<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<BreadcrumbData> buildBreadcrumbs(
|
|
||||||
final CategoryTreeNode category,
|
|
||||||
final List<BreadcrumbData> breadcrumbs
|
|
||||||
) {
|
|
||||||
final Optional<CategoryTreeNode> selected = category
|
|
||||||
.getSubCategories()
|
|
||||||
.stream()
|
|
||||||
.filter(subCat -> subCat.isSelected())
|
|
||||||
.findAny();
|
|
||||||
|
|
||||||
if (selected.isPresent()) {
|
|
||||||
final BreadcrumbData breadcrumb = new BreadcrumbData();
|
|
||||||
breadcrumb.setPath(selected.get().getCategoryPath());
|
|
||||||
breadcrumb.setTitle(selected.get().getTitle());
|
|
||||||
breadcrumb.setLink(selected.get().getCategoryLink());
|
|
||||||
|
|
||||||
buildBreadcrumbs(selected.get(), breadcrumbs);
|
|
||||||
}
|
|
||||||
|
|
||||||
return breadcrumbs;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,8 +93,6 @@ public class ConfigurationController {
|
||||||
return "org/librecms/ui/contentsection/configuration/index.xhtml";
|
return "org/librecms/ui/contentsection/configuration/index.xhtml";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the current user is permitted to access the configurations page
|
* Checks if the current user is permitted to access the configurations page
|
||||||
* of the content section.
|
* of the content section.
|
||||||
|
|
|
||||||
|
|
@ -1,90 +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.libreccm.security.AuthorizationRequired;
|
|
||||||
import org.librecms.contentsection.ContentSection;
|
|
||||||
import org.librecms.ui.contentsections.fixpermissions.FixItemPermissionsTaskManager;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
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 ContentSectionModel sectionModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common functions for views working with {@link ContentSection}s.
|
|
||||||
*/
|
|
||||||
@Inject
|
|
||||||
private ContentSectionsUi sectionsUi;
|
|
||||||
|
|
||||||
@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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
taskManager.fixItemPermissions(section);
|
|
||||||
|
|
||||||
return String.format(
|
|
||||||
"redirect:%s/configuration", sectionIdentifierParam
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -76,7 +76,6 @@ public class ContentSectionApplication extends Application {
|
||||||
classes.add(ConfigurationController.class);
|
classes.add(ConfigurationController.class);
|
||||||
classes.add(ConfigurationContactEntryKeysController.class);
|
classes.add(ConfigurationContactEntryKeysController.class);
|
||||||
classes.add(ConfigurationDocumentTypesController.class);
|
classes.add(ConfigurationDocumentTypesController.class);
|
||||||
classes.add(ConfigurationFixItemPermissionsController.class);
|
|
||||||
classes.add(ConfigurationLifecyclesController.class);
|
classes.add(ConfigurationLifecyclesController.class);
|
||||||
classes.add(ConfigurationRolesController.class);
|
classes.add(ConfigurationRolesController.class);
|
||||||
classes.add(ConfigurationWorkflowController.class);
|
classes.add(ConfigurationWorkflowController.class);
|
||||||
|
|
|
||||||
|
|
@ -1,90 +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.fixpermissions;
|
|
||||||
|
|
||||||
import org.apache.shiro.mgt.SecurityManager;
|
|
||||||
import org.librecms.contentsection.ContentSection;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,162 +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.fixpermissions;
|
|
||||||
|
|
||||||
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()
|
|
||||||
== FixPermissionsTaskStatus.RUNNING
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTaskFailedForContentSection(final String name) {
|
|
||||||
return tasks
|
|
||||||
.stream()
|
|
||||||
.anyMatch(
|
|
||||||
task -> task.getContentSection().equals(name)
|
|
||||||
&& task.getStatus()
|
|
||||||
== FixPermissionsTaskStatus.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()
|
|
||||||
== FixPermissionsTaskStatus.ERROR
|
|
||||||
|| task.getStatus()
|
|
||||||
== FixPermissionsTaskStatus.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(FixPermissionsTaskStatus.RUNNING);
|
|
||||||
tasks.add(taskStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object handleTaskResult(
|
|
||||||
final FixItemPermissionsTask task,
|
|
||||||
final Throwable ex,
|
|
||||||
final FixItemPermissionsTaskStatus status
|
|
||||||
) {
|
|
||||||
if (ex == null) {
|
|
||||||
status.setStatus(FixPermissionsTaskStatus.FINISHED);
|
|
||||||
} else {
|
|
||||||
status.setStatus(FixPermissionsTaskStatus.ERROR);
|
|
||||||
status.setException(ex);
|
|
||||||
LOGGER.error(
|
|
||||||
"Fix Item Permissions for Content Section {} failed ",
|
|
||||||
status.getContentSection()
|
|
||||||
);
|
|
||||||
LOGGER.error("with exception:", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,152 +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.fixpermissions;
|
|
||||||
|
|
||||||
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 FixPermissionsTaskStatus 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 FixPermissionsTaskStatus getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setStatus(final FixPermissionsTaskStatus 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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +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.fixpermissions;
|
|
||||||
|
|
||||||
import org.librecms.ui.contentsections.ContentSectionModel;
|
|
||||||
|
|
||||||
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()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,404 +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.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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,78 +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.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,78 +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.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +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.fixpermissions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
public enum FixPermissionsTaskStatus {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An error occured during the process.
|
|
||||||
*/
|
|
||||||
ERROR,
|
|
||||||
/**
|
|
||||||
* The import or export task is finished.
|
|
||||||
*/
|
|
||||||
FINISHED,
|
|
||||||
/**
|
|
||||||
* The task is still running.
|
|
||||||
*/
|
|
||||||
RUNNING,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +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.fixpermissions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
public class ReadyForNextAssetTaskEvent {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +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.fixpermissions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
|
||||||
*/
|
|
||||||
public class ReadyForNextItemTaskEvent {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -136,51 +136,6 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
</div>
|
</div>
|
||||||
</ui:define>
|
</ui:define>
|
||||||
|
|
|
||||||
|
|
@ -1030,7 +1030,3 @@ pages.page.details.displayname.dialog.displayname.help=The display name of the p
|
||||||
pages.page.details.displayname.dialog.submit=Save
|
pages.page.details.displayname.dialog.submit=Save
|
||||||
pages.page.details.displayname.edit=Edit display name
|
pages.page.details.displayname.edit=Edit display name
|
||||||
pages.page.details.dialog.displayname.label=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,7 +1031,3 @@ pages.page.details.displayname.dialog.displayname.help=The display name of the p
|
||||||
pages.page.details.displayname.dialog.submit=Speichern
|
pages.page.details.displayname.dialog.submit=Speichern
|
||||||
pages.page.details.displayname.edit=Display Name bearbeiten
|
pages.page.details.displayname.edit=Display Name bearbeiten
|
||||||
pages.page.details.dialog.displayname.label=Display Name
|
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.
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@libreccm/ccm-core",
|
"name": "@libreccm/ccm-core",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@libreccm/ccm-core",
|
"name": "@libreccm/ccm-core",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0",
|
||||||
"license": "LGPL-3.0-or-later",
|
"license": "LGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bootstrap": "^4.6.0",
|
"bootstrap": "^4.6.0",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@libreccm/ccm-core",
|
"name": "@libreccm/ccm-core",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0",
|
||||||
"description": "JavaScript stuff for ccm-core",
|
"description": "JavaScript stuff for ccm-core",
|
||||||
"main": "target/generated-resources/assets/@admin/ccm-admin.js",
|
"main": "target/generated-resources/assets/@admin/ccm-admin.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -334,16 +334,6 @@
|
||||||
<goal>npm</goal>
|
<goal>npm</goal>
|
||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
<!-- Sync Maven module version and NPM module version -->
|
|
||||||
<execution>
|
|
||||||
<id>npm version</id>
|
|
||||||
<goals>
|
|
||||||
<goal>npm</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<arguments>version --allow-same-version=true ${project.version}</arguments>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
<execution>
|
||||||
<id>build</id>
|
<id>build</id>
|
||||||
<goals>
|
<goals>
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.libreccm.mvc.freemarker;
|
package org.libreccm.mvc.freemarker;
|
||||||
|
|
||||||
import com.arsdigita.kernel.KernelConfig;
|
|
||||||
|
|
||||||
import freemarker.cache.ClassTemplateLoader;
|
import freemarker.cache.ClassTemplateLoader;
|
||||||
import freemarker.cache.MultiTemplateLoader;
|
import freemarker.cache.MultiTemplateLoader;
|
||||||
import freemarker.cache.TemplateLoader;
|
import freemarker.cache.TemplateLoader;
|
||||||
|
|
@ -28,7 +26,6 @@ import freemarker.template.Configuration;
|
||||||
import freemarker.template.TemplateExceptionHandler;
|
import freemarker.template.TemplateExceptionHandler;
|
||||||
import org.eclipse.krazo.engine.ViewEngineConfig;
|
import org.eclipse.krazo.engine.ViewEngineConfig;
|
||||||
import org.eclipse.krazo.ext.freemarker.DefaultConfigurationProducer;
|
import org.eclipse.krazo.ext.freemarker.DefaultConfigurationProducer;
|
||||||
import org.libreccm.configuration.ConfigurationManager;
|
|
||||||
import org.libreccm.theming.Themes;
|
import org.libreccm.theming.Themes;
|
||||||
|
|
||||||
import javax.enterprise.inject.Produces;
|
import javax.enterprise.inject.Produces;
|
||||||
|
|
@ -46,9 +43,6 @@ import javax.servlet.ServletContext;
|
||||||
public class MvcFreemarkerConfigurationProducer
|
public class MvcFreemarkerConfigurationProducer
|
||||||
extends DefaultConfigurationProducer {
|
extends DefaultConfigurationProducer {
|
||||||
|
|
||||||
@Inject
|
|
||||||
private ConfigurationManager confManager;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Models models;
|
private Models models;
|
||||||
|
|
||||||
|
|
@ -66,27 +60,15 @@ public class MvcFreemarkerConfigurationProducer
|
||||||
@Specializes
|
@Specializes
|
||||||
@Override
|
@Override
|
||||||
public Configuration getConfiguration() {
|
public Configuration getConfiguration() {
|
||||||
final KernelConfig kernelConfig = confManager.findConfiguration(
|
|
||||||
KernelConfig.class
|
|
||||||
);
|
|
||||||
|
|
||||||
final Configuration configuration = new Configuration(
|
final Configuration configuration = new Configuration(
|
||||||
Configuration.VERSION_2_3_30
|
Configuration.VERSION_2_3_30
|
||||||
);
|
);
|
||||||
|
|
||||||
configuration.setDefaultEncoding("UTF-8");
|
configuration.setDefaultEncoding("UTF-8");
|
||||||
if (kernelConfig.isDebugEnabled()) {
|
|
||||||
configuration.setTemplateExceptionHandler(
|
|
||||||
TemplateExceptionHandler.DEBUG_HANDLER
|
|
||||||
);
|
|
||||||
configuration.setLogTemplateExceptions(true);
|
|
||||||
} else {
|
|
||||||
configuration.setTemplateExceptionHandler(
|
configuration.setTemplateExceptionHandler(
|
||||||
TemplateExceptionHandler.RETHROW_HANDLER
|
TemplateExceptionHandler.RETHROW_HANDLER
|
||||||
);
|
);
|
||||||
configuration.setLogTemplateExceptions(false);
|
configuration.setLogTemplateExceptions(false);
|
||||||
}
|
|
||||||
|
|
||||||
configuration.setWrapUncheckedExceptions(false);
|
configuration.setWrapUncheckedExceptions(false);
|
||||||
configuration.setLocalizedLookup(false);
|
configuration.setLocalizedLookup(false);
|
||||||
configuration.setTemplateLoader(
|
configuration.setTemplateLoader(
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,8 @@ public class PermissionManager implements Serializable {
|
||||||
|
|
||||||
@SuppressWarnings("PMD.LongVariable")
|
@SuppressWarnings("PMD.LongVariable")
|
||||||
private static final String QUERY_PARAM_OBJECT = "object";
|
private static final String QUERY_PARAM_OBJECT = "object";
|
||||||
|
|
||||||
@SuppressWarnings("PMD.LongVariable")
|
@SuppressWarnings("PMD.LongVariable")
|
||||||
private static final String QUERY_PARAM_GRANTEE = "grantee";
|
private static final String QUERY_PARAM_GRANTEE = "grantee";
|
||||||
|
|
||||||
@SuppressWarnings("PMD.LongVariable")
|
@SuppressWarnings("PMD.LongVariable")
|
||||||
private static final String QUERY_PARAM_PRIVILEGE = "privilege";
|
private static final String QUERY_PARAM_PRIVILEGE = "privilege";
|
||||||
|
|
||||||
|
|
@ -81,12 +79,8 @@ public class PermissionManager implements Serializable {
|
||||||
* @return The permission identified by the provided {@code permissionId).
|
* @return The permission identified by the provided {@code permissionId).
|
||||||
*/
|
*/
|
||||||
public Optional<Permission> findById(final long permissionId) {
|
public Optional<Permission> findById(final long permissionId) {
|
||||||
return Optional.ofNullable(
|
return Optional.ofNullable(entityManager.find(Permission.class,
|
||||||
entityManager.find(
|
permissionId));
|
||||||
Permission.class,
|
|
||||||
permissionId
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -99,9 +93,7 @@ public class PermissionManager implements Serializable {
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<Permission> findPermissionsForRole(final Role role) {
|
public List<Permission> findPermissionsForRole(final Role role) {
|
||||||
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
||||||
"Permission.findPermissionsForRole",
|
"Permission.findPermissionsForRole", Permission.class);
|
||||||
Permission.class
|
|
||||||
);
|
|
||||||
query.setParameter("grantee", role);
|
query.setParameter("grantee", role);
|
||||||
|
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
|
|
@ -118,22 +110,17 @@ public class PermissionManager implements Serializable {
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public List<Permission> findPermissionsForObject(final CcmObject object) {
|
public List<Permission> findPermissionsForObject(final CcmObject object) {
|
||||||
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
||||||
"Permission.findPermissionsForCcmObject",
|
"Permission.findPermissionsForCcmObject", Permission.class);
|
||||||
Permission.class
|
|
||||||
);
|
|
||||||
query.setParameter("object", object);
|
query.setParameter("object", object);
|
||||||
|
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Permission> findPermissionsForRoleAndObject(
|
public List<Permission> findPermissionsForRoleAndObject(
|
||||||
final Role role,
|
final Role role, final CcmObject object) {
|
||||||
final CcmObject object
|
|
||||||
) {
|
|
||||||
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
||||||
"Permission.findPermissionsForRoleAndObject",
|
"Permission.findPermissionsForRoleAndObject", Permission.class);
|
||||||
Permission.class
|
|
||||||
);
|
|
||||||
query.setParameter("object", object);
|
query.setParameter("object", object);
|
||||||
query.setParameter("grantee", role);
|
query.setParameter("grantee", role);
|
||||||
|
|
||||||
|
|
@ -161,11 +148,9 @@ public class PermissionManager implements Serializable {
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public Permission grantPrivilege(
|
public Permission grantPrivilege(final String privilege,
|
||||||
final String privilege,
|
|
||||||
final Role grantee,
|
final Role grantee,
|
||||||
final CcmObject object
|
final CcmObject object) {
|
||||||
) {
|
|
||||||
if (privilege == null || privilege.isEmpty()) {
|
if (privilege == null || privilege.isEmpty()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't grant a permission without a privilege.");
|
"Can't grant a permission without a privilege.");
|
||||||
|
|
@ -197,13 +182,7 @@ public class PermissionManager implements Serializable {
|
||||||
|
|
||||||
entityManager.persist(permission);
|
entityManager.persist(permission);
|
||||||
|
|
||||||
grantRecursive(
|
grantRecursive(privilege, grantee, object, object.getClass(), object);
|
||||||
privilege,
|
|
||||||
grantee,
|
|
||||||
object,
|
|
||||||
object.getClass(),
|
|
||||||
object
|
|
||||||
);
|
|
||||||
|
|
||||||
return permission;
|
return permission;
|
||||||
}
|
}
|
||||||
|
|
@ -223,44 +202,32 @@ public class PermissionManager implements Serializable {
|
||||||
* {@link #grantPrivilege(java.lang.String, org.libreccm.security.Role, org.libreccm.core.CcmObject)}
|
* {@link #grantPrivilege(java.lang.String, org.libreccm.security.Role, org.libreccm.core.CcmObject)}
|
||||||
* was invoked.
|
* was invoked.
|
||||||
*/
|
*/
|
||||||
private void grantRecursive(
|
private void grantRecursive(final String privilege,
|
||||||
final String privilege,
|
|
||||||
final Role grantee,
|
final Role grantee,
|
||||||
final CcmObject object,
|
final CcmObject object,
|
||||||
final Class<?> clazz,
|
final Class<?> clazz,
|
||||||
final CcmObject inheritedFrom
|
final CcmObject inheritedFrom) {
|
||||||
) {
|
|
||||||
final Field[] fields = clazz.getDeclaredFields();
|
final Field[] fields = clazz.getDeclaredFields();
|
||||||
Arrays.stream(fields)
|
Arrays.stream(fields)
|
||||||
.filter(field -> field.isAnnotationPresent(
|
.filter(field -> field.isAnnotationPresent(
|
||||||
RecursivePermissions.class))
|
RecursivePermissions.class))
|
||||||
.filter(
|
.filter(field -> {
|
||||||
field -> checkIfPrivilegeIsRecursive(
|
return checkIfPrivilegeIsRecursive(
|
||||||
field.getAnnotation(RecursivePermissions.class),
|
field.getAnnotation(RecursivePermissions.class),
|
||||||
privilege
|
privilege);
|
||||||
)
|
})
|
||||||
)
|
.forEach(field -> {
|
||||||
.forEach(
|
|
||||||
field -> {
|
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
grantRecursive(
|
grantRecursive(privilege, grantee, field, object, inheritedFrom);
|
||||||
privilege,
|
|
||||||
grantee,
|
|
||||||
field,
|
|
||||||
object,
|
|
||||||
inheritedFrom
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Repeat for superclass of the current class.
|
// Repeat for superclass of the current class.
|
||||||
if (clazz.getSuperclass() != null) {
|
if (clazz.getSuperclass() != null) {
|
||||||
grantRecursive(
|
grantRecursive(privilege,
|
||||||
privilege,
|
|
||||||
grantee,
|
grantee,
|
||||||
object,
|
object,
|
||||||
clazz.getSuperclass(),
|
clazz.getSuperclass(),
|
||||||
inheritedFrom
|
inheritedFrom);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,14 +246,13 @@ public class PermissionManager implements Serializable {
|
||||||
*/
|
*/
|
||||||
private boolean checkIfPrivilegeIsRecursive(
|
private boolean checkIfPrivilegeIsRecursive(
|
||||||
final RecursivePermissions annotation,
|
final RecursivePermissions annotation,
|
||||||
final String privilege
|
final String privilege) {
|
||||||
) {
|
|
||||||
if (annotation.privileges() == null
|
if (annotation.privileges() == null
|
||||||
|| annotation.privileges().length == 0) {
|
|| annotation.privileges().length == 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return Arrays
|
return Arrays.stream(annotation.privileges())
|
||||||
.stream(annotation.privileges())
|
|
||||||
.anyMatch(privilege::equals);
|
.anyMatch(privilege::equals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -300,35 +266,24 @@ public class PermissionManager implements Serializable {
|
||||||
* @param owner The object which own the provided {@code field}.
|
* @param owner The object which own the provided {@code field}.
|
||||||
* @param inheritedFrom The object from which the permission is inherited.
|
* @param inheritedFrom The object from which the permission is inherited.
|
||||||
*/
|
*/
|
||||||
private void grantRecursive(
|
private void grantRecursive(final String privilege,
|
||||||
final String privilege,
|
|
||||||
final Role grantee,
|
final Role grantee,
|
||||||
final Field field,
|
final Field field,
|
||||||
final CcmObject owner,
|
final CcmObject owner,
|
||||||
final CcmObject inheritedFrom
|
final CcmObject inheritedFrom) {
|
||||||
) {
|
|
||||||
final CcmObject ownerObject = ccmObjectRepo
|
final CcmObject ownerObject = ccmObjectRepo
|
||||||
.findObjectById(owner.getObjectId())
|
.findObjectById(owner.getObjectId())
|
||||||
.orElseThrow(
|
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||||
() -> new IllegalArgumentException(
|
|
||||||
String.format(
|
|
||||||
"No CcmObject with ID %d in the database. "
|
"No CcmObject with ID %d in the database. "
|
||||||
+ "Where did that ID come from?",
|
+ "Where did that ID come from?",
|
||||||
owner.getObjectId()
|
owner.getObjectId())));
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
final CcmObject inheritedFromObject = ccmObjectRepo
|
final CcmObject inheritedFromObject = ccmObjectRepo
|
||||||
.findObjectById(inheritedFrom.getObjectId())
|
.findObjectById(inheritedFrom.getObjectId())
|
||||||
.orElseThrow(
|
.orElseThrow(() -> new IllegalArgumentException(String.format(
|
||||||
() -> new IllegalArgumentException(
|
|
||||||
String.format(
|
|
||||||
"No CcmObject with ID %d in the database. "
|
"No CcmObject with ID %d in the database. "
|
||||||
+ "Where did that ID come from?",
|
+ "Where did that ID come from?",
|
||||||
inheritedFrom.getObjectId()
|
inheritedFrom.getObjectId())));
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
final Object value;
|
final Object value;
|
||||||
try {
|
try {
|
||||||
|
|
@ -348,14 +303,10 @@ public class PermissionManager implements Serializable {
|
||||||
collection.stream()
|
collection.stream()
|
||||||
.filter(obj -> obj instanceof CcmObject)
|
.filter(obj -> obj instanceof CcmObject)
|
||||||
.map(obj -> (CcmObject) obj)
|
.map(obj -> (CcmObject) obj)
|
||||||
.forEach(
|
.forEach(obj -> grantInherited(privilege,
|
||||||
obj -> grantInherited(
|
|
||||||
privilege,
|
|
||||||
grantee,
|
grantee,
|
||||||
obj,
|
obj,
|
||||||
inheritedFromObject
|
inheritedFromObject));
|
||||||
)
|
|
||||||
);
|
|
||||||
// Relations between two CcmObjects with attributes or n:m relations
|
// Relations between two CcmObjects with attributes or n:m relations
|
||||||
// use an object to represent the relation. The object must implement
|
// use an object to represent the relation. The object must implement
|
||||||
// the Relation interface. For each Relation object in the collection
|
// the Relation interface. For each Relation object in the collection
|
||||||
|
|
@ -365,44 +316,33 @@ public class PermissionManager implements Serializable {
|
||||||
.map(obj -> (Relation) obj)
|
.map(obj -> (Relation) obj)
|
||||||
.filter(relation -> relation.getRelatedObject() != null)
|
.filter(relation -> relation.getRelatedObject() != null)
|
||||||
.map(relation -> relation.getRelatedObject())
|
.map(relation -> relation.getRelatedObject())
|
||||||
.forEach(
|
.forEach(obj -> grantInherited(privilege,
|
||||||
obj -> grantInherited(
|
|
||||||
privilege,
|
|
||||||
grantee,
|
grantee,
|
||||||
obj,
|
obj,
|
||||||
inheritedFromObject
|
inheritedFromObject));
|
||||||
)
|
|
||||||
);
|
|
||||||
} else if (CcmObject.class.isAssignableFrom(field.getType())) {
|
} else if (CcmObject.class.isAssignableFrom(field.getType())) {
|
||||||
// If the provided object is a CcmObject create an inherited
|
// If the provided object is a CcmObject create an inherited
|
||||||
// permission for this object.
|
// permission for this object.
|
||||||
grantInherited(
|
grantInherited(privilege,
|
||||||
privilege,
|
|
||||||
grantee,
|
grantee,
|
||||||
(CcmObject) value,
|
(CcmObject) value,
|
||||||
inheritedFromObject
|
inheritedFromObject);
|
||||||
);
|
|
||||||
} else if (Relation.class.isAssignableFrom(field.getType())) {
|
} else if (Relation.class.isAssignableFrom(field.getType())) {
|
||||||
// If the provided field is a Relation object created an inherited
|
// If the provided field is a Relation object created an inherited
|
||||||
// permission on the related object.
|
// permission on the related object.
|
||||||
final Relation relation = (Relation) value;
|
final Relation relation = (Relation) value;
|
||||||
if (relation.getRelatedObject() != null) {
|
if (relation.getRelatedObject() != null) {
|
||||||
grantInherited(
|
grantInherited(privilege,
|
||||||
privilege,
|
|
||||||
grantee,
|
grantee,
|
||||||
relation.getRelatedObject(),
|
relation.getRelatedObject(),
|
||||||
inheritedFromObject
|
inheritedFromObject);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(String.format(
|
||||||
String.format(
|
|
||||||
"Found a field annotated with \"%s\" but the field is not a "
|
"Found a field annotated with \"%s\" but the field is not a "
|
||||||
+ "collection nor a CcmObject nore a Relation object. This "
|
+ "collection nor a CcmObject nore a Relation object. This "
|
||||||
+ "is not supported.",
|
+ "is not supported.",
|
||||||
RecursivePermissions.class
|
RecursivePermissions.class));
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -415,12 +355,11 @@ public class PermissionManager implements Serializable {
|
||||||
* granted.
|
* granted.
|
||||||
* @param inheritedFrom The object from which the permission is inherited.
|
* @param inheritedFrom The object from which the permission is inherited.
|
||||||
*/
|
*/
|
||||||
private void grantInherited(
|
private void grantInherited(final String privilege,
|
||||||
final String privilege,
|
|
||||||
final Role grantee,
|
final Role grantee,
|
||||||
final CcmObject object,
|
final CcmObject object,
|
||||||
final CcmObject inheritedFrom
|
final CcmObject inheritedFrom) {
|
||||||
) {
|
|
||||||
if (!existsPermission(privilege, grantee, object)) {
|
if (!existsPermission(privilege, grantee, object)) {
|
||||||
final Permission permission = new Permission();
|
final Permission permission = new Permission();
|
||||||
permission.setGrantee(grantee);
|
permission.setGrantee(grantee);
|
||||||
|
|
@ -432,13 +371,11 @@ public class PermissionManager implements Serializable {
|
||||||
|
|
||||||
entityManager.persist(permission);
|
entityManager.persist(permission);
|
||||||
|
|
||||||
grantRecursive(
|
grantRecursive(privilege,
|
||||||
privilege,
|
|
||||||
grantee,
|
grantee,
|
||||||
object,
|
object,
|
||||||
object.getClass(),
|
object.getClass(),
|
||||||
inheritedFrom
|
inheritedFrom);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -452,20 +389,16 @@ public class PermissionManager implements Serializable {
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void grantPrivilege(
|
public void grantPrivilege(final String privilege,
|
||||||
final String privilege,
|
final Role grantee) {
|
||||||
final Role grantee
|
|
||||||
) {
|
|
||||||
if (privilege == null || privilege.isEmpty()) {
|
if (privilege == null || privilege.isEmpty()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't grant a permission without a privilege."
|
"Can't grant a permission without a privilege.");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grantee == null) {
|
if (grantee == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't grant a permission to grantee null."
|
"Can't grant a permission to grantee null.");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!existsPermission(privilege, grantee)) {
|
if (!existsPermission(privilege, grantee)) {
|
||||||
|
|
@ -490,52 +423,42 @@ public class PermissionManager implements Serializable {
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void revokePrivilege(
|
public void revokePrivilege(final String privilege,
|
||||||
final String privilege,
|
|
||||||
final Role grantee,
|
final Role grantee,
|
||||||
final CcmObject object
|
final CcmObject object) {
|
||||||
) {
|
|
||||||
|
|
||||||
if (privilege == null || privilege.isEmpty()) {
|
if (privilege == null || privilege.isEmpty()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't revoke a permission without a privilege."
|
"Can't revoke a permission without a privilege.");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grantee == null) {
|
if (grantee == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't revoke a permission from grantee null."
|
"Can't revoke a permission from grantee null.");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't revoke a permission from object NULL."
|
"Can't revoke a permission from object NULL.");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.debug(
|
LOGGER.debug("Revoking permission granting privilege \"{}\" "
|
||||||
"Revoking permission granting privilege \"{}\" "
|
|
||||||
+ "on object \"{}\" to role \"{}\"...",
|
+ "on object \"{}\" to role \"{}\"...",
|
||||||
privilege,
|
privilege,
|
||||||
grantee.getName(),
|
grantee.getName(),
|
||||||
object.getUuid()
|
object.getUuid());
|
||||||
);
|
|
||||||
|
|
||||||
if (existsPermission(privilege, grantee, object)
|
if (existsPermission(privilege, grantee, object)
|
||||||
|| existsInheritedPermission(privilege, grantee, object)) {
|
|| existsInheritedPermission(privilege, grantee, object)) {
|
||||||
|
|
||||||
LOGGER.debug(
|
LOGGER.debug("There is a permission for the provided parameters, "
|
||||||
"There is a permission for the provided parameters, "
|
+ "revoking it...");
|
||||||
+ "revoking it..."
|
|
||||||
);
|
|
||||||
|
|
||||||
final Query deleteQuery = entityManager.createQuery(
|
final Query deleteQuery = entityManager.createQuery(
|
||||||
"DELETE FROM Permission p "
|
"DELETE FROM Permission p "
|
||||||
+ "WHERE p.grantedPrivilege = :privilege "
|
+ "WHERE p.grantedPrivilege = :privilege "
|
||||||
+ "AND p.grantee = :grantee "
|
+ "AND p.grantee = :grantee "
|
||||||
+ "AND p.object = :object"
|
+ "AND p.object = :object");
|
||||||
);
|
|
||||||
deleteQuery.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
deleteQuery.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||||
deleteQuery.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
deleteQuery.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||||
deleteQuery.setParameter(QUERY_PARAM_OBJECT, object);
|
deleteQuery.setParameter(QUERY_PARAM_OBJECT, object);
|
||||||
|
|
@ -547,21 +470,18 @@ public class PermissionManager implements Serializable {
|
||||||
+ "WHERE p.grantedPrivilege = :privilege "
|
+ "WHERE p.grantedPrivilege = :privilege "
|
||||||
+ "AND p.grantee = :grantee "
|
+ "AND p.grantee = :grantee "
|
||||||
+ "AND p.inheritedFrom = :object "
|
+ "AND p.inheritedFrom = :object "
|
||||||
+ "AND p.inherited = true"
|
+ "AND p.inherited = true");
|
||||||
);
|
|
||||||
deleteInheritedQuery.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
deleteInheritedQuery.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||||
deleteInheritedQuery.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
deleteInheritedQuery.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||||
deleteInheritedQuery.setParameter("object", object);
|
deleteInheritedQuery.setParameter("object", object);
|
||||||
final int deletedInherited = deleteInheritedQuery.executeUpdate();
|
final int deletedInherited = deleteInheritedQuery.executeUpdate();
|
||||||
LOGGER.debug("{} inherited permissions deleted.", deletedInherited);
|
LOGGER.debug("{} inherited permissions deleted.", deletedInherited);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.warn(
|
LOGGER.warn("No permission granting privilege \"{}\" "
|
||||||
"No permission granting privilege \"{}\" "
|
|
||||||
+ "on object \"{}\" to role \"{}\". Ignoring.",
|
+ "on object \"{}\" to role \"{}\". Ignoring.",
|
||||||
privilege,
|
privilege,
|
||||||
grantee.getName(),
|
grantee.getName(),
|
||||||
object.getUuid()
|
object.getUuid());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -575,20 +495,16 @@ public class PermissionManager implements Serializable {
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void revokePrivilege(
|
public void revokePrivilege(final String privilege,
|
||||||
final String privilege,
|
final Role grantee) {
|
||||||
final Role grantee
|
|
||||||
) {
|
|
||||||
if (privilege == null || privilege.isEmpty()) {
|
if (privilege == null || privilege.isEmpty()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't revoke a permission without a privilege."
|
"Can't revoke a permission without a privilege.");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grantee == null) {
|
if (grantee == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't revoke a permission from grantee null."
|
"Can't revoke a permission from grantee null.");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existsPermission(privilege, grantee)) {
|
if (existsPermission(privilege, grantee)) {
|
||||||
|
|
@ -596,8 +512,7 @@ public class PermissionManager implements Serializable {
|
||||||
"DELETE FROM Permission p "
|
"DELETE FROM Permission p "
|
||||||
+ "WHERE p.grantedPrivilege = :privilege "
|
+ "WHERE p.grantedPrivilege = :privilege "
|
||||||
+ "AND p.grantee = :grantee "
|
+ "AND p.grantee = :grantee "
|
||||||
+ "AND p.object IS NULL"
|
+ "AND p.object IS NULL");
|
||||||
);
|
|
||||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||||
query.executeUpdate();
|
query.executeUpdate();
|
||||||
|
|
@ -617,10 +532,8 @@ public class PermissionManager implements Serializable {
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void copyPermissions(
|
public void copyPermissions(final CcmObject source,
|
||||||
final CcmObject source,
|
final CcmObject target) {
|
||||||
final CcmObject target
|
|
||||||
) {
|
|
||||||
copyPermissions(source, target, false);
|
copyPermissions(source, target, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -639,27 +552,21 @@ public class PermissionManager implements Serializable {
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
public void copyPermissions(
|
public void copyPermissions(final CcmObject source,
|
||||||
final CcmObject source,
|
|
||||||
final CcmObject target,
|
final CcmObject target,
|
||||||
final boolean inherited
|
final boolean inherited) {
|
||||||
) {
|
|
||||||
if (source == null) {
|
if (source == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't copy permissions from source NULL."
|
"Can't copy permissions from source NULL.");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Can't copy permissions to target NULL."
|
"Can't copy permissions to target NULL.");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
final TypedQuery<Permission> query = entityManager.createNamedQuery(
|
||||||
"Permission.findPermissionsForCcmObject",
|
"Permission.findPermissionsForCcmObject", Permission.class);
|
||||||
Permission.class
|
|
||||||
);
|
|
||||||
query.setParameter(QUERY_PARAM_OBJECT, source);
|
query.setParameter(QUERY_PARAM_OBJECT, source);
|
||||||
final List<Permission> result = query.getResultList();
|
final List<Permission> result = query.getResultList();
|
||||||
|
|
||||||
|
|
@ -667,11 +574,7 @@ public class PermissionManager implements Serializable {
|
||||||
final Permission granted = grantPrivilege(
|
final Permission granted = grantPrivilege(
|
||||||
permission.getGrantedPrivilege(),
|
permission.getGrantedPrivilege(),
|
||||||
permission.getGrantee(),
|
permission.getGrantee(),
|
||||||
target
|
target);
|
||||||
);
|
|
||||||
if (granted == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
granted.setInherited(inherited);
|
granted.setInherited(inherited);
|
||||||
if (inherited) {
|
if (inherited) {
|
||||||
granted.setInheritedFrom(source);
|
granted.setInheritedFrom(source);
|
||||||
|
|
@ -695,17 +598,12 @@ public class PermissionManager implements Serializable {
|
||||||
* @return A list with all privileges defined by the provided class.
|
* @return A list with all privileges defined by the provided class.
|
||||||
*/
|
*/
|
||||||
public List<String> listDefiniedPrivileges(final Class<?> clazz) {
|
public List<String> listDefiniedPrivileges(final Class<?> clazz) {
|
||||||
return Arrays
|
return Arrays.stream(clazz.getDeclaredFields())
|
||||||
.stream(clazz.getDeclaredFields())
|
|
||||||
.filter(field -> field.getType().isAssignableFrom(String.class))
|
.filter(field -> field.getType().isAssignableFrom(String.class))
|
||||||
.filter(
|
.filter(field -> Modifier.isStatic(field.getModifiers())
|
||||||
field -> Modifier.isStatic(field.getModifiers())
|
&& Modifier.isFinal(field.getModifiers()))
|
||||||
&& Modifier.isFinal(field.getModifiers())
|
.filter(field -> field.getName().startsWith("PRIVILEGE_")
|
||||||
)
|
|| clazz.getSimpleName().endsWith("Privileges"))
|
||||||
.filter(
|
|
||||||
field -> field.getName().startsWith("PRIVILEGE_")
|
|
||||||
|| clazz.getSimpleName().endsWith("Privileges")
|
|
||||||
)
|
|
||||||
.map(field -> getPrivilegeString(field))
|
.map(field -> getPrivilegeString(field))
|
||||||
.sorted()
|
.sorted()
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
@ -731,15 +629,11 @@ public class PermissionManager implements Serializable {
|
||||||
* @return {@code true} if there is a matching permission, {@code false} if
|
* @return {@code true} if there is a matching permission, {@code false} if
|
||||||
* not.
|
* not.
|
||||||
*/
|
*/
|
||||||
private boolean existsPermission(
|
private boolean existsPermission(final String privilege,
|
||||||
final String privilege,
|
|
||||||
final Role grantee,
|
final Role grantee,
|
||||||
final CcmObject object
|
final CcmObject object) {
|
||||||
) {
|
|
||||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||||
"Permission.existsDirectForPrivilegeRoleObject",
|
"Permission.existsDirectForPrivilegeRoleObject", Long.class);
|
||||||
Long.class
|
|
||||||
);
|
|
||||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||||
query.setParameter(QUERY_PARAM_OBJECT, object);
|
query.setParameter(QUERY_PARAM_OBJECT, object);
|
||||||
|
|
@ -747,15 +641,11 @@ public class PermissionManager implements Serializable {
|
||||||
return query.getSingleResult() > 0;
|
return query.getSingleResult() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean existsInheritedPermission(
|
private boolean existsInheritedPermission(final String privilege,
|
||||||
final String privilege,
|
|
||||||
final Role grantee,
|
final Role grantee,
|
||||||
final CcmObject object
|
final CcmObject object) {
|
||||||
) {
|
|
||||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||||
"Permission.existsInheritedForPrivilegeRoleObject",
|
"Permission.existsInheritedForPrivilegeRoleObject", Long.class);
|
||||||
Long.class
|
|
||||||
);
|
|
||||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||||
query.setParameter(QUERY_PARAM_OBJECT, object);
|
query.setParameter(QUERY_PARAM_OBJECT, object);
|
||||||
|
|
@ -773,14 +663,10 @@ public class PermissionManager implements Serializable {
|
||||||
* @return {@code true} if there is a matching permission, {@code false} if
|
* @return {@code true} if there is a matching permission, {@code false} if
|
||||||
* not.
|
* not.
|
||||||
*/
|
*/
|
||||||
private boolean existsPermission(
|
private boolean existsPermission(final String privilege,
|
||||||
final String privilege,
|
final Role grantee) {
|
||||||
final Role grantee
|
|
||||||
) {
|
|
||||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||||
"Permission.existsForPrivilegeAndRole",
|
"Permission.existsForPrivilegeAndRole", Long.class);
|
||||||
Long.class
|
|
||||||
);
|
|
||||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,41 +99,50 @@ public class StaticThemeProvider implements ThemeProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ThemeInfo> getThemes() {
|
public List<ThemeInfo> getThemes() {
|
||||||
|
|
||||||
LOGGER.debug("Retrieving static themes...");
|
LOGGER.debug("Retrieving static themes...");
|
||||||
|
|
||||||
final Reflections reflections = new Reflections(
|
final Reflections reflections = new Reflections(
|
||||||
new ConfigurationBuilder()
|
new ConfigurationBuilder()
|
||||||
.setUrls(ClasspathHelper.forPackage(""))
|
.setUrls(ClasspathHelper.forPackage(""))
|
||||||
.setScanners(new ResourcesScanner())
|
.setScanners(new ResourcesScanner()
|
||||||
);
|
// .filterResultsBy(new FilterBuilder()
|
||||||
|
// .include(THEMES_PACKAGE)
|
||||||
|
// .include(THEMES_PACKAGE + "/([\\w\\d\\s\\.]*)/theme.json")
|
||||||
|
// .include(THEMES_PACKAGE + "/([\\w\\d\\s\\.]*)/theme.xml")
|
||||||
|
// .exclude(THEMES_PACKAGE + "(.*)/(.*)")
|
||||||
|
// )
|
||||||
|
));
|
||||||
|
|
||||||
final Set<String> jsonThemes = reflections.getResources(
|
final Set<String> jsonThemes = reflections
|
||||||
Pattern.compile(THEME_MANIFEST_JSON)
|
.getResources(Pattern.compile(THEME_MANIFEST_JSON));
|
||||||
);
|
final Set<String> xmlThemes = reflections
|
||||||
final Set<String> xmlThemes = reflections.getResources(
|
.getResources(Pattern.compile(THEME_MANIFEST_XML));
|
||||||
Pattern.compile(THEME_MANIFEST_XML)
|
|
||||||
);
|
|
||||||
final List<String> themes = new ArrayList<>();
|
final List<String> themes = new ArrayList<>();
|
||||||
themes.addAll(
|
themes.addAll(jsonThemes
|
||||||
jsonThemes
|
|
||||||
.stream()
|
.stream()
|
||||||
.filter(
|
.filter(themePackage -> {
|
||||||
themePackage -> themePackage.matches(
|
return themePackage
|
||||||
THEMES_PACKAGE + "/([\\w\\d\\s\\.\\-_])*/theme.json"
|
.matches(THEMES_PACKAGE + "/([\\w\\d\\s\\.])*/theme.json");
|
||||||
)
|
})
|
||||||
)
|
// .map(themePackage -> {
|
||||||
|
// return themePackage
|
||||||
|
// .substring((THEMES_PACKAGE + "/").length(),
|
||||||
|
// ("/" + THEME_MANIFEST_JSON).length() - 1);
|
||||||
|
// })
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
themes.addAll(
|
themes.addAll(xmlThemes
|
||||||
xmlThemes
|
|
||||||
.stream()
|
.stream()
|
||||||
.filter(
|
.filter(themePackage -> {
|
||||||
themePackage -> themePackage
|
return themePackage
|
||||||
.matches(
|
.matches(THEMES_PACKAGE + "/([\\w\\d\\s\\.])*/theme.xml");
|
||||||
THEMES_PACKAGE + "/([\\w\\d\\s\\.])*/theme.xml"
|
})
|
||||||
)
|
// .map(themePackage -> {
|
||||||
)
|
// return themePackage
|
||||||
.collect(Collectors.toList())
|
// .substring((THEMES_PACKAGE + "/").length(),
|
||||||
);
|
// ("/" + THEME_MANIFEST_XML).length() - 1);
|
||||||
|
// })
|
||||||
|
.collect(Collectors.toList()));
|
||||||
Collections.sort(themes);
|
Collections.sort(themes);
|
||||||
|
|
||||||
LOGGER.debug("Found static themes:");
|
LOGGER.debug("Found static themes:");
|
||||||
|
|
@ -142,10 +151,9 @@ public class StaticThemeProvider implements ThemeProvider {
|
||||||
for (final String theme : themes) {
|
for (final String theme : themes) {
|
||||||
final InputStream inputStream = StaticThemeProvider.class
|
final InputStream inputStream = StaticThemeProvider.class
|
||||||
.getResourceAsStream(String.format("/%s", theme));
|
.getResourceAsStream(String.format("/%s", theme));
|
||||||
final ThemeManifest manifest = manifestUtil.loadManifest(
|
final ThemeManifest manifest = manifestUtil
|
||||||
inputStream,
|
.loadManifest(inputStream,
|
||||||
theme
|
theme);
|
||||||
);
|
|
||||||
LOGGER.debug("Got manifest: {}", Objects.toString(manifest));
|
LOGGER.debug("Got manifest: {}", Objects.toString(manifest));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +165,19 @@ public class StaticThemeProvider implements ThemeProvider {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private boolean isThemeDir(final String dirPath) {
|
||||||
|
//
|
||||||
|
// Objects.requireNonNull(dirPath);
|
||||||
|
//
|
||||||
|
// final URL manifestJsonUrl = StaticThemeProvider.class.getResource(
|
||||||
|
// String.format(THEME_MANIFEST_JSON_PATH, dirPath));
|
||||||
|
// final URL manifestXmlUrl = StaticThemeProvider.class.getResource(
|
||||||
|
// String.format(THEME_MANIFEST_XML_PATH, dirPath));
|
||||||
|
//
|
||||||
|
// return (manifestJsonUrl != null) || (manifestXmlUrl != null);
|
||||||
|
// }
|
||||||
private ThemeManifest loadThemeManifest(final String manifestPath) {
|
private ThemeManifest loadThemeManifest(final String manifestPath) {
|
||||||
|
|
||||||
Objects.requireNonNull(manifestPath);
|
Objects.requireNonNull(manifestPath);
|
||||||
|
|
||||||
final String pathToManifest;
|
final String pathToManifest;
|
||||||
|
|
@ -170,7 +190,9 @@ public class StaticThemeProvider implements ThemeProvider {
|
||||||
final ThemeManifest manifest;
|
final ThemeManifest manifest;
|
||||||
try (final InputStream inputStream = StaticThemeProvider.class
|
try (final InputStream inputStream = StaticThemeProvider.class
|
||||||
.getResourceAsStream(pathToManifest)) {
|
.getResourceAsStream(pathToManifest)) {
|
||||||
|
|
||||||
manifest = manifestUtil.loadManifest(inputStream, manifestPath);
|
manifest = manifestUtil.loadManifest(inputStream, manifestPath);
|
||||||
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new UnexpectedErrorException(ex);
|
throw new UnexpectedErrorException(ex);
|
||||||
}
|
}
|
||||||
|
|
@ -196,23 +218,22 @@ public class StaticThemeProvider implements ThemeProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<ThemeInfo> getThemeInfo(
|
public Optional<ThemeInfo> getThemeInfo(final String theme,
|
||||||
final String theme,
|
final ThemeVersion version) {
|
||||||
final ThemeVersion version
|
|
||||||
) {
|
|
||||||
Objects.requireNonNull(theme);
|
Objects.requireNonNull(theme);
|
||||||
|
|
||||||
final String manifestJsonPath = String.format(
|
final String manifestJsonPath = String.format("/" + THEMES_PACKAGE
|
||||||
"/" + THEMES_PACKAGE + "/%s/" + THEME_MANIFEST_JSON,
|
+ "/%s/"
|
||||||
theme
|
+ THEME_MANIFEST_JSON,
|
||||||
);
|
theme);
|
||||||
final String manifestXmlPath = String.format(
|
final String manifestXmlPath = String.format("/" + THEMES_PACKAGE
|
||||||
"/" + THEMES_PACKAGE + "/%s/" + THEME_MANIFEST_XML, theme
|
+ "/%s/"
|
||||||
);
|
+ THEME_MANIFEST_XML,
|
||||||
|
theme);
|
||||||
|
|
||||||
final URL manifestJsonUrl = StaticThemeProvider.class.getResource(
|
final URL manifestJsonUrl = StaticThemeProvider.class
|
||||||
manifestJsonPath
|
.getResource(manifestJsonPath);
|
||||||
);
|
|
||||||
final URL manifestXmlUrl = StaticThemeProvider.class
|
final URL manifestXmlUrl = StaticThemeProvider.class
|
||||||
.getResource(manifestXmlPath);
|
.getResource(manifestXmlPath);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,36 +57,32 @@ class FreemarkerConfigurationProvider {
|
||||||
private final Map<ThemeInfo, Configuration> configurations = new HashMap<>();
|
private final Map<ThemeInfo, Configuration> configurations = new HashMap<>();
|
||||||
|
|
||||||
protected Configuration getConfiguration(final ThemeInfo forTheme) {
|
protected Configuration getConfiguration(final ThemeInfo forTheme) {
|
||||||
|
|
||||||
if (configurations.containsKey(forTheme)) {
|
if (configurations.containsKey(forTheme)) {
|
||||||
|
|
||||||
return configurations.get(forTheme);
|
return configurations.get(forTheme);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
final Configuration configuration = new Configuration(
|
final Configuration configuration = new Configuration(
|
||||||
Configuration.VERSION_2_3_27
|
Configuration.VERSION_2_3_27);
|
||||||
);
|
|
||||||
configuration.setDefaultEncoding("UTF-8");
|
configuration.setDefaultEncoding("UTF-8");
|
||||||
configuration
|
configuration
|
||||||
.setTemplateExceptionHandler(
|
.setTemplateExceptionHandler(
|
||||||
TemplateExceptionHandler.DEBUG_HANDLER
|
TemplateExceptionHandler.RETHROW_HANDLER);
|
||||||
);
|
configuration.setLogTemplateExceptions(false);
|
||||||
configuration.setLogTemplateExceptions(true);
|
|
||||||
configuration.setWrapUncheckedExceptions(false);
|
configuration.setWrapUncheckedExceptions(false);
|
||||||
configuration.setLocalizedLookup(false);
|
configuration.setLocalizedLookup(false);
|
||||||
|
|
||||||
configuration.setTemplateLoader(
|
configuration.setTemplateLoader(
|
||||||
new MultiTemplateLoader(
|
new MultiTemplateLoader(new TemplateLoader[]{
|
||||||
new TemplateLoader[]{
|
|
||||||
// For for files from themes
|
// For for files from themes
|
||||||
new CcmTemplateLoader(forTheme),
|
new CcmTemplateLoader(forTheme),
|
||||||
// Loader for MacroLibs provided by CCM modules
|
// Loader for MacroLibs provided by CCM modules
|
||||||
new WebappTemplateLoader(
|
new WebappTemplateLoader(
|
||||||
servletContext, "/themes/freemarker"
|
servletContext, "/themes/freemarker"
|
||||||
),
|
),
|
||||||
new ClassTemplateLoader(
|
new ClassTemplateLoader(getClass(), "/themes/freemarker")
|
||||||
getClass(),
|
})
|
||||||
"/themes/freemarker"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
configurations.put(forTheme, configuration);
|
configurations.put(forTheme, configuration);
|
||||||
|
|
@ -107,8 +103,7 @@ class FreemarkerConfigurationProvider {
|
||||||
public Object findTemplateSource(final String name) throws IOException {
|
public Object findTemplateSource(final String name) throws IOException {
|
||||||
|
|
||||||
final Optional<InputStream> source = themes.getFileFromTheme(
|
final Optional<InputStream> source = themes.getFileFromTheme(
|
||||||
fromTheme, name
|
fromTheme, name);
|
||||||
);
|
|
||||||
if (source.isPresent()) {
|
if (source.isPresent()) {
|
||||||
return source.get();
|
return source.get();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -123,10 +118,9 @@ class FreemarkerConfigurationProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Reader getReader(
|
public Reader getReader(final Object templateSource,
|
||||||
final Object templateSource,
|
final String encoding) throws IOException {
|
||||||
final String encoding
|
|
||||||
) throws IOException {
|
|
||||||
final InputStream inputStream = (InputStream) templateSource;
|
final InputStream inputStream = (InputStream) templateSource;
|
||||||
return new InputStreamReader(inputStream, encoding);
|
return new InputStreamReader(inputStream, encoding);
|
||||||
}
|
}
|
||||||
|
|
@ -134,6 +128,7 @@ class FreemarkerConfigurationProvider {
|
||||||
@Override
|
@Override
|
||||||
public void closeTemplateSource(final Object templateSource)
|
public void closeTemplateSource(final Object templateSource)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
|
||||||
final InputStream inputStream = (InputStream) templateSource;
|
final InputStream inputStream = (InputStream) templateSource;
|
||||||
inputStream.close();
|
inputStream.close();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,50 +50,39 @@ public class L10NUtils implements Serializable {
|
||||||
@Inject
|
@Inject
|
||||||
private GlobalizationHelper globalizationHelper;
|
private GlobalizationHelper globalizationHelper;
|
||||||
|
|
||||||
public ResourceBundle getBundle(
|
public ResourceBundle getBundle(final ThemeInfo fromTheme,
|
||||||
final ThemeInfo fromTheme,
|
|
||||||
final ThemeProvider themeProvider,
|
final ThemeProvider themeProvider,
|
||||||
final String bundleName
|
final String bundleName) {
|
||||||
) {
|
|
||||||
return ResourceBundle
|
return ResourceBundle
|
||||||
.getBundle(
|
.getBundle(
|
||||||
bundleName,
|
bundleName,
|
||||||
globalizationHelper.getNegotiatedLocale(),
|
globalizationHelper.getNegotiatedLocale(),
|
||||||
new LocalizedResourceBundleControl(
|
new LocalizedResourceBundleControl(fromTheme,
|
||||||
fromTheme,
|
themeProvider));
|
||||||
themeProvider
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText(
|
public String getText(final ThemeInfo fromTheme,
|
||||||
final ThemeInfo fromTheme,
|
|
||||||
final ThemeProvider themeProvider,
|
final ThemeProvider themeProvider,
|
||||||
final String bundleName,
|
final String bundleName,
|
||||||
final String key
|
final String key) {
|
||||||
) {
|
|
||||||
|
|
||||||
final ResourceBundle bundle = getBundle(
|
final ResourceBundle bundle = getBundle(fromTheme,
|
||||||
fromTheme,
|
|
||||||
themeProvider,
|
themeProvider,
|
||||||
bundleName
|
bundleName);
|
||||||
);
|
|
||||||
|
|
||||||
return bundle.getString(key);
|
return bundle.getString(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getText(
|
public String getText(final ThemeInfo fromTheme,
|
||||||
final ThemeInfo fromTheme,
|
|
||||||
final ThemeProvider themeProvider,
|
final ThemeProvider themeProvider,
|
||||||
final String bundleName,
|
final String bundleName,
|
||||||
final String key,
|
final String key,
|
||||||
final String arguments
|
final String arguments) {
|
||||||
) {
|
|
||||||
final ResourceBundle bundle = getBundle(
|
final ResourceBundle bundle = getBundle(fromTheme,
|
||||||
fromTheme,
|
|
||||||
themeProvider,
|
themeProvider,
|
||||||
bundleName
|
bundleName);
|
||||||
);
|
|
||||||
|
|
||||||
return MessageFormat.format(bundle.getString(key), arguments);
|
return MessageFormat.format(bundle.getString(key), arguments);
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +91,6 @@ public class L10NUtils implements Serializable {
|
||||||
extends ResourceBundle.Control {
|
extends ResourceBundle.Control {
|
||||||
|
|
||||||
private final ThemeInfo theme;
|
private final ThemeInfo theme;
|
||||||
|
|
||||||
private final ThemeProvider themeProvider;
|
private final ThemeProvider themeProvider;
|
||||||
|
|
||||||
public LocalizedResourceBundleControl(
|
public LocalizedResourceBundleControl(
|
||||||
|
|
@ -121,49 +109,41 @@ public class L10NUtils implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResourceBundle newBundle(
|
public ResourceBundle newBundle(final String baseName,
|
||||||
final String baseName,
|
|
||||||
final Locale locale,
|
final Locale locale,
|
||||||
final String format,
|
final String format,
|
||||||
final ClassLoader classLoader,
|
final ClassLoader classLoader,
|
||||||
final boolean reload
|
final boolean reload)
|
||||||
)
|
|
||||||
throws IllegalAccessException,
|
throws IllegalAccessException,
|
||||||
InstantiationException,
|
InstantiationException,
|
||||||
IOException {
|
IOException {
|
||||||
|
|
||||||
if ("java.properties".equals(format)) {
|
if ("java.properties".equals(format)) {
|
||||||
|
|
||||||
final String bundleName = toBundleName(baseName, locale);
|
final String bundleName = toBundleName(baseName, locale);
|
||||||
|
|
||||||
final Optional<InputStream> inputStream = themeProvider
|
final Optional<InputStream> inputStream = themeProvider
|
||||||
.getThemeFileAsStream(
|
.getThemeFileAsStream(theme.getName(),
|
||||||
theme.getName(),
|
|
||||||
theme.getVersion(),
|
theme.getVersion(),
|
||||||
String.format(
|
String.format("%s.properties",
|
||||||
"%s.properties",
|
bundleName));
|
||||||
bundleName
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (inputStream.isPresent()) {
|
if (inputStream.isPresent()) {
|
||||||
return new PropertyResourceBundle(inputStream.get());
|
return new PropertyResourceBundle(inputStream.get());
|
||||||
} else {
|
} else {
|
||||||
return super.newBundle(
|
return super.newBundle(baseName,
|
||||||
baseName,
|
|
||||||
locale,
|
locale,
|
||||||
format,
|
format,
|
||||||
classLoader,
|
classLoader,
|
||||||
reload
|
reload);
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return super.newBundle(
|
|
||||||
baseName,
|
|
||||||
locale,
|
|
||||||
format,
|
|
||||||
classLoader,
|
|
||||||
reload
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return super.newBundle(baseName,
|
||||||
|
locale,
|
||||||
|
format,
|
||||||
|
classLoader,
|
||||||
|
reload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -217,9 +217,7 @@ public class ImportExportTaskManager {
|
||||||
* @see CompletionStage#handle(java.util.function.BiFunction)
|
* @see CompletionStage#handle(java.util.function.BiFunction)
|
||||||
*/
|
*/
|
||||||
private Object handleExportTaskResult(
|
private Object handleExportTaskResult(
|
||||||
final ExportTask task,
|
final ExportTask task, final Throwable ex, final ExportTaskStatus status
|
||||||
final Throwable ex,
|
|
||||||
final ExportTaskStatus status
|
|
||||||
) {
|
) {
|
||||||
if (ex == null) {
|
if (ex == null) {
|
||||||
status.setStatus(ImExportTaskStatus.FINISHED);
|
status.setStatus(ImExportTaskStatus.FINISHED);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@libreccm/ccm-pagemodelseditor",
|
"name": "@libreccm/ccm-pagemodelseditor",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@libreccm/ccm-pagemodelseditor",
|
"name": "@libreccm/ccm-pagemodelseditor",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^16.4.2",
|
"react": "^16.4.2",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@libreccm/ccm-pagemodelseditor",
|
"name": "@libreccm/ccm-pagemodelseditor",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0",
|
||||||
"main": "target/dist/PageModelsEditor.js",
|
"main": "target/dist/PageModelsEditor.js",
|
||||||
"types": "target/dist/PageModelsEditor.d.ts",
|
"types": "target/dist/PageModelsEditor.d.ts",
|
||||||
"description": "Editor for PageModels build using React.js",
|
"description": "Editor for PageModels build using React.js",
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<timestamp>${maven.build.timestamp}</timestamp>
|
<timestamp>${maven.build.timestamp}</timestamp>
|
||||||
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'Z</maven.build.timestamp.format>
|
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'Z</maven.build.timestamp.format>
|
||||||
<buildNumber></buildNumber>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
@ -142,16 +141,6 @@
|
||||||
<arguments>install</arguments>
|
<arguments>install</arguments>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<!-- Sync Maven module version and NPM module version -->
|
|
||||||
<execution>
|
|
||||||
<id>npm version</id>
|
|
||||||
<goals>
|
|
||||||
<goal>npm</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<arguments>version --allow-same-version=true ${project.version}${buildNumber}</arguments>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
<execution>
|
||||||
<id>build</id>
|
<id>build</id>
|
||||||
<goals>
|
<goals>
|
||||||
|
|
@ -185,21 +174,10 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>with-buildnumber</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>env.BUILD_NUMBER</name>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<properties>
|
|
||||||
<buildNumber>.${env.BUILD_NUMBER}</buildNumber>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@libreccm/ccm-static-theme-index-builder",
|
"name": "@libreccm/ccm-static-theme-index-builder",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@libreccm/ccm-static-theme-index-builder",
|
"name": "@libreccm/ccm-static-theme-index-builder",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/mime-types": "^2.1.1",
|
"@types/mime-types": "^2.1.1",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@libreccm/ccm-static-theme-index-builder",
|
"name": "@libreccm/ccm-static-theme-index-builder",
|
||||||
"version": "7.0.0-SNAPSHOT",
|
"version": "7.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "target/dist/StaticThemeIndexBuilder.js",
|
"main": "target/dist/StaticThemeIndexBuilder.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<timestamp>${maven.build.timestamp}</timestamp>
|
<timestamp>${maven.build.timestamp}</timestamp>
|
||||||
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'Z</maven.build.timestamp.format>
|
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'Z</maven.build.timestamp.format>
|
||||||
<buildNumber></buildNumber>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
@ -74,16 +73,6 @@
|
||||||
<arguments>install</arguments>
|
<arguments>install</arguments>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<!-- Sync Maven module version and NPM module version -->
|
|
||||||
<execution>
|
|
||||||
<id>npm version</id>
|
|
||||||
<goals>
|
|
||||||
<goal>npm</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<arguments>version --allow-same-version=true ${project.version}${buildNumber}</arguments>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
<execution>
|
||||||
<id>build</id>
|
<id>build</id>
|
||||||
<goals>
|
<goals>
|
||||||
|
|
@ -112,7 +101,7 @@
|
||||||
<phase>deploy</phase>
|
<phase>deploy</phase>
|
||||||
|
|
||||||
<configuration>
|
<configuration>
|
||||||
<arguments>publish -userconfig ../libreccm.npmrc</arguments>
|
<arguments>publish --userconfig ../libreccm.npmrc</arguments>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
|
@ -121,18 +110,4 @@
|
||||||
|
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>with-buildnumber</id>
|
|
||||||
<activation>
|
|
||||||
<property>
|
|
||||||
<name>env.BUILD_NUMBER</name>
|
|
||||||
</property>
|
|
||||||
</activation>
|
|
||||||
<properties>
|
|
||||||
<buildNumber>.${env.BUILD_NUMBER}</buildNumber>
|
|
||||||
</properties>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
auth-type=legacy
|
@libreccm:registry=https://packages.libreccm.org/repository/libreccm-npm/
|
||||||
@libreccm:registry=https://git.libreccm.org/api/packages/libreccm/npm/
|
@librecms:registry=https://packages.libreccm.org/repository/libreccm-npm/
|
||||||
@librecms:registry=https://git.libreccm.org/api/packages/libreccm/npm/
|
|
||||||
@libreccm:access=public
|
@libreccm:access=public
|
||||||
@librecms:access=public
|
@librecms:access=public
|
||||||
//git.libreccm.org/api/packages/libreccm/npm/:_authToken=${NPM_TOKEN}
|
//packages.libreccm.org/repository/libreccm-npm/:_authToken=NpmToken.a5eb72e5-056e-3a5d-ab91-ac163d36ac5b
|
||||||
//git.libreccm.org/api/packages/npm/:_authToken=${NPM_TOKEN}
|
|
||||||
|
|
|
||||||
10
pom.xml
10
pom.xml
|
|
@ -38,21 +38,13 @@
|
||||||
<name>LibreCCM</name>
|
<name>LibreCCM</name>
|
||||||
<url>http://www.libreccm.org/project-sites/</url>
|
<url>http://www.libreccm.org/project-sites/</url>
|
||||||
</site>
|
</site>
|
||||||
<!-- <snapshotRepository>
|
<snapshotRepository>
|
||||||
<id>libreccm-snapshots</id>
|
<id>libreccm-snapshots</id>
|
||||||
<url>https://packages.libreccm.org/repository/maven-snapshots/</url>
|
<url>https://packages.libreccm.org/repository/maven-snapshots/</url>
|
||||||
</snapshotRepository>
|
</snapshotRepository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>libreccm-releases</id>
|
<id>libreccm-releases</id>
|
||||||
<url>https://packages.libreccm.org/repository/maven-releases/</url>
|
<url>https://packages.libreccm.org/repository/maven-releases/</url>
|
||||||
</repository> -->
|
|
||||||
<snapshotRepository>
|
|
||||||
<id>libreccm-snapshots</id>
|
|
||||||
<url>https://git.libreccm.org/api/packages/libreccm/maven</url>
|
|
||||||
</snapshotRepository>
|
|
||||||
<repository>
|
|
||||||
<id>libreccm-releases</id>
|
|
||||||
<url>https://git.libreccm.org/api/packages/libreccm/maven</url>
|
|
||||||
</repository>
|
</repository>
|
||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue