From 3c3f73a6357e4d98e14f8c127488009113a5e4fc Mon Sep 17 00:00:00 2001 From: tiliavir Date: Sat, 26 Feb 2022 13:16:34 +0100 Subject: [PATCH 1/2] #72: Replaces deprecated methods, plugin type: both, Java 17, constants for text keys --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- docs/docker.md | 21 ++- pom.xml | 29 +++- .../DigitalSignatureMacro.java | 163 ++++++++++-------- .../digitalsignature/Signature.java | 4 +- .../digitalsignature/UserProfileByName.java | 12 +- .../digitalsignature/i18n/TextProperties.java | 15 ++ .../impl/DigitalSignatureComponentImpl.java | 2 + .../rest/DigitalSignatureService.java | 35 ++-- src/main/resources/atlassian-plugin.xml | 5 +- .../resources/digital-signature.properties | 1 + .../resources/digital-signature_de.properties | 3 +- .../resources/digital-signature_fr.properties | 1 + .../DigitalSignatureComponentTest.java} | 4 +- .../DigitalSignatureMacroTest.java | 33 +++- .../SignatureSerialisationTest.java | 2 - src/test/resources/atlassian-plugin.xml | 17 +- src/test/resources/log4j.xml | 33 ++-- 19 files changed, 245 insertions(+), 139 deletions(-) create mode 100644 src/main/java/com/baloise/confluence/digitalsignature/i18n/TextProperties.java rename src/test/java/{ut/com/baloise/confluence/digitalsignature/MyComponentUnitTest.java => com/baloise/confluence/digitalsignature/DigitalSignatureComponentTest.java} (84%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2c2908b..30fc8b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,6 @@ jobs: - name: Set up Java uses: actions/setup-java@v1 with: - java-version: '11' + java-version: '17' - name: Build with Maven run: mvn -B package --file pom.xml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d07aa91..2e88de6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Java uses: actions/setup-java@v1 with: - java-version: '11' + java-version: '17' - name: Build with Maven 🔧 run: mvn -B package --file pom.xml diff --git a/docs/docker.md b/docs/docker.md index 82a33ae..57cb695 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -1,14 +1,19 @@ -Setup following a [tutorial from coffeetime.solutions]( http://coffeetime.solutions/run-atlassian-jira-and-confluence-with-postgresql-on-docker/#Overview_of_series_How_to_run_Jira_and_Confluence_behind_NGINX_reverse_proxy_on_Docker): +# Simple Confluence Setup ```bash docker run --name=confluence -d -p 8090:8090 -p 8091:8091 atlassian/confluence-server:latest docker run --name postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres -``` -Start confluence setup and configure Postgres: -- jdbc:postgresql://192.168.65.2:5432/postgres (`docker inspect postgres` to get ip address) -- user: postgres -- password: mysecretpassword (defined above) +docker inspect postgres # to get IP +``` -Skip tutorial -Create new space "Test" +Start confluence setup +- add a new license +- and configure Postgres connection: + - hostname: IP from docker inspect + - port: 5432 + - db: postgres + - user: postgres + - password: `mysecretpassword` (defined above) +- Skip tutorial +- Create new space "Test" diff --git a/pom.xml b/pom.xml index c84e0f0..cb007fb 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ Baloise - http://www.baloise.ch/ + https://www.baloise.ch/ @@ -32,13 +32,13 @@ com.vladsch.flexmark flexmark - 0.62.2 + 0.64.0 com.google.code.gson gson - 2.8.9 + 2.9.0 @@ -105,10 +105,16 @@ 1.10.19 test + + org.slf4j + slf4j-api + 2.0.0-alpha6 + provided + org.slf4j slf4j-simple - 2.0.0-alpha1 + 2.0.0-alpha6 test @@ -176,13 +182,22 @@ false + + 3.8.1 + org.apache.maven.plugins + maven-compiler-plugin + + 14 + 14 + + - 7.4.0 - 7.4.0 - 8.1.0 + 7.9.3 + 7.9.3 + 8.4.0 2.0.1 1.2.13 diff --git a/src/main/java/com/baloise/confluence/digitalsignature/DigitalSignatureMacro.java b/src/main/java/com/baloise/confluence/digitalsignature/DigitalSignatureMacro.java index aaeb4a8..2ca44c8 100644 --- a/src/main/java/com/baloise/confluence/digitalsignature/DigitalSignatureMacro.java +++ b/src/main/java/com/baloise/confluence/digitalsignature/DigitalSignatureMacro.java @@ -14,6 +14,7 @@ import com.atlassian.confluence.setup.BootstrapManager; import com.atlassian.confluence.user.AuthenticatedUserThreadLocal; import com.atlassian.confluence.user.ConfluenceUser; +import com.atlassian.confluence.user.UserAccessor; import com.atlassian.plugin.spring.scanner.annotation.component.Scanned; import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport; import com.atlassian.sal.api.message.I18nResolver; @@ -23,19 +24,18 @@ import com.atlassian.user.Group; import com.atlassian.user.GroupManager; import com.atlassian.user.search.page.Pager; +import org.apache.commons.lang.StringUtils; import org.apache.velocity.tools.generic.DateTool; import org.jetbrains.annotations.NotNull; -import org.springframework.beans.factory.annotation.Autowired; -import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.security.InvalidParameterException; +import java.nio.charset.StandardCharsets; import java.util.*; import static com.atlassian.confluence.renderer.radeox.macros.MacroUtils.defaultVelocityContext; import static com.atlassian.confluence.security.ContentPermission.*; -import static com.atlassian.confluence.setup.bandana.ConfluenceBandanaContext.GLOBAL_CONTEXT; import static com.atlassian.confluence.util.velocity.VelocityUtils.getRenderedTemplate; +import static com.baloise.confluence.digitalsignature.i18n.TextProperties.*; import static java.util.Arrays.asList; import static java.util.stream.Collectors.toList; @@ -44,7 +44,6 @@ public class DigitalSignatureMacro implements Macro { private static final int MAX_MAILTO_CHARACTER_COUNT = 500; private static final String REST_PATH = "/rest/signature/1.0"; private static final String DISPLAY_PATH = "/display"; - private final BandanaManager bandanaManager; private final UserManager userManager; private final BootstrapManager bootstrapManager; @@ -52,13 +51,14 @@ public class DigitalSignatureMacro implements Macro { private final PermissionManager permissionManager; private final GroupManager groupManager; private final I18nResolver i18nResolver; - private final transient Markdown markdown = new Markdown(); + private final UserAccessor userAccessor; private final Set all = new HashSet<>(); + private final transient Markdown markdown = new Markdown(); private final ContextHelper contextHelper = new ContextHelper(); - @Autowired public DigitalSignatureMacro(@ComponentImport BandanaManager bandanaManager, @ComponentImport UserManager userManager, + @ComponentImport UserAccessor userAccessor, @ComponentImport BootstrapManager bootstrapManager, @ComponentImport PageManager pageManager, @ComponentImport PermissionManager permissionManager, @@ -71,28 +71,38 @@ public DigitalSignatureMacro(@ComponentImport BandanaManager bandanaManager, this.permissionManager = permissionManager; this.groupManager = groupManager; this.i18nResolver = i18nResolver; + this.userAccessor = userAccessor; all.add("*"); } + static long getLong(Map params, String key, long fallback) { + String value = params.get(key); + return value == null ? fallback : Long.parseLong(value); + } + @Override public String execute(Map params, String body, ConversionContext conversionContext) { if (body == null || body.length() <= 10) { - return warning(i18nResolver.getText("com.baloise.confluence.digital-signature.signature.macro.warning.bodyToShort")); + return warning(i18nResolver.getText(WARN_BODY_TOO_SHORT)); + } + + ContentEntityObject entity = conversionContext.getEntity(); + if (entity == null) { + return warning(i18nResolver.getText(WARN_UNKNOWN_CONTEXT)); } Set userGroups = getSet(params, "signerGroups"); boolean petitionMode = Signature.isPetitionMode(userGroups); Set signers = petitionMode ? all : contextHelper.union(getSet(params, "signers"), loadUserGroups(userGroups), loadInheritedSigners(InheritSigners.ofValue(params.get("inheritSigners")), conversionContext)); - ContentEntityObject entity = conversionContext.getEntity(); Signature signature = sync(new Signature(entity.getLatestVersionId(), body, params.get("title")).withNotified(getSet(params, "notified")).withMaxSignatures(getLong(params, "maxSignatures", -1)).withVisibilityLimit(getLong(params, "visibilityLimit", -1)), signers); boolean protectedContent = getBoolean(params, "protectedContent", false); - if (protectedContent && isPage(conversionContext)) { + if (protectedContent && entity instanceof Page) { try { - ensureProtectedPage(conversionContext, (Page) entity, signature); + ensureProtectedPage((Page) entity, signature); } catch (Exception e) { - return warning(i18nResolver.getText("com.baloise.confluence.digital-signature.signature.macro.warning.editPermissionRequiredForProtectedContent", "")); + return warning(i18nResolver.getText(WARN_EDIT_PERMISSION_REQ, "")); } } @@ -115,7 +125,7 @@ private Map buildContext(Map params, ConversionC } context.put("panel", getBoolean(params, "panel", true)); context.put("protectedContent", protectedContentAccess); - if (protectedContentAccess && isPage(conversionContext)) { + if (protectedContentAccess && conversionContext.getEntity() instanceof Page) { context.put("protectedContentURL", bootstrapManager.getWebAppContextPath() + DISPLAY_PATH + "/" + ((Page) page).getSpaceKey() + "/" + signature.getProtectedKey()); } @@ -135,8 +145,13 @@ private Map buildContext(Map params, ConversionC return context; } - private void ensureProtectedPage(ConversionContext conversionContext, Page page, Signature signature) { - Page protectedPage = pageManager.getPage(conversionContext.getSpaceKey(), signature.getProtectedKey()); + private void ensureProtectedPage(Page page, Signature signature) { + Page protectedPage = page.getChildren() + .stream() + .filter(p -> signature.getProtectedKey().equals(p.getTitle())) + .findFirst() + .orElse(null); + if (protectedPage == null) { ContentPermissionSet editors = page.getContentPermissionSet(EDIT_PERMISSION); if (editors == null || editors.size() == 0) { @@ -152,7 +167,8 @@ private void ensureProtectedPage(ConversionContext conversionContext, Page page, protectedPage.addPermission(createUserPermission(VIEW_PERMISSION, editor.getUserSubject())); } for (String signedUserName : signature.getSignatures().keySet()) { - protectedPage.addPermission(createUserPermission(VIEW_PERMISSION, signedUserName)); + ConfluenceUser user = userAccessor.getUserByName(signedUserName); + protectedPage.addPermission(createUserPermission(VIEW_PERMISSION, user)); } protectedPage.setTitle(signature.getProtectedKey()); pageManager.saveContentEntity(protectedPage, DefaultSaveContext.DEFAULT); @@ -162,31 +178,32 @@ private void ensureProtectedPage(ConversionContext conversionContext, Page page, private boolean hideSignatures(Map params, Signature signature, String currentUserName) { boolean pendingVisible = isVisible(signature, currentUserName, params.get("pendingVisible")); + if (!pendingVisible) { + signature.setMissingSignatures(Collections.emptySet()); + } + boolean signaturesVisible = isVisible(signature, currentUserName, params.get("signaturesVisible")); - if (!pendingVisible) signature.setMissingSignatures(new TreeSet<>()); - if (!signaturesVisible) signature.setSignatures(new HashMap<>()); + if (!signaturesVisible) { + signature.setSignatures(Collections.emptyMap()); + } return pendingVisible && signaturesVisible; } private boolean isVisible(Signature signature, String currentUserName, String signaturesVisibleParam) { - switch (SignaturesVisible.ofValue(signaturesVisibleParam)) { - case IF_SIGNATORY: - return signature.hasSigned(currentUserName) || signature.isSignatory(currentUserName); - case IF_SIGNED: - return signature.hasSigned(currentUserName); - case ALWAYS: - return true; - default: - throw new InvalidParameterException(String.format("'%s' is an unknown value of SignaturesVisible!", signaturesVisibleParam)); - } + return switch (SignaturesVisible.ofValue(signaturesVisibleParam)) { + case IF_SIGNATORY -> signature.hasSigned(currentUserName) || signature.isSignatory(currentUserName); + case IF_SIGNED -> signature.hasSigned(currentUserName); + case ALWAYS -> true; + }; } - private boolean isPage(ConversionContext conversionContext) { - return conversionContext.getEntity() instanceof Page; - } - - private String warning(String message) { - return "
\n" + "

