Skip to content

Commit

Permalink
Revert Signature
Browse files Browse the repository at this point in the history
  • Loading branch information
kullmanp committed Sep 8, 2023
1 parent 1747f91 commit f1338e7
Show file tree
Hide file tree
Showing 2 changed files with 370 additions and 162 deletions.
352 changes: 190 additions & 162 deletions src/main/java/com/baloise/confluence/digitalsignature/Signature.java
Original file line number Diff line number Diff line change
@@ -1,175 +1,203 @@
package com.baloise.confluence.digitalsignature;

import com.atlassian.bandana.BandanaManager;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import static org.apache.commons.codec.digest.DigestUtils.sha256Hex;

import java.io.Serializable;
import java.util.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

public class Signature implements Serializable, Cloneable {

private static final long serialVersionUID = 1L;

private String key = "";
private String hash = "";
private long pageId;
private String title = "";
private String body = "";
private long maxSignatures = -1;
private long visibilityLimit = -1;
private Map<String, Date> signatures = new HashMap<>();
private Set<String> missingSignatures = new TreeSet<>();
private Set<String> notified = new TreeSet<>();

public Signature() {
}

import static com.atlassian.confluence.setup.bandana.ConfluenceBandanaContext.GLOBAL_CONTEXT;
import static org.apache.commons.codec.digest.DigestUtils.sha256Hex;
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;
}

public static boolean isPetitionMode(Set<String> userGroups) {
return userGroups != null && userGroups.size() == 1 && userGroups.iterator().next().trim().equals("*");
}

public String getHash() {
if (hash == null) {
hash = getKey().replace("signature.", "");
}
return hash;
}

