Author: jflesch
Date: 2008-02-16 01:12:47 +0000 (Sat, 16 Feb 2008)
New Revision: 17968

Added:
   trunk/apps/Thaw/src/thaw/fcp/FCPMetaTransferQuery.java
   trunk/apps/Thaw/src/thaw/plugins/webOfTrust/WotIdentity.java
Modified:
   trunk/apps/Thaw/src/thaw/fcp/FCPClientGet.java
   trunk/apps/Thaw/src/thaw/fcp/FCPClientPut.java
   trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties
   trunk/apps/Thaw/src/thaw/i18n/thaw.properties
   trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties
   trunk/apps/Thaw/src/thaw/plugins/WebOfTrust.java
   trunk/apps/Thaw/src/thaw/plugins/signatures/Identity.java
   trunk/apps/Thaw/src/thaw/plugins/signatures/SigConfigTab.java
   trunk/apps/Thaw/src/thaw/plugins/signatures/TrustListParser.java
   trunk/apps/Thaw/src/thaw/plugins/webOfTrust/DatabaseManager.java
   trunk/apps/Thaw/src/thaw/plugins/webOfTrust/TrustListDownloader.java
   trunk/apps/Thaw/src/thaw/plugins/webOfTrust/TrustListUploader.java
Log:
WoT : can now download automatically trust lists from other users

Modified: trunk/apps/Thaw/src/thaw/fcp/FCPClientGet.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPClientGet.java      2008-02-16 00:48:13 UTC 
(rev 17967)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPClientGet.java      2008-02-16 01:12:47 UTC 
(rev 17968)
@@ -82,10 +82,10 @@
         *                       this file will be deleted on jvm exit)
         */
        protected FCPClientGet(final String id, final String key, final int 
priority,
-                           final int persistence, final boolean globalQueue,
-                           final String destinationDir, String status,
-                           final int maxRetries,
-                           final FCPQueueManager queueManager) {
+                                               final int persistence, final 
boolean globalQueue,
+                                               final String destinationDir, 
String status,
+                                               final int maxRetries,
+                                               final FCPQueueManager 
queueManager) {

                this(key, priority, persistence, globalQueue, maxRetries, 
destinationDir);


Modified: trunk/apps/Thaw/src/thaw/fcp/FCPClientPut.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPClientPut.java      2008-02-16 00:48:13 UTC 
(rev 17967)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPClientPut.java      2008-02-16 01:12:47 UTC 
(rev 17968)
@@ -558,7 +558,7 @@
                        return;
                }

-               if(o == queueManager.getQueryManager()) {
+               if (param != null && param instanceof FCPMessage) {
                        final FCPMessage msg = (FCPMessage)param;

                        if((msg == null)

Added: trunk/apps/Thaw/src/thaw/fcp/FCPMetaTransferQuery.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/FCPMetaTransferQuery.java                      
        (rev 0)
+++ trunk/apps/Thaw/src/thaw/fcp/FCPMetaTransferQuery.java      2008-02-16 
01:12:47 UTC (rev 17968)
@@ -0,0 +1,152 @@
+package thaw.fcp;
+
+import java.util.Iterator;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Hashtable;
+
+import thaw.core.Logger;
+
+/**
+ * This class is designed to handle a LOT of FCPTransferQuery
+ * without overloading the observer/observable model.
+ * FCPTransferQueries must be non-persistent !
+ * It's useful when you have a lot of ULPR to handle
+ * @author jflesch
+ */
+public class FCPMetaTransferQuery extends Observable implements Observer {
+
+       private final FCPQueueManager queueManager;
+       private final Hashtable idToQuery;
+       private final String idField;
+       
+       public FCPMetaTransferQuery(FCPQueueManager queueManager) {
+               this(queueManager, "Identifier");
+       }
+       
+       private FCPMetaTransferQuery(FCPQueueManager queueManager, String 
idField) {
+               this.queueManager = queueManager;
+               this.idToQuery = new Hashtable();
+               this.idField = idField;
+               
+               queueManager.getQueryManager().addObserver(this);
+       }
+       
+       private void add(String id, FCPTransferQuery query) {
+               idToQuery.put(id, query);
+       }
+
+       /***
+        * Will call query.start() itself
+        * @param query
+        * @return
+        */
+       public boolean start(FCPTransferQuery query) {
+               if (query == null)
+                       return false;
+               
+               /* safety check */
+               if (query.isPersistent()) {
+                       Logger.error(this, "A persistent query was given to 
FCPMetaTransferQuery ! this should never happen !");
+                       try {
+                               throw new Exception("meh");
+                       } catch(Exception e) {
+                               e.printStackTrace();
+                       }
+
+                       return false;
+               }
+               
+               /* safety check */
+               if (!(query instanceof Observer)) {
+                       Logger.error(this, "A non-observer query 
("+query.getClass().getName()+") was given to FCPMetaTransferQuery ! this 
should never happen !");
+                       try {
+                               throw new Exception("meh");
+                       } catch(Exception e) {
+                               e.printStackTrace();
+                       }
+
+                       return false;
+               }
+               
+               /* here we start for real */
+               boolean r = query.start(queueManager);
+               
+               if (r) {
+                       /* Ugly hack to replace the query manager by the 
metaTransferQuery */
+                       add(query.getIdentifier(), query);
+                       query.addObserver(this);
+                       
queueManager.getQueryManager().deleteObserver((Observer)query);
+               }
+               
+               return r;
+       }
+       
+       private void remove(String id) {
+               idToQuery.remove(id);
+       }
+       
+       /**
+        * Will call query.stop() itself
+        * Can't work atm on non-persistent requests .... (node r1111)
+        * @param query
+        * @return
+        */
+       public boolean stop(FCPTransferQuery query) {
+               
+               query.deleteObserver(this);
+               
+               boolean r = true;
+               
+               if (!query.isFinished())
+                       r = query.stop(queueManager);
+               
+               if (r) {
+                       remove(query.getIdentifier());
+               } else {
+                       query.addObserver(this);
+               }
+               
+               return r;
+       }
+
+
+       public void stopAll() {
+               for (Iterator it = idToQuery.values().iterator(); it.hasNext() 
; ) {
+                       
+                       FCPTransferQuery query = (FCPTransferQuery)it.next();
+                       stop(query);
+                       
+               }
+       }
+
+
+       public void update(Observable o, Object param) {
+               if (o instanceof FCPQueryManager) {
+                       
+                       FCPMessage msg = (FCPMessage)param;
+                       String targetId;
+                       
+                       if (msg != null && (targetId = msg.getValue(idField)) 
!= null) {
+                               Observer obs = 
(Observer)(idToQuery.get(targetId));
+                               
+                               if (obs != null) {
+                                       /* we redirect only to the target 
FCPTransferQuery */
+                                       obs.update(o, param);
+                               }
+                       }
+                       
+               } if (o instanceof FCPTransferQuery) {
+                       FCPTransferQuery q = (FCPTransferQuery)o;
+
+                       if (q.isFinished()) {
+                               q.deleteObserver(this);
+                               remove(q.getIdentifier());
+                       }
+
+                       setChanged();
+                       notifyObservers(o);
+               }
+       }
+       
+}

Modified: trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties     2008-02-16 
00:48:13 UTC (rev 17967)
+++ trunk/apps/Thaw/src/thaw/i18n/source.thaw_fr.properties     2008-02-16 
01:12:47 UTC (rev 17968)
@@ -262,7 +262,7 @@
 ## About
 thaw.about.title=? propos
 thaw.about.l02=par Jerome Flesch
-thaw.about.l03=2006-2007(c) Freenet Project Incorporated
+thaw.about.l03=2006-2008(c) Freenet Project Incorporated
 thaw.about.l04=sous GPLv3 ( http://www.fsf.org/licensing/licenses/gpl.html )
 thaw.about.l06=Les principaux composants de Thaw sont:
 thaw.about.l07=- Le jeu d'icones "Tango" ( http://tango.freedesktop.org/ ; CC 
attribution share-alike )

Modified: trunk/apps/Thaw/src/thaw/i18n/thaw.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw.properties       2008-02-16 00:48:13 UTC 
(rev 17967)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw.properties       2008-02-16 01:12:47 UTC 
(rev 17968)
@@ -258,7 +258,7 @@
 ## About
 thaw.about.title=About
 thaw.about.l02=by Jerome Flesch
-thaw.about.l03=2006-2007(c) Freenet Project Incorporated
+thaw.about.l03=2006-2008(c) Freenet Project Incorporated

 thaw.about.l04=under GPLv3 or higher ( 
http://www.fsf.org/licensing/licenses/gpl.html )


Modified: trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties    2008-02-16 00:48:13 UTC 
(rev 17967)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties    2008-02-16 01:12:47 UTC 
(rev 17968)
@@ -262,7 +262,7 @@
 ## About
 thaw.about.title=\u00c0 propos
 thaw.about.l02=par Jerome Flesch
-thaw.about.l03=2006-2007(c) Freenet Project Incorporated
+thaw.about.l03=2006-2008(c) Freenet Project Incorporated
 thaw.about.l04=sous GPLv3 ( http://www.fsf.org/licensing/licenses/gpl.html )
 thaw.about.l06=Les principaux composants de Thaw sont:
 thaw.about.l07=- Le jeu d'icones "Tango" ( http://tango.freedesktop.org/ ; CC 
attribution share-alike )

Modified: trunk/apps/Thaw/src/thaw/plugins/WebOfTrust.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/WebOfTrust.java    2008-02-16 00:48:13 UTC 
(rev 17967)
+++ trunk/apps/Thaw/src/thaw/plugins/WebOfTrust.java    2008-02-16 01:12:47 UTC 
(rev 17968)
@@ -15,8 +15,6 @@
 import thaw.plugins.webOfTrust.*;

 public class WebOfTrust extends thaw.core.LibraryPlugin {
-       public final static long UPLOAD_AFTER_MS = 30*60*1000; /* 30 min */ 
-       
        private Core core;
        private Hsqldb db;
        private Signatures sigs;
@@ -165,6 +163,8 @@
                if (!loadDeps(core))
                        return false;

+               DatabaseManager.init(db, core.getConfig(), 
core.getSplashScreen());
+               
                configTab = new WebOfTrustConfigTab(core.getConfigWindow(),
                                                                                
        core.getConfig(), db);

@@ -172,7 +172,9 @@
                              thaw.gui.IconBox.minTrust,
                              configTab.getPanel());

-               initThread();
+               if (core.getConfig().getValue("wotActivated") == null
+                               || 
Boolean.valueOf(core.getConfig().getValue("wotActivated")).booleanValue())
+                               initThread();

                return true;
        }
@@ -198,18 +200,21 @@


        public void addTrustList(Identity identity, String publicKey, 
java.util.Date dateOfTheKey) {
+               if (identity.getPrivateKey() != null)
+                       return;
+               
                Logger.info(this, "Adding key to the WoT ...");

                try {
                        synchronized(db.dbLock) {
-                               PreparedStatement st = 
db.getConnection().prepareStatement("SELECT id, date FROM wotKeys WHERE 
publicKey = ? OR sigId = ? LIMIT 1");
+                               PreparedStatement st = 
db.getConnection().prepareStatement("SELECT id, keyDate FROM wotKeys WHERE 
publicKey = ? OR sigId = ? LIMIT 1");
                                st.setString(1, publicKey);
                                st.setInt(2, identity.getId());

                                ResultSet set = st.executeQuery();

                                if (set.next()) {
-                                       Timestamp date = 
set.getTimestamp("date");
+                                       Timestamp date = 
set.getTimestamp("keyDate");
                                        int id = set.getInt("id");

                                        if (date.getTime() >= 
dateOfTheKey.getTime()) {
@@ -217,26 +222,27 @@
                                                return;
                                        }

-                                       PreparedStatement up = 
db.getConnection().prepareStatement("UPDATE wotKeys SET publicKey = ?, date = ? 
WHERE id = ?");
+                                       PreparedStatement up = 
db.getConnection().prepareStatement("UPDATE wotKeys SET publicKey = ?, keyDate 
= ?, lastUpdate = ? WHERE id = ?");
                                        up.setString(1, publicKey);
                                        up.setTimestamp(2, new 
java.sql.Timestamp(dateOfTheKey.getTime()));
-                                       up.setInt(3, id);
+                                       up.setNull(3, Types.TIMESTAMP);
+                                       up.setInt(4, id);
                                        up.execute();
                                }
                                else
                                {
-                                       PreparedStatement in = 
db.getConnection().prepareStatement("INSERT INTO wotKeys (publicKey, date, 
score, sigId) VALUES (?, ?, 0, ?)");
+                                       PreparedStatement in = 
db.getConnection().prepareStatement("INSERT INTO wotKeys (publicKey, keyDate, 
score, sigId) VALUES (?, ?, 0, ?)");
                                        in.setString(1, publicKey);
                                        in.setTimestamp(2, new 
java.sql.Timestamp(dateOfTheKey.getTime()));
                                        in.setInt(3, identity.getId());
                                        in.execute();
-                                       
-                                       /* TODO : the newly added identity may 
have a good mark from the WoT, so it would be interresting to refresh it 
immediatly */
                                }
                        }
                } catch(SQLException e) {
                        Logger.error(this, "Error while adding a key to the 
list of trust list");
                }
+               
+               trustListDownloader.startULPR(publicKey, identity);
        }

        public void stop() {

Modified: trunk/apps/Thaw/src/thaw/plugins/signatures/Identity.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/signatures/Identity.java   2008-02-16 
00:48:13 UTC (rev 17967)
+++ trunk/apps/Thaw/src/thaw/plugins/signatures/Identity.java   2008-02-16 
01:12:47 UTC (rev 17968)
@@ -90,8 +90,7 @@
        private static FrostCrypt frostCrypt;


-       private Identity() {
-       }
+       protected Identity() { }


        /**
@@ -129,6 +128,10 @@
        protected void setDb(Hsqldb db) {
                this.db = db;
        }
+       
+       public Hsqldb getDb() {
+               return db;
+       }

        protected void setId(int id) {
                this.id = id;
@@ -176,7 +179,7 @@
                        return 
I18n.getMessage("thaw.plugin.signature.trustLevel.me");
                }

-               return getTrustLevelStr(trustLevel);
+               return getTrustLevelStr(getTrustLevel());
        }

        public static String getTrustLevelStr(int trustLevel) {
@@ -309,6 +312,9 @@
                                           String nick,
                                           String publicKey,
                                           boolean create) {
+               if (nick == null || publicKey == null)
+                       return null;
+               
                try {
                        synchronized(db.dbLock) {
                                PreparedStatement st;

Modified: trunk/apps/Thaw/src/thaw/plugins/signatures/SigConfigTab.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/signatures/SigConfigTab.java       
2008-02-16 00:48:13 UTC (rev 17967)
+++ trunk/apps/Thaw/src/thaw/plugins/signatures/SigConfigTab.java       
2008-02-16 01:12:47 UTC (rev 17968)
@@ -639,6 +639,10 @@
                        Identity id = Identity.getIdentity(db, 
importedId.getNick(), importedId.getPublicKey(), true /* create if doesn't 
exist */);
                        id.setTrustLevel(importedId.getTrustLevel());
                }
+
+               public void start() { }
+
+               public void end() { }
        }



Modified: trunk/apps/Thaw/src/thaw/plugins/signatures/TrustListParser.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/signatures/TrustListParser.java    
2008-02-16 00:48:13 UTC (rev 17967)
+++ trunk/apps/Thaw/src/thaw/plugins/signatures/TrustListParser.java    
2008-02-16 01:12:47 UTC (rev 17968)
@@ -150,12 +150,16 @@
        /*********************** IMPORT 
****************************************/

        public static interface TrustListContainer {
+               public void start();
+               
                /**
                 * Identity is used here just as a container.
                 * no ref to the db was provided to these identity
                 * @param i
                 */
                public void updateIdentity(Identity i);
+               
+               public void end();
        }


@@ -167,10 +171,17 @@
                private TrustListContainer container;

                public TrustListHandler(TrustListContainer container) {
+                       setTrustListContainer(container);
+               }
+               
+               protected void setTrustListContainer(TrustListContainer 
container) {
                        this.container = container;
                }

-               public void startDocument() throws SAXException {       }
+               public void startDocument() throws SAXException {
+                       if (container != null)
+                               container.start();
+               }

                private boolean nickTag = false;
                private boolean publicKeyTag = false;
@@ -220,7 +231,7 @@
                                return;

                        if ("identity".equals(rawName)) {
-                               if (nick != null && publicKey != null && 
trustLevel != null) {
+                               if (nick != null && publicKey != null && 
trustLevel != null && container != null) {
                                        Identity i = new Identity(null, -1, 
nick, publicKey, null, false, Integer.parseInt(trustLevel)/10);
                                        container.updateIdentity(i);
                                }
@@ -246,7 +257,8 @@
                }

                public void endDocument() throws SAXException {
-
+                       if (container != null)
+                               container.end();
                }
        }


Modified: trunk/apps/Thaw/src/thaw/plugins/webOfTrust/DatabaseManager.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/webOfTrust/DatabaseManager.java    
2008-02-16 00:48:13 UTC (rev 17967)
+++ trunk/apps/Thaw/src/thaw/plugins/webOfTrust/DatabaseManager.java    
2008-02-16 01:12:47 UTC (rev 17968)
@@ -35,11 +35,22 @@
                sendQuery(db, "CREATE CACHED TABLE wotKeys ("
                                + "id INTEGER IDENTITY NOT NULL, "
                                + "publicKey VARCHAR(400) NOT NULL, "
-                               + "date TIMESTAMP NOT NULL, "
+                               + "keyDate TIMESTAMP NOT NULL, "
                                + "score SMALLINT NOT NULL, "
                                + "sigId INTEGER NOT NULL, "
+                               + "lastDownload TIMESTAMP DEFAULT NULL NULL, "
+                               + "lastUpdate TIMESTAMP DEFAULT NULL NULL, "
                                + "PRIMARY KEY(id), "
                                + "FOREIGN KEY(sigId) REFERENCES signatures 
(id))");
+               
+               sendQuery(db, "CREATE CACHED TABLE wotTrustLists ("
+                               + "id INTEGER IDENTITY NOT NULL, "
+                               + "source INTEGER NOT NULL, "
+                               + "destination INTEGER NOT NULL, "
+                               + "trustLevel SMALLINT NOT NULL, "
+                               + "PRIMARY KEY(id), "
+                               + "FOREIGN KEY(source) REFERENCES signatures 
(id), "
+                               + "FOREIGN KEY(destination) REFERENCES 
signatures(id))");
        }

        /**

Modified: trunk/apps/Thaw/src/thaw/plugins/webOfTrust/TrustListDownloader.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/webOfTrust/TrustListDownloader.java        
2008-02-16 00:48:13 UTC (rev 17967)
+++ trunk/apps/Thaw/src/thaw/plugins/webOfTrust/TrustListDownloader.java        
2008-02-16 01:12:47 UTC (rev 17968)
@@ -1,32 +1,199 @@
 package thaw.plugins.webOfTrust;

+import java.util.Hashtable;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Date;

+import java.io.File;
+import java.sql.*;
+
 import thaw.core.Config;
+import thaw.core.Logger;

 import thaw.fcp.FCPQueueManager;
+import thaw.fcp.FCPClientGet;
+import thaw.fcp.FCPMetaTransferQuery;
+import thaw.fcp.FreenetURIHelper;
 import thaw.plugins.Hsqldb;
+import thaw.plugins.signatures.Identity;
+import thaw.plugins.Signatures;

+/**
+ * Will start ULPR on all the non-obsolete keys (I think I know what I'm doing)
+ * and do also active polling
+ * @author jflesch
+ */
+public class TrustListDownloader implements Observer, 
Signatures.SignaturesObserver {
+       public final static long KEY_OBSOLETE_AFTER = 2 /* week */ *7 /* days 
*/ * 24 /* hour */ * 60 /*min */ * 60 /* sec */ * 1000 /* ms */;
+       public final static int CLIENTGET_PRIORITY = 2;
+       public final static int MAX_SIZE = 102400; /* 100 KB */
+       public final static int MIN_TRUSTLEVEL = 0;

-public class TrustListDownloader {
-       private final FCPQueueManager queueManager;
-       private final Config config;
        private final Hsqldb db;

+       private final FCPMetaTransferQuery metaQuery;
+       private Hashtable ulprs;
+       
        public TrustListDownloader(Hsqldb db, FCPQueueManager queueManager, 
Config config) {
-               this.queueManager = queueManager;
-               this.config = config;
                this.db = db;
+               this.metaQuery = new FCPMetaTransferQuery(queueManager);
+               ulprs = new Hashtable();
+               
+               metaQuery.addObserver(this);
+               
+               Signatures.addObserver(this);
        }

-       public void init() {
+       public boolean startULPR(String key, Identity identity) {
+               WotIdentity id = new WotIdentity(identity);

+               int tl = id.getTrustLevel();
+               
+               if (tl <= MIN_TRUSTLEVEL || tl == Identity.trustLevelInt[0] /* 
dev */)
+                       return false;
+               
+               Logger.notice(this, "Starting ULPR for the identity : 
'"+identity.toString()+"'");
+               
+               if (ulprs.get(FreenetURIHelper.getComparablePart(key)) != null) 
{
+                       Logger.notice(this, "An ulpr is already running for 
this key");
+                       return false;
+               }
+
+               
+               if (id.currentTrustListHasAlreadyBeenDownloaded()) {
+                       /* increment the revision of one */
+                       key = FreenetURIHelper.changeUSKRevision(key, 0, 1);
+               }
+               
+               FCPClientGet get = new FCPClientGet(key,
+                                               CLIENTGET_PRIORITY, /* <= 
priority */
+                                               
FCPClientGet.PERSISTENCE_UNTIL_DISCONNECT,
+                                               false, /* <= globalQueue */
+                                               -1, /* maxRetries => -1 => ULPR 
*/
+                                               
System.getProperty("java.io.tmpdir"), /* destination directory */
+                                               MAX_SIZE, /* max size */
+                                               true /* <= noDDA */);
+               ulprs.put(FreenetURIHelper.getComparablePart(key), get);
+               metaQuery.start(get);
+               
+               return true;
        }

+       public boolean stopULPR(String key) {
+               FCPClientGet get = 
(FCPClientGet)ulprs.get(FreenetURIHelper.getComparablePart(key));
+               metaQuery.stop(get);            
+               ulprs.remove(FreenetURIHelper.getComparablePart(key));
+               
+               return true;
+       }
+       
+       
+       
+       public void init() {
+               synchronized(db.dbLock) {
+                       try {
+                               PreparedStatement st;
+                               /* select all the non-obsolete keys */
+                               st = 
db.getConnection().prepareStatement("SELECT publicKey, sigId FROM wotKeys WHERE 
keyDate IS NULL OR keyDate >= ?");
+                               
+                               st.setTimestamp(1, new java.sql.Timestamp(new 
Date().getTime() - KEY_OBSOLETE_AFTER));
+                               
+                               ResultSet set = st.executeQuery();
+                               
+                               while(set.next()) {
+                                       String key = set.getString("publicKey");
+                                       int sigId = set.getInt("sigId");
+                                       String filename = 
FreenetURIHelper.getFilenameFromKey(key);
+                                       
+                                       if (filename == null || 
"".equals(filename.trim())) {
+                                               if (!key.endsWith("/"))
+                                                       key += "/";
+                                               key += "trustList.xml";
+                                       }
+                                       
+                                       Identity id = Identity.getIdentity(db, 
sigId);
+                                       
+                                       startULPR(key, id);
+                               }
+                               
+                       } catch(SQLException e) {
+                               Logger.error(this, "Error while starting ULPRs 
: "+e.toString());
+                               e.printStackTrace();
+                       }
+               }
+       }
+       
        public synchronized void process() {

        }

        public void stop() {
+               metaQuery.stopAll();
+               ulprs = new Hashtable();
+       }
+       
+       public synchronized void update(Observable o, Object param) {
+               if (o == metaQuery && param instanceof FCPClientGet) {
+                       FCPClientGet q = (FCPClientGet)param;
+                       
+                       if (q.isFinished() && q.isSuccessful()) {               
+                               /* the meta query already forgot this query, so 
we don't have to care of this point */
+                               File f = new File(q.getPath());
+
+                               WotIdentity expectedIdentity = 
WotIdentity.getIdentity(db, q.getFileKey());
+                               
+                               if (expectedIdentity == null) {
+                                       Logger.notice(this, "can't find the 
identity corresponding to the wot key ... :'(");
+                                       f.delete();
+                                       return;
+                               }
+                               
+                               stopULPR(q.getFileKey());
+                               
+                               if (expectedIdentity.getTrustLevel() > 0 /* 
trust level may have changed during the download */
+                                       && 
expectedIdentity.doSecurityChecks(f)) {
+
+                                       Logger.notice(this, "Parsing trust list 
of '"+expectedIdentity.toString()+"'");
+                                       if (expectedIdentity.loadTrustList(f)) {
+
+                                               
expectedIdentity.updateInfos(q.getFileKey(), new java.util.Date());
+                                               
+                                               startULPR(q.getFileKey(), 
expectedIdentity);
+                                               
+                                       }
+                               }
+                               
+                               f.delete();
+                       }
+               }
+       }
+
+       public void identityUpdated(Identity i) {
+               if (i.getTrustLevel() < 0) {
+                       /* someone has been marked as BAD */
+                       WotIdentity id = new WotIdentity(i);
+                       String key;
+
+                       if ( (key = id.getWoTPublicKey()) != null) {
+                               id.purgeTrustList();
+                               stopULPR(key);
+                       }
+               } else if (i.getTrustLevel() > 0) {
+                       WotIdentity id = new WotIdentity(i);
+                       String key;
+                       if ( (key = id.getWoTPublicKey()) != null) {
+                               startULPR(key, id);
+                       }
+               }
+       }
+
+       public void privateIdentityAdded(Identity i) {

        }
+
+       public void publicIdentityAdded(Identity i) {
+               
+       }
+
 }

Modified: trunk/apps/Thaw/src/thaw/plugins/webOfTrust/TrustListUploader.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/webOfTrust/TrustListUploader.java  
2008-02-16 00:48:13 UTC (rev 17967)
+++ trunk/apps/Thaw/src/thaw/plugins/webOfTrust/TrustListUploader.java  
2008-02-16 01:12:47 UTC (rev 17968)
@@ -2,7 +2,6 @@

 import thaw.plugins.Hsqldb;
 import thaw.plugins.Signatures;
-import thaw.plugins.WebOfTrust;
 import thaw.plugins.signatures.Identity;
 import thaw.plugins.signatures.TrustListParser;

@@ -34,6 +33,8 @@
 import org.w3c.dom.Element;

 public class TrustListUploader implements Signatures.SignaturesObserver, 
Observer {
+       public final static long UPLOAD_AFTER_MS = 10*60*1000; /* 10 min */ 
+
        private final FCPQueueManager queueManager;
        private final Config config;
        private final Hsqldb db;
@@ -125,7 +126,7 @@
                if (lastUpload.compareTo(lastTrustChange) < 0) {

                        /* last change was done more than UPLOAD_AFTER_MS ms 
(for example 30min) */
-                       if (new Date().getTime() - lastTrustChange.getTime() >= 
WebOfTrust.UPLOAD_AFTER_MS)
+                       if (new Date().getTime() - lastTrustChange.getTime() >= 
UPLOAD_AFTER_MS)
                                return true;

                }
@@ -250,7 +251,7 @@

                if (mustUpload() && hasSomethingToUpload()) {

-                       Logger.notice(this, "Uploading your trust list ...");
+                       Logger.notice(this, "MARK : Uploading your trust list 
...");

                        try {
                                File file = File.createTempFile("thaw-", 
"-trustList.xml");
@@ -327,6 +328,7 @@

                                upload.deleteObserver(this);

+                               upload.stop(queueManager);
                                queueManager.remove(upload);

                                if (upload.isSuccessful()) {

Added: trunk/apps/Thaw/src/thaw/plugins/webOfTrust/WotIdentity.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/webOfTrust/WotIdentity.java                
                (rev 0)
+++ trunk/apps/Thaw/src/thaw/plugins/webOfTrust/WotIdentity.java        
2008-02-16 01:12:47 UTC (rev 17968)
@@ -0,0 +1,294 @@
+package thaw.plugins.webOfTrust;
+
+import thaw.core.Logger;
+import thaw.fcp.FreenetURIHelper;
+import thaw.plugins.Hsqldb;
+import thaw.plugins.signatures.*;
+
+import java.io.File;
+import java.sql.*;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public class WotIdentity extends Identity implements 
TrustListParser.TrustListContainer {
+       protected WotIdentity() { }
+       
+       protected WotIdentity(Identity i) {
+               super(i.getDb(), i.getId(), i.getNick(), i.getPublicKey(), 
i.getPrivateKey(), i.isDup(), i.getTrustLevel());
+       }
+       
+       public int getTrustLevel() {
+               int t;
+
+               if ( (t = getUserTrustLevel()) != 0)
+                       return t;
+               
+               return getWotTrustLevel();
+       }
+       
+       public int getWotTrustLevel() {
+               /* TODO */
+               return 0;
+       }
+       
+       public int getUserTrustLevel() {
+               return super.getTrustLevel();
+       }
+       
+       /**
+        * @return true if lastUpdate in the db is == NULL
+        */
+       public boolean currentTrustListHasAlreadyBeenDownloaded() {
+               try {
+                       synchronized(getDb().dbLock) {
+                               PreparedStatement st = 
getDb().getConnection().prepareStatement("SELECT lastDownload FROM wotKeys 
WHERE sigId = ? LIMIT 1");
+                               st.setInt(1, getId());
+
+                               ResultSet set = st.executeQuery();
+                               
+                               if (set.next())
+                                       return 
(set.getTimestamp("lastDownload") != null);
+                       }
+               } catch(SQLException e) {
+                       Logger.error(this, "Error while checking if we already 
have the trust list of the identity '"+toString()+"'");
+                       e.printStackTrace();
+               }
+               
+               return false;
+       }
+       
+       /**
+        * @param db
+        * @return null if unknown
+        */
+       public static WotIdentity getIdentity(Hsqldb db, String wotPublicKey) {
+               try {
+                       synchronized(db.dbLock) {
+                               /* TODO : Optimize ! sluggard ! */
+                               PreparedStatement st = 
db.getConnection().prepareStatement("SELECT sigId FROM wotKeys WHERE 
LOWER(publicKey) LIKE ? LIMIT 1");
+                               st.setString(1, 
FreenetURIHelper.getComparablePart(wotPublicKey)+"%");
+                               
+                               ResultSet set = st.executeQuery();
+
+                               if (!set.next())
+                                       return null;
+                               
+                               return new WotIdentity(Identity.getIdentity(db, 
set.getInt("sigId")));
+                       }
+               } catch(SQLException e) {
+                       Logger.error(new WotIdentity(), "Error while getting 
the identity corresponding to a wot public key: "+e.toString());
+                       e.printStackTrace();
+               }
+               
+               return null;
+       }
+       
+       /**
+        * TODO : Check and update uploadDate
+        * @author jflesch
+        */
+       protected class TrustListSecurityHandler extends 
TrustListParser.TrustListHandler implements TrustListParser.TrustListContainer {
+               private TrustListSecurityHandler() {
+                       super(null /* java doesn't accept 'this' as argument 
here */);
+                       setTrustListContainer(this);
+               }
+               
+               private boolean trustListOwnerTag = false;
+               private boolean nickTag = false;
+               private boolean publicKeyTag = false;
+               
+               private String nick = null;
+               private String publicKey = null;
+               
+               public void startElement(String nameSpaceURI, String localName,
+                                                               String rawName, 
Attributes attrs) throws SAXException {
+                       if (rawName == null) {
+                               rawName = localName;
+                       }
+
+                       if (rawName == null)
+                               return;
+                       
+                       if ("trustListOwner".equals(rawName)) {
+                               trustListOwnerTag = true;
+                       } else if (trustListOwnerTag && "nick".equals(rawName)) 
{
+                               nickTag = true;
+                       } else if (trustListOwnerTag && 
"publicKey".equals(rawName)) {
+                               publicKeyTag = true;
+                       } else
+                               super.startElement(nameSpaceURI, localName, 
rawName, attrs);                    
+               }
+               
+               public void characters(char[] ch, int start, int end) throws 
SAXException {
+                       String txt = new String(ch, start, end);
+                       
+                       if (trustListOwnerTag && nickTag)
+                               nick = txt;
+                       else if (trustListOwnerTag && publicKeyTag)
+                               publicKey = txt;
+                       else
+                               super.characters(ch, start, end);
+               }               
+               
+               public void endElement(String nameSpaceURI, String localName,
+                                                               String rawName) 
throws SAXException {
+                       if (rawName == null) {
+                               rawName = localName;
+                       }
+
+                       if (rawName == null)
+                               return;
+                       
+                       if ("trustListOwner".equals(rawName)) {
+                               trustListOwnerTag = false;
+                       } else if (trustListOwnerTag && "nick".equals(rawName)) 
{
+                               nickTag = false;
+                       } else if (trustListOwnerTag && 
"publicKey".equals(rawName)) {
+                               publicKeyTag = false;
+                       } else
+                               super.endElement(nameSpaceURI, localName, 
rawName);
+               }
+               
+
+               public void updateIdentity(Identity i) {
+                       /* TODO : Check the signature of the trust list */
+               }
+               
+               public boolean trustListIsValid() {
+                       boolean hasExpectedOwner = false;
+                       
+                       hasExpectedOwner = (getNick().equals(nick)) && 
(getPublicKey().equals(publicKey));
+                       
+                       return hasExpectedOwner;
+               }
+
+               public void start() { }
+
+               public void end() { }
+       }       
+       
+       public boolean doSecurityChecks(File trustList) {
+               TrustListSecurityHandler handler = new 
TrustListSecurityHandler();
+               
+               
TrustListParser.importTrustList((TrustListParser.TrustListHandler)handler, 
trustList);
+
+               return handler.trustListIsValid();
+       }
+
+       public boolean loadTrustList(File trustList) {
+               try {
+                       TrustListParser.importTrustList(this, trustList);
+               } catch(Exception e) {
+                       Logger.error(this, "Exception while parsing the trust 
list of '"+toString()+"' : '"+e.toString()+"' => trust list ignored");
+                       purgeTrustList();
+                       return false;
+               }
+               return true;
+       }
+       
+       public void start() {
+               purgeTrustList();
+       }
+
+       public void purgeTrustList() {
+               try {
+                       synchronized(getDb().dbLock) {
+                               PreparedStatement st;
+                               
+                               st = 
getDb().getConnection().prepareStatement("DELETE FROM wotTrustLists WHERE 
source = ?");
+                               st.setInt(1, getId());
+                               st.execute();
+                       }
+               } catch(SQLException e) {
+                       Logger.error(this, "Error while updating a trust list 
in the db (1) : "+e.toString());
+                       e.printStackTrace();
+               }
+       }
+
+       public void end() {
+               /* \_o< */
+       }
+       
+       private PreparedStatement insertTrustLinkSt = null;
+
+       public void updateIdentity(Identity i) {
+               try {
+                       if (insertTrustLinkSt == null)
+                               insertTrustLinkSt = 
getDb().getConnection().prepareStatement("INSERT INTO wotTrustLists (source, 
destination, trustLevel) VALUES (?, ?, ?)");
+               } catch(SQLException e) {
+                       Logger.error(this, "Error while updating a trust list 
in the db (3) : "+e.toString());
+                       return;
+               }
+               
+               if (i.getTrustLevel() == 0 
+                       || i.getTrustLevel() < 
Identity.trustLevelInt[Identity.trustLevelInt.length-1]
+                       || i.getTrustLevel() > Identity.trustLevelInt[1]) {
+                       Logger.error(this, "Invalid trust level in the trust 
list of '"+toString()+"' !");
+                       throw new RuntimeException("Invalid trust level in the 
trust list of '"+toString()+"' !");
+               }
+                       
+               
+               Identity target = Identity.getIdentity(getDb(), i.getNick(), 
i.getPublicKey());
+               
+               if (target == null) {
+                       Logger.notice(this, "Minor problem while parsing the 
trust list (1)");
+                       return;
+               }
+               
+               try {
+                       synchronized(getDb().dbLock) {
+                               insertTrustLinkSt.setInt(1, getId());
+                               insertTrustLinkSt.setInt(2, target.getId());
+                               insertTrustLinkSt.setInt(3, i.getTrustLevel());
+                               insertTrustLinkSt.execute();
+                       }
+               } catch(SQLException e) {
+                       Logger.error(this, "Error while updating a trust list 
in the db (2) : "+e.toString());
+                       e.printStackTrace();
+               }
+       }
+       
+       
+       public void updateInfos(String wotPublicKey, java.util.Date 
lastDownload) {
+               try {
+                       synchronized(getDb().dbLock) {
+                               PreparedStatement st;
+                               
+                               st = 
getDb().getConnection().prepareStatement("UPDATE wotKeys SET publicKey = ?, 
keyDate = ?, lastDownload = ? WHERE sigId = ?");
+                               st.setString(1, wotPublicKey);
+                               st.setTimestamp(2, new Timestamp(new 
java.util.Date().getTime()));
+                               st.setTimestamp(3, new 
Timestamp(lastDownload.getTime()));
+                               st.setInt(4, getId());
+                               
+                               st.execute();
+                       }
+               } catch(SQLException e) {
+                       Logger.error(this, "Error while updating infos in the 
wotKeys table : "+e.toString());
+                       e.printStackTrace();
+               }               
+       }
+       
+       public String getWoTPublicKey() {
+               try {
+                       synchronized(getDb().dbLock) {
+                               PreparedStatement st;
+                               
+                               st = 
getDb().getConnection().prepareStatement("SELECT publicKey FROM wotKeys WHERE 
sigId = ? LIMIT 1");
+                               
+                               st.setInt(1, getId());
+                               
+                               ResultSet set = st.executeQuery();
+                               
+                               if (!set.next())
+                                       return null;
+                               
+                               return set.getString("publicKey");
+                       }
+               } catch(SQLException e) {
+                       Logger.error(this, "Unable to check if an identity is 
in the WoT because : "+e.toString());
+               }
+               
+               return null;
+       }
+}


Reply via email to