\n" + " " + i18nResolver.getText("com.baloise.confluence.digital-signature.signature.label") + "\n" + "

\n" + "

" + message + "

\n" + "
"; + String warning(String message) { + return String.format("
\n" + + "

\n" + + " %s\n" + + "

\n" + + "

%s

\n" + + "
", i18nResolver.getText(LABEL), message); } private Set loadInheritedSigners(InheritSigners inheritSigners, ConversionContext conversionContext) { @@ -212,16 +229,22 @@ private Set loadInheritedSigners(InheritSigners inheritSigners, Conversi } private Set loadUsers(ConversionContext conversionContext, String permission) { - Set users = new HashSet<>(); + if (conversionContext == null || conversionContext.getEntity() == null) { + throw new IllegalArgumentException("permission may not be null!"); + } + ContentPermissionSet contentPermissionSet = conversionContext.getEntity().getContentPermissionSet(permission); - if (contentPermissionSet != null) { - for (ContentPermission cp : contentPermissionSet) { - if (cp.getGroupName() != null) { - users.addAll(loadUserGroup(cp.getGroupName())); - } - if (cp.getUserSubject() != null) { - users.add(cp.getUserSubject().getName()); - } + if (contentPermissionSet == null) { + return Collections.emptySet(); + } + + Set users = new HashSet<>(); + for (ContentPermission cp : contentPermissionSet) { + if (cp.getGroupName() != null) { + users.addAll(loadUserGroup(cp.getGroupName())); + } + if (cp.getUserSubject() != null) { + users.add(cp.getUserSubject().getName()); } } return users; @@ -236,21 +259,26 @@ private Set loadUserGroups(Iterable groupNames) { } private Set loadUserGroup(String groupName) { - Set ret = new HashSet<>(); + if (StringUtils.isBlank(groupName)) { + return Collections.emptySet(); + } + + Set set = new HashSet<>(); try { - if (groupName == null) return ret; Group group = groupManager.getGroup(groupName.trim()); - if (group == null) return ret; + if (group == null) { + return set; + } Pager pager = groupManager.getMemberNames(group); while (!pager.onLastPage()) { - ret.addAll(pager.getCurrentPage()); + set.addAll(pager.getCurrentPage()); pager.nextPage(); } - ret.addAll(pager.getCurrentPage()); + set.addAll(pager.getCurrentPage()); } catch (EntityException e) { e.printStackTrace(); } - return ret; + return set; } private Boolean getBoolean(Map params, String key, Boolean fallback) { @@ -258,11 +286,6 @@ private Boolean getBoolean(Map params, String key, Boolean fallb return value == null ? fallback : Boolean.valueOf(value); } - private long getLong(Map params, String key, long fallback) { - String value = params.get(key); - return value == null ? fallback : Long.parseLong(value); - } - private Set getSet(Map params, String key) { String value = params.get(key); return value == null || value.trim().isEmpty() ? new TreeSet<>() : new TreeSet<>(asList(value.split("[;, ]+"))); @@ -296,7 +319,9 @@ private Signature sync(Signature signature, Set signers) { save = true; } - if (save) save(loaded); + if (save) { + save(loaded); + } } else { signature.setMissingSignatures(signers); save(signature); @@ -321,34 +346,34 @@ public OutputType getOutputType() { } protected String getMailto(Collection profiles, String subject, boolean signed, Signature signature) { - if (profiles == null || profiles.isEmpty()) return null; - Collection profilesWithMail = profiles.stream().filter(contextHelper::hasEmail).collect(toList()); + if (profiles == null || profiles.isEmpty()) { + return null; + } + Collection profilesWithMail = profiles.stream() + .filter(contextHelper::hasEmail) + .collect(toList()); StringBuilder ret = new StringBuilder("mailto:"); for (UserProfile profile : profilesWithMail) { - if (ret.length() > 7) ret.append(','); + if (ret.length() > 7) { + ret.append(','); + } ret.append(contextHelper.mailTo(profile)); } - ret.append("?Subject=").append(urlEncode(subject)); + ret.append("?Subject=").append(URLEncoder.encode(subject, StandardCharsets.UTF_8)); if (ret.length() > MAX_MAILTO_CHARACTER_COUNT) { ret.setLength(0); ret.append("mailto:"); for (UserProfile profile : profilesWithMail) { - if (ret.length() > 7) ret.append(','); + if (ret.length() > 7) { + ret.append(','); + } ret.append(profile.getEmail().trim()); } - ret.append("?Subject=").append(urlEncode(subject)); + ret.append("?Subject=").append(URLEncoder.encode(subject, StandardCharsets.UTF_8)); } if (ret.length() > MAX_MAILTO_CHARACTER_COUNT) { return bootstrapManager.getWebAppContextPath() + REST_PATH + "/emails?key=" + signature.getKey() + "&signed=" + signed; } return ret.toString(); } - - public String urlEncode(String string) { - try { - return URLEncoder.encode(string, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e); - } - } } diff --git a/src/main/java/com/baloise/confluence/digitalsignature/Signature.java b/src/main/java/com/baloise/confluence/digitalsignature/Signature.java index 20448f0..b9837c9 100644 --- a/src/main/java/com/baloise/confluence/digitalsignature/Signature.java +++ b/src/main/java/com/baloise/confluence/digitalsignature/Signature.java @@ -7,6 +7,7 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import java.io.Serial; import java.io.Serializable; import java.util.*; @@ -18,8 +19,9 @@ @Setter @NoArgsConstructor public class Signature implements Serializable { - public static final Gson GSON = new Gson(); + @Serial private static final long serialVersionUID = 1L; + public static final Gson GSON = new Gson(); private String key = ""; private String hash = ""; private long pageId; diff --git a/src/main/java/com/baloise/confluence/digitalsignature/UserProfileByName.java b/src/main/java/com/baloise/confluence/digitalsignature/UserProfileByName.java index 1687b06..f6d8eef 100644 --- a/src/main/java/com/baloise/confluence/digitalsignature/UserProfileByName.java +++ b/src/main/java/com/baloise/confluence/digitalsignature/UserProfileByName.java @@ -8,13 +8,19 @@ public class UserProfileByName implements Comparator { @Override public int compare(UserProfile u1, UserProfile u2) { int ret = nn(u1.getFullName()).compareTo(nn(u2.getFullName())); - if (ret != 0) return ret; + if (ret != 0) { + return ret; + } ret = nn(u1.getEmail()).compareTo(nn(u2.getEmail())); - if (ret != 0) return ret; + if (ret != 0) { + return ret; + } ret = nn(u1.getUsername()).compareTo(nn(u2.getUsername())); - if (ret != 0) return ret; + if (ret != 0) { + return ret; + } return Integer.compare(u1.hashCode(), u2.hashCode()); } diff --git a/src/main/java/com/baloise/confluence/digitalsignature/i18n/TextProperties.java b/src/main/java/com/baloise/confluence/digitalsignature/i18n/TextProperties.java new file mode 100644 index 0000000..e10be90 --- /dev/null +++ b/src/main/java/com/baloise/confluence/digitalsignature/i18n/TextProperties.java @@ -0,0 +1,15 @@ +package com.baloise.confluence.digitalsignature.i18n; + +public class TextProperties { + private static final String TEXT_PREFIX = "com.baloise.confluence.digital-signature.signature."; + + public static final String LABEL = TEXT_PREFIX + "label"; + public static final String WARN_MAX_SIGNATURES_REACHED = TextProperties.TEXT_PREFIX + "service.warning.maxSignaturesReached"; + public static final String WARN_BODY_TOO_SHORT = TEXT_PREFIX + "macro.warning.bodyToShort"; + public static final String WARN_UNKNOWN_CONTEXT = TEXT_PREFIX + "macro.warning.unknownContext"; + public static final String WARN_EDIT_PERMISSION_REQ = TEXT_PREFIX + "macro.warning.editPermissionRequiredForProtectedContent"; + public static final String ERROR_BAD_USER = TextProperties.TEXT_PREFIX + "service.error.badUser"; + public static final String MESSAGE_HAS_SIGNED_SHORT = TextProperties.TEXT_PREFIX + "service.message.hasSignedShort"; + public static final String MESSAGE_SIGNED_USERS_EMAILS = TextProperties.TEXT_PREFIX + "service.message.signedUsersEmails"; + public static final String MESSAGE_UNSIGNED_USERS_EMAILS = TextProperties.TEXT_PREFIX + "service.message.unsignedUsersEmails"; +} diff --git a/src/main/java/com/baloise/confluence/digitalsignature/impl/DigitalSignatureComponentImpl.java b/src/main/java/com/baloise/confluence/digitalsignature/impl/DigitalSignatureComponentImpl.java index 4a49a44..e23edfa 100644 --- a/src/main/java/com/baloise/confluence/digitalsignature/impl/DigitalSignatureComponentImpl.java +++ b/src/main/java/com/baloise/confluence/digitalsignature/impl/DigitalSignatureComponentImpl.java @@ -14,6 +14,7 @@ public class DigitalSignatureComponentImpl implements DigitalSignatureComponent @ComponentImport private final ApplicationProperties applicationProperties; + @SuppressWarnings("unused") public DigitalSignatureComponentImpl() { this(null); } @@ -23,6 +24,7 @@ public DigitalSignatureComponentImpl(final ApplicationProperties applicationProp this.applicationProperties = applicationProperties; } + @SuppressWarnings("unused") public String getName() { if (null != applicationProperties) { return "digitalSignatureComponent:" + applicationProperties.getDisplayName(); diff --git a/src/main/java/com/baloise/confluence/digitalsignature/rest/DigitalSignatureService.java b/src/main/java/com/baloise/confluence/digitalsignature/rest/DigitalSignatureService.java index 251458f..82cee0f 100644 --- a/src/main/java/com/baloise/confluence/digitalsignature/rest/DigitalSignatureService.java +++ b/src/main/java/com/baloise/confluence/digitalsignature/rest/DigitalSignatureService.java @@ -3,7 +3,7 @@ import com.atlassian.bandana.BandanaManager; import com.atlassian.confluence.pages.Page; import com.atlassian.confluence.pages.PageManager; -import com.atlassian.confluence.setup.settings.SettingsManager; +import com.atlassian.confluence.setup.settings.GlobalSettingsManager; import com.atlassian.confluence.user.AuthenticatedUserThreadLocal; import com.atlassian.confluence.user.ConfluenceUser; import com.atlassian.mail.Email; @@ -43,6 +43,7 @@ import static com.atlassian.confluence.security.ContentPermission.createUserPermission; import static com.atlassian.confluence.util.velocity.VelocityUtils.getRenderedTemplate; import static com.baloise.confluence.digitalsignature.api.DigitalSignatureComponent.PLUGIN_KEY; +import static com.baloise.confluence.digitalsignature.i18n.TextProperties.*; import static java.lang.String.format; import static java.net.URI.create; import static java.util.stream.Collectors.toList; @@ -56,7 +57,7 @@ public class DigitalSignatureService { private static final Logger log = LoggerFactory.getLogger(DigitalSignatureService.class); private final BandanaManager bandanaManager; - private final SettingsManager settingsManager; + private final GlobalSettingsManager settingsManager; private final UserManager userManager; private final LocalNotificationService notificationService; private final MailServerManager mailServerManager; @@ -67,7 +68,7 @@ public class DigitalSignatureService { public DigitalSignatureService( @ComponentImport BandanaManager bandanaManager, - @ComponentImport SettingsManager settingsManager, + @ComponentImport GlobalSettingsManager settingsManager, @ComponentImport UserManager userManager, @ComponentImport LocalNotificationService notificationService, @ComponentImport MailServerManager mailServerManager, @@ -98,7 +99,7 @@ public Response sign(@QueryParam("key") final String key, if (!signature.sign(userName)) { status(Response.Status.BAD_REQUEST) - .entity(i18nResolver.getText("com.baloise.confluence.digital-signature.signature.service.error.badUser", userName, key)) + .entity(i18nResolver.getText(ERROR_BAD_USER, userName, key)) .type(MediaType.TEXT_PLAIN) .build(); } @@ -109,13 +110,19 @@ public Response sign(@QueryParam("key") final String key, notify(notifiedUser, confluenceUser, signature, baseUrl); } Page parentPage = pageManager.getPage(signature.getPageId()); - Page protectedPage = pageManager.getPage(parentPage.getSpaceKey(), signature.getProtectedKey()); - if (protectedPage != null) { - protectedPage.addPermission(createUserPermission(VIEW_PERMISSION, confluenceUser)); - pageManager.saveContentEntity(protectedPage, null); + if (parentPage != null) { + Page protectedPage = parentPage.getChildren() + .stream() + .filter(p -> signature.getProtectedKey().equals(p.getTitle())) + .findFirst() + .orElse(null); + if (protectedPage != null) { + protectedPage.addPermission(createUserPermission(VIEW_PERMISSION, confluenceUser)); + pageManager.saveContentEntity(protectedPage, null); + } } - URI pageUri = create(settingsManager.getGlobalSettings().getBaseUrl() + "/pages/viewpage.action?pageId=" + signature.getPageId()); + URI pageUri = create(String.format("%s/pages/viewpage.action?pageId=%d", baseUrl, signature.getPageId())); return temporaryRedirect(pageUri).build(); } @@ -133,11 +140,11 @@ private void notify(final String notifiedUser, ConfluenceUser signedUser, final signature.getPageId(), signature.getTitle() ); - String html = i18nResolver.getText("com.baloise.confluence.digital-signature.signature.service.message.hasSignedShort", user, document); + String html = i18nResolver.getText(MESSAGE_HAS_SIGNED_SHORT, user, document); if (signature.isMaxSignaturesReached()) { - html += "
" + i18nResolver.getText("com.baloise.confluence.digital-signature.signature.service.warning.maxSignaturesReached", signature.getMaxSignatures()); + html += "
" + i18nResolver.getText(WARN_MAX_SIGNATURES_REACHED, signature.getMaxSignatures()); } - String titleText = i18nResolver.getText("com.baloise.confluence.digital-signature.signature.service.message.hasSignedShort", signedUser.getFullName(), signature.getTitle()); + String titleText = i18nResolver.getText(MESSAGE_HAS_SIGNED_SHORT, signedUser.getFullName(), signature.getTitle()); notificationService.createOrUpdate(notifiedUser, new NotificationBuilder() @@ -216,8 +223,8 @@ public Response emails(@QueryParam("key") final String key, context.put("signature", signature); String signatureText = format("%s ( %s )", signature.getTitle(), signature.getHash()); String rawTemplate = signed ? - i18nResolver.getRawText("com.baloise.confluence.digital-signature.signature.service.message.signedUsersEmails") : - i18nResolver.getRawText("com.baloise.confluence.digital-signature.signature.service.message.unsignedUsersEmails"); + i18nResolver.getRawText(MESSAGE_SIGNED_USERS_EMAILS) : + i18nResolver.getRawText(MESSAGE_UNSIGNED_USERS_EMAILS); context.put("signedOrNotWithHtml", MessageFormat.format(rawTemplate, "", "", signatureText)); context.put("withNamesChecked", emailOnly ? "" : "checked"); context.put("signedChecked", signed ? "checked" : ""); diff --git a/src/main/resources/atlassian-plugin.xml b/src/main/resources/atlassian-plugin.xml index ef33be4..081d466 100644 --- a/src/main/resources/atlassian-plugin.xml +++ b/src/main/resources/atlassian-plugin.xml @@ -1,4 +1,5 @@ - ${project.description} @@ -6,6 +7,7 @@ images/pluginIcon.png images/pluginLogo.png + both @@ -63,5 +65,4 @@ Provides signature services. com.baloise.confluence.digitalsignature.rest - diff --git a/src/main/resources/digital-signature.properties b/src/main/resources/digital-signature.properties index 8dca015..8328e12 100644 --- a/src/main/resources/digital-signature.properties +++ b/src/main/resources/digital-signature.properties @@ -40,6 +40,7 @@ com.baloise.confluence.digital-signature.signature.macro.panel.email.label=Send com.baloise.confluence.digital-signature.signature.macro.panel.email.menu.already-signed=Completed signatories com.baloise.confluence.digital-signature.signature.macro.panel.email.menu.not-yet-signed=Pending signatories com.baloise.confluence.digital-signature.signature.macro.warning.bodyToShort=Please enter at least 10 characters of text to be signed. You can type into the macro's body, once added to a page. +com.baloise.confluence.digital-signature.signature.macro.warning.unknownContext=Digital Signature macro is being used in an unknown or unsupported context. com.baloise.confluence.digital-signature.signature.macro.warning.editPermissionRequiredForProtectedContent=You need to {0}restrict{1} page access and have at least one edit permission in order to allow protected content. com.baloise.confluence.digital-signature.signature.service.error.badUser={0} is not expected to sign document {1} com.baloise.confluence.digital-signature.signature.service.message.label.withNames=With names diff --git a/src/main/resources/digital-signature_de.properties b/src/main/resources/digital-signature_de.properties index 2438986..74057f6 100644 --- a/src/main/resources/digital-signature_de.properties +++ b/src/main/resources/digital-signature_de.properties @@ -4,7 +4,7 @@ com.baloise.confluence.digital-signature.signature.desc=F com.baloise.confluence.digital-signature.signature.param.title.label=Titel com.baloise.confluence.digital-signature.signature.param.title.desc=Titel des unterzeichneten Bereichs. com.baloise.confluence.digital-signature.signature.param.signers.label=Unterzeichnende Benutzer -com.baloise.confluence.digital-signature.signature.param.signers.desc=Einzelne Benutzer, welche den Bereich unterzeichnen können. Zusätzlich zu den unterzeichnenden Gruppen und aus Seitenbeschränkungen vererbten Unterzeichnenden (siehe Unten). +com.baloise.confluence.digital-signature.signature.param.signers.desc=Einzelne Benutzer, welche den Bereich unterzeichnen können. Zusätzlich zu den unterzeichnenden Gruppen und aus Seitenbeschränkungen vererbten Unterzeichnenden (siehe unten). com.baloise.confluence.digital-signature.signature.param.signerGroups.label=Unterzeichnende Gruppen com.baloise.confluence.digital-signature.signature.param.signerGroups.desc=Kommagetrennte Liste von Confluence Gruppen deren Mitglieder den Bereich unterzeichnen können. Zusätzlich zu den unterzeichnenden Benutzern (siehe oben) und aus Seitenbeschränkungen vererbten Unterzeichnenden (siehe Unten). Gruppennamen müssen exakt eingegeben werden (z.B. Gruppen-Name). Geben Sie * (Stern) ein um allen angemeldeten Benutzern die Unterschrift zu ermöglichen. com.baloise.confluence.digital-signature.signature.param.inheritSigners.label=Aus Seitenbeschränkungen vererbte Unterzeichnende @@ -40,6 +40,7 @@ com.baloise.confluence.digital-signature.signature.macro.panel.email.label=Email com.baloise.confluence.digital-signature.signature.macro.panel.email.menu.already-signed=Bereits unterzeichnet com.baloise.confluence.digital-signature.signature.macro.panel.email.menu.not-yet-signed=Noch nicht unterzeichnet com.baloise.confluence.digital-signature.signature.macro.warning.bodyToShort=Bitte geben Sie mindesten 10 Zeichen zu signierenden Text ein. Sie können diesen direkt im Macro eingeben, sobald dieses auf einer Seite platziert ist. +com.baloise.confluence.digital-signature.signature.macro.warning.unknownContext=Digital Signature Macro wird in einem unbekannten oder nicht unterstützten Kontext verwendet. com.baloise.confluence.digital-signature.signature.macro.warning.editPermissionRequiredForProtectedContent=Die müssen das Bearbeiten der Seite {0}beschränken{1} um eine geschütze Unterseite zu erstellen. com.baloise.confluence.digital-signature.signature.service.error.badUser=Es wird nicht erwartet, dass {0} {1} unterzeichnet. com.baloise.confluence.digital-signature.signature.service.message.label.withNames=Mit Namen diff --git a/src/main/resources/digital-signature_fr.properties b/src/main/resources/digital-signature_fr.properties index 3d7a52f..ca19468 100644 --- a/src/main/resources/digital-signature_fr.properties +++ b/src/main/resources/digital-signature_fr.properties @@ -40,6 +40,7 @@ com.baloise.confluence.digital-signature.signature.macro.panel.email.label=Envoy com.baloise.confluence.digital-signature.signature.macro.panel.email.menu.already-signed=Signataires ayant sign\u00E9s com.baloise.confluence.digital-signature.signature.macro.panel.email.menu.not-yet-signed=Signataires en attente com.baloise.confluence.digital-signature.signature.macro.warning.bodyToShort=Veuillez saisir au moins 10 caract\u00E8res de texte \u00E0 signer. Vous pouvez taper dans le corps de la macro, une fois ajout\u00E9e \u00E0 une page. +com.baloise.confluence.digital-signature.signature.macro.warning.unknownContext=La macro de digital signature est utilis\u00E9e dans un contexte inconnu ou non pris en charge. com.baloise.confluence.digital-signature.signature.macro.warning.editPermissionRequiredForProtectedContent=Vous devez {0}restreindre{1} l'acc\u00E8s aux pages et disposer d'au moins une autorisation de modification pour autoriser le contenu prot\u00E9g\u00E9. com.baloise.confluence.digital-signature.signature.service.error.badUser={0} n'est pas cens\u00E9 signer le document {1} com.baloise.confluence.digital-signature.signature.service.message.label.withNames=Avec les noms diff --git a/src/test/java/ut/com/baloise/confluence/digitalsignature/MyComponentUnitTest.java b/src/test/java/com/baloise/confluence/digitalsignature/DigitalSignatureComponentTest.java similarity index 84% rename from src/test/java/ut/com/baloise/confluence/digitalsignature/MyComponentUnitTest.java rename to src/test/java/com/baloise/confluence/digitalsignature/DigitalSignatureComponentTest.java index 6e66e1c..d8a548b 100644 --- a/src/test/java/ut/com/baloise/confluence/digitalsignature/MyComponentUnitTest.java +++ b/src/test/java/com/baloise/confluence/digitalsignature/DigitalSignatureComponentTest.java @@ -1,11 +1,11 @@ -package ut.com.baloise.confluence.digitalsignature; +package com.baloise.confluence.digitalsignature; import com.baloise.confluence.digitalsignature.api.DigitalSignatureComponent; import com.baloise.confluence.digitalsignature.impl.DigitalSignatureComponentImpl; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -class MyComponentUnitTest { +class DigitalSignatureComponentTest { @Test void testMyName() { DigitalSignatureComponent component = new DigitalSignatureComponentImpl(null); diff --git a/src/test/java/com/baloise/confluence/digitalsignature/DigitalSignatureMacroTest.java b/src/test/java/com/baloise/confluence/digitalsignature/DigitalSignatureMacroTest.java index 8bebb10..18826c8 100644 --- a/src/test/java/com/baloise/confluence/digitalsignature/DigitalSignatureMacroTest.java +++ b/src/test/java/com/baloise/confluence/digitalsignature/DigitalSignatureMacroTest.java @@ -2,13 +2,17 @@ import com.atlassian.bandana.BandanaManager; import com.atlassian.confluence.setup.BootstrapManager; +import com.atlassian.sal.api.message.I18nResolver; import com.atlassian.sal.api.user.UserProfile; import org.junit.jupiter.api.Test; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -19,7 +23,7 @@ class DigitalSignatureMacroTest { @Test void getMailtoLong() { - DigitalSignatureMacro macro = new DigitalSignatureMacro(bandana, null, null, null, null, null, null); + DigitalSignatureMacro macro = new DigitalSignatureMacro(bandana, null, null, null, null, null, null, null); List profiles = new ArrayList<>(); UserProfile profile = mock(UserProfile.class); when(profile.getFullName()).thenReturn("Heinz Meier"); @@ -37,7 +41,7 @@ void getMailtoLong() { void getMailtoVeryLong() { when(bootstrapManager.getWebAppContextPath()).thenReturn("nirvana"); - DigitalSignatureMacro macro = new DigitalSignatureMacro(bandana, null, bootstrapManager, null, null, null, null); + DigitalSignatureMacro macro = new DigitalSignatureMacro(bandana, null, null, bootstrapManager, null, null, null, null); List profiles = new ArrayList<>(); UserProfile profile = mock(UserProfile.class); when(profile.getFullName()).thenReturn("Heinz Meier"); @@ -53,7 +57,7 @@ void getMailtoVeryLong() { @Test void getMailtoShort() { - DigitalSignatureMacro macro = new DigitalSignatureMacro(bandana, null, null, null, null, null, null); + DigitalSignatureMacro macro = new DigitalSignatureMacro(bandana, null, null, null, null, null, null, null); List profiles = new ArrayList<>(); UserProfile profile = mock(UserProfile.class); when(profile.getFullName()).thenReturn("Heinz Meier"); @@ -64,4 +68,27 @@ void getMailtoShort() { assertEquals("mailto:Heinz Meier?Subject=Subject", mailto); } + + @Test + void getLong() { + assertAll( + () -> assertEquals(2, DigitalSignatureMacro.getLong(Collections.singletonMap("Key", "2"), "Key", -1)), + () -> assertEquals(1, DigitalSignatureMacro.getLong(Collections.singletonMap("Key", "1"), "Key", -1)), + () -> assertEquals(-1, DigitalSignatureMacro.getLong(Collections.singletonMap("Key", "1"), "other", -1)), + () -> assertEquals(0, DigitalSignatureMacro.getLong(Collections.singletonMap("Key", "1"), "other", 0)) + ); + } + + @Test + void warning() { + I18nResolver mock = mock(I18nResolver.class); + when(mock.getText(anyString())).thenReturn("i18n"); + DigitalSignatureMacro macro = new DigitalSignatureMacro(null, null, null, null, null, null, null, mock); + assertEquals("
\n" + + "

