diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AbstractMvcAssetEditStep.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AbstractMvcAssetEditStep.java index 263a25993..f06a1a2a0 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AbstractMvcAssetEditStep.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AbstractMvcAssetEditStep.java @@ -19,6 +19,7 @@ package org.librecms.ui.contentsections.assets; import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.security.AuthorizationRequired; import org.librecms.contentsection.Asset; import org.librecms.contentsection.AssetManager; import org.librecms.contentsection.AssetRepository; @@ -36,6 +37,10 @@ import java.util.Optional; import javax.inject.Inject; import javax.mvc.Models; import javax.servlet.http.HttpServletRequest; +import javax.transaction.Transactional; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.WebApplicationException; @@ -312,4 +317,6 @@ public abstract class AbstractMvcAssetEditStep implements MvcAssetEditStep { .orElse(""); } + + } diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AssetsController.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AssetsController.java index 8ccd9dcd9..423851ad4 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AssetsController.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/AssetsController.java @@ -370,7 +370,7 @@ public class AssetsController { models.put("contentSection", section.getLabel()); models.put("assetType", assetType); - return "org/librecms/ui/contentsection/assetfolder/asset-type-not-found.xhtml"; + return "org/librecms/ui/contentsection/assets/asset-type-not-found.xhtml"; } private String showCreateStepNotAvailable( @@ -382,7 +382,7 @@ public class AssetsController { models.put("folderPath", folderPath); models.put("assetType", assetType); - return "org/librecms/ui/contentsection/assetfolder/create-step-not-available.xhtml"; + return "org/librecms/ui/contentsection/assets/create-step-not-available.xhtml"; } diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PostalAddressEditStep.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PostalAddressEditStep.java index 483eee044..6a6304a42 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PostalAddressEditStep.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/PostalAddressEditStep.java @@ -18,12 +18,35 @@ */ package org.librecms.ui.contentsections.assets; +import org.libreccm.l10n.GlobalizationHelper; +import org.libreccm.security.AuthorizationRequired; import org.librecms.assets.PostalAddress; +import org.librecms.contentsection.AssetManager; +import org.librecms.contentsection.AssetRepository; +import org.librecms.contentsection.FolderManager; +import org.librecms.ui.contentsections.AssetPermissionsChecker; +import org.librecms.ui.contentsections.ContentSectionNotFoundException; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; import javax.inject.Named; import javax.mvc.Controller; +import javax.mvc.Models; +import javax.transaction.Transactional; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; /** * @@ -39,6 +62,322 @@ import javax.ws.rs.Path; labelKey = "postaladdress.editstep.label", supportedAssetType = PostalAddress.class ) -public class PostalAddressEditStep { - +public class PostalAddressEditStep extends AbstractMvcAssetEditStep { + + @Inject + private AssetStepsDefaultMessagesBundle messageBundle; + + @Inject + private AssetManager assetManager; + + @Inject + private AssetUi assetUi; + + @Inject + private AssetRepository assetRepo; + + @Inject + private FolderManager folderManager; + + @Inject + private GlobalizationHelper globalizationHelper; + + @Inject + private AssetPermissionsChecker assetPermissionsChecker; + + @Inject + private Models models; + + private Map titleValues; + + private List unusedTitleLocales; + + @Override + public Class getStepClass() { + return PostalAddressEditStep.class; + } + + @GET + @Path("/") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String showStep( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + titleValues = getAsset() + .getTitle() + .getValues() + .entrySet() + .stream() + .collect( + Collectors.toMap( + entry -> entry.getKey().toString(), + entry -> entry.getValue() + ) + ); + + final Set titleLocales = getAsset() + .getTitle() + .getAvailableLocales(); + + unusedTitleLocales = globalizationHelper + .getAvailableLocales() + .stream() + .filter(locale -> !titleLocales.contains(locale)) + .map(Locale::toString) + .collect(Collectors.toList()); + + return "org/librecms/ui/assets/postaladdress/edit-postaladdress.xhtml"; + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + + public String getName() { + return getAsset().getDisplayName(); + } + + public PostalAddress getPostalAddress() { + return (PostalAddress) getAsset(); + } + + @POST + @Path("/name") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String updateName( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath, + @FormParam("name") @DefaultValue("") final String name + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + if (name.isEmpty() || name.matches("\\s*")) { + models.put("nameMissing", true); + + return showStep(sectionIdentifier, assetPath); + } + + getAsset().setDisplayName(name); + assetRepo.save(getAsset()); + + updateAssetPath(); + + return buildRedirectPathForStep(); + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + + public Map getTitleValues() { + return Collections.unmodifiableMap(titleValues); + } + + public List getUnusedTitleLocales() { + return Collections.unmodifiableList(unusedTitleLocales); + } + + @POST + @Path("/title/@add") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String addTitle( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath, + @FormParam("locale") final String localeParam, + @FormParam("value") final String value + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + final Locale locale = new Locale(localeParam); + getAsset().getTitle().addValue(locale, value); + assetRepo.save(getAsset()); + + return buildRedirectPathForStep(); + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + + @POST + @Path("/title/@edit/{locale}") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String editTitle( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath, + @PathParam("locale") final String localeParam, + @PathParam("value") final String value + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + final Locale locale = new Locale(localeParam); + getAsset().getTitle().addValue(locale, value); + assetRepo.save(getAsset()); + + return buildRedirectPathForStep(); + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + + @POST + @Path("/title/@remove/{locale}") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String removeTitle( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath, + @PathParam("locale") final String localeParam + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + final Locale locale = new Locale(localeParam); + getAsset().getTitle().removeValue(locale); + assetRepo.save(getAsset()); + + return buildRedirectPathForStep(); + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + + public String getAddress() { + return getPostalAddress().getAddress(); + } + + public String getPostalCode() { + return getPostalAddress().getPostalCode(); + } + + public String getCity() { + return getPostalAddress().getCity(); + } + + public String getState() { + return getPostalAddress().getState(); + } + + public String getIsoCountryCode() { + return getPostalAddress().getIsoCountryCode(); + } + + @POST + @Path("/properties") + @AuthorizationRequired + @Transactional(Transactional.TxType.REQUIRED) + public String updateProperties( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPath, + @FormParam("address") final String address, + @FormParam("postalCode") final String postalCode, + @FormParam("city") final String city, + @FormParam("state") final String state, + @FormParam("isoCountryCode") final String isoCountryCode + ) { + try { + init(); + } catch (ContentSectionNotFoundException ex) { + return ex.showErrorMessage(); + } catch (AssetNotFoundException ex) { + return ex.showErrorMessage(); + } + + if (assetPermissionsChecker.canEditAsset(getAsset())) { + final PostalAddress postalAddress = getPostalAddress(); + postalAddress.setAddress(address); + postalAddress.setCity(city); + postalAddress.setIsoCountryCode(isoCountryCode); + postalAddress.setPostalCode(postalCode); + postalAddress.setState(state); + + assetRepo.save(postalAddress); + + return buildRedirectPathForStep(); + } else { + return assetUi.showAccessDenied( + getContentSection(), + getAsset(), + messageBundle.get("asset.edit.denied")); + } + } + + public Map getCountries() { + return Arrays + .stream(Locale.getISOCountries()) + .map(country -> new Locale(country)) + .collect( + Collectors.toMap( + Locale::toString, + locale -> locale.getDisplayCountry(globalizationHelper + .getNegotiatedLocale()) + ) + ); + } + } diff --git a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticlePropertiesStep.java b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticlePropertiesStep.java index 8c375a299..24a2fc693 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticlePropertiesStep.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticlePropertiesStep.java @@ -20,6 +20,7 @@ package org.librecms.ui.contenttypes; import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.l10n.LocalizedString; +import org.libreccm.security.AuthorizationRequired; import org.librecms.contentsection.ContentItemManager; import org.librecms.contentsection.ContentItemRepository; import org.librecms.contentsection.FolderManager; @@ -122,6 +123,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep { @GET @Path("/") + @AuthorizationRequired @Transactional(Transactional.TxType.REQUIRED) public String showStep( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @@ -215,6 +217,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep { */ @POST @Path("/name") + @AuthorizationRequired @Transactional(Transactional.TxType.REQUIRED) public String updateName( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @@ -283,6 +286,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep { */ @POST @Path("/title/@add") + @AuthorizationRequired @Transactional(Transactional.TxType.REQUIRED) public String addTitle( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @@ -327,6 +331,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep { */ @POST @Path("/title/@edit/{locale}") + @AuthorizationRequired @Transactional(Transactional.TxType.REQUIRED) public String editTitle( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @@ -370,6 +375,7 @@ public class MvcArticlePropertiesStep extends AbstractMvcAuthoringStep { */ @POST @Path("/title/@remove/{locale}") + @AuthorizationRequired @Transactional(Transactional.TxType.REQUIRED) public String removeTitle( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/access-denied.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/access-denied.xhtml new file mode 100644 index 000000000..fc35d5ac6 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/access-denied.xhtml @@ -0,0 +1,27 @@ +]> + + + + + + + + + + + +
+ +
+
+ +
+ diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/asset-not-found.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/asset-not-found.xhtml new file mode 100644 index 000000000..9c16bc9cd --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/asset-not-found.xhtml @@ -0,0 +1,29 @@ +]> + + + + + + + + + + + + +
+ +
+
+ +
+ + diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/asset-type-not-found.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/asset-type-not-found.xhtml new file mode 100644 index 000000000..ce71eed23 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/asset-type-not-found.xhtml @@ -0,0 +1,28 @@ +]> + + + + + + + + + + + +
+ +
+
+ + +
+ diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/asset.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/asset.xhtml new file mode 100644 index 000000000..d62244e41 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/asset.xhtml @@ -0,0 +1,57 @@ +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

#{CmsAdminMessages.getMessage("contentsection.asset.heading", [ContentSectionModel.sectionName, CmsSelectedAssetModel.assetTitle])}

+ + + +
+
+ +
+ diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/create-step-not-available.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/create-step-not-available.xhtml new file mode 100644 index 000000000..2bb829e29 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/create-step-not-available.xhtml @@ -0,0 +1,30 @@ +]> + + + + + + + + + + + +
+ +
+
+ +
+ + + + diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/postaladdress/create-postaladdress.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/postaladdress/create-postaladdress.xhtml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/postaladdress/create-postaladdress.xhtml @@ -0,0 +1 @@ + diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/postaladdress/edit-postaladdress.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/postaladdress/edit-postaladdress.xhtml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/postaladdress/edit-postaladdress.xhtml @@ -0,0 +1 @@ + diff --git a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties index 8520cd2f3..fbd40a8ef 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties @@ -783,3 +783,14 @@ contentsection.assetfolder.new_asset_dialog.title=Create new asset contentsection.assetfolder.new_asset_dialog.assettype.help=Select the type of the new asset. contentsection.assetfolder.new_asset_dialog.assettype.label=Type contentsection.assetfolder.new_asset_dialog.submit=Create asset +contentsection.asset_access_denied.title=Access denied +contentsection.asset_access_denied.breadcrumb=Access denied +contentsection.asset_access_denied.message=Access to edit step of asset {1} of content section {0} denied. +contentsection.assets.asset_not_found.title=Asset not found +contentsection.asset_not_found.breadcrumb=Asset not found +contentsection.asset.not_found.message=There is no asset {1} in content section {0}. +contentsection.assets.asset_type.not_available.title=Asset Type not available +contentsection.assets.asset_type.not_available.message=No asset type {1} available for content section {0}. +contentsection.assets.createstep.not_available.title=No create step available +contentsection.assets.createstep.breadcrumb=Create {0} asset +contentsection.assets.createstep.not_available.message=Unable to create new asset of type {2} in folder {1} of content section{0}. Create step for asset type {2} not available. diff --git a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties index cfc5d3f47..f4a4b47dc 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties @@ -784,3 +784,14 @@ contentsection.assetfolder.new_asset_dialog.title=Neues Asset erstellen contentsection.assetfolder.new_asset_dialog.assettype.help=W\u00e4hlen Sie den Typ des neuen Assets aus. contentsection.assetfolder.new_asset_dialog.assettype.label=Typ contentsection.assetfolder.new_asset_dialog.submit=Asset erstellen +contentsection.asset_access_denied.title=Zugriff verweigert +contentsection.asset_access_denied.breadcrumb=Zugriff verweigert +contentsection.asset_access_denied.message=Zugriff zur Bearbeitung von Asset {1} der Content Section {0} verweigert. +contentsection.assets.asset_not_found.title=Asset nicht gefunden +contentsection.asset_not_found.breadcrumb=Asset nicht gefunden +contentsection.asset.not_found.message=Es kein Asset {1} in Content Section {0}. +contentsection.assets.asset_type.not_available.title=Asset Typ nicht verf\u00fcgbar +contentsection.assets.asset_type.not_available.message=Kein Asset Typ {1} f\u00fcr Content Section {0} verf\u00fcgbar. +contentsection.assets.createstep.not_available.title=Kein Formular zum Erstellen verf\u00fcgbar +contentsection.assets.createstep.breadcrumb={0} asset anlegen +contentsection.assets.createstep.not_available.message=Anlegen eines Assets vom Type {2} in Ordner {1} der Content Section {0} nicht m\u00f6glich. Formular zum Anlegen von Assets des Types {2} nicht verf\u00fcgbar. diff --git a/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle.properties b/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle.properties index be5bf4c66..e574b0d5d 100644 --- a/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle.properties +++ b/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle.properties @@ -1,2 +1,3 @@ create_step=Access denied +asset.edit.denied=Access denied. diff --git a/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle_de.properties b/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle_de.properties index f05bf4dc0..e1558d64c 100644 --- a/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle_de.properties @@ -1,2 +1,3 @@ create_step=Zugriff verweigert +asset.edit.denied=Zugriff verweigert