Skip to content

Commit

Permalink
#82: Bandana only used to store Strings in future
Browse files Browse the repository at this point in the history
- BandanaManager.init() is called initially
- removes workaround with clone
- serialization of Signature to JSON using GSON
  • Loading branch information
Tiliavir committed Feb 5, 2022
1 parent 14fba9c commit b86a2cf
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.baloise.confluence.digitalsignature;

import com.atlassian.bandana.BandanaContext;
import com.atlassian.bandana.BandanaManager;
import com.atlassian.confluence.content.render.xhtml.ConversionContext;
import com.atlassian.confluence.core.ContentEntityObject;
Expand Down Expand Up @@ -57,14 +58,22 @@ public class DigitalSignatureMacro implements Macro {
private final ContextHelper contextHelper = new ContextHelper();

@Autowired
public DigitalSignatureMacro(@ComponentImport BandanaManager bandanaManager, @ComponentImport UserManager userManager, @ComponentImport BootstrapManager bootstrapManager, @ComponentImport PageManager pageManager, @ComponentImport PermissionManager permissionManager, @ComponentImport GroupManager groupManager, @ComponentImport I18nResolver i18nResolver) {
public DigitalSignatureMacro(@ComponentImport BandanaManager bandanaManager,
@ComponentImport UserManager userManager,
@ComponentImport BootstrapManager bootstrapManager,
@ComponentImport PageManager pageManager,
@ComponentImport PermissionManager permissionManager,
@ComponentImport GroupManager groupManager,
@ComponentImport I18nResolver i18nResolver) {
this.bandanaManager = bandanaManager;
this.userManager = userManager;
this.bootstrapManager = bootstrapManager;
this.pageManager = pageManager;
this.permissionManager = permissionManager;
this.groupManager = groupManager;
this.i18nResolver = i18nResolver;

this.bandanaManager.init();
all.add("*");
}

Expand Down Expand Up @@ -154,11 +163,6 @@ private void ensureProtectedPage(ConversionContext conversionContext, Page page,
}

private boolean hideSignatures(Map<String, String> params, Signature signature, String currentUserName) {
try {
signature = signature.clone();
} catch (CloneNotSupportedException e) {
throw new IllegalStateException(e);
}
boolean pendingVisible = isVisible(signature, currentUserName, params.get("pendingVisible"));
boolean signaturesVisible = isVisible(signature, currentUserName, params.get("signaturesVisible"));
if (!pendingVisible) signature.setMissingSignatures(new TreeSet<>());
Expand Down Expand Up @@ -267,7 +271,7 @@ private Set<String> getSet(Map<String, String> params, String key) {
}

private Signature sync(Signature signature, Set<String> signers) {
Signature loaded = (Signature) bandanaManager.getValue(GLOBAL_CONTEXT, signature.getKey());
Signature loaded = fromBandana(GLOBAL_CONTEXT, signature.getKey());
if (loaded != null) {
signature.setSignatures(loaded.getSignatures());
boolean save = false;
Expand Down Expand Up @@ -303,7 +307,25 @@ private Signature sync(Signature signature, Set<String> signers) {
}

private void save(Signature signature) {
if (signature.hasMissingSignatures()) bandanaManager.setValue(GLOBAL_CONTEXT, signature.getKey(), signature);
if (signature.hasMissingSignatures()) {
bandanaManager.setValue(GLOBAL_CONTEXT, signature.getKey(), signature.serialize());
}
}

Signature fromBandana(BandanaContext context, String key) {
Object value = this.bandanaManager.getValue(context, key);
if (value instanceof Signature) {
// required for downward compatibility - update for next time.
Signature signature = (Signature) value;
this.bandanaManager.setValue(context, key, signature.serialize());
return signature;
}

if (value instanceof String) {
return Signature.deserialize((String) value);
}

throw new IllegalArgumentException("Cannot read value from Bandana.");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package com.baloise.confluence.digitalsignature;

import com.google.gson.Gson;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import static org.apache.commons.codec.digest.DigestUtils.sha256Hex;

import java.io.Serializable;
import java.util.*;

import static org.apache.commons.codec.digest.DigestUtils.sha256Hex;

@Getter
@Setter
@NoArgsConstructor
public class Signature implements Serializable, Cloneable {
public class Signature implements Serializable {
public static final Gson GSON = new Gson();
private static final long serialVersionUID = 1L;

private String key = "";
private String hash = "";
private long pageId;
Expand All @@ -30,8 +31,8 @@ public Signature(long pageId, String body, String title) {
this.pageId = pageId;
this.body = body;
this.title = title == null ? "" : title;
hash = sha256Hex(pageId + ":" + title + ":" + body);
key = "signature." + hash;
this.hash = sha256Hex(pageId + ":" + title + ":" + body);
this.key = "signature." + hash;
}

public static boolean isPetitionMode(Set<String> userGroups) {
Expand All @@ -40,6 +41,14 @@ public static boolean isPetitionMode(Set<String> userGroups) {
&& userGroups.iterator().next().trim().equals("*");
}

public static Signature deserialize(String serialization) {
return GSON.fromJson(serialization, Signature.class);
}

public String serialize() {
return GSON.toJson(this, Signature.class);
}

public String getHash() {
if (hash == null) {
hash = getKey().replace("signature.", "");
Expand Down Expand Up @@ -118,9 +127,4 @@ public boolean isSignatory(String userName) {
public boolean hasMissingSignatures() {
return !isMaxSignaturesReached() && (isPetitionMode() || !getMissingSignatures().isEmpty());
}

@Override
public Signature clone() throws CloneNotSupportedException {
return (Signature) super.clone();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.baloise.confluence.digitalsignature;

import com.atlassian.bandana.BandanaManager;
import com.atlassian.confluence.setup.BootstrapManager;
import com.atlassian.sal.api.user.UserProfile;
import org.junit.jupiter.api.Test;
Expand All @@ -14,10 +15,11 @@
class DigitalSignatureMacroTest {
private final Signature signature = new Signature(1, "test", "title");
private final BootstrapManager bootstrapManager = mock(BootstrapManager.class);
private final BandanaManager bandana = mock(BandanaManager.class);

@Test
void getMailtoLong() {
DigitalSignatureMacro macro = new DigitalSignatureMacro(null, null, null, null, null, null, null);
DigitalSignatureMacro macro = new DigitalSignatureMacro(bandana, null, null, null, null, null, null);
List<UserProfile> profiles = new ArrayList<>();
UserProfile profile = mock(UserProfile.class);
when(profile.getFullName()).thenReturn("Heinz Meier");
Expand All @@ -35,7 +37,7 @@ void getMailtoLong() {
void getMailtoVeryLong() {
when(bootstrapManager.getWebAppContextPath()).thenReturn("nirvana");

DigitalSignatureMacro macro = new DigitalSignatureMacro(null, null, bootstrapManager, null, null, null, null);
DigitalSignatureMacro macro = new DigitalSignatureMacro(bandana, null, bootstrapManager, null, null, null, null);
List<UserProfile> profiles = new ArrayList<>();
UserProfile profile = mock(UserProfile.class);
when(profile.getFullName()).thenReturn("Heinz Meier");
Expand All @@ -51,7 +53,7 @@ void getMailtoVeryLong() {

@Test
void getMailtoShort() {
DigitalSignatureMacro macro = new DigitalSignatureMacro(null, null, null, null, null, null, null);
DigitalSignatureMacro macro = new DigitalSignatureMacro(bandana, null, null, null, null, null, null);
List<UserProfile> profiles = new ArrayList<>();
UserProfile profile = mock(UserProfile.class);
when(profile.getFullName()).thenReturn("Heinz Meier");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,51 @@

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;
import java.util.Set;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

class SignatureTest {
@Test
void testClone() throws Exception {
Signature signature = new Signature(999, "title", "body");
signature.getMissingSignatures().add("Hans");
Signature cloned = signature.clone();

assertAll(
() -> assertNotSame(signature, cloned),
() -> assertEquals(signature, cloned),
() -> assertEquals("Hans", cloned.getMissingSignatures().iterator().next())
);
void serialize_empty() {
Signature signature = new Signature();

String json = signature.serialize();

assertEquals("{\"key\":\"\",\"hash\":\"\",\"pageId\":0,\"title\":\"\",\"body\":\"\",\"maxSignatures\":-1,\"visibilityLimit\":-1,\"signatures\":{},\"missingSignatures\":[],\"notify\":[]}", json);
}

@Test
void serialize_initializedObject() {
Signature signature = new Signature(42L, "body text", "title text");
signature.sign("max.mustermann");
signature.setMissingSignatures(Set.of("max.muster"));
signature.setNotify(Set.of("max.meier"));

String json = signature.serialize();

assertEquals("{\"key\":\"signature.752b4cc6b4933fc7f0a6efa819c1bcc440c32155457e836d99d1bfe927cc22f5\",\"hash\":\"752b4cc6b4933fc7f0a6efa819c1bcc440c32155457e836d99d1bfe927cc22f5\",\"pageId\":42,\"title\":\"title text\",\"body\":\"body text\",\"maxSignatures\":-1,\"visibilityLimit\":-1,\"signatures\":{},\"missingSignatures\":[\"max.muster\"],\"notify\":[\"max.meier\"]}", json);
}

@Test
void deserialize_empty() {
assertNull(Signature.deserialize(null));
assertNull(Signature.deserialize(""));
}

@Test
void serializeAndDeserialize() {
Signature signature = new Signature(42L, "body text", "title text");
signature.sign("max.mustermann");
signature.setMissingSignatures(Set.of("max.muster"));
signature.setNotify(Set.of("max.meier"));

String json = signature.serialize();

Signature restoredSignature = Signature.deserialize(json);

assertEquals("{\"key\":\"signature.752b4cc6b4933fc7f0a6efa819c1bcc440c32155457e836d99d1bfe927cc22f5\",\"hash\":\"752b4cc6b4933fc7f0a6efa819c1bcc440c32155457e836d99d1bfe927cc22f5\",\"pageId\":42,\"title\":\"title text\",\"body\":\"body text\",\"maxSignatures\":-1,\"visibilityLimit\":-1,\"signatures\":{},\"missingSignatures\":[\"max.muster\"],\"notify\":[\"max.meier\"]}", json);
assertEquals(signature, restoredSignature);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@
import com.atlassian.sal.api.user.UserProfile;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.SortedSet;
import java.util.TreeSet;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

class UserProfileByNameTest {
@Test
void testCompare() {
UserProfile profile1 = Mockito.mock(UserProfile.class);
UserProfile profile1 = mock(UserProfile.class);
when(profile1.getFullName()).thenReturn("Heinz Meier");
when(profile1.getEmail()).thenReturn("heinz.meier@meier.com");
when(profile1.toString()).thenReturn("Heinz Meier");
UserProfile profile2 = Mockito.mock(UserProfile.class);
UserProfile profile2 = mock(UserProfile.class);
when(profile2.getFullName()).thenReturn("Abraham Aebischer");
when(profile2.getEmail()).thenReturn("Abraham Aebischer@meier.com");
when(profile2.toString()).thenReturn("Abraham Aebischer");
Expand Down

0 comments on commit b86a2cf

Please sign in to comment.