\n" + + " i18n\n" + + "

\n" + + "

test

\n" + + "
", macro.warning("test")); + } } diff --git a/src/test/java/com/baloise/confluence/digitalsignature/SignatureSerialisationTest.java b/src/test/java/com/baloise/confluence/digitalsignature/SignatureSerialisationTest.java index 80efb2a..cd3912c 100644 --- a/src/test/java/com/baloise/confluence/digitalsignature/SignatureSerialisationTest.java +++ b/src/test/java/com/baloise/confluence/digitalsignature/SignatureSerialisationTest.java @@ -1,6 +1,5 @@ package com.baloise.confluence.digitalsignature; - import org.junit.jupiter.api.Test; import java.io.FileOutputStream; @@ -11,7 +10,6 @@ import static org.junit.jupiter.api.Assertions.*; - class SignatureSerialisationTest { @Test void deserialize() throws IOException, ClassNotFoundException { diff --git a/src/test/resources/atlassian-plugin.xml b/src/test/resources/atlassian-plugin.xml index 140bc08..a90ccc1 100644 --- a/src/test/resources/atlassian-plugin.xml +++ b/src/test/resources/atlassian-plugin.xml @@ -1,14 +1,15 @@ - + ${project.description} ${project.version} - + + both - - - - - - + diff --git a/src/test/resources/log4j.xml b/src/test/resources/log4j.xml index ef3fdf8..aac6e3d 100644 --- a/src/test/resources/log4j.xml +++ b/src/test/resources/log4j.xml @@ -1,20 +1,19 @@ - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + From 4bacc1b1267151b68474a73da808f54eb9489527 Mon Sep 17 00:00:00 2001 From: Markus Lindenmann <8123039+Tiliavir@users.noreply.github.com> Date: Sun, 21 Aug 2022 16:20:32 +0200 Subject: [PATCH 2/2] Command order in md --- docs/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docker.md b/docs/docker.md index 41cd66b..1d48245 100644 --- a/docs/docker.md +++ b/docs/docker.md @@ -1,9 +1,9 @@ # Simple Confluence Setup ```bash +docker run --name=confluence -d -p 8090:8090 -p 8091:8091 atlassian/confluence-server:latest docker run --name postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres docker inspect postgres # to get IP -docker run --name=confluence -d -p 8090:8090 -p 8091:8091 atlassian/confluence-server:latest ``` Start confluence setup and configure Postgres: