From 4834ebcbb00826db47cb58e29671d16343ae79fb Mon Sep 17 00:00:00 2001
From: blavenie <benoit.lavenier@e-is.pro>
Date: Tue, 13 Dec 2016 18:26:11 +0100
Subject: [PATCH] - change security logger name - allow search rest access on
 user event - user event : add pubkeys AND names on TX events

---
 .../core/client/model/bma/Protocol.java       |  2 ++
 .../client/model/elasticsearch/Protocol.java  | 35 +++++++++++++++++++
 .../src/test/es-home/config/logging.yml       |  1 +
 .../rest/security/RestSecurityController.java |  2 +-
 .../rest/security/RestSecurityFilter.java     |  6 ++--
 .../elasticsearch/gchange/model/Protocol.java | 33 +++++++++++++++++
 .../gchange/service/SynchroService.java       |  3 +-
 .../elasticsearch/user/PluginSettings.java    | 12 -------
 .../elasticsearch/user/rest/RestModule.java   |  1 +
 .../rest/user/RestUserEventSearchAction.java  | 20 +++++++++++
 .../service/BlockchainUserEventService.java   | 29 ++++++++++++---
 .../user/service/SynchroService.java          |  4 ++-
 12 files changed, 126 insertions(+), 22 deletions(-)
 create mode 100644 duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Protocol.java
 create mode 100644 duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/model/Protocol.java
 create mode 100644 duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserEventSearchAction.java

diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java
index 20653d2d..df822dd0 100644
--- a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/bma/Protocol.java
@@ -36,4 +36,6 @@ public interface Protocol {
     String TYPE_MEMBERSHIP = "Membership";
 
     String TYPE_TRANSACTION = "Transaction";
+
+    String BMA_API = "BASIC_MERKLED_API";
 }
diff --git a/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Protocol.java b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Protocol.java
new file mode 100644
index 00000000..1fdb62ae
--- /dev/null
+++ b/duniter4j-core-client/src/main/java/org/duniter/core/client/model/elasticsearch/Protocol.java
@@ -0,0 +1,35 @@
+package org.duniter.core.client.model.elasticsearch;
+
+/*
+ * #%L
+ * Duniter4j :: Core Client API
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+/**
+ * Created by blavenie on 31/03/16.
+ */
+public interface Protocol {
+
+    String VERSION = "1";
+
+    String ES_API = "ELASTICSEARCH_API";
+
+    String CESIUM_PLUS_API = "CESIUM_PLUS_API";
+}
diff --git a/duniter4j-es-assembly/src/test/es-home/config/logging.yml b/duniter4j-es-assembly/src/test/es-home/config/logging.yml
index 5b11ce00..077a8d57 100644
--- a/duniter4j-es-assembly/src/test/es-home/config/logging.yml
+++ b/duniter4j-es-assembly/src/test/es-home/config/logging.yml
@@ -21,6 +21,7 @@ logger:
   org.duniter.elasticsearch: DEBUG
 
   duniter : DEBUG
