Skip to content
Snippets Groups Projects
Commit 4347d54a authored by Benoit Lavenier's avatar Benoit Lavenier
Browse files

[enh] Allow node admin to remove some data

parent 39fc610d
No related branches found
No related tags found
No related merge requests found
......@@ -188,6 +188,7 @@ duniter.p2p.discovery.enable: false
duniter.p2p.includes.pubkeys: [
"38MEAZN68Pz1DTvT3tqgxx4yQP6snJCQhPqEFxbDk4aE"
]
#duniter.p2p.fullResyncAtStartup: true
#
# ---------------------------------- Duniter4j Mail module -----------------------
#
......
......@@ -226,6 +226,10 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
return settings.getAsBoolean("duniter.p2p.ws.enable", true);
}
public boolean fullResyncAtStartup() {
return settings.getAsBoolean("duniter.p2p.fullResyncAtStartup", false);
}
public int getSynchroTimeOffset() {
return settings.getAsInt("duniter.p2p.peerTimeOffset", 60*60/*=1hour*/);
}
......@@ -298,6 +302,10 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
return settings.getAsInt("duniter.document.time.maxFutureDelta", 600); // in seconds = 10min
}
public boolean allowDocumentDeletionByAdmin() {
return settings.getAsBoolean("duniter.document.allowAdminDeletion", true); //
}
public String getWebSocketHost() {
return settings.get("network.host", "locahost");
}
......
......@@ -75,6 +75,7 @@ public class SynchroService extends AbstractService {
private final SynchroExecutionDao synchroExecutionDao;
private List<WebsocketClientEndpoint> wsClientEndpoints = Lists.newArrayList();
private List<SynchroAction> actions = Lists.newArrayList();
private boolean forceFullResync = false;
@Inject
public SynchroService(Duniter4jClient client,
......@@ -124,7 +125,12 @@ public class SynchroService extends AbstractService {
// If can be launched now: do it
if (launchAtStartup) {
forceFullResync = pluginSettings.fullResyncAtStartup();
synchronize();
forceFullResync = false;
}
// Schedule next execution, to 5 min before each hour
......@@ -185,7 +191,8 @@ public class SynchroService extends AbstractService {
} else {
logger.info(String.format("[%s] [%s] Synchronization [OK] - no endpoint to synchronize", currencyId, peerApiFilter.name()));
}
}));
}
));
}
public SynchroResult synchronizePeer(final Peer peer, boolean enableSynchroWebsocket) {
......@@ -203,7 +210,7 @@ public class SynchroService extends AbstractService {
// Get the last execution time (or 0 is never synchronized)
// If not the first synchro, add a delay to last execution time
// to avoid missing data because incorrect clock configuration
long lastExecutionTime = getLastExecutionTime(peer);
long lastExecutionTime = forceFullResync ? 0 : getLastExecutionTime(peer);
if (logger.isDebugEnabled() && lastExecutionTime > 0) {
logger.debug(String.format("[%s] [%s] Found last synchronization execution at {%s}. Will apply time offset of {-%s ms}", peer.getCurrency(), peer,
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM)
......@@ -213,6 +220,7 @@ public class SynchroService extends AbstractService {
final long fromTime = lastExecutionTime > 0 ? lastExecutionTime - pluginSettings.getSynchroTimeOffset() : 0;
if (logger.isInfoEnabled()) {
if (fromTime == 0) {
logger.info(String.format("[%s] [%s] Synchronization {ALL}...", peer.getCurrency(), peer));
......
......@@ -185,6 +185,9 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
return delegate.getKeyringSecretKey();
}
public boolean allowDocumentDeletionByAdmin() {
return delegate.allowDocumentDeletionByAdmin();
}
public void addI18nBundleName(String bundleName) {
delegate.addI18nBundleName(bundleName);
......@@ -210,6 +213,8 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
}
/* -- protected methods -- */
protected String getI18nBundleName() {
......
......@@ -29,6 +29,7 @@ import org.duniter.core.client.model.elasticsearch.DeleteRecord;
import org.duniter.core.exception.TechnicalException;
import org.duniter.core.service.CryptoService;
import org.duniter.elasticsearch.client.Duniter4jClient;
import org.duniter.elasticsearch.exception.AccessDeniedException;
import org.duniter.elasticsearch.exception.NotFoundException;
import org.duniter.elasticsearch.user.PluginSettings;
import org.duniter.elasticsearch.user.model.Message;
......@@ -46,6 +47,7 @@ import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import java.io.IOException;
import java.util.Objects;
/**
* Created by Benoit on 30/03/2015.
......@@ -147,18 +149,34 @@ public class HistoryService extends AbstractService {
throw new NotFoundException(String.format("Index [%s] not exists.", index));
}
try {
// Message: check if deletion issuer is the message recipient
if (MessageService.INDEX.equals(index) && MessageService.INBOX_TYPE.equals(type)) {
client.checkSameDocumentField(index, type, id, Message.PROPERTY_RECIPIENT, issuer);
}
// Invitation: check if deletion issuer is the invitation recipient
else if (UserInvitationService.INDEX.equals(index)) {
client.checkSameDocumentField(index, type, id, Message.PROPERTY_RECIPIENT, issuer);
}
else {
// Check same document issuer
client.checkSameDocumentIssuer(index, type, id, issuer);
}
}
catch(AccessDeniedException e) {
// Check if admin ask the deletion
// If deletion done by admin: continue if allow in settings
if (!pluginSettings.isRandomNodeKeypair()
&& pluginSettings.allowDocumentDeletionByAdmin()
&& Objects.equals(issuer, pluginSettings.getNodePubkey())) {
logger.warn(String.format("[%s/%s] Deletion forced by admin, on doc [%s]", index, type, id));
}
else {
throw e;
}
}
// Check time is valid - fix #27
verifyTimeForInsert(actualObj);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment