🔀 Merge release branch for 0.14
[jSite.git] / src / main / java / de / todesbaum / jsite / application / WebOfTrustInterface.java
1 /*
2  * jSite - WebOfTrustInterface.java - Copyright Â© 2012–2019 David Roden
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  */
18
19 package de.todesbaum.jsite.application;
20
21 import static java.util.Collections.emptyList;
22
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.concurrent.atomic.AtomicLong;
27 import java.util.logging.Level;
28 import java.util.logging.Logger;
29
30 import net.pterodactylus.util.logging.Logging;
31 import de.todesbaum.util.freenet.fcp2.Client;
32 import de.todesbaum.util.freenet.fcp2.Connection;
33 import de.todesbaum.util.freenet.fcp2.FcpPluginMessage;
34 import de.todesbaum.util.freenet.fcp2.Message;
35 import de.todesbaum.util.freenet.fcp2.wot.DefaultOwnIdentity;
36 import de.todesbaum.util.freenet.fcp2.wot.OwnIdentity;
37
38 /**
39  * FCP interface to the node’s web of trust.
40  *
41  * @author David â€˜Bombe’ Roden <bombe@freenetproject.org>
42  */
43 public class WebOfTrustInterface {
44
45         /** The logger. */
46         private static final Logger logger = Logging.getLogger(WebOfTrustInterface.class);
47
48         /** Unique ID for the command identifier. */
49         private static final AtomicLong commandCounter = new AtomicLong(System.nanoTime());
50
51         /** The freenet interface. */
52         private final Freenet7Interface freenetInterface;
53
54         /**
55          * Creates a new web of trust interface.
56          *
57          * @param freenetInterface
58          *            The freenet interface
59          */
60         public WebOfTrustInterface(Freenet7Interface freenetInterface) {
61                 this.freenetInterface = freenetInterface;
62         }
63
64         //
65         // ACCESSORS
66         //
67
68         /**
69          * Returns a list of own identities. If the identities have not yet been
70          * retrieved, an empty list is returned.
71          *
72          * @return The list of own identities
73          */
74         public List<OwnIdentity> getOwnIdentities() {
75                 try {
76
77                         /* connect. */
78                         Connection connection = freenetInterface.getConnection("jSite-WoT-Connector");
79                         logger.log(Level.INFO, String.format("Trying to connect to node at %s...", freenetInterface.getNode()));
80                         if (!connection.connect()) {
81                                 logger.log(Level.WARNING, "Connection failed.");
82                                 return emptyList();
83                         }
84                         Client client = new Client(connection);
85
86                         /* send FCP command to WebOfTrust plugin. */
87                         sendFcpCommandToWotPlugin(client);
88
89                         /* read a message. */
90                         Message message = null;
91                         while (!client.isDisconnected() && (message == null)) {
92                                 message = client.readMessage(1000);
93                         }
94                         if (message == null) {
95                                 return emptyList();
96                         }
97
98                         /* evaluate message. */
99                         List<OwnIdentity> ownIdentities = parseOwnIdentitiesFromMessage(message);
100
101             /* disconnect. */
102                         logger.log(Level.INFO, "Disconnecting from Node.");
103                         connection.disconnect();
104                         return ownIdentities;
105                 } catch (IOException ioe1) {
106                         logger.log(Level.WARNING, String.format("Communication with node at %s failed.", freenetInterface.getNode()), ioe1);
107                         return emptyList();
108                 }
109         }
110
111         private void sendFcpCommandToWotPlugin(Client client) throws IOException {
112                 String messageIdentifier = "jSite-WoT-Command-" + commandCounter.getAndIncrement();
113                 FcpPluginMessage pluginMessage = new FcpPluginMessage(messageIdentifier);
114                 pluginMessage.setPluginName("plugins.WebOfTrust.WebOfTrust");
115                 pluginMessage.setParameter("Message", "GetOwnIdentities");
116                 client.execute(pluginMessage);
117         }
118
119         private List<OwnIdentity> parseOwnIdentitiesFromMessage(Message message) {
120                 List<OwnIdentity> ownIdentities = new ArrayList<OwnIdentity>();
121                 if (message.getName().equals("FCPPluginReply")) {
122                         logger.log(Level.FINE, "Got matching Reply from WebOfTrust.");
123                                 /* parse identities. */
124                         int identityCounter = -1;
125                         while (message.get("Replies.Identity" + ++identityCounter) != null) {
126                                 String id = message.get("Replies.Identity" + identityCounter);
127                                 String nickname = message.get("Replies.Nickname" + identityCounter);
128                                 String requestUri = shortenUri(message.get("Replies.RequestURI" + identityCounter));
129                                 String insertUri = shortenUri(message.get("Replies.InsertURI" + identityCounter));
130                                 DefaultOwnIdentity ownIdentity = new DefaultOwnIdentity(id, nickname, requestUri, insertUri);
131                                 logger.log(Level.FINE, String.format("Parsed Own Identity %s.", ownIdentity));
132                                 ownIdentities.add(ownIdentity);
133                         }
134                         logger.log(Level.INFO, String.format("Parsed %d Own Identities.", ownIdentities.size()));
135                 } else if ("ProtocolError".equals(message.getName())) {
136                         logger.log(Level.WARNING, "WebOfTrust Plugin not found!");
137                 } else if ("Error".equals(message.getName())) {
138                         logger.log(Level.WARNING, "WebOfTrust Plugin returned an error!");
139                 }
140                 return ownIdentities;
141         }
142
143         /**
144          * Returns the essential parts of an URI, consisting of only the
145          * private/public key, decryption key, and the flags.
146          *
147          * @param uri
148          *            The URI to shorten
149          * @return The shortened URI
150          */
151         private static String shortenUri(String uri) {
152                 String shortenedUri = uri;
153                 if (shortenedUri.charAt(3) == '@') {
154                         shortenedUri = shortenedUri.substring(4);
155                 }
156                 if (shortenedUri.indexOf('/') > -1) {
157                         shortenedUri = shortenedUri.substring(0, shortenedUri.indexOf('/'));
158                 }
159                 return shortenedUri;
160         }
161
162 }