+  duniter.security : ERROR
   duniter.user.event : INFO
   duniter.network.p2p: TRACE
 
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityController.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityController.java
index 69e7ee7e..52c63a78 100644
--- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityController.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityController.java
@@ -37,7 +37,7 @@ import java.util.*;
  */
 public class RestSecurityController extends AbstractLifecycleComponent<RestSecurityController> {
 
-    private static final ESLogger log = ESLoggerFactory.getLogger("security");
+    private static final ESLogger log = ESLoggerFactory.getLogger("duniter.security");
 
     private boolean enable;
 
diff --git a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityFilter.java b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityFilter.java
index 9b6557d0..64319346 100644
--- a/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityFilter.java
+++ b/duniter4j-es-core/src/main/java/org/duniter/elasticsearch/rest/security/RestSecurityFilter.java
@@ -32,9 +32,10 @@ import static org.elasticsearch.rest.RestStatus.FORBIDDEN;
 
 public class RestSecurityFilter extends RestFilter {
 
-    private static final ESLogger log = ESLoggerFactory.getLogger("security");
+    private static final ESLogger log = ESLoggerFactory.getLogger("duniter.security");
 
     private RestSecurityController securityController;
+    private final boolean debug;
 
     @Inject
     public RestSecurityFilter(PluginSettings pluginSettings, RestController controller, RestSecurityController securityController) {
@@ -44,13 +45,14 @@ public class RestSecurityFilter extends RestFilter {
             controller.registerFilter(this);
         }
         this.securityController = securityController;
+        this.debug = log.isDebugEnabled();
     }
 
     @Override
     public void process(RestRequest request, RestChannel channel, RestFilterChain filterChain) throws Exception {
 
         if (securityController.isAllow(request)) {
-            if (log.isDebugEnabled()) {
+            if (debug) {
                 log.debug(String.format("Allow %s request [%s]", request.method().name(), request.path()));
             }
             filterChain.continueProcessing(request, channel);
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/model/Protocol.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/model/Protocol.java
new file mode 100644
index 00000000..3d5539e6
--- /dev/null
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/model/Protocol.java
@@ -0,0 +1,33 @@
+package org.duniter.elasticsearch.gchange.model;
+
+/*
+ * #%L
+ * Duniter4j :: Core Client API
+ * %%
+ * Copyright (C) 2014 - 2016 EIS
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the 
+ * License, or (at your option) any later version.
+ * 
+ * This program 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program.  If not, see
+ * <http://www.gnu.org/licenses/gpl-3.0.html>.
+ * #L%
+ */
+
+/**
+ * Created by blavenie on 31/03/16.
+ */
+public interface Protocol {
+
+    String VERSION = "1";
+
+    String GCHANGE_API = "GCHANGE_API";
+}
diff --git a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/SynchroService.java b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/SynchroService.java
index c9156858..a023c322 100644
--- a/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/SynchroService.java
+++ b/duniter4j-es-gchange/src/main/java/org/duniter/elasticsearch/gchange/service/SynchroService.java
@@ -25,6 +25,7 @@ package org.duniter.elasticsearch.gchange.service;
 import org.duniter.core.client.model.local.Peer;
 import org.duniter.core.service.CryptoService;
 import org.duniter.elasticsearch.gchange.PluginSettings;
+import org.duniter.elasticsearch.gchange.model.Protocol;
 import org.duniter.elasticsearch.service.AbstractSynchroService;
 import org.duniter.elasticsearch.service.ServiceLocator;
 import org.duniter.elasticsearch.threadpool.ThreadPool;
@@ -44,7 +45,7 @@ public class SynchroService extends AbstractSynchroService {
 
     public void synchronize() {
         logger.info("Synchronizing data...");
-        Peer peer = getPeerFromAPI("GCHANGE API");
+        Peer peer = getPeerFromAPI(Protocol.GCHANGE_API);
         synchronize(peer);
     }
 
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginSettings.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginSettings.java
index 2f6e1077..9669ad28 100644
--- a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginSettings.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/PluginSettings.java
@@ -58,18 +58,6 @@ public class PluginSettings extends org.duniter.elasticsearch.PluginSettings {
         return settings.get("duniter.keyring.sec");
     }
 
-    public boolean enableDataSync()  {
-        return settings.getAsBoolean("duniter.user.sync.enable", false);
-    }
-
-    public String getDataSyncHost()  {
-        return settings.get("duniter.user.sync.host", "data.duniter.fr");
-    }
-
-    public int getDataSyncPort()  {
-        return settings.getAsInt("duniter.user.sync.port", 80);
-    }
-
     public String getMailSmtpHost()  {
         return settings.get("duniter.mail.smtp.host", "localhost");
     }
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/RestModule.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/RestModule.java
index a1945c0f..b0eacbd1 100644
--- a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/RestModule.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/RestModule.java
@@ -40,6 +40,7 @@ public class RestModule extends AbstractModule implements Module {
         bind(RestUserSettingsIndexAction.class).asEagerSingleton();
         bind(RestUserSettingsUpdateAction.class).asEagerSingleton();
         bind(RestUserEventMarkAsReadAction.class).asEagerSingleton();
+        bind(RestUserEventSearchAction.class).asEagerSingleton();
 
         // History
         bind(RestHistoryDeleteIndexAction.class).asEagerSingleton();
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserEventSearchAction.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserEventSearchAction.java
new file mode 100644
index 00000000..57dc1e7c
--- /dev/null
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/rest/user/RestUserEventSearchAction.java
@@ -0,0 +1,20 @@
+package org.duniter.elasticsearch.user.rest.user;
+
+import org.duniter.elasticsearch.rest.security.RestSecurityController;
+import org.duniter.elasticsearch.user.service.UserEventService;
+import org.elasticsearch.common.inject.Inject;
+import org.elasticsearch.rest.RestRequest;
+
+/**
+ * Created by blavenie on 13/12/16.
+ */
+public class RestUserEventSearchAction {
+
+    @Inject
+    public RestUserEventSearchAction(RestSecurityController securityController) {
+        securityController.allow(RestRequest.Method.GET, String.format("/%s/%s/_search", UserEventService.INDEX, UserEventService.EVENT_TYPE));
+        securityController.allow(RestRequest.Method.POST, String.format("/%s/%s/_search", UserEventService.INDEX, UserEventService.EVENT_TYPE));
+        securityController.allow(RestRequest.Method.GET, String.format("/%s/%s/_count", UserEventService.INDEX, UserEventService.EVENT_TYPE));
+        securityController.allow(RestRequest.Method.POST, String.format("/%s/%s/_count", UserEventService.INDEX, UserEventService.EVENT_TYPE));
+    }
+}
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/BlockchainUserEventService.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/BlockchainUserEventService.java
index 30a9d2ba..56674f08 100644
--- a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/BlockchainUserEventService.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/BlockchainUserEventService.java
@@ -204,14 +204,15 @@ public class BlockchainUserEventService extends AbstractService implements Chang
         Set<String> senders = ImmutableSet.copyOf(tx.getIssuers());
 
         // Received
-        String sendersString = joinPubkeys(senders, true);
+        String senderNames = getNamesFromPubkeys(senders, true);
+        String sendersPubkeys = joinPubkeys(senders, false);
         Set<String> receivers = new HashSet<>();
         for (String output : tx.getOutputs()) {
             String[] parts = output.split(":");
             if (parts.length >= 3 && parts[2].startsWith("SIG(")) {
                 String receiver = parts[2].substring(4, parts[2].length() - 1);
                 if (!senders.contains(receiver) && !receivers.contains(receiver)) {
-                    notifyUserEvent(block, receiver, UserEventCodes.TX_RECEIVED, I18n.n("duniter.user.event.tx.received"), sendersString);
+                    notifyUserEvent(block, receiver, UserEventCodes.TX_RECEIVED, I18n.n("duniter.user.event.tx.received"), senderNames, sendersPubkeys);
                     receivers.add(receiver);
                 }
             }
@@ -219,9 +220,10 @@ public class BlockchainUserEventService extends AbstractService implements Chang
 
         // Sent
         if (CollectionUtils.isNotEmpty(receivers)) {
-            String receiverStr = joinPubkeys(receivers, true);
+            String receiverNames = getNamesFromPubkeys(receivers, true);
+            String receiverPubkeys = joinPubkeys(receivers, false);
             for (String sender : senders) {
-                notifyUserEvent(block, sender, UserEventCodes.TX_SENT, I18n.n("duniter.user.event.tx.sent"), receiverStr);
+                notifyUserEvent(block, sender, UserEventCodes.TX_SENT, I18n.n("duniter.user.event.tx.sent"), receiverNames, receiverPubkeys);
             }
         }
 
@@ -247,7 +249,7 @@ public class BlockchainUserEventService extends AbstractService implements Chang
         userEventService.deleteEventsByReference(new UserEvent.Reference(change.getIndex(), change.getType(), change.getId()));
     }
 
-    private String joinPubkeys(Set<String> pubkeys, boolean minify) {
+    private String getNamesFromPubkeys(Set<String> pubkeys, boolean minify) {
         Preconditions.checkNotNull(pubkeys);
         Preconditions.checkArgument(pubkeys.size()>0);
         if (pubkeys.size() == 1) {
@@ -268,4 +270,21 @@ public class BlockchainUserEventService extends AbstractService implements Chang
 
         return sb.substring(DEFAULT_PUBKEYS_SEPARATOR.length());
     }
+
+    private String joinPubkeys(Set<String> pubkeys, boolean minify) {
+        Preconditions.checkNotNull(pubkeys);
+        Preconditions.checkArgument(pubkeys.size()>0);
+        if (pubkeys.size() == 1) {
+            String pubkey = pubkeys.iterator().next();
+            return (minify ? ModelUtils.minifyPubkey(pubkey) : pubkey);
+        }
+
+        StringBuilder sb = new StringBuilder();
+        pubkeys.stream().forEach((pubkey)-> {
+            sb.append(DEFAULT_PUBKEYS_SEPARATOR);
+            sb.append(minify ? ModelUtils.minifyPubkey(pubkey) : pubkey);
+        });
+
+        return sb.substring(DEFAULT_PUBKEYS_SEPARATOR.length());
+    }
 }
diff --git a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/SynchroService.java b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/SynchroService.java
index 155e9c56..263f0af0 100644
--- a/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/SynchroService.java
+++ b/duniter4j-es-user/src/main/java/org/duniter/elasticsearch/user/service/SynchroService.java
@@ -22,6 +22,7 @@ package org.duniter.elasticsearch.user.service;
  * #L%
  */
 
+import org.duniter.core.client.model.elasticsearch.Protocol;
 import org.duniter.core.client.model.local.Peer;
 import org.duniter.core.service.CryptoService;
 import org.duniter.elasticsearch.PluginSettings;
@@ -45,7 +46,7 @@ public class SynchroService extends AbstractSynchroService {
     public void synchronize() {
         logger.info("Synchronizing user data...");
 
-        Peer peer = getPeerFromAPI("ES API");
+        Peer peer = getPeerFromAPI(Protocol.ES_API);
         synchronize(peer);
     }
 
@@ -71,5 +72,6 @@ public class SynchroService extends AbstractSynchroService {
 
     protected void importMessageChanges(Peer peer, long sinceTime) {
         importChanges(peer, MessageService.INDEX, MessageService.RECORD_TYPE,  sinceTime);
+        importChanges(peer, MessageService.INDEX, MessageService.OUTBOX_TYPE,  sinceTime);
     }
 }
-- 
GitLab