public void setHash(String hash) {
this.hash = hash;
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getProtectedKey() {
return "protected." + getHash();
}

public long getPageId() {
return pageId;
}

@Slf4j
@Getter
@Setter
@NoArgsConstructor
public class Signature implements Serializable {
public static final Gson GSON = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssz").create();
private static final long serialVersionUID = 1L;
private String key = "";
private String hash = "";
private long pageId;
private String title = "";
private String body = "";
private long maxSignatures = -1;
private long visibilityLimit = -1;
private Map<String, Date> signatures = new HashMap<>();
private Set<String> missingSignatures = new TreeSet<>();
private Set<String> notify = new TreeSet<>();

public Signature(long pageId, String body, String title) {
this.pageId = pageId;
this.body = body;
this.title = title == null ? "" : title;
this.hash = sha256Hex(pageId + ":" + title + ":" + body);
this.key = "signature." + hash;
}

public static boolean isPetitionMode(Set<String> userGroups) {
return userGroups != null
&& userGroups.size() == 1
&& userGroups.iterator().next().trim().equals("*");
}

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

public static Signature fromBandana(BandanaManager mgr, String key) {
if (mgr.getKeys(GLOBAL_CONTEXT) == null
|| !Sets.newHashSet(mgr.getKeys(GLOBAL_CONTEXT)).contains(key)) {
return null;
}

Object value = mgr.getValue(GLOBAL_CONTEXT, key);

if (value == null) {
throw new IllegalArgumentException("Value is null in Bandana???");
}

if (value instanceof Signature) {
// required for downward compatibility - update for next time.
Signature signature = (Signature) value;
toBandana(mgr, key, signature);
return signature;
}

if (value instanceof String) {
try {
return deserialize((String) value);
} catch (Exception e) {
log.error("Could not deserialize String value from Bandana", e);
return null;
}
}

throw new IllegalArgumentException(String.format("Could not deserialize %s value from Bandana. Please clear the plugin-cache and reboot confluence. (https://github.com/baloise/digital-signature/issues/82)", value));
}

public static void toBandana(BandanaManager mgr, String key, Signature sig) {
mgr.setValue(GLOBAL_CONTEXT, key, sig.serialize());
}

public static void toBandana(BandanaManager mgr, Signature sig) {
toBandana(mgr, sig.getKey(), sig);
}

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

public String getHash() {
if (hash == null) {
hash = getKey().replace("signature.", "");
}
return hash;
}

public String getProtectedKey() {
return "protected." + getHash();
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;

return Objects.equals(key, ((Signature) obj).key);
}

public Signature withNotified(Set<String> notified) {
this.notify = notified;
return this;
}

public Signature withMaxSignatures(long maxSignatures) {
this.maxSignatures = maxSignatures;
return this;
}

public Signature withVisibilityLimit(long visibilityLimit) {
this.visibilityLimit = visibilityLimit;
return this;
}
public void setPageId(long pageId) {
this.pageId = pageId;
}

public boolean hasSigned(String userName) {
return signatures.containsKey(userName);
}
public String getBody() {
return body;
}

public boolean isPetitionMode() {
return isPetitionMode(getMissingSignatures());
}
public void setBody(String body) {
this.body = body;
}

public boolean sign(String userName) {
if (!isMaxSignaturesReached() && !isPetitionMode() && !getMissingSignatures().remove(userName)) {
return false;
public Map<String, Date> getSignatures() {
return signatures;
}

getSignatures().put(userName, new Date());
return true;
}
public void setSignatures(Map<String, Date> signatures) {
this.signatures = signatures;
}

public Set<String> getMissingSignatures() {
return missingSignatures;
}

public void setMissingSignatures(Set<String> missingSignatures) {
this.missingSignatures = missingSignatures;
}

public long getVisibilityLimit() {
return visibilityLimit;
}

public void setVisibilityLimit(long visibilityLimit) {
this.visibilityLimit = visibilityLimit;
}

public long getMaxSignatures() {
return maxSignatures;
}

public void setMaxSignatures(long maxSignatures) {
this.maxSignatures = maxSignatures;
}

public boolean isMaxSignaturesReached() {
return maxSignatures > -1 && maxSignatures <= getSignatures().size();
}

public boolean isSignatureMissing(String userName) {
return !isMaxSignaturesReached() && !hasSigned(userName) && isSignatory(userName);
}

public boolean isSignatory(String userName) {
return isPetitionMode() || getMissingSignatures().contains(userName);
}

public boolean hasMissingSignatures() {
return !isMaxSignaturesReached() && (isPetitionMode() || !getMissingSignatures().isEmpty());
}
public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public Set<String> getNotify() {
return notified;
}

public void setNotify(Set<String> notify) {
this.notified = notify;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Signature other = (Signature) obj;
if (key == null) {
return other.key == null;
} else return key.equals(other.key);
}

public Signature withNotified(Set<String> notified) {
this.notified = notified;
return this;
}

public Signature withMaxSignatures(long maxSignatures) {
this.maxSignatures = maxSignatures;
return this;
}

public Signature withVisibilityLimit(long visibilityLimit) {
this.visibilityLimit = visibilityLimit;
return this;
}

public boolean hasSigned(String userName) {
return signatures.containsKey(userName);
}

public boolean isPetitionMode() {
return isPetitionMode(getMissingSignatures());
}

public boolean sign(String userName) {
if (!isMaxSignaturesReached() && !isPetitionMode() && !getMissingSignatures().remove(userName)) {
return false;
} else {
getSignatures().put(userName, new Date());
return true;
}
}

public boolean isMaxSignaturesReached() {
return maxSignatures > -1 && maxSignatures <= getSignatures().size();
}

public boolean isSignatureMissing(String userName) {
return !isMaxSignaturesReached() && !hasSigned(userName) && isSignatory(userName);
}

public boolean isSignatory(String userName) {
return isPetitionMode() || getMissingSignatures().contains(userName);
}

public boolean hasMissingSignatures() {
return !isMaxSignaturesReached() && (isPetitionMode() || !getMissingSignatures().isEmpty());
}

@Override
public Signature clone() throws CloneNotSupportedException{
return (Signature) super.clone();
}
}
Loading

0 comments on commit f1338e7

Please sign in to comment.