From 5711a086ea061f245322006dc317afa8a7f18a17 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Tue, 18 May 2021 20:29:55 +0200 Subject: [PATCH] SideNoteEditStep bugfixes --- .../assets/CmsAssetEditSteps.java | 11 ++ .../assets/SideNoteEditStep.java | 5 +- .../assets/SideNoteEditStepResources.java | 133 +++++++++++++ .../MvcArticleTextBodyStepResources.java | 4 +- .../assets/sidenote/edit-sidenote.xhtml | 178 +++++++++--------- .../ui/MvcAssetStepsBundle.properties | 8 + .../ui/MvcAssetStepsBundle_de.properties | 8 + .../libreccm/security/PermissionChecker.java | 52 ++--- 8 files changed, 285 insertions(+), 114 deletions(-) create mode 100644 ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/SideNoteEditStepResources.java diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/CmsAssetEditSteps.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/CmsAssetEditSteps.java index a4b8c3b38..f68f9efc9 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/CmsAssetEditSteps.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/CmsAssetEditSteps.java @@ -37,5 +37,16 @@ public class CmsAssetEditSteps implements MvcAssetEditSteps { return classes; } + + @Override + public Set> getResourceClasses() { + final Set> classes = new HashSet<>(); + + classes.add(SideNoteEditStepResources.class); + + return classes; + } + + } diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/SideNoteEditStep.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/SideNoteEditStep.java index 9b18af44a..e5f8d70d6 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/SideNoteEditStep.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/SideNoteEditStep.java @@ -173,8 +173,7 @@ public class SideNoteEditStep extends AbstractMvcAssetEditStep { final String sectionIdentifier, @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) final String assetPath, - @FormParam("locale") final String localeParam, - @FormParam("value") final String value + @FormParam("locale") final String localeParam ) { try { init(); @@ -186,7 +185,7 @@ public class SideNoteEditStep extends AbstractMvcAssetEditStep { if (assetPermissionsChecker.canEditAsset(getAsset())) { final Locale locale = new Locale(localeParam); - getSideNote().getText().addValue(locale, value); + getSideNote().getText().addValue(locale, ""); assetRepo.save(getSideNote()); return buildRedirectPathForStep(); diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/SideNoteEditStepResources.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/SideNoteEditStepResources.java new file mode 100644 index 000000000..9ac28f8ba --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/SideNoteEditStepResources.java @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2021 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.assets; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.librecms.assets.SideNote; +import org.librecms.contentsection.Asset; +import org.librecms.contentsection.AssetRepository; +import org.librecms.contentsection.ContentSection; +import org.librecms.ui.contentsections.AssetPermissionsChecker; +import org.librecms.ui.contentsections.ContentSectionsUi; + +import java.util.Locale; +import java.util.StringTokenizer; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.transaction.Transactional; +import javax.ws.rs.ForbiddenException; +import javax.ws.rs.GET; +import javax.ws.rs.NotFoundException; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +/** + * + * @author Jens Pelzetter + */ +@RequestScoped +@Path(MvcAssetEditSteps.PATH_PREFIX + "sidenote-edit-resources") +public class SideNoteEditStepResources { + + @Inject + private AssetRepository assetRepo; + + @Inject + private ContentSectionsUi sectionsUi; + + @Inject + private AssetPermissionsChecker assetPermissionsChecker; + + @GET + @Path("/variants/wordcount/{locale}") + @Produces(MediaType.TEXT_HTML) + @Transactional(Transactional.TxType.REQUIRED) + public String getWordCount( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPathParam, + @PathParam("locale") final String localeParam + ) { + final ContentSection contentSection = sectionsUi + .findContentSection(sectionIdentifier) + .orElseThrow( + () -> new NotFoundException() + ); + + final Asset asset = assetRepo + .findByPath(contentSection, assetPathParam) + .orElseThrow(() -> new NotFoundException()); + + if (!(asset instanceof SideNote)) { + throw new NotFoundException(); + } + + final SideNote sideNote = (SideNote) asset; + if (assetPermissionsChecker.canEditAsset(asset)) { + final String text = sideNote + .getText() + .getValue(new Locale(localeParam)); + final Document jsoupDoc = Jsoup.parseBodyFragment(text); + final long result = new StringTokenizer( + jsoupDoc.body().text() + ).countTokens(); + return Long.toString(result); + } else { + throw new ForbiddenException(); + } + } + + @GET + @Path("/variants/{locale}") + @Produces(MediaType.TEXT_HTML) + @Transactional(Transactional.TxType.REQUIRED) + public String viewTextValue( + @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) + final String sectionIdentifier, + @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) + final String assetPathParam, + @PathParam("locale") final String localeParam + ) { + final ContentSection contentSection = sectionsUi + .findContentSection(sectionIdentifier) + .orElseThrow( + () -> new NotFoundException() + ); + + final Asset asset = assetRepo + .findByPath(contentSection, assetPathParam) + .orElseThrow(() -> new NotFoundException()); + + if (!(asset instanceof SideNote)) { + throw new NotFoundException(); + } + + final SideNote sideNote = (SideNote) asset; + if (assetPermissionsChecker.canEditAsset(asset)) { + return sideNote.getText().getValue(new Locale(localeParam)); + } else { + throw new ForbiddenException(); + } + } +} \ No newline at end of file diff --git a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticleTextBodyStepResources.java b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticleTextBodyStepResources.java index 0e13c47a7..876f3d1ab 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticleTextBodyStepResources.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticleTextBodyStepResources.java @@ -95,7 +95,9 @@ public class MvcArticleTextBodyStepResources { .getText() .getValue(new Locale(localeParam)); final Document jsoupDoc = Jsoup.parseBodyFragment(text); - long result = new StringTokenizer(jsoupDoc.body().text()).countTokens(); + final long result = new StringTokenizer( + jsoupDoc.body().text() + ).countTokens(); return Long.toString(result); } else { throw new ForbiddenException(); diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/sidenote/edit-sidenote.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/sidenote/edit-sidenote.xhtml index 976773b1a..2b462c31e 100644 --- a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/sidenote/edit-sidenote.xhtml +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contentsection/assets/sidenote/edit-sidenote.xhtml @@ -11,74 +11,74 @@

#{CmsAssetsStepsDefaultMessagesBundle.getMessage('sidenote.editstep.header', [CmsSideNoteEditStep.name])}

-
-

#{CmsAssetsStepsDefaultMessagesBundle['editstep.name.header']}

-
-
#{CmsSideNoteEditStep.name}
- - - -
- -
+ + + + + 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 9cb368033..63819681a 100644 --- a/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle.properties +++ b/ccm-cms/src/main/resources/org/librecms/ui/MvcAssetStepsBundle.properties @@ -69,3 +69,11 @@ postal_address.description=A postal address. side_note.label=Side Note side_note.description=A side note. sidenote.createform.title=Create a new side note +sidenote.editstep.header=Edit Side Note {0} +sidenote.editstep.text.header=Text +sidenote.sidenote.text.editor.add_variant=Add localized text +sidenote.text.editor.add.locale.help=The locale of the text variant. +sidenote.text.editor.add.locale.label=Locale +sidenote.text.editor.edit.value.help=The localized text. +sidenote.text.editor.edit.value.label=Text +sidenote.text.editor.header=Edit Side Note Text 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 5b6145fad..bcc9352d5 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 @@ -69,3 +69,11 @@ postal_address.description=Eine Postanschrift. side_note.label=Randbemerkung side_note.description=Eine Randbemerkung. sidenote.createform.title=Eine neue Randbemerkungen anlegen +sidenote.editstep.header=Randbemerkung {0} bearbeiten +sidenote.editstep.text.header=Text +sidenote.sidenote.text.editor.add_variant=\u00dcbersetzung hinzuf\u00fcgen +sidenote.text.editor.add.locale.help=Die Sprache der \u00dcbersetzung. +sidenote.text.editor.add.locale.label=Sprache +sidenote.text.editor.edit.value.help=The translated text. +sidenote.text.editor.edit.value.label=Text +sidenote.text.editor.header=Text der Randbemerkung bearbeiten diff --git a/ccm-core/src/main/java/org/libreccm/security/PermissionChecker.java b/ccm-core/src/main/java/org/libreccm/security/PermissionChecker.java index d762a78bc..81644d244 100644 --- a/ccm-core/src/main/java/org/libreccm/security/PermissionChecker.java +++ b/ccm-core/src/main/java/org/libreccm/security/PermissionChecker.java @@ -67,14 +67,14 @@ public class PermissionChecker { * @param privilege The privilege granted by the permission. * * @return {@code true} if the current subject has a permission granting the - * provided {@code privilege}, {@code false} otherwise. + * provided {@code privilege}, {@code false} otherwise. */ public boolean isPermitted(final String privilege) { if (subject.isAuthenticated()) { if (shiro.isSystemUser()) { return true; } else { - return subject.isPermitted(generatePermissionString(privilege)); + return subject.isPermitted(generatePermissionString(privilege)); } } else { return shiro.getPublicUser().isPermitted(generatePermissionString( @@ -87,11 +87,11 @@ public class PermissionChecker { * provided {@code privilege}. * * @param privilege The privilege granted by the permission. - * @param role The role to check for a permission granting the - * {@code privilege}. + * @param role The role to check for a permission granting the + * {@code privilege}. * * @return {@code true} if the role has a permission granting the provided - * {@code privilege}, {@code false} otherwise. + * {@code privilege}, {@code false} otherwise. */ @Transactional(Transactional.TxType.REQUIRED) public boolean isPermitted(final String privilege, final Role role) { @@ -129,22 +129,25 @@ public class PermissionChecker { * {@code privilege} on the provided {@code object}. * * @param privilege The granted privilege. - * @param object The object on which the privilege is granted. + * @param object The object on which the privilege is granted. * * @return {@code true} if the there is a permission granting the provided - * {@code privilege} on the provided {@code object} to the current subject. + * {@code privilege} on the provided {@code object} to the current + * subject. */ public boolean isPermitted(final String privilege, final CcmObject object) { if (subject.isAuthenticated()) { if (shiro.isSystemUser()) { return true; } else { - return subject.isPermitted(generatePermissionString( - privilege, object)); + return subject.isPermitted( + generatePermissionString(privilege, object) + ); } } else { - return shiro.getPublicUser().isPermitted(generatePermissionString( - privilege, object)); + return shiro.getPublicUser().isPermitted( + generatePermissionString(privilege, object) + ); } } @@ -153,13 +156,13 @@ public class PermissionChecker { * provided {@code privilege} on the provided object. * * @param privilege The granted privilege. - * @param object The object on which the {@code privilege} is granted. - * @param role The role to check for a permission granting the - * {@code privilege}. + * @param object The object on which the {@code privilege} is granted. + * @param role The role to check for a permission granting the + * {@code privilege}. * * @return {@code true} if the there is a permission granting the provided - * {@code privilege} on the provided {@code object} to the provided - * {@code role}. + * {@code privilege} on the provided {@code object} to the provided + * {@code role}. */ public boolean isPermitted(final String privilege, final CcmObject object, @@ -196,7 +199,7 @@ public class PermissionChecker { * @param privilege The privilege to check for. * * @throws AuthorizationException If the current subject has not permission - * granting the provided privilege. + * granting the provided privilege. */ public void checkPermission(final String privilege) throws AuthorizationException { @@ -216,10 +219,11 @@ public class PermissionChecker { * * * @param privilege The privilege to check for. - * @param object The object on which the privilege is granted. + * @param object The object on which the privilege is granted. * * @throws AuthorizationException If there is no permission granting the - * provided privilege to the current subject on the provided object.. + * provided privilege to the current subject + * on the provided object.. */ public void checkPermission(final String privilege, final CcmObject object) @@ -243,13 +247,13 @@ public class PermissionChecker { * placeholder object is returned with the {@link CcmObject#displayName} * property set the {@code Access denied}. * - * @param The type of the object to check. + * @param The type of the object to check. * @param privilege The privilige to check for. - * @param object The object on which the privilege is granted. - * @param clazz The class of the object. + * @param object The object on which the privilege is granted. + * @param clazz The class of the object. * * @return The object if the current subject is permitted to access, a - * placeholder object if not. + * placeholder object if not. */ public T checkPermission(final String privilege, final T object, @@ -265,7 +269,7 @@ public class PermissionChecker { * @param object The object to check. * * @return {@code true} if the object is a Access denied object, - * {@code false} if not. + * {@code false} if not. */ public boolean isAccessDeniedObject(final CcmObject object) { if (object